You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2019/02/25 16:49:45 UTC
[ignite] branch master updated: IGNITE-11338 Web Console: Fixed
edit mode of "list-editable" component.
This is an automated email from the ASF dual-hosted git repository.
akuznetsov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new b0bc736 IGNITE-11338 Web Console: Fixed edit mode of "list-editable" component.
b0bc736 is described below
commit b0bc736924f49baf820df5682285e2041005b943
Author: Ilya Borisov <kl...@gmail.com>
AuthorDate: Mon Feb 25 23:49:30 2019 +0700
IGNITE-11338 Web Console: Fixed edit mode of "list-editable" component.
---
.../{component.js => component.ts} | 27 ++-----
.../{index.js => index.ts} | 0
.../{directive.js => directive.ts} | 31 +++-----
.../list-editable-one-way/{index.js => index.ts} | 0
.../{directives.js => directives.ts} | 25 ++-----
.../{index.js => index.ts} | 0
.../{directive.js => directive.ts} | 27 +++----
.../{index.js => index.ts} | 0
.../list-editable/{controller.js => controller.ts} | 83 ++++++++++++----------
.../list-editable/{index.js => index.ts} | 0
.../app/components/list-editable/template.pug | 14 ++--
11 files changed, 87 insertions(+), 120 deletions(-)
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.ts
similarity index 79%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.ts
index 84ee1e8..793270f 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.js
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/component.ts
@@ -22,33 +22,20 @@ import './style.scss';
/**
* Adds "add new item" button to list-editable-no-items slot and after list-editable
- * @type {ng.IComponentController}
*/
-export class ListEditableAddItemButton {
+export class ListEditableAddItemButton<T> {
/**
* Template for button that's inserted after list-editable
- * @type {string}
*/
- static hasItemsTemplate = hasItemsTemplate;
- /** @type {ListEditable} */
- _listEditable;
- /** @type {string} */
- labelSingle;
- /** @type {string} */
- labelMultiple;
- /** @type {ng.ICompiledExpression} */
- _addItem;
+ static hasItemsTemplate: string = hasItemsTemplate;
+ _listEditable: ListEditable<T>;
+ labelSingle: string;
+ labelMultiple: string;
+ _addItem: ng.ICompiledExpression;
static $inject = ['$compile', '$scope'];
- /**
- * @param {ng.ICompileService} $compile
- * @param {ng.IScope} $scope
- */
- constructor($compile, $scope) {
- this.$compile = $compile;
- this.$scope = $scope;
- }
+ constructor(private $compile: ng.ICompileService, private $scope: ng.IScope) {}
$onDestroy() {
this._listEditable = this._hasItemsButton = null;
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/index.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/index.ts
similarity index 100%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/index.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-add-item-button/index.ts
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.ts
similarity index 54%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.ts
index 320791b..91b0441 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.js
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/directive.ts
@@ -16,10 +16,9 @@
*/
import isMatch from 'lodash/isMatch';
-import {default as ListEditableController} from '../../controller';
+import {default as ListEditableController, ID} from '../../controller';
-/** @type {ng.IDirectiveFactory} */
-export default function listEditableOneWay() {
+export default function listEditableOneWay(): ng.IDirective {
return {
require: {
list: 'listEditable'
@@ -28,26 +27,18 @@ export default function listEditableOneWay() {
onItemChange: '&?',
onItemRemove: '&?'
},
- controller: class Controller {
- /** @type {ListEditableController} */
- list;
- /** @type {ng.ICompiledExpression} onItemChange */
- onItemChange;
- /** @type {ng.ICompiledExpression} onItemRemove */
- onItemRemove;
+ controller: class Controller<T> {
+ list: ListEditableController<T>;
+ onItemChange: ng.ICompiledExpression;
+ onItemRemove: ng.ICompiledExpression;
- static $inject = ['$scope'];
- /**
- * @param {ng.IScope} $scope
- */
- constructor($scope) {
- this.$scope = $scope;
- }
$onInit() {
- this.list.save = (item, index) => {
- if (!isMatch(this.list.ngModel.$viewValue[index], item)) this.onItemChange({$event: item});
+ this.list.save = (item: T, id: ID) => {
+ if (!isMatch(this.list.getItem(id), item)) this.onItemChange({$event: item});
};
- this.list.remove = (index) => this.onItemRemove({$event: this.list.ngModel.$viewValue[index]});
+ this.list.remove = (id: ID) => this.onItemRemove({
+ $event: this.list.getItem(id)
+ });
}
}
};
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/index.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/index.ts
similarity index 100%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/index.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-one-way/index.ts
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.ts
similarity index 77%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.ts
index f408647..b3cab9e 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.js
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/directives.ts
@@ -15,21 +15,17 @@
* limitations under the License.
*/
-import {default as ListEditableController} from '../../controller';
+import {default as ListEditableController, ID, ItemScope} from '../../controller';
+import {ListEditableTransclude} from '../list-editable-transclude/directive';
const CUSTOM_EVENT_TYPE = '$ngModel.change';
/**
* Emits $ngModel.change event on every ngModel.$viewValue change
- * @type {ng.IDirectiveFactory}
*/
-export function ngModel() {
+export function ngModel<T>(): ng.IDirective {
return {
- /**
- * @param {JQLite} el
- * @param {ng.INgModelController} ngModel
- */
- link(scope, el, attr, {ngModel, list}) {
+ link(scope, el, attr, {ngModel, list}: {ngModel: ng.INgModelController, list?: ListEditableController<T>}) {
if (!list)
return;
@@ -45,17 +41,10 @@ export function ngModel() {
}
/**
* Triggers $ctrl.save when any ngModel emits $ngModel.change event
- * @type {ng.IDirectiveFactory}
*/
-export function listEditableTransclude() {
+export function listEditableTransclude<T>(): ng.IDirective {
return {
- /**
- * @param {ng.IScope} scope
- * @param {JQLite} el
- * @param {ng.IAttributes} attr
- * @param {ListEditableController} list
- */
- link(scope, el, attr, {list, transclude}) {
+ link(scope: ItemScope<T>, el, attr, {list, transclude}: {list?: ListEditableController<T>, transclude: ListEditableTransclude<T>}) {
if (attr.listEditableTransclude !== 'itemEdit')
return;
@@ -65,7 +54,7 @@ export function listEditableTransclude() {
let listener = (e) => {
e.stopPropagation();
scope.$evalAsync(() => {
- if (scope.form.$valid) list.save(scope.item, transclude.$index);
+ if (scope.form.$valid) list.save(scope.item, list.id(scope.item, transclude.$index));
});
};
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/index.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/index.ts
similarity index 100%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/index.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-save-on-changes/index.ts
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.ts
similarity index 89%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.ts
index 36750ae..272a423 100644
--- a/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.js
+++ b/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/directive.ts
@@ -15,38 +15,29 @@
* limitations under the License.
*/
-// eslint-disable-next-line
-import {default as ListEditable} from '../../controller';
+import {default as ListEditable, ItemScope} from '../../controller';
+
+type TranscludedScope<T> = {$form: ng.IFormController, $item?: T} & ng.IScope
/**
* Transcludes list-editable slots and proxies item and form scope values to the slot scope,
* also provides a way to retrieve internal list-editable ng-repeat $index by controller getter.
* User can provide an alias for $item by setting item-name attribute on transclusion slot element.
*/
-export class ListEditableTransclude {
+export class ListEditableTransclude<T> {
/**
* Transcluded slot name.
- *
- * @type {string}
*/
- slot;
+ slot: string;
- /**
- * List-editable controller.
- *
- * @type {ListEditable}
- */
- list;
+ list: ListEditable<T>;
static $inject = ['$scope', '$element'];
- constructor($scope, $element) {
- this.$scope = $scope;
- this.$element = $element;
- }
+ constructor(private $scope: ItemScope<T>, private $element: JQLite) {}
$postLink() {
- this.list.$transclude((clone, transcludedScope) => {
+ this.list.$transclude((clone, transcludedScope: TranscludedScope<T>) => {
// Ilya Borisov: at first I tried to use a slave directive to get value from
// attribute and set it to ListEditableTransclude controller, but it turns out
// this directive would run after list-editable-transclude, so that approach
@@ -98,8 +89,6 @@ export class ListEditableTransclude {
/**
* Returns list-editable ng-repeat $index.
- *
- * @returns {number}
*/
get $index() {
if (!this.$scope)
diff --git a/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/index.js b/modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/index.ts
similarity index 100%
rename from modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/index.js
rename to modules/web-console/frontend/app/components/list-editable/components/list-editable-transclude/index.ts
diff --git a/modules/web-console/frontend/app/components/list-editable/controller.js b/modules/web-console/frontend/app/components/list-editable/controller.ts
similarity index 58%
rename from modules/web-console/frontend/app/components/list-editable/controller.js
rename to modules/web-console/frontend/app/components/list-editable/controller.ts
index d1b8900..e870e82 100644
--- a/modules/web-console/frontend/app/components/list-editable/controller.js
+++ b/modules/web-console/frontend/app/components/list-editable/controller.ts
@@ -17,34 +17,40 @@
import _ from 'lodash';
-/** @type {ng.IComponentController} */
-export default class {
- /** @type {ng.INgModelController} */
- ngModel;
+export interface ListEditableNgModel<T> extends ng.INgModelController {
+ $viewValue: T[],
+ editListItem(item: T): void,
+ editListIndex(index: number): void
+}
+
+export type ID = (string | number) & {tag: 'ItemID'}
+export type ItemScope<T> = {$index: number, item: T, form: ng.IFormController} & ng.IScope
+
+export default class ListEditable<T extends {_id?: any}> {
static $inject = ['$animate', '$element', '$transclude', '$timeout'];
- /**
- * @param {ng.animate.IAnimateService} $animate
- * @param {JQLite} $element
- * @param {ng.ITranscludeFunction} $transclude
- * @param {ng.ITimeoutService} $timeout
- */
- constructor($animate, $element, $transclude, $timeout) {
+ constructor(
+ $animate: ng.animate.IAnimateService,
+ public $element: JQLite,
+ public $transclude: ng.ITranscludeFunction,
+ private $timeout: ng.ITimeoutService
+ ) {
$animate.enabled($element, false);
- this.$transclude = $transclude;
- this.$element = $element;
- this.$timeout = $timeout;
this.hasItemView = $transclude.isSlotFilled('itemView');
- this._cache = {};
+ this._cache = new Map();
}
- $index(item, $index) {
- if (item._id)
- return item._id;
+ ngModel: ListEditableNgModel<T>;
+ hasItemView: boolean
+ private _cache: Map<ID, T>
+
+ id(item: T | undefined, index: number): ID {
+ if (item && item._id)
+ return item._id as ID;
- return $index;
+ return index as ID;
}
$onDestroy() {
@@ -57,7 +63,7 @@ export default class {
};
this.ngModel.editListItem = (item) => {
this.$timeout(() => {
- this.startEditView(this.ngModel.$viewValue.indexOf(item));
+ this.startEditView(this.id(item, this.ngModel.$viewValue.indexOf(item)));
// For some reason required validator does not re-run after adding an item,
// the $validate call fixes the issue.
this.ngModel.$validate();
@@ -65,7 +71,7 @@ export default class {
};
this.ngModel.editListIndex = (index) => {
this.$timeout(() => {
- this.startEditView(index);
+ this.startEditView(this.id(this.ngModel.$viewValue[index], index));
// For some reason required validator does not re-run after adding an item,
// the $validate call fixes the issue.
this.ngModel.$validate();
@@ -73,31 +79,36 @@ export default class {
};
}
- save(data, idx) {
- this.ngModel.$setViewValue(this.ngModel.$viewValue.map((v, i) => i === idx ? _.cloneDeep(data) : v));
+ save(item: T, id: ID) {
+ this.ngModel.$setViewValue(
+ this.ngModel.$viewValue.map((v, i) => this.id(v, i) === id ? _.cloneDeep(item) : v)
+ );
}
- revert(idx) {
- delete this._cache[idx];
+ remove(id: ID): void {
+ this.ngModel.$setViewValue(this.ngModel.$viewValue.filter((v, i) => this.id(v, i) !== id));
}
- remove(idx) {
- this.ngModel.$setViewValue(this.ngModel.$viewValue.filter((v, i) => i !== idx));
+ isEditView(id: ID): boolean {
+ return this._cache.has(id);
}
- isEditView(idx) {
- return this._cache.hasOwnProperty(idx);
+ getEditView(id: ID): T {
+ return this._cache.get(id);
}
- getEditView(idx) {
- return this._cache[idx];
+ getItem(id: ID): T {
+ return this.ngModel.$viewValue.find((v, i) => this.id(v, i) === id);
}
- startEditView(idx) {
- this._cache[idx] = _.cloneDeep(this.ngModel.$viewValue[idx]);
+ startEditView(id: ID) {
+ this._cache.set(
+ id,
+ _.cloneDeep(this.getItem(id))
+ );
}
- stopEditView(data, idx, form) {
+ stopEditView(data: T, id: ID, form: ng.IFormController) {
// By default list-editable saves only valid values, but if you specify {allowInvalid: true}
// ng-model-option, then it will always save. Be careful and pay extra attention to validation
// when doing so, it's an easy way to miss invalid values this way.
@@ -106,8 +117,8 @@ export default class {
if (!form.$valid && !this.ngModel.$options.getOption('allowInvalid'))
return;
- delete this._cache[idx];
+ this._cache.delete(id);
- this.save(data, idx);
+ this.save(data, id);
}
}
diff --git a/modules/web-console/frontend/app/components/list-editable/index.js b/modules/web-console/frontend/app/components/list-editable/index.ts
similarity index 100%
rename from modules/web-console/frontend/app/components/list-editable/index.js
rename to modules/web-console/frontend/app/components/list-editable/index.ts
diff --git a/modules/web-console/frontend/app/components/list-editable/template.pug b/modules/web-console/frontend/app/components/list-editable/template.pug
index b52bfd2..19a9507 100644
--- a/modules/web-console/frontend/app/components/list-editable/template.pug
+++ b/modules/web-console/frontend/app/components/list-editable/template.pug
@@ -16,9 +16,9 @@
.le-body
.le-row(
- ng-repeat='item in $ctrl.ngModel.$viewValue track by $ctrl.$index(item, $index)'
+ ng-repeat='item in $ctrl.ngModel.$viewValue track by $ctrl.id(item, $index)'
ng-class=`{
- 'le-row--editable': $ctrl.isEditView($index),
+ 'le-row--editable': $ctrl.isEditView($ctrl.id(item, $index)),
'le-row--has-item-view': $ctrl.hasItemView
}`)
@@ -30,20 +30,20 @@
span {{ $index+1 }}
.le-row-item
- .le-row-item-view(ng-if='$ctrl.hasItemView && !$ctrl.isEditView($index)' ng-click='$ctrl.startEditView($index);')
+ .le-row-item-view(ng-if='$ctrl.hasItemView && !$ctrl.isEditView($ctrl.id(item, $index))' ng-click='$ctrl.startEditView($ctrl.id(item, $index))')
div(list-editable-transclude='itemView')
div(
- ng-if='!$ctrl.hasItemView || $ctrl.isEditView($index)'
- ignite-on-focus-out='$ctrl.stopEditView(item, $index, form);'
+ ng-if='!$ctrl.hasItemView || $ctrl.isEditView($ctrl.id(item, $index))'
+ ignite-on-focus-out='$ctrl.stopEditView(item, $ctrl.id(item, $index), form)'
ignite-on-focus-out-ignored-classes='bssm-click-overlay bssm-item-text bssm-item-button'
)
- .le-row-item-view(ng-show='$ctrl.hasItemView' ng-init='$ctrl.startEditView($index);item = $ctrl.getEditView($index);')
+ .le-row-item-view(ng-show='$ctrl.hasItemView' ng-init='$ctrl.startEditView($ctrl.id(item, $index));item = $ctrl.getEditView($ctrl.id(item, $index))')
div(list-editable-transclude='itemView')
.le-row-item-edit(ng-form name='form')
div(list-editable-transclude='itemEdit')
.le-row-cross
- button.btn-ignite.btn-ignite--link-dashed-secondary(type='button' ng-click='$ctrl.remove($index)')
+ button.btn-ignite.btn-ignite--link-dashed-secondary(type='button' ng-click='$ctrl.remove($ctrl.id(item, $index))')
svg(ignite-icon='cross')
.le-row(ng-hide='$ctrl.ngModel.$viewValue.length')