From 7b04f5f07bc2e88cad86888389831892f12cd202 Mon Sep 17 00:00:00 2001 From: vitam Date: Tue, 25 Jul 2017 23:03:52 +0200 Subject: [PATCH 01/14] group file into folder in select file --- css/modals.css | 4 ++-- index.html | 42 +++++++++++++++++++++++++++++++----------- js/ctrls/modal.js | 17 +++++++++++++++++ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/css/modals.css b/css/modals.css index 9aedb6a1..f5740ae5 100644 --- a/css/modals.css +++ b/css/modals.css @@ -34,11 +34,11 @@ width: 80px; } -.selectFiles > div > .control-label { +.selectFiles div .control-label { font-weight: normal; margin-left: 30px; } -.selectFiles > div > .controls { +.selectFiles div .controls { margin-left: 30px; } diff --git a/index.html b/index.html index 18551bca..e7cca560 100644 --- a/index.html +++ b/index.html @@ -1028,6 +1028,36 @@

{{ 'Add Downloads By Metalinks' | translate }}

+ + + + @@ -1039,17 +1069,7 @@

{{ 'Choose files to start download for' | translate }}

diff --git a/js/ctrls/modal.js b/js/ctrls/modal.js index 3177c3de..7dc8c9c9 100644 --- a/js/ctrls/modal.js +++ b/js/ctrls/modal.js @@ -113,6 +113,23 @@ angular var self = this; this.files = _.cloneDeep(files); + var groupFile = function (files) { + var i, j, str, arr, folder = {}, tmp = folder; + for (i = 0; i < files.length; i++) { + str = files[i].relpath; + arr = str.split("/"); + for (j = 0; j < arr.length - 1; j++) { + if (!tmp[arr[j]]) { + tmp[arr[j]] = {}; + } + tmp = tmp[arr[j]]; + } + tmp[arr[arr.length - 1]] = files[i]; + tmp = folder; + } + return folder; + }; + this.groupedFiles = groupFile(this.files); this.inst = $modal.open({ templateUrl: "selectFiles.html", scope: scope, From 8af0a6dbcb5d527d006eff52a41446d85526c15a Mon Sep 17 00:00:00 2001 From: vitam Date: Thu, 27 Jul 2017 12:31:18 +0200 Subject: [PATCH 02/14] group file into folder in select file --- index.html | 44 ++++++++++++++------------ js/ctrls/modal.js | 61 +++++++++++++++++++++++++++++-------- js/directives/fileselect.js | 21 +++++++++++++ js/init.js | 2 +- 4 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 js/directives/fileselect.js diff --git a/index.html b/index.html index e7cca560..8214268b 100644 --- a/index.html +++ b/index.html @@ -23,7 +23,7 @@ - + @@ -41,6 +41,7 @@ + @@ -1032,30 +1033,33 @@

{{ 'Add Downloads By Metalinks' | translate }}

diff --git a/js/ctrls/modal.js b/js/ctrls/modal.js index 7dc8c9c9..9f0a7b78 100644 --- a/js/ctrls/modal.js +++ b/js/ctrls/modal.js @@ -113,23 +113,60 @@ angular var self = this; this.files = _.cloneDeep(files); - var groupFile = function (files) { - var i, j, str, arr, folder = {}, tmp = folder; - for (i = 0; i < files.length; i++) { - str = files[i].relpath; - arr = str.split("/"); - for (j = 0; j < arr.length - 1; j++) { - if (!tmp[arr[j]]) { - tmp[arr[j]] = {}; + var groupFiles = function (files) { + var createSubFolder = function () { + var folder = { + dirs : {}, + files : {}, + show : false, + _selected : false, + change : function () { + for (var file in this.files) { + if (this.files.hasOwnProperty(file)) { + this.files[file].selected = this.selected; + } + } + for (var folder in this.dirs) { + if (this.dirs.hasOwnProperty(folder)) { + this.dirs[folder].selected = this.selected; + } + } + console.log(this); } - tmp = tmp[arr[j]]; - } - tmp[arr[arr.length - 1]] = files[i]; + }; + Object.defineProperty(folder, "selected", { + get : function () { + return this._selected; + }, + set : function (newValue) { + this._selected = newValue; + this.change(); + } + }); + Object.defineProperty(folder, "indeterminate", { + get : function () { + return this._selected; + } + }); + return folder; + }; + var folder = createSubFolder(), + tmp; + for (var i = 0; i < files.length; i++) { tmp = folder; + var str = files[i].relpath; + var arr = str.split("/"); + for (var j = 0; j < arr.length - 1; j++) { + if (!tmp.dirs[arr[j]]) { + tmp.dirs[arr[j]] = createSubFolder(); + } + tmp = tmp.dirs[arr[j]]; + } + tmp.files[arr[arr.length - 1]] = files[i]; } return folder; }; - this.groupedFiles = groupFile(this.files); + this.groupedFiles = groupFiles(this.files); this.inst = $modal.open({ templateUrl: "selectFiles.html", scope: scope, diff --git a/js/directives/fileselect.js b/js/directives/fileselect.js new file mode 100644 index 00000000..d0d01c5d --- /dev/null +++ b/js/directives/fileselect.js @@ -0,0 +1,21 @@ +// watches changes in the file upload control (input[file]) and +// puts the files selected in an attribute +angular.module("webui.directives.fileselect", []).directive("indeterminate", function () { + return { + // Restrict the directive so it can only be used as an attribute + restrict : "A", + + link : function link (scope, elem, attr) { + // Whenever the bound value of the attribute changes we update + // the internal 'indeterminate' flag on the attached dom element + var watcher = scope.$watch(attr.indeterminate, function (value) { + elem[0].indeterminate = value; + }); + + // Remove the watcher when the directive is destroyed + scope.$on("$destroy", function () { + watcher(); + }); + } + }; +}); diff --git a/js/init.js b/js/init.js index 72fe0ff5..ce964e7f 100644 --- a/js/init.js +++ b/js/init.js @@ -4,7 +4,7 @@ var webui = angular.module('webui', [ 'webui.services.modals', 'webui.services.alerts', 'webui.services.settings', 'webui.services.settings.filters', 'webui.filters.bytes','webui.filters.url', - 'webui.directives.chunkbar', 'webui.directives.dgraph', 'webui.directives.fselect', + 'webui.directives.chunkbar', 'webui.directives.dgraph', 'webui.directives.fselect', "webui.directives.fileselect", 'webui.ctrls.download', 'webui.ctrls.nav', 'webui.ctrls.modal', 'webui.ctrls.alert', 'webui.ctrls.props', // external deps From 286cc301fe6618c33565d97593ca362ac6d8a725 Mon Sep 17 00:00:00 2001 From: vitam Date: Thu, 27 Jul 2017 22:31:33 +0200 Subject: [PATCH 03/14] change some code for better perfomance, support indeterminate --- index.html | 6 +-- js/ctrls/modal.js | 81 ++++++++++++++++++++----------------- js/directives/fileselect.js | 48 +++++++++++++++++++--- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/index.html b/index.html index 8214268b..6358a6f2 100644 --- a/index.html +++ b/index.html @@ -1031,7 +1031,7 @@

{{ 'Add Downloads By Metalinks' | translate }}

- + + + + + @@ -1039,17 +1069,7 @@

{{ 'Choose files to start download for' | translate }}

diff --git a/js/ctrls/modal.js b/js/ctrls/modal.js index 0387038b..8e28c341 100644 --- a/js/ctrls/modal.js +++ b/js/ctrls/modal.js @@ -123,6 +123,23 @@ angular var self = this; this.files = _.cloneDeep(files); + var groupFile = function (files) { + var i, j, str, arr, folder = {}, tmp = folder; + for (i = 0; i < files.length; i++) { + str = files[i].relpath; + arr = str.split("/"); + for (j = 0; j < arr.length - 1; j++) { + if (!tmp[arr[j]]) { + tmp[arr[j]] = {}; + } + tmp = tmp[arr[j]]; + } + tmp[arr[arr.length - 1]] = files[i]; + tmp = folder; + } + return folder; + }; + this.groupedFiles = groupFile(this.files); this.inst = $modal.open({ templateUrl: "selectFiles.html", scope: scope, From 2b6fe4b2bd6e7f00d41905ead6535431a09bdfa9 Mon Sep 17 00:00:00 2001 From: vitam Date: Thu, 27 Jul 2017 12:31:18 +0200 Subject: [PATCH 07/14] group file into folder in select file --- index.html | 44 ++++++++++++++------------ js/ctrls/modal.js | 61 +++++++++++++++++++++++++++++-------- js/directives/fileselect.js | 21 +++++++++++++ js/init.js | 2 +- 4 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 js/directives/fileselect.js diff --git a/index.html b/index.html index e7cca560..8214268b 100644 --- a/index.html +++ b/index.html @@ -23,7 +23,7 @@ - + @@ -41,6 +41,7 @@ + @@ -1032,30 +1033,33 @@

{{ 'Add Downloads By Metalinks' | translate }}

diff --git a/js/ctrls/modal.js b/js/ctrls/modal.js index 8e28c341..64af2042 100644 --- a/js/ctrls/modal.js +++ b/js/ctrls/modal.js @@ -123,23 +123,60 @@ angular var self = this; this.files = _.cloneDeep(files); - var groupFile = function (files) { - var i, j, str, arr, folder = {}, tmp = folder; - for (i = 0; i < files.length; i++) { - str = files[i].relpath; - arr = str.split("/"); - for (j = 0; j < arr.length - 1; j++) { - if (!tmp[arr[j]]) { - tmp[arr[j]] = {}; + var groupFiles = function (files) { + var createSubFolder = function () { + var folder = { + dirs : {}, + files : {}, + show : false, + _selected : false, + change : function () { + for (var file in this.files) { + if (this.files.hasOwnProperty(file)) { + this.files[file].selected = this.selected; + } + } + for (var folder in this.dirs) { + if (this.dirs.hasOwnProperty(folder)) { + this.dirs[folder].selected = this.selected; + } + } + console.log(this); } - tmp = tmp[arr[j]]; - } - tmp[arr[arr.length - 1]] = files[i]; + }; + Object.defineProperty(folder, "selected", { + get : function () { + return this._selected; + }, + set : function (newValue) { + this._selected = newValue; + this.change(); + } + }); + Object.defineProperty(folder, "indeterminate", { + get : function () { + return this._selected; + } + }); + return folder; + }; + var folder = createSubFolder(), + tmp; + for (var i = 0; i < files.length; i++) { tmp = folder; + var str = files[i].relpath; + var arr = str.split("/"); + for (var j = 0; j < arr.length - 1; j++) { + if (!tmp.dirs[arr[j]]) { + tmp.dirs[arr[j]] = createSubFolder(); + } + tmp = tmp.dirs[arr[j]]; + } + tmp.files[arr[arr.length - 1]] = files[i]; } return folder; }; - this.groupedFiles = groupFile(this.files); + this.groupedFiles = groupFiles(this.files); this.inst = $modal.open({ templateUrl: "selectFiles.html", scope: scope, diff --git a/js/directives/fileselect.js b/js/directives/fileselect.js new file mode 100644 index 00000000..d0d01c5d --- /dev/null +++ b/js/directives/fileselect.js @@ -0,0 +1,21 @@ +// watches changes in the file upload control (input[file]) and +// puts the files selected in an attribute +angular.module("webui.directives.fileselect", []).directive("indeterminate", function () { + return { + // Restrict the directive so it can only be used as an attribute + restrict : "A", + + link : function link (scope, elem, attr) { + // Whenever the bound value of the attribute changes we update + // the internal 'indeterminate' flag on the attached dom element + var watcher = scope.$watch(attr.indeterminate, function (value) { + elem[0].indeterminate = value; + }); + + // Remove the watcher when the directive is destroyed + scope.$on("$destroy", function () { + watcher(); + }); + } + }; +}); diff --git a/js/init.js b/js/init.js index 72fe0ff5..ce964e7f 100644 --- a/js/init.js +++ b/js/init.js @@ -4,7 +4,7 @@ var webui = angular.module('webui', [ 'webui.services.modals', 'webui.services.alerts', 'webui.services.settings', 'webui.services.settings.filters', 'webui.filters.bytes','webui.filters.url', - 'webui.directives.chunkbar', 'webui.directives.dgraph', 'webui.directives.fselect', + 'webui.directives.chunkbar', 'webui.directives.dgraph', 'webui.directives.fselect', "webui.directives.fileselect", 'webui.ctrls.download', 'webui.ctrls.nav', 'webui.ctrls.modal', 'webui.ctrls.alert', 'webui.ctrls.props', // external deps From caa1e940e2003c8b71328f494ee04f7aeadbc52e Mon Sep 17 00:00:00 2001 From: vitam Date: Thu, 27 Jul 2017 22:31:33 +0200 Subject: [PATCH 08/14] change some code for better perfomance, support indeterminate --- index.html | 6 +-- js/ctrls/modal.js | 81 ++++++++++++++++++++----------------- js/directives/fileselect.js | 48 +++++++++++++++++++--- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/index.html b/index.html index 8214268b..6358a6f2 100644 --- a/index.html +++ b/index.html @@ -1031,7 +1031,7 @@

{{ 'Add Downloads By Metalinks' | translate }}

- + - + diff --git a/js/directives/fileselect.js b/js/directives/fileselect.js index 67006916..d1f5f61c 100644 --- a/js/directives/fileselect.js +++ b/js/directives/fileselect.js @@ -12,8 +12,10 @@ app.directive("indeterminate", [ // Whenever the bound value of the attribute changes we update // use upward emit notification for change to prevent the performance penalty bring by $scope.$watch var getter = parse(attr["ngModel"]); - var setter = getter.assign; + // var setter = getter.assign; var children = []; // cache children input + var cacheSelectedSubInputNumber = 0; + var cacheNoSelectedSubInputNumber = 0; var get = function () { return getter(scope); }; @@ -21,18 +23,18 @@ app.directive("indeterminate", [ var setIndeterminateState = function (newValue) { elem.prop("indeterminate", newValue); }; - var setWithSideEffect = function (newVal) { + var setModelValueWithSideEffect = function (newVal) { // will cause to emit corresponding events ngModelCtrl.$setViewValue(newVal); ngModelCtrl.$render(); }; - var passIfLeafChild = function (callback) { // ensure to execute callback when this input have one or more subinputs + var passIfIsLeafChild = function (callback) { // ensure to execute callback only when this input has one or more subinputs return function () { if (children.length > 0) { callback.apply(this, arguments); } }; }; - var passIfNotIsLeafChild = function (callback) { // ensure to execute callback when this input havent subinput + var passIfNotIsLeafChild = function (callback) { // ensure to execute callback only when this input hasn't subinput return function () { if (children.length === 0) { callback.apply(this, arguments); @@ -46,19 +48,27 @@ app.directive("indeterminate", [ } }; }; + var catchEventOnlyOnce = function (callback) { // only fire once, and stop event's propagation + return function (event) { + callback.apply(this, arguments); + return event.stopPropagation(); + }; + }; + if (attr["indeterminate"] && parse(attr["indeterminate"]).constant) { + setIndeterminateState(scope.$eval(attr["indeterminate"])); // set to default value (set in template) + } if (attr["indeterminate"] && parse(attr["indeterminate"]).constant && !scope.$eval(attr["indeterminate"])) { - // is leaf input, Only receive parent change and emit child change event - setIndeterminateState(scope.$eval(attr["indeterminate"])); + // when this input wont have subinput, they will only receive parent change and emit child change event ngModelCtrl.$viewChangeListeners.push(passIfNotIsLeafChild(function () { - scope.$emit("childSelectedChange"); + scope.$emit("childSelectedChange", get()); })); - scope.$on("ParentSelectedChange", passThroughThisScope( + scope.$on("ParentSelectedChange", passThroughThisScope(passIfNotIsLeafChild( function (event, newVal) { - setWithSideEffect(newVal); // set value to parent's value; this will cause listener to emit childChange event; this won't be a infinite loop - })); + setModelValueWithSideEffect(newVal); // set value to parent's value; this will cause listener to emit childChange event; this won't be a infinite loop + }))); // init first time and only once scope.$emit("i'm child input", get); - scope.$emit("childSelectedChange"); // force emitted, and force the parent change their state base on children at first time + scope.$emit("childSelectedChange", get()); // force emitted, and force the parent change their state base on children at first time } else { // establish parent-child's relation // listen for the child emitted token @@ -67,25 +77,42 @@ app.directive("indeterminate", [ children.push(child); }) ); - var updateBaseOnChildrenState = function () { - var allSelected = children.every(function (child) { - return child(); - }); - var anySeleted = children.some(function (child) { - return child(); - }); + var updateBaseOnChildrenState = function (event, newChildValue) { + if ((cacheSelectedSubInputNumber + cacheNoSelectedSubInputNumber) !== children.length) { + cacheSelectedSubInputNumber = 0; + cacheNoSelectedSubInputNumber = 0; + for (var i = 0; i < children.length; i++) { + if (children[i]()) { + cacheSelectedSubInputNumber += 1; + } else { + cacheNoSelectedSubInputNumber += 1; + } + } + } else { + // no need for recalculated children state + // just make a few change to cache value + if (newChildValue) { + cacheSelectedSubInputNumber++; + cacheNoSelectedSubInputNumber--; + } else { + cacheSelectedSubInputNumber--; + cacheNoSelectedSubInputNumber++; + } + } + var allSelected = (cacheNoSelectedSubInputNumber === 0); + var anySeleted = (cacheSelectedSubInputNumber > 0); setIndeterminateState(allSelected !== anySeleted); // if at least one is selected, but not all then set input property indeterminate to true - setWithSideEffect(allSelected); + setModelValueWithSideEffect(allSelected); }; // is not leaf input, Only receive child change and parent change event - ngModelCtrl.$viewChangeListeners.push(passIfLeafChild(function () { + ngModelCtrl.$viewChangeListeners.push(passIfIsLeafChild(function () { // emit when property indeterminate is set to false, prevent recursively emitting event from parent to children, children to parent if (!elem.prop("indeterminate")) { scope.$broadcast("ParentSelectedChange", get()); } })); // reset input state base on children inputs - scope.$on("childSelectedChange", passThroughThisScope(passIfLeafChild(updateBaseOnChildrenState))); + scope.$on("childSelectedChange", passThroughThisScope(passIfIsLeafChild(updateBaseOnChildrenState))); } } }; From 2f4cb14b09cbaf587f3aa59e952cf9104f94913f Mon Sep 17 00:00:00 2001 From: vitam Date: Sat, 29 Jul 2017 21:59:14 +0200 Subject: [PATCH 12/14] modify css --- css/modals.css | 4 ++++ index.html | 4 ++-- js/directives/fileselect.js | 19 ++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/css/modals.css b/css/modals.css index f5740ae5..35488319 100644 --- a/css/modals.css +++ b/css/modals.css @@ -42,3 +42,7 @@ .selectFiles div .controls { margin-left: 30px; } + +.selectFiles div.recursivedir { + width: 100%; +} \ No newline at end of file diff --git a/index.html b/index.html index c58e77e8..4caa7af9 100644 --- a/index.html +++ b/index.html @@ -23,7 +23,7 @@ - + @@ -1044,7 +1044,7 @@

{{ 'Add Downloads By Metalinks' | translate }}

{{ 'click the text to expand the folder' | translate }} {{ 'click the text to collapse the folder' | translate }} -
+
diff --git a/js/directives/fileselect.js b/js/directives/fileselect.js index d1f5f61c..235fddb3 100644 --- a/js/directives/fileselect.js +++ b/js/directives/fileselect.js @@ -48,6 +48,13 @@ app.directive("indeterminate", [ } }; }; + var passIfIsIndeterminate = function (callback) { // pass through the event from the scope where they sent + return function () { + if (!elem.prop("indeterminate")) { + return callback.apply(this, arguments); + } + }; + }; var catchEventOnlyOnce = function (callback) { // only fire once, and stop event's propagation return function (event) { callback.apply(this, arguments); @@ -102,15 +109,13 @@ app.directive("indeterminate", [ var allSelected = (cacheNoSelectedSubInputNumber === 0); var anySeleted = (cacheSelectedSubInputNumber > 0); setIndeterminateState(allSelected !== anySeleted); // if at least one is selected, but not all then set input property indeterminate to true - setModelValueWithSideEffect(allSelected); + setModelValueWithSideEffect(allSelected); // change binding model value and trigger onchange event }; // is not leaf input, Only receive child change and parent change event - ngModelCtrl.$viewChangeListeners.push(passIfIsLeafChild(function () { - // emit when property indeterminate is set to false, prevent recursively emitting event from parent to children, children to parent - if (!elem.prop("indeterminate")) { - scope.$broadcast("ParentSelectedChange", get()); - } - })); + ngModelCtrl.$viewChangeListeners.push(passIfIsLeafChild(passIfIsIndeterminate(function () { + // emit when input property indeterminate is false, prevent recursively emitting event from parent to children, children to parent + scope.$broadcast("ParentSelectedChange", get()); + }))); // reset input state base on children inputs scope.$on("childSelectedChange", passThroughThisScope(passIfIsLeafChild(updateBaseOnChildrenState))); } From 19ba83f27384a9807049881fef0b15708b88056e Mon Sep 17 00:00:00 2001 From: vitam Date: Sat, 29 Jul 2017 22:35:07 +0200 Subject: [PATCH 13/14] add more comments --- js/directives/fileselect.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/js/directives/fileselect.js b/js/directives/fileselect.js index 235fddb3..08904c36 100644 --- a/js/directives/fileselect.js +++ b/js/directives/fileselect.js @@ -34,7 +34,7 @@ app.directive("indeterminate", [ } }; }; - var passIfNotIsLeafChild = function (callback) { // ensure to execute callback only when this input hasn't subinput + var passIfNotIsLeafChild = function (callback) { // ensure to execute callback only when this input hasn't any subinput return function () { if (children.length === 0) { callback.apply(this, arguments); @@ -48,44 +48,45 @@ app.directive("indeterminate", [ } }; }; - var passIfIsIndeterminate = function (callback) { // pass through the event from the scope where they sent + var passIfIsIndeterminate = function (callback) { // pass through the event when this input is indeterminate return function () { if (!elem.prop("indeterminate")) { return callback.apply(this, arguments); } }; }; - var catchEventOnlyOnce = function (callback) { // only fire once, and stop event's propagation - return function (event) { - callback.apply(this, arguments); - return event.stopPropagation(); - }; - }; + /* var catchEventOnlyOnce = function (callback) { // only fire once, and stop event's propagation + return function (event) { + callback.apply(this, arguments); + return event.stopPropagation(); + }; + }; */ if (attr["indeterminate"] && parse(attr["indeterminate"]).constant) { setIndeterminateState(scope.$eval(attr["indeterminate"])); // set to default value (set in template) } if (attr["indeterminate"] && parse(attr["indeterminate"]).constant && !scope.$eval(attr["indeterminate"])) { // when this input wont have subinput, they will only receive parent change and emit child change event ngModelCtrl.$viewChangeListeners.push(passIfNotIsLeafChild(function () { - scope.$emit("childSelectedChange", get()); + scope.$emit("childSelectedChange", get()); // notifies parents to change their state })); scope.$on("ParentSelectedChange", passThroughThisScope(passIfNotIsLeafChild( function (event, newVal) { setModelValueWithSideEffect(newVal); // set value to parent's value; this will cause listener to emit childChange event; this won't be a infinite loop }))); // init first time and only once - scope.$emit("i'm child input", get); + scope.$emit("i'm child input", get); // traverses upwards toward the root scope notifying the listeners for keep reference to this input's value scope.$emit("childSelectedChange", get()); // force emitted, and force the parent change their state base on children at first time } else { // establish parent-child's relation // listen for the child emitted token - scope.$on("i'm child input", passThroughThisScope( + scope.$on("i'm child input", passThroughThisScope( // can't apply pass passIfIsLeafChild, at beginning all has not child input function (event, child) { children.push(child); }) ); var updateBaseOnChildrenState = function (event, newChildValue) { if ((cacheSelectedSubInputNumber + cacheNoSelectedSubInputNumber) !== children.length) { + // cache childern state cacheSelectedSubInputNumber = 0; cacheNoSelectedSubInputNumber = 0; for (var i = 0; i < children.length; i++) { @@ -106,7 +107,7 @@ app.directive("indeterminate", [ cacheNoSelectedSubInputNumber++; } } - var allSelected = (cacheNoSelectedSubInputNumber === 0); + var allSelected = (cacheNoSelectedSubInputNumber === 0); // if doesn't has any no selected input var anySeleted = (cacheSelectedSubInputNumber > 0); setIndeterminateState(allSelected !== anySeleted); // if at least one is selected, but not all then set input property indeterminate to true setModelValueWithSideEffect(allSelected); // change binding model value and trigger onchange event From 44d46a607ce3c1ae63788e587a463e1aa0b97fcb Mon Sep 17 00:00:00 2001 From: vitam Date: Mon, 31 Jul 2017 14:58:49 +0200 Subject: [PATCH 14/14] sort files alphabetically, make more easier to find file --- js/ctrls/modal.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/ctrls/modal.js b/js/ctrls/modal.js index 351bd0ef..0e220a1a 100644 --- a/js/ctrls/modal.js +++ b/js/ctrls/modal.js @@ -124,6 +124,14 @@ angular this.files = _.cloneDeep(files); var groupFiles = function (files) { + // sort files alphabetically + files.sort(function (a, b) { + if (a.relpath < b.relpath) { + return -1; + } else { + return 1; + } + }); function OrganizedFolder () { this.dirs = {}; this.files = [];