@sumaris-net/ngx-components 18.6.58 → 18.6.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/doc/changelog.md +6 -0
- package/esm2022/src/app/admin/users/users.mjs +2 -2
- package/esm2022/src/app/core/account/account.page.mjs +1 -1
- package/esm2022/src/app/core/account/password/change-password.page.mjs +2 -2
- package/esm2022/src/app/core/home/home.mjs +2 -2
- package/esm2022/src/app/core/menu/testing/menu-other.testing.mjs +1 -1
- package/esm2022/src/app/core/menu/testing/menu.testing.mjs +1 -1
- package/esm2022/src/app/core/register/register-confirm.page.mjs +1 -1
- package/esm2022/src/app/core/services/model/entity.model.mjs +4 -1
- package/esm2022/src/app/core/settings/settings.page.mjs +1 -1
- package/esm2022/src/app/core/table/testing/table.testing.mjs +1 -1
- package/esm2022/src/app/core/table/testing/table2.testing.mjs +1 -1
- package/esm2022/src/app/shared/named-filter/testing/named-filter-selector.testing.mjs +1 -1
- package/esm2022/src/app/shared/toast/toast.testing.mjs +11 -8
- package/esm2022/src/app/shared/toast/toasts.mjs +15 -29
- package/esm2022/src/app/shared/toolbar/toolbar.mjs +7 -3
- package/fesm2022/sumaris-net.ngx-components.mjs +44 -49
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app/core/services/model/entity.model.d.ts +1 -0
- package/src/app/shared/toast/toast.testing.d.ts +1 -1
- package/src/app/shared/toast/toasts.d.ts +2 -3
- package/src/app/shared/toolbar/toolbar.d.ts +3 -1
- package/src/assets/manifest.json +1 -1
- package/src/theme/_ngx-components.scss +2 -2
|
@@ -243,7 +243,7 @@ export class Table2TestPage extends AppTable {
|
|
|
243
243
|
provide: AppTable,
|
|
244
244
|
useExisting: forwardRef(() => Table2TestPage),
|
|
245
245
|
},
|
|
246
|
-
], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n color=\"primary\"\n [canGoBack]=\"true\"\n [hasValidate]=\"(loadingSubject | async) !== true && (dirtySubject | async) === true\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\"\n>\n <ion-title>Table 2 (click to select)</ion-title>\n\n <ion-buttons slot=\"end\">\n @if (selection | isEmptySelection) {\n <input matInput type=\"number\" step=\"1\" style=\"color: black; width: 50px\" [(ngModel)]=\"rowHeight\" />\n\n <!-- Add -->\n <button mat-icon-button *ngIf=\"canEdit && !mobile\" [title]=\"'COMMON.BTN_ADD' | translate\" (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\" [disabled]=\"(dirtySubject | async) !== true\" (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n } @else {\n <!-- if row selection -->\n <!-- delete -->\n <button\n mat-icon-button\n *ngIf=\"canEdit\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button\n mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: { equals: 1 }\"\n [title]=\"'COMMON.BTN_DUPLICATE' | translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\"\n >\n <mat-icon>file_copy</mat-icon>\n </button>\n }\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n [class.filter-panel-pinned]=\"!filterPanelFloating\"\n >\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{ 'TABLE.TESTING.SEARCH_TEXT' | translate }}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput formControlName=\"searchText\" autocomplete=\"off\" />\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '»' : '«' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"checkBoxSelection\" [class.mat-column-sticky]=\"checkBoxSelection\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!checkBoxSelection\">\n @if (selection | isMultipleSelection) {\n <mat-checkbox\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n (change)=\"$event ? masterToggle() : null\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!checkBoxSelection\">\n <mat-checkbox [checked]=\"selection | isSelected: row\" (click)=\"toggleSelectRow($event, row)\"></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef>\n <span mat-sort-header>\n <ion-label title=\"Id\">#</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"!readOnly && row.id === -1 && row.editing; else readOnlyId\">\n <input\n matInput\n autocomplete=\"off\"\n required\n [formControl]=\"row.validator | formGetControl: 'id'\"\n placeholder=\"Id\"\n [appAutofocus]=\"true\"\n />\n <mat-error *ngIf=\"(row.validator | formGetControl: 'id').hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'id').hasError('alreadyExists')\" translate>\n ERROR.FIELD_NOT_UNIQUE_ID\n </mat-error>\n </mat-form-field>\n\n <ng-template #readOnlyId>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'id') || (row.currentData | propertyGet: 'id') }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label [title]=\"'TABLE.TESTING.NAME' | translate\">{{ 'TABLE.TESTING.NAME' | translate }}</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'name'\">\n <mat-form-field *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\">\n <input\n matInput\n autocomplete=\"off\"\n [required]=\"true\"\n [formControl]=\"row.validator | formGetControl: 'name'\"\n [placeholder]=\"'TABLE.TESTING.NAME' | translate\"\n [appAutofocus]=\"row.id === -1 || focusColumn === 'name'\"\n />\n <ng-content select=\"[suffix]\"></ng-content>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('maxlength')\" translate>\n ERROR.FIELD_MAX_LENGTH_COMPACT\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('minlength')\" translate>\n ERROR.FIELD_MIN_LENGTH_COMPACT\n </mat-error>\n </mat-form-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'name') || (row.currentData | propertyGet: 'name') }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef [resizable]=\"resizable\">\n <span mat-sort-header>\n <ion-label>{{ 'TABLE.TESTING.LEVEL_ID' | translate }}</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-autocomplete-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n panelWidth=\"750px\"\n [formControl]=\"row.validator | formGetControl: 'levelId'\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID' | translate\"\n floatLabel=\"never\"\n [required]=\"true\"\n [config]=\"autocompleteFields.level\"\n [highlightAccent]=\"true\"\n >\n <mat-error matError *ngIf=\"(row.validator | formGetControl: 'levelId').hasError('invalid')\" translate>\n ERROR.FIELD_INVALID\n </mat-error>\n </mat-autocomplete-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n autocompleteFields.level?.displayWith(\n (row.validator | formGetValue: 'levelId') || (row.currentData | propertyGet: 'levelId')\n ) ||\n ((row.validator | formGetValue: 'levelId') || (row.currentData | propertyGet: 'levelId')\n | referentialToString)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n floatLabel=\"never\"\n [style]=\"'checkbox'\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean') || formBuilder.control(row.currentData['boolean'])\n \"\n [compact]=\"true\"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean') || (row.currentData | propertyGet: 'boolean')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean2\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean 2</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n [floatLabel]=\"'never'\"\n [style]=\"'radio'\"\n [showRadio]=\"true\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean2') || formBuilder.control(row.currentData['boolean2'])\n \"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean2') || (row.currentData | propertyGet: 'boolean2')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean3\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean 3</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n floatLabel=\"never\"\n [style]=\"'button'\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean2') || formBuilder.control(row.currentData['boolean2'])\n \"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean2') || (row.currentData | propertyGet: 'boolean2')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"stickyEnd\"\n [canCancel]=\"false\"\n [style]=\"'table'\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll\n *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\"\n position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\"\n >\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS' | translate\"\n ></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator\n *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\"\n showFirstLastButtons\n ></mat-paginator>\n\n <app-form-buttons-bar\n *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject | async) || !dirty\"\n >\n <!-- error -->\n <ion-item *ngIf=\"error$ | async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i4.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i7.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i7.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i7.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i14.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i15.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i16.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i17.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: i18.MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "label", "appearance", "subscriptSizing", "placeholder", "suggestFn", "required", "hideRequiredMarker", "mobile", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "reloadItemsOnFocus", "clearInvalidValueOnBlur", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "splitSearchText", "selectInputContentOnFocus", "selectInputContentOnFocusDelay", "previewImplicitValue", "class", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keydown.backspace", "keyup.enter", "selectionChange"] }, { kind: "component", type: i19.MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "directive", type: i20.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: i21.AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: i22.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i23.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i24.ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i25.ResizableComponent, selector: "th[resizable]", inputs: ["resizable"], outputs: ["sizeChanged"] }, { kind: "directive", type: i26.ResizableDirective, selector: "[resizable]", outputs: ["resizable", "fit"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i27.PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: i28.NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: i29.ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: i30.FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: i30.FormGetValuePipe, name: "formGetValue" }, { kind: "pipe", type: i31.IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: i31.IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: i31.IsMultipleSelectionPipe, name: "isMultipleSelection" }, { kind: "pipe", type: i32.IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: i32.IsNotAllSelectedPipe, name: "isNotAllSelected" }, { kind: "pipe", type: i33.ReferentialToStringPipe, name: "referentialToString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
246
|
+
], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }, { propertyName: "infiniteScroll", first: true, predicate: IonInfiniteScroll, descendants: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n color=\"primary\"\n [canGoBack]=\"true\"\n [hasValidate]=\"(loadingSubject | async) !== true && (dirtySubject | async) === true\"\n (onValidate)=\"save()\"\n [backHref]=\"'/testing'\"\n>\n <ion-title>Table 2 (click to select)</ion-title>\n\n <ion-buttons slot=\"end\">\n @if (selection | isEmptySelection) {\n <input matInput type=\"number\" step=\"1\" style=\"color: black; width: 50px\" [(ngModel)]=\"rowHeight\" />\n\n <!-- Add -->\n <button mat-icon-button *ngIf=\"canEdit && !mobile\" [title]=\"'COMMON.BTN_ADD' | translate\" (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n\n <!-- save -->\n <button mat-icon-button *ngIf=\"mobile\" [disabled]=\"(dirtySubject | async) !== true\" (click)=\"save()\">\n <mat-icon>save</mat-icon>\n </button>\n } @else {\n <!-- if row selection -->\n <!-- delete -->\n <button\n mat-icon-button\n *ngIf=\"canEdit\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n\n <!-- duplicate -->\n <button\n mat-icon-button\n *ngIf=\"canEdit && selection.selected | isArrayLength: { equals: 1 }\"\n [title]=\"'COMMON.BTN_DUPLICATE' | translate\"\n (click)=\"duplicateRow($event, selection.selected[0])\"\n >\n <mat-icon>file_copy</mat-icon>\n </button>\n }\n </ion-buttons>\n</app-toolbar>\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- error -->\n <ion-item *ngIf=\"mobile && error\" lines=\"none\" @slideUpDownAnimation>\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <!-- search -->\n <mat-expansion-panel\n #filterExpansionPanel\n class=\"filter-panel\"\n [class.filter-panel-floating]=\"filterPanelFloating\"\n [class.filter-panel-pinned]=\"!filterPanelFloating\"\n >\n <form class=\"form-container ion-padding-top\" [formGroup]=\"filterForm\" (ngSubmit)=\"applyFilterAndClosePanel($event)\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search text -->\n <mat-form-field>\n <mat-label>{{ 'TABLE.TESTING.SEARCH_TEXT' | translate }}</mat-label>\n <ion-icon matPrefix name=\"search\"></ion-icon>\n <input matInput formControlName=\"searchText\" autocomplete=\"off\" />\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n </ion-row>\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat)\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <button\n mat-icon-button\n color=\"accent\"\n *ngIf=\"filterPanelFloating\"\n (click)=\"toggleFilterPanelFloating()\"\n class=\"hidden-xs hidden-sm hidden-md\"\n [title]=\"(filterPanelFloating ? 'COMMON.BTN_EXPAND' : 'COMMON.BTN_HIDE') | translate\"\n >\n <mat-icon>\n <span style=\"transform: rotate(90deg)\">{{ filterPanelFloating ? '»' : '«' }}</span>\n </mat-icon>\n </button>\n\n <!-- Close panel -->\n <ion-button mat-button fill=\"clear\" color=\"dark\" (click)=\"closeFilterPanel()\" [disabled]=\"loadingSubject | async\">\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- table -->\n <div [class.table-container]=\"!enableInfiniteScroll\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n [style.--mat-row-height]=\"rowHeight + 'px'\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"checkBoxSelection\" [class.mat-column-sticky]=\"checkBoxSelection\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!checkBoxSelection\">\n @if (selection | isMultipleSelection) {\n <mat-checkbox\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n (change)=\"$event ? masterToggle() : null\"\n ></mat-checkbox>\n }\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!checkBoxSelection\">\n <mat-checkbox [checked]=\"selection | isSelected: row\" (click)=\"toggleSelectRow($event, row)\"></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef>\n <span mat-sort-header>\n <ion-label title=\"Id\">#</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-form-field *ngIf=\"!readOnly && row.id === -1 && row.editing; else readOnlyId\">\n <input\n matInput\n autocomplete=\"off\"\n required\n [formControl]=\"row.validator | formGetControl: 'id'\"\n placeholder=\"Id\"\n [appAutofocus]=\"true\"\n />\n <mat-error *ngIf=\"(row.validator | formGetControl: 'id').hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'id').hasError('alreadyExists')\" translate>\n ERROR.FIELD_NOT_UNIQUE_ID\n </mat-error>\n </mat-form-field>\n\n <ng-template #readOnlyId>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'id') || (row.currentData | propertyGet: 'id') }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label [title]=\"'TABLE.TESTING.NAME' | translate\">{{ 'TABLE.TESTING.NAME' | translate }}</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'name'\">\n <mat-form-field *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\">\n <input\n matInput\n autocomplete=\"off\"\n [required]=\"true\"\n [formControl]=\"row.validator | formGetControl: 'name'\"\n [placeholder]=\"'TABLE.TESTING.NAME' | translate\"\n [appAutofocus]=\"row.id === -1 || focusColumn === 'name'\"\n />\n <ng-content select=\"[suffix]\"></ng-content>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('maxlength')\" translate>\n ERROR.FIELD_MAX_LENGTH_COMPACT\n </mat-error>\n <mat-error *ngIf=\"(row.validator | formGetControl: 'name').hasError('minlength')\" translate>\n ERROR.FIELD_MIN_LENGTH_COMPACT\n </mat-error>\n </mat-form-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{ (row.validator | formGetValue: 'name') || (row.currentData | propertyGet: 'name') }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Level column -->\n <ng-container matColumnDef=\"levelId\">\n <th mat-header-cell *matHeaderCellDef [resizable]=\"resizable\">\n <span mat-sort-header>\n <ion-label>{{ 'TABLE.TESTING.LEVEL_ID' | translate }}</ion-label>\n <ion-label color=\"danger\" [innerHTML]=\"' *'\"></ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-autocomplete-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n panelWidth=\"750px\"\n [formControl]=\"row.validator | formGetControl: 'levelId'\"\n [placeholder]=\"'TABLE.TESTING.LEVEL_ID' | translate\"\n floatLabel=\"never\"\n [required]=\"true\"\n [config]=\"autocompleteFields.level\"\n [highlightAccent]=\"true\"\n >\n <mat-error matError *ngIf=\"(row.validator | formGetControl: 'levelId').hasError('invalid')\" translate>\n ERROR.FIELD_INVALID\n </mat-error>\n </mat-autocomplete-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n autocompleteFields.level?.displayWith(\n (row.validator | formGetValue: 'levelId') || (row.currentData | propertyGet: 'levelId')\n ) ||\n ((row.validator | formGetValue: 'levelId') || (row.currentData | propertyGet: 'levelId')\n | referentialToString)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n floatLabel=\"never\"\n [style]=\"'checkbox'\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean') || formBuilder.control(row.currentData['boolean'])\n \"\n [compact]=\"true\"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean') || (row.currentData | propertyGet: 'boolean')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean2\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean 2</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n [floatLabel]=\"'never'\"\n [style]=\"'radio'\"\n [showRadio]=\"true\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean2') || formBuilder.control(row.currentData['boolean2'])\n \"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean2') || (row.currentData | propertyGet: 'boolean2')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"boolean3\">\n <th mat-header-cell *matHeaderCellDef cdkDrag [resizable]=\"resizable\">\n <!-- if sortable, wrap the header with a mat-sort-header -->\n <span mat-sort-header>\n <ion-label>Boolean 3</ion-label>\n </span>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-boolean-field\n *ngIf=\"!readOnly && row.editing; else readOnlyTemplate\"\n floatLabel=\"never\"\n [style]=\"'button'\"\n [formControl]=\"\n (row.validator | formGetControl: 'boolean2') || formBuilder.control(row.currentData['boolean2'])\n \"\n ></mat-boolean-field>\n <ng-template #readOnlyTemplate>\n <ion-label appAutoTitle>\n {{\n (row.validator | formGetValue: 'boolean2') || (row.currentData | propertyGet: 'boolean2')\n ? ('COMMON.YES' | translate)\n : ('COMMON.NO' | translate)\n }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"stickyEnd\"\n [canCancel]=\"false\"\n [style]=\"'table'\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [cellTemplate]=\"cellInjection\"\n >\n <!-- cell injection-->\n <ng-template #cellInjection let-row>\n <span *ngIf=\"row.editing && !row.validator.dirty\">-</span>\n </ng-template>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.invalid\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-row-dirty]=\"row.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n\n <ion-infinite-scroll\n *ngIf=\"enableInfiniteScroll\"\n [threshold]=\"mobile ? '10%' : '2%'\"\n position=\"bottom\"\n (ionInfinite)=\"fetchMore($event)\"\n >\n <ion-infinite-scroll-content\n loadingSpinner=\"circles\"\n [loadingText]=\"'COMMON.LOADING_DOTS' | translate\"\n ></ion-infinite-scroll-content>\n </ion-infinite-scroll>\n </div>\n</ion-content>\n\n<ion-footer>\n <!-- Paginator -->\n <mat-paginator\n *ngIf=\"!enableInfiniteScroll\"\n [length]=\"totalRowCount\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\"\n showFirstLastButtons\n ></mat-paginator>\n\n <app-form-buttons-bar\n *ngIf=\"canEdit && !mobile\"\n (onCancel)=\"load()\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject | async) || !dirty\"\n >\n <!-- error -->\n <ion-item *ngIf=\"error$ | async\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"canEdit && mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".table-container .mat-mdc-table .mat-column-select{min-width:30px}.table-container .mat-mdc-table .mat-column-id{min-width:30px;max-width:30px}.table-container .mat-mdc-table .mat-column-label,.table-container .mat-mdc-table .mat-column-name,.table-container .mat-mdc-table .mat-column-levelId,.table-container .mat-mdc-table .mat-column-statusId{min-width:150px}.table-container .mat-mdc-table .mat-column-comments{min-width:100px;max-width:100px}.table-container .mat-mdc-table .mat-column-updateDate{min-width:110px;max-width:110px}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: i4.IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i7.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i7.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i7.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i7.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i7.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i7.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i7.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i7.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i7.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i7.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i14.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i15.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i16.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i17.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: i18.MatAutocompleteField, selector: "mat-autocomplete-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "label", "appearance", "subscriptSizing", "placeholder", "suggestFn", "required", "hideRequiredMarker", "mobile", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "reloadItemsOnFocus", "clearInvalidValueOnBlur", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "multiple", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "debug", "showSearchBar", "stickySearchBar", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "splitSearchText", "selectInputContentOnFocus", "selectInputContentOnFocusDelay", "previewImplicitValue", "class", "filter", "readonly", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keydown.backspace", "keyup.enter", "selectionChange"] }, { kind: "component", type: i19.MatBooleanField, selector: "mat-boolean-field", inputs: ["disabled", "formControl", "formControlName", "placeholder", "floatLabel", "appearance", "subscriptSizing", "readonly", "required", "compact", "style", "buttonsColCount", "class", "yesLabel", "noLabel", "showButtonIcons", "yesIcon", "noIcon", "clearable", "labelPosition", "tabindex", "showRadio", "value"], outputs: ["keyup.enter", "focus", "blur"] }, { kind: "directive", type: i20.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: i21.AutoTitleDirective, selector: "[appAutoTitle]" }, { kind: "component", type: i22.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "id", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i23.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i24.ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i25.ResizableComponent, selector: "th[resizable]", inputs: ["resizable"], outputs: ["sizeChanged"] }, { kind: "directive", type: i26.ResizableDirective, selector: "[resizable]", outputs: ["resizable", "fit"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i27.PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: i28.NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: i29.ArrayLengthPipe, name: "isArrayLength" }, { kind: "pipe", type: i30.FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: i30.FormGetValuePipe, name: "formGetValue" }, { kind: "pipe", type: i31.IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: i31.IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: i31.IsMultipleSelectionPipe, name: "isMultipleSelection" }, { kind: "pipe", type: i32.IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: i32.IsNotAllSelectedPipe, name: "isNotAllSelected" }, { kind: "pipe", type: i33.ReferentialToStringPipe, name: "referentialToString" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
247
247
|
}
|
|
248
248
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: Table2TestPage, decorators: [{
|
|
249
249
|
type: Component,
|
|
@@ -63,7 +63,7 @@ export class NamedFilterSelectorTestingPage {
|
|
|
63
63
|
this.markForCheck();
|
|
64
64
|
}
|
|
65
65
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NamedFilterSelectorTestingPage, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.LocalSettingsService }, { token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
66
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: NamedFilterSelectorTestingPage, selector: "app-name-filter-selector-testing", inputs: { filterForm: "filterForm" }, ngImport: i0, template: "<app-toolbar defaultBackHref=\"testing/shared\">\n <ion-title>Named filter selector testing page</ion-title>\n @if (!mobile) {\n <ion-buttons slot=\"end\">\n <app-named-filter-selector\n class=\"ion-padding-right ion-padding-top\"\n [entityName]=\"'DummyEntity'\"\n [subscriptSizing]=\"'dynamic'\"\n [filterContentProvider]=\"namedFilterContentProvider\"\n [filterFormDirty]=\"filterForm.dirty\"\n [autocompleteConfig]=\"namedFilterAutocompleteConfig\"\n [filterImportCallback]=\"filterImportCallback\"\n (filterSelected)=\"setFilter($event)\"\n [detectChangeOnSelectFilter]=\"true\"\n ></app-named-filter-selector>\n </ion-buttons>\n }\n</app-toolbar>\n<ion-content>\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-label>Dummy filter</ion-label>\n </ion-card-header>\n <ion-card-content>\n @if (mobile) {\n <app-named-filter-selector\n class=\"ion-padding-right ion-padding-top\"\n [entityName]=\"'DummyEntity'\"\n [subscriptSizing]=\"'dynamic'\"\n [filterContentProvider]=\"namedFilterContentProvider\"\n [filterFormDirty]=\"filterForm.dirty\"\n [autocompleteConfig]=\"namedFilterAutocompleteConfig\"\n [filterImportCallback]=\"filterImportCallback\"\n (filterSelected)=\"setFilter($event)\"\n [detectChangeOnSelectFilter]=\"true\"\n ></app-named-filter-selector>\n }\n\n <form class=\"form-container\" [formGroup]=\"filterForm\">\n <div class=\"form-group\">\n <label for=\"filter-a\">Filter A </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-a\" name=\"filter-a\" formControlName=\"filterA\" />\n </div>\n <div class=\"form-group\">\n <label for=\"filter-b\">Filter B </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-b\" name=\"filter-b\" formControlName=\"filterB\" />\n </div>\n <div class=\"form-group\">\n <label for=\"filter-a\">Filter C </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-c\" name=\"filter-c\" formControlName=\"filterC\" />\n </div>\n </form>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n</ion-content>\n", dependencies: [{ kind: "component", type: i3.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i3.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i3.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i3.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i3.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i3.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i3.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonRow, selector: "ion-row" }, { kind: "component", type: i3.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i5.NamedFilterSelector, selector: "app-named-filter-selector", inputs: ["mobile", "entityName", "appearance", "subscriptSizing", "filterContentProvider", "filterImportCallback", "filterFormDirty", "showButtons", "exportFileNamePrefix", "autocompleteConfig", "dropButtonTitle", "clearButtonTitle", "detectChangeOnSelectFilter", "buttonsPosition", "disabled"], outputs: ["filterSelected", "filterDeleted", "filterCleared"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
66
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: NamedFilterSelectorTestingPage, selector: "app-name-filter-selector-testing", inputs: { filterForm: "filterForm" }, ngImport: i0, template: "<app-toolbar defaultBackHref=\"testing/shared\">\n <ion-title>Named filter selector testing page</ion-title>\n @if (!mobile) {\n <ion-buttons slot=\"end\">\n <app-named-filter-selector\n class=\"ion-padding-right ion-padding-top\"\n [entityName]=\"'DummyEntity'\"\n [subscriptSizing]=\"'dynamic'\"\n [filterContentProvider]=\"namedFilterContentProvider\"\n [filterFormDirty]=\"filterForm.dirty\"\n [autocompleteConfig]=\"namedFilterAutocompleteConfig\"\n [filterImportCallback]=\"filterImportCallback\"\n (filterSelected)=\"setFilter($event)\"\n [detectChangeOnSelectFilter]=\"true\"\n ></app-named-filter-selector>\n </ion-buttons>\n }\n</app-toolbar>\n<ion-content>\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-card>\n <ion-card-header>\n <ion-label>Dummy filter</ion-label>\n </ion-card-header>\n <ion-card-content>\n @if (mobile) {\n <app-named-filter-selector\n class=\"ion-padding-right ion-padding-top\"\n [entityName]=\"'DummyEntity'\"\n [subscriptSizing]=\"'dynamic'\"\n [filterContentProvider]=\"namedFilterContentProvider\"\n [filterFormDirty]=\"filterForm.dirty\"\n [autocompleteConfig]=\"namedFilterAutocompleteConfig\"\n [filterImportCallback]=\"filterImportCallback\"\n (filterSelected)=\"setFilter($event)\"\n [detectChangeOnSelectFilter]=\"true\"\n ></app-named-filter-selector>\n }\n\n <form class=\"form-container\" [formGroup]=\"filterForm\">\n <div class=\"form-group\">\n <label for=\"filter-a\">Filter A </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-a\" name=\"filter-a\" formControlName=\"filterA\" />\n </div>\n <div class=\"form-group\">\n <label for=\"filter-b\">Filter B </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-b\" name=\"filter-b\" formControlName=\"filterB\" />\n </div>\n <div class=\"form-group\">\n <label for=\"filter-a\">Filter C </label>\n <input type=\"text\" class=\"form-control\" id=\"filter-c\" name=\"filter-c\" formControlName=\"filterC\" />\n </div>\n </form>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n</ion-content>\n", dependencies: [{ kind: "component", type: i3.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i3.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i3.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i3.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i3.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i3.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i3.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonRow, selector: "ion-row" }, { kind: "component", type: i3.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "id", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i5.NamedFilterSelector, selector: "app-named-filter-selector", inputs: ["mobile", "entityName", "appearance", "subscriptSizing", "filterContentProvider", "filterImportCallback", "filterFormDirty", "showButtons", "exportFileNamePrefix", "autocompleteConfig", "dropButtonTitle", "clearButtonTitle", "detectChangeOnSelectFilter", "buttonsPosition", "disabled"], outputs: ["filterSelected", "filterDeleted", "filterCleared"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
67
67
|
}
|
|
68
68
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NamedFilterSelectorTestingPage, decorators: [{
|
|
69
69
|
type: Component,
|
|
@@ -5,18 +5,21 @@ import * as i1 from "@ionic/angular";
|
|
|
5
5
|
import * as i2 from "@angular/forms";
|
|
6
6
|
export class ToastTestingPage {
|
|
7
7
|
injector;
|
|
8
|
-
|
|
9
|
-
showCloseButton:
|
|
10
|
-
duration: 5000, // 5s
|
|
8
|
+
options = {
|
|
9
|
+
showCloseButton: false,
|
|
10
|
+
duration: -1, // 5000, // 5s
|
|
11
|
+
header: undefined,
|
|
11
12
|
message: 'This is a message text !',
|
|
12
13
|
positionAnchor: 'header',
|
|
14
|
+
position: 'top',
|
|
13
15
|
};
|
|
14
16
|
constructor(injector) {
|
|
15
17
|
this.injector = injector;
|
|
16
18
|
}
|
|
17
19
|
showToast(opts) {
|
|
18
20
|
return Toasts.showSimple(this.injector, {
|
|
19
|
-
...this.
|
|
21
|
+
...this.options,
|
|
22
|
+
position: this.options.position === 'auto' ? null : this.options.position,
|
|
20
23
|
...opts,
|
|
21
24
|
});
|
|
22
25
|
}
|
|
@@ -39,13 +42,13 @@ export class ToastTestingPage {
|
|
|
39
42
|
});
|
|
40
43
|
}
|
|
41
44
|
toggleCloseButton() {
|
|
42
|
-
this.
|
|
45
|
+
this.options.showCloseButton = !this.options.showCloseButton;
|
|
43
46
|
}
|
|
44
47
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToastTestingPage, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
|
|
45
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ToastTestingPage, selector: "toast-testing", ngImport: i0, template: "<ion-toolbar color=\"primary\" id=\"header\">\n <ion-title>Toasts</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n <p>Toast examples:</p>\n\n <ion-button (click)=\"showToast()\" color=\"dark\">default</ion-button>\n\n <ion-button (click)=\"showInfo()\" color=\"secondary\">info</ion-button>\n\n <ion-button (click)=\"showWarning()\" color=\"accent\">warning</ion-button>\n\n <ion-button (click)=\"showError()\" color=\"danger\">error</ion-button>\n\n <ion-button (click)=\"showInfo({ message: 'This is <b>HTML</b> text' })\" color=\"danger\">message with HTML</ion-button>\n <br />\n\n <ion-list>\n <ion-item>\n <ion-label>Message</ion-label>\n <ion-input [(ngModel)]=\"
|
|
48
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ToastTestingPage, selector: "toast-testing", ngImport: i0, template: "<ion-toolbar color=\"primary\" id=\"header\">\n <ion-title>Toasts</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n <p>Toast examples:</p>\n\n <ion-button (click)=\"showToast()\" color=\"dark\">default</ion-button>\n\n <ion-button (click)=\"showInfo()\" color=\"secondary\">info</ion-button>\n\n <ion-button (click)=\"showWarning()\" color=\"accent\">warning</ion-button>\n\n <ion-button (click)=\"showError()\" color=\"danger\">error</ion-button>\n\n <ion-button (click)=\"showInfo({ message: 'This is <b>HTML</b> text' })\" color=\"danger\">message with HTML</ion-button>\n <br />\n\n <ion-list>\n <ion-item>\n <ion-label>Header (optional)</ion-label>\n <ion-input [(ngModel)]=\"options.header\"></ion-input>\n </ion-item>\n <ion-item>\n <ion-label>Message</ion-label>\n <ion-input [(ngModel)]=\"options.message\"></ion-input>\n </ion-item>\n\n <ion-item>\n <ion-checkbox [(ngModel)]=\"options.showCloseButton\">\n <ion-label>Close button ?</ion-label>\n </ion-checkbox>\n </ion-item>\n\n <ion-item>\n <ion-label>Duration</ion-label>\n <ion-input [(ngModel)]=\"options.duration\"></ion-input>\n </ion-item>\n\n <ion-item>\n <ion-label>Position</ion-label>\n <ion-select [(ngModel)]=\"options.position\">\n <ion-select-option value=\"auto\">auto</ion-select-option>\n <ion-select-option value=\"top\">top</ion-select-option>\n <ion-select-option value=\"bottom\">bottom</ion-select-option>\n <ion-select-option value=\"middle\">middle</ion-select-option>\n </ion-select>\n </ion-item>\n </ion-list>\n</ion-content>\n", dependencies: [{ kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "legacy", "mode", "name", "value"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "legacy", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i1.IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "legacy", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: i1.IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: i1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i1.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i1.SelectValueAccessor, selector: "ion-select, ion-radio-group, ion-segment, ion-datetime" }, { kind: "directive", type: i1.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
46
49
|
}
|
|
47
50
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ToastTestingPage, decorators: [{
|
|
48
51
|
type: Component,
|
|
49
|
-
args: [{ selector: 'toast-testing', template: "<ion-toolbar color=\"primary\" id=\"header\">\n <ion-title>Toasts</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n <p>Toast examples:</p>\n\n <ion-button (click)=\"showToast()\" color=\"dark\">default</ion-button>\n\n <ion-button (click)=\"showInfo()\" color=\"secondary\">info</ion-button>\n\n <ion-button (click)=\"showWarning()\" color=\"accent\">warning</ion-button>\n\n <ion-button (click)=\"showError()\" color=\"danger\">error</ion-button>\n\n <ion-button (click)=\"showInfo({ message: 'This is <b>HTML</b> text' })\" color=\"danger\">message with HTML</ion-button>\n <br />\n\n <ion-list>\n <ion-item>\n <ion-label>Message</ion-label>\n <ion-input [(ngModel)]=\"
|
|
52
|
+
args: [{ selector: 'toast-testing', template: "<ion-toolbar color=\"primary\" id=\"header\">\n <ion-title>Toasts</ion-title>\n</ion-toolbar>\n\n<ion-content class=\"ion-padding\">\n <p>Toast examples:</p>\n\n <ion-button (click)=\"showToast()\" color=\"dark\">default</ion-button>\n\n <ion-button (click)=\"showInfo()\" color=\"secondary\">info</ion-button>\n\n <ion-button (click)=\"showWarning()\" color=\"accent\">warning</ion-button>\n\n <ion-button (click)=\"showError()\" color=\"danger\">error</ion-button>\n\n <ion-button (click)=\"showInfo({ message: 'This is <b>HTML</b> text' })\" color=\"danger\">message with HTML</ion-button>\n <br />\n\n <ion-list>\n <ion-item>\n <ion-label>Header (optional)</ion-label>\n <ion-input [(ngModel)]=\"options.header\"></ion-input>\n </ion-item>\n <ion-item>\n <ion-label>Message</ion-label>\n <ion-input [(ngModel)]=\"options.message\"></ion-input>\n </ion-item>\n\n <ion-item>\n <ion-checkbox [(ngModel)]=\"options.showCloseButton\">\n <ion-label>Close button ?</ion-label>\n </ion-checkbox>\n </ion-item>\n\n <ion-item>\n <ion-label>Duration</ion-label>\n <ion-input [(ngModel)]=\"options.duration\"></ion-input>\n </ion-item>\n\n <ion-item>\n <ion-label>Position</ion-label>\n <ion-select [(ngModel)]=\"options.position\">\n <ion-select-option value=\"auto\">auto</ion-select-option>\n <ion-select-option value=\"top\">top</ion-select-option>\n <ion-select-option value=\"bottom\">bottom</ion-select-option>\n <ion-select-option value=\"middle\">middle</ion-select-option>\n </ion-select>\n </ion-item>\n </ion-list>\n</ion-content>\n" }]
|
|
50
53
|
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
51
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3QudGVzdGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3RvYXN0L3RvYXN0LnRlc3RpbmcudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC90b2FzdC90b2FzdC50ZXN0aW5nLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBWSxNQUFNLGVBQWUsQ0FBQztBQUNwRCxPQUFPLEVBQW9CLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQzs7OztBQU1wRCxNQUFNLE9BQU8sZ0JBQWdCO0lBVVA7SUFUVixPQUFPLEdBQXFCO1FBQ3BDLGVBQWUsRUFBRSxLQUFLO1FBQ3RCLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxjQUFjO1FBQzVCLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE9BQU8sRUFBRSwwQkFBMEI7UUFDbkMsY0FBYyxFQUFFLFFBQVE7UUFDeEIsUUFBUSxFQUFFLEtBQUs7S0FDaEIsQ0FBQztJQUVGLFlBQW9CLFFBQWtCO1FBQWxCLGFBQVEsR0FBUixRQUFRLENBQVU7SUFBRyxDQUFDO0lBRTFDLFNBQVMsQ0FBQyxJQUF1QjtRQUMvQixPQUFPLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUN0QyxHQUFHLElBQUksQ0FBQyxPQUFPO1lBQ2YsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFNLE1BQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVE7WUFDbEYsR0FBRyxJQUFJO1NBQ1IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVEsQ0FBQyxJQUF1QjtRQUM5QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDcEIsSUFBSSxFQUFFLE1BQU07WUFDWixHQUFHLElBQUk7U0FDUixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVyxDQUFDLElBQXVCO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNwQixJQUFJLEVBQUUsU0FBUztZQUNmLEdBQUcsSUFBSTtTQUNSLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTLENBQUMsSUFBdUI7UUFDL0IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3BCLElBQUksRUFBRSxPQUFPO1lBQ2IsR0FBRyxJQUFJO1NBQ1IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUM7SUFDL0QsQ0FBQzt3R0EzQ1UsZ0JBQWdCOzRGQUFoQixnQkFBZ0IscURDUDdCLG9vREFrREE7OzRGRDNDYSxnQkFBZ0I7a0JBSjVCLFNBQVM7K0JBQ0UsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0b3IgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNob3dUb2FzdE9wdGlvbnMsIFRvYXN0cyB9IGZyb20gJy4vdG9hc3RzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9hc3QtdGVzdGluZycsXG4gIHRlbXBsYXRlVXJsOiAndG9hc3QudGVzdGluZy5odG1sJyxcbn0pXG5leHBvcnQgY2xhc3MgVG9hc3RUZXN0aW5nUGFnZSB7XG4gIHByb3RlY3RlZCBvcHRpb25zOiBTaG93VG9hc3RPcHRpb25zID0ge1xuICAgIHNob3dDbG9zZUJ1dHRvbjogZmFsc2UsXG4gICAgZHVyYXRpb246IC0xLCAvLyA1MDAwLCAvLyA1c1xuICAgIGhlYWRlcjogdW5kZWZpbmVkLFxuICAgIG1lc3NhZ2U6ICdUaGlzIGlzIGEgbWVzc2FnZSB0ZXh0ICEnLFxuICAgIHBvc2l0aW9uQW5jaG9yOiAnaGVhZGVyJyxcbiAgICBwb3NpdGlvbjogJ3RvcCcsXG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IpIHt9XG5cbiAgc2hvd1RvYXN0KG9wdHM/OiBTaG93VG9hc3RPcHRpb25zKSB7XG4gICAgcmV0dXJuIFRvYXN0cy5zaG93U2ltcGxlKHRoaXMuaW5qZWN0b3IsIHtcbiAgICAgIC4uLnRoaXMub3B0aW9ucyxcbiAgICAgIHBvc2l0aW9uOiB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICgnYXV0bycgYXMgYW55KSA/IG51bGwgOiB0aGlzLm9wdGlvbnMucG9zaXRpb24sXG4gICAgICAuLi5vcHRzLFxuICAgIH0pO1xuICB9XG5cbiAgc2hvd0luZm8ob3B0cz86IFNob3dUb2FzdE9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zaG93VG9hc3Qoe1xuICAgICAgdHlwZTogJ2luZm8nLFxuICAgICAgLi4ub3B0cyxcbiAgICB9KTtcbiAgfVxuXG4gIHNob3dXYXJuaW5nKG9wdHM/OiBTaG93VG9hc3RPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1RvYXN0KHtcbiAgICAgIHR5cGU6ICd3YXJuaW5nJyxcbiAgICAgIC4uLm9wdHMsXG4gICAgfSk7XG4gIH1cblxuICBzaG93RXJyb3Iob3B0cz86IFNob3dUb2FzdE9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zaG93VG9hc3Qoe1xuICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAgIC4uLm9wdHMsXG4gICAgfSk7XG4gIH1cblxuICB0b2dnbGVDbG9zZUJ1dHRvbigpIHtcbiAgICB0aGlzLm9wdGlvbnMuc2hvd0Nsb3NlQnV0dG9uID0gIXRoaXMub3B0aW9ucy5zaG93Q2xvc2VCdXR0b247XG4gIH1cbn1cbiIsIjxpb24tdG9vbGJhciBjb2xvcj1cInByaW1hcnlcIiBpZD1cImhlYWRlclwiPlxuICA8aW9uLXRpdGxlPlRvYXN0czwvaW9uLXRpdGxlPlxuPC9pb24tdG9vbGJhcj5cblxuPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgPHA+VG9hc3QgZXhhbXBsZXM6PC9wPlxuXG4gIDxpb24tYnV0dG9uIChjbGljayk9XCJzaG93VG9hc3QoKVwiIGNvbG9yPVwiZGFya1wiPmRlZmF1bHQ8L2lvbi1idXR0b24+XG5cbiAgPGlvbi1idXR0b24gKGNsaWNrKT1cInNob3dJbmZvKClcIiBjb2xvcj1cInNlY29uZGFyeVwiPmluZm88L2lvbi1idXR0b24+XG5cbiAgPGlvbi1idXR0b24gKGNsaWNrKT1cInNob3dXYXJuaW5nKClcIiBjb2xvcj1cImFjY2VudFwiPndhcm5pbmc8L2lvbi1idXR0b24+XG5cbiAgPGlvbi1idXR0b24gKGNsaWNrKT1cInNob3dFcnJvcigpXCIgY29sb3I9XCJkYW5nZXJcIj5lcnJvcjwvaW9uLWJ1dHRvbj5cblxuICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwic2hvd0luZm8oeyBtZXNzYWdlOiAnVGhpcyBpcyA8Yj5IVE1MPC9iPiB0ZXh0JyB9KVwiIGNvbG9yPVwiZGFuZ2VyXCI+bWVzc2FnZSB3aXRoIEhUTUw8L2lvbi1idXR0b24+XG4gIDxiciAvPlxuXG4gIDxpb24tbGlzdD5cbiAgICA8aW9uLWl0ZW0+XG4gICAgICA8aW9uLWxhYmVsPkhlYWRlciAob3B0aW9uYWwpPC9pb24tbGFiZWw+XG4gICAgICA8aW9uLWlucHV0IFsobmdNb2RlbCldPVwib3B0aW9ucy5oZWFkZXJcIj48L2lvbi1pbnB1dD5cbiAgICA8L2lvbi1pdGVtPlxuICAgIDxpb24taXRlbT5cbiAgICAgIDxpb24tbGFiZWw+TWVzc2FnZTwvaW9uLWxhYmVsPlxuICAgICAgPGlvbi1pbnB1dCBbKG5nTW9kZWwpXT1cIm9wdGlvbnMubWVzc2FnZVwiPjwvaW9uLWlucHV0PlxuICAgIDwvaW9uLWl0ZW0+XG5cbiAgICA8aW9uLWl0ZW0+XG4gICAgICA8aW9uLWNoZWNrYm94IFsobmdNb2RlbCldPVwib3B0aW9ucy5zaG93Q2xvc2VCdXR0b25cIj5cbiAgICAgICAgPGlvbi1sYWJlbD5DbG9zZSBidXR0b24gPzwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY2hlY2tib3g+XG4gICAgPC9pb24taXRlbT5cblxuICAgIDxpb24taXRlbT5cbiAgICAgIDxpb24tbGFiZWw+RHVyYXRpb248L2lvbi1sYWJlbD5cbiAgICAgIDxpb24taW5wdXQgWyhuZ01vZGVsKV09XCJvcHRpb25zLmR1cmF0aW9uXCI+PC9pb24taW5wdXQ+XG4gICAgPC9pb24taXRlbT5cblxuICAgIDxpb24taXRlbT5cbiAgICAgIDxpb24tbGFiZWw+UG9zaXRpb248L2lvbi1sYWJlbD5cbiAgICAgIDxpb24tc2VsZWN0IFsobmdNb2RlbCldPVwib3B0aW9ucy5wb3NpdGlvblwiPlxuICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCJhdXRvXCI+YXV0bzwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cInRvcFwiPnRvcDwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cImJvdHRvbVwiPmJvdHRvbTwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIm1pZGRsZVwiPm1pZGRsZTwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICA8L2lvbi1zZWxlY3Q+XG4gICAgPC9pb24taXRlbT5cbiAgPC9pb24tbGlzdD5cbjwvaW9uLWNvbnRlbnQ+XG4iXX0=
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IonicSafeString, ToastController } from '@ionic/angular';
|
|
2
2
|
import { TranslateService } from '@ngx-translate/core';
|
|
3
3
|
import { isEmptyArray, isNotNil } from '../functions';
|
|
4
|
+
import { TOOLBAR_HEADER_ID } from '../toolbar/toolbar';
|
|
4
5
|
const TOAST_MAX_HEIGHT_PX = 75;
|
|
5
6
|
const TOAST_MAX_STACK_SIZE = 4;
|
|
6
7
|
export class Toasts {
|
|
7
8
|
static counter = 0;
|
|
8
9
|
static stackSize = 0;
|
|
9
10
|
static async showSimple(injector, opts) {
|
|
10
|
-
return this.show(injector.get(ToastController), injector.get(TranslateService),
|
|
11
|
+
return this.show(injector.get(ToastController), injector.get(TranslateService), {
|
|
12
|
+
// FIXME: 'ios' mode use bottom position, but this is not working
|
|
13
|
+
//mode: injector.get(Platform)?.is('ios') ? 'ios' : 'md',
|
|
14
|
+
...opts,
|
|
15
|
+
});
|
|
11
16
|
}
|
|
12
17
|
static async show(toastController, translate, opts) {
|
|
13
18
|
// DEBUG
|
|
@@ -87,14 +92,10 @@ export class Toasts {
|
|
|
87
92
|
}
|
|
88
93
|
// Retrieve the toast position
|
|
89
94
|
const position = opts.position || (opts.mode === 'ios' ? 'bottom' : 'top');
|
|
90
|
-
if (!opts.enterAnimation &&
|
|
91
|
-
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
// opts.enterAnimation = (baseEl: HTMLElement, opts) => createAnimation()
|
|
95
|
-
// .addElement(baseEl)
|
|
96
|
-
// .delay(400)
|
|
97
|
-
// .afterAddClass('stacked');
|
|
95
|
+
if (!opts.enterAnimation &&
|
|
96
|
+
position !== 'middle' &&
|
|
97
|
+
// FIXME: ignore bottom position (stacked not working)
|
|
98
|
+
position !== 'bottom') {
|
|
98
99
|
// As workaround, we add an offset using a CSS class
|
|
99
100
|
cssArray.push('toast-stacked-' + position);
|
|
100
101
|
cssArray.push('toast-stack-offset-' + currentOffset);
|
|
@@ -104,9 +105,11 @@ export class Toasts {
|
|
|
104
105
|
// Default values
|
|
105
106
|
position,
|
|
106
107
|
duration: opts.showCloseButton ? 10000 : 4000,
|
|
108
|
+
positionAnchor: position === 'top' ? TOOLBAR_HEADER_ID : undefined, // If display on top, avoid to override the app-toolbar (if any)
|
|
109
|
+
swipeGesture: isEmptyArray(opts.buttons) ? 'vertical' : undefined, // Allow to swipe to dismiss, if no button
|
|
107
110
|
...opts,
|
|
108
111
|
message: translations[message],
|
|
109
|
-
|
|
112
|
+
header: (opts.header && translations[opts.header]) || undefined,
|
|
110
113
|
});
|
|
111
114
|
if (opts.onWillPresent)
|
|
112
115
|
opts.onWillPresent(toast);
|
|
@@ -123,22 +126,5 @@ export class Toasts {
|
|
|
123
126
|
return result;
|
|
124
127
|
}
|
|
125
128
|
}
|
|
126
|
-
static createEnterAnimation(animationCtrl, currentOffset, opts) {
|
|
127
|
-
if (opts.position === 'middle') {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
const direction = opts.position === 'top' ? 1 : -1;
|
|
131
|
-
const start = currentOffset * TOAST_MAX_HEIGHT_PX - direction * TOAST_MAX_HEIGHT_PX;
|
|
132
|
-
const end = direction * currentOffset * TOAST_MAX_HEIGHT_PX;
|
|
133
|
-
return (baseEl, opts) => {
|
|
134
|
-
// FIXME: wrapper is always null
|
|
135
|
-
const wrapper = baseEl.querySelector('.toast-wrapper');
|
|
136
|
-
return createAnimation()
|
|
137
|
-
.addElement(wrapper)
|
|
138
|
-
.duration(250)
|
|
139
|
-
.fromTo('transform', `translateY(${start}px)`, `translateY(${end}px)`)
|
|
140
|
-
.fromTo('opacity', '0', '1');
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
129
|
}
|
|
144
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvdG9hc3QvdG9hc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBdUIsZUFBZSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUd2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd0RCxNQUFNLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztBQUMvQixNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQVMvQixNQUFNLE9BQU8sTUFBTTtJQUNqQixNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNuQixNQUFNLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUVyQixNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBVSxRQUFrQixFQUFFLElBQXNCO1FBQ3pFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQVUsZUFBZ0MsRUFBRSxTQUEyQixFQUFFLElBQXNCO1FBQzlHLFFBQVE7UUFDUix1Q0FBdUM7UUFFdkMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsNERBQTRELENBQUMsQ0FBQztZQUM1RSxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksZUFBZTtnQkFDekMsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLENBQUMsU0FBUyxJ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O2FBQU0sQ0FBQztZQUNOLHlCQUF5QjtZQUN6QixNQUFNLE1BQU0sR0FBRyxNQUFNLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUUxQyxjQUFjLEVBQUUsQ0FBQztZQUVqQixPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxhQUFrQyxFQUFFLGFBQXFCLEVBQUUsSUFBc0I7UUFDM0csSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sS0FBSyxHQUFHLGFBQWEsR0FBRyxtQkFBbUIsR0FBRyxTQUFTLEdBQUcsbUJBQW1CLENBQUM7UUFDcEYsTUFBTSxHQUFHLEdBQUcsU0FBUyxHQUFHLGFBQWEsR0FBRyxtQkFBbUIsQ0FBQztRQUM1RCxPQUFPLENBQUMsTUFBbUIsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNuQyxnQ0FBZ0M7WUFDaEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sZUFBZSxFQUFFO2lCQUNyQixVQUFVLENBQUMsT0FBTyxDQUFDO2lCQUNuQixRQUFRLENBQUMsR0FBRyxDQUFDO2lCQUNiLE1BQU0sQ0FBQyxXQUFXLEVBQUUsY0FBYyxLQUFLLEtBQUssRUFBRSxjQUFjLEdBQUcsS0FBSyxDQUFDO2lCQUNyRSxNQUFNLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUM7SUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQW5pbWF0aW9uQ29udHJvbGxlciwgY3JlYXRlQW5pbWF0aW9uLCBJb25pY1NhZmVTdHJpbmcsIFRvYXN0Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IEFuaW1hdGlvbkJ1aWxkZXIsIE92ZXJsYXlFdmVudERldGFpbCwgVG9hc3RPcHRpb25zIH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuaW1wb3J0IHsgVG9hc3RCdXR0b24gfSBmcm9tICdAaW9uaWMvY29yZS9kaXN0L3R5cGVzL2NvbXBvbmVudHMvdG9hc3QvdG9hc3QtaW50ZXJmYWNlJztcbmltcG9ydCB7IGlzRW1wdHlBcnJheSwgaXNOb3ROaWwgfSBmcm9tICcuLi9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgSW5qZWN0b3IgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuY29uc3QgVE9BU1RfTUFYX0hFSUdIVF9QWCA9IDc1O1xuY29uc3QgVE9BU1RfTUFYX1NUQUNLX1NJWkUgPSA0O1xuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgU2hvd1RvYXN0T3B0aW9ucyBleHRlbmRzIFRvYXN0T3B0aW9ucyB7XG4gIHR5cGU/OiAnZXJyb3InIHwgJ3dhcm5pbmcnIHwgJ2luZm8nO1xuICBtZXNzYWdlUGFyYW1zPzogYW55O1xuICBzaG93Q2xvc2VCdXR0b24/OiBib29sZWFuO1xuICBvbldpbGxQcmVzZW50PzogKHRvYXN0OiBIVE1MSW9uVG9hc3RFbGVtZW50KSA9PiB2b2lkO1xufVxuXG5leHBvcnQgY2xhc3MgVG9hc3RzIHtcbiAgc3RhdGljIGNvdW50ZXIgPSAwO1xuICBzdGF0aWMgc3RhY2tTaXplID0gMDtcblxuICBzdGF0aWMgYXN5bmMgc2hvd1NpbXBsZTxUID0gYW55PihpbmplY3RvcjogSW5qZWN0b3IsIG9wdHM6IFNob3dUb2FzdE9wdGlvbnMpOiBQcm9taXNlPE92ZXJsYXlFdmVudERldGFpbDxUPj4ge1xuICAgIHJldHVybiB0aGlzLnNob3coaW5qZWN0b3IuZ2V0KFRvYXN0Q29udHJvbGxlciksIGluamVjdG9yLmdldChUcmFuc2xhdGVTZXJ2aWNlKSwgb3B0cyk7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgc2hvdzxUID0gYW55Pih0b2FzdENvbnRyb2xsZXI6IFRvYXN0Q29udHJvbGxlciwgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLCBvcHRzOiBTaG93VG9hc3RPcHRpb25zKTogUHJvbWlzZTxPdmVybGF5RXZlbnREZXRhaWw8VD4+IHtcbiAgICAvLyBERUJVR1xuICAgIC8vY29uc29sZS5kZWJ1ZygnW1RvYXN0cy5zaG93XScsIG9wdHMpO1xuXG4gICAgaWYgKCF0b2FzdENvbnRyb2xsZXIgfHwgIXRyYW5zbGF0ZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgYXJndW1lbnQgJ3RvYXN0Q29udHJvbGxlcicgb3IgJ3RyYW5zbGF0ZSdcIik7XG4gICAgICBpZiAob3B0cy5tZXNzYWdlIGluc3RhbmNlb2YgSW9uaWNTYWZlU3RyaW5nKVxuICAgICAgICBjb25zb2xlLmluZm8oJ1t0b2FzdHNdIG1lc3NhZ2U6ICcgKyAoKHRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUuaW5zdGFudChvcHRzLm1lc3NhZ2UudmFsdWUpKSB8fCBvcHRzLm1lc3NhZ2UudmFsdWUpKTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBvcHRzLm1lc3NhZ2UgPT09ICdzdHJpbmcnKVxuICAgICAgICBjb25zb2xlLmluZm8oJ1t0b2FzdHNdIG1lc3NhZ2U6ICcgKyAoKHRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUuaW5zdGFudChvcHRzLm1lc3NhZ2UsIG9wdHMubWVzc2FnZVBhcmFtcykpIHx8IG9wdHMubWVzc2FnZSkpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb3VudGVyKys7IC8vIEluY3JlbWVudCB0b2FzdCBjb3VudGVyXG4gICAgbGV0IGN1cnJlbnRPZmZzZXQgPSB0aGlzLnN0YWNrU2l6ZTtcbiAgICBpZiAodGhpcy5zdGFja1NpemUgPCBUT0FTVF9NQVhfU1RBQ0tfU0laRSkge1xuICAgICAgdGhpcy5zdGFja1NpemUrKzsgLy8gSW5jcmVtZW50IHN0YWNrIG9mZnNldFxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YWNrU2l6ZSA9IDE7IC8vIFJlc2V0IHRoZSBzdGFja1xuICAgICAgY3VycmVudE9mZnNldCA9IDA7XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZUNvdW50ZXJzID0gKCkgPT4ge1xuICAgICAgLy8gRGVjcmVhc2UgY291bnRlclxuICAgICAgdGhpcy5jb3VudGVyLS07XG4gICAgICAvLyBJZiBhbGwgdG9hc3QgY2xvc2VkOiByZXNldCB0aGUgc3RhY2sgb2Zmc2V0XG4gICAgICBpZiAodGhpcy5jb3VudGVyID09PSAwKSB7XG4gICAgICAgIHRoaXMuc3RhY2tTaXplID0gMDtcbiAgICAgIH1cbiAgICAgIC8vIElmIGN1cnJlbnQgdG9hc3QgaXMgdGhlIGxhc3Qgb25lLCBkZWNyZWFzZSB0aGUgb2Zmc2V0XG4gICAgICBlbHNlIGlmICh0aGlzLnN0YWNrU2l6ZSA9PT0gY3VycmVudE9mZnNldCArIDEpIHtcbiAgICAgICAgdGhpcy5zdGFja1NpemUtLTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgbWVzc2FnZSA9IG9wdHMubWVzc2FnZSAmJiBvcHRzLm1lc3NhZ2UgaW5zdGFuY2VvZiBJb25pY1NhZmVTdHJpbmcgPyBvcHRzLm1lc3NhZ2UudmFsdWUgOiAob3B0cy5tZXNzYWdlIGFzIHN0cmluZyk7XG4gICAgY29uc3QgaTE4bktleXMgPSBbbWVzc2FnZV07XG4gICAgaWYgKG9wdHMuaGVhZGVyKSBpMThuS2V5cy5wdXNoKG9wdHMuaGVhZGVyKTtcblxuICAgIGxldCBjbG9zZUJ1dHRvbjogVG9hc3RCdXR0b247XG4gICAgaWYgKG9wdHMuc2hvd0Nsb3NlQnV0dG9uKSB7XG4gICAgICBvcHRzLmJ1dHRvbnMgPSBvcHRzLmJ1dHRvbnMgfHwgW107XG4gICAgICBjb25zdCBidXR0b25JbmRleCA9IG9wdHMuYnV0dG9uc1xuICAgICAgICAubWFwKChiKSA9PiAodHlwZW9mIGIgPT09ICdvYmplY3QnICYmIChiIGFzIFRvYXN0QnV0dG9uKSkgfHwgdW5kZWZpbmVkKVxuICAgICAgICAuZmlsdGVyKGlzTm90TmlsKVxuICAgICAgICAuZmluZEluZGV4KChiKSA9PiBiLnJvbGUgPT09ICdjbG9zZScpO1xuICAgICAgaWYgKGJ1dHRvbkluZGV4ICE9PSAtMSkge1xuICAgICAgICBjbG9zZUJ1dHRvbiA9IG9wdHMuYnV0dG9uc1tidXR0b25JbmRleF0gYXMgVG9hc3RCdXR0b247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9zZUJ1dHRvbiA9IHsgcm9sZTogJ2Nsb3NlJyB9O1xuICAgICAgICBvcHRzLmJ1dHRvbnMucHVzaChjbG9zZUJ1dHRvbik7XG4gICAgICB9XG4gICAgICBjbG9zZUJ1dHRvbi50ZXh0ID0gY2xvc2VCdXR0b24udGV4dCB8fCAnQ09NTU9OLkJUTl9PSyc7XG4gICAgICBpMThuS2V5cy5wdXNoKGNsb3NlQnV0dG9uLnRleHQpO1xuICAgIH1cblxuICAgIC8vIFJlYWQgQ1NTXG4gICAgY29uc3QgY3NzQXJyYXkgPSAob3B0cy5jc3NDbGFzcyAmJiB0eXBlb2Ygb3B0cy5jc3NDbGFzcyA9PT0gJ3N0cmluZycgJiYgb3B0cy5jc3NDbGFzcy5zcGxpdCgnLCcpKSB8fCAob3B0cy5jc3NDbGFzcyBhcyBBcnJheTxzdHJpbmc+KSB8fCBbXTtcblxuICAgIC8vIEFkZCAnZXJyb3InIGNsYXNzLCBpZiBuZWVkXG4gICAgaWYgKG9wdHMudHlwZSkge1xuICAgICAgc3dpdGNoIChvcHRzLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgIGNzc0FycmF5LnB1c2goJ2RhbmdlcicpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd3YXJuaW5nJzpcbiAgICAgICAgICBjc3NBcnJheS5wdXNoKCdhY2NlbnQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnaW5mbyc6XG4gICAgICAgICAgY3NzQXJyYXkucHVzaCgnc2Vjb25kYXJ5Jyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNsYXRpb25zID0gdHJhbnNsYXRlLmluc3RhbnQoaTE4bktleXMpO1xuICAgIGlmIChvcHRzLm1lc3NhZ2VQYXJhbXMpIHtcbiAgICAgIHRyYW5zbGF0aW9uc1ttZXNzYWdlXSA9IHRyYW5zbGF0ZS5pbnN0YW50KG1lc3NhZ2UsIG9wdHMubWVzc2FnZVBhcmFtcyk7XG4gICAgfVxuXG4gICAgaWYgKGNsb3NlQnV0dG9uKSB7XG4gICAgICBjbG9zZUJ1dHRvbi50ZXh0ID0gdHJhbnNsYXRpb25zW2Nsb3NlQnV0dG9uLnRleHRdO1xuICAgIH1cblxuICAgIC8vIFJldHJpZXZlIHRoZSB0b2FzdCBwb3NpdGlvblxuICAgIGNvbnN0IHBvc2l0aW9uID0gb3B0cy5wb3NpdGlvbiB8fCAob3B0cy5tb2RlID09PSAnaW9zJyA/ICdib3R0b20nIDogJ3RvcCcpO1xuXG4gICAgaWYgKCFvcHRzLmVudGVyQW5pbWF0aW9uICYmIHBvc2l0aW9uICE9PSAnbWlkZGxlJykge1xuICAgICAgLy8gRklYTUU6IGFuaW1hdGlvbiBmYWlsZWQsIHNpbmNlIG1pZ3JhdGlvbiB0byBJb25pYyA2XG4gICAgICAvLyBXaGVuIGNvbXB1dGluZywgdGhlIGJhc2VFbGUgaGFzIG5vIHdyYXBwZXIgeWV0XG4gICAgICAvL29wdHMuZW50ZXJBbmltYXRpb24gPSB0aGlzLmNyZWF0ZUVudGVyQW5pbWF0aW9uKGFuaW1hdGlvbkN0cmwsIGN1cnJlbnRPZmZzZXQsIG9wdHMpO1xuICAgICAgLy8gb3B0cy5lbnRlckFuaW1hdGlvbiA9IChiYXNlRWw6IEhUTUxFbGVtZW50LCBvcHRzKSA9PiBjcmVhdGVBbmltYXRpb24oKVxuICAgICAgLy8gICAgIC5hZGRFbGVtZW50KGJhc2VFbClcbiAgICAgIC8vICAgICAuZGVsYXkoNDAwKVxuICAgICAgLy8gICAgIC5hZnRlckFkZENsYXNzKCdzdGFja2VkJyk7XG4gICAgICAvLyBBcyB3b3JrYXJvdW5kLCB3ZSBhZGQgYW4gb2Zmc2V0IHVzaW5nIGEgQ1NTIGNsYXNzXG4gICAgICBjc3NBcnJheS5wdXNoKCd0b2FzdC1zdGFja2VkLScgKyBwb3NpdGlvbik7XG4gICAgICBjc3NBcnJheS5wdXNoKCd0b2FzdC1zdGFjay1vZmZzZXQtJyArIGN1cnJlbnRPZmZzZXQpO1xuICAgIH1cblxuICAgIG9wdHMuY3NzQ2xhc3MgPSBjc3NBcnJheTtcblxuICAgIGNvbnN0IHRvYXN0ID0gYXdhaXQgdG9hc3RDb250cm9sbGVyLmNyZWF0ZSh7XG4gICAgICAvLyBEZWZhdWx0IHZhbHVlc1xuICAgICAgcG9zaXRpb24sXG4gICAgICBkdXJhdGlvbjogb3B0cy5zaG93Q2xvc2VCdXR0b24gPyAxMDAwMCA6IDQwMDAsXG4gICAgICAuLi5vcHRzLFxuICAgICAgbWVzc2FnZTogdHJhbnNsYXRpb25zW21lc3NhZ2VdLFxuICAgICAgLy9oZWFkZXI6IG9wdHMuaGVhZGVyICYmIHRyYW5zbGF0aW9uc1tvcHRzLmhlYWRlcl0gfHwgdW5kZWZpbmVkXG4gICAgfSk7XG5cbiAgICBpZiAob3B0cy5vbldpbGxQcmVzZW50KSBvcHRzLm9uV2lsbFByZXNlbnQodG9hc3QpO1xuXG4gICAgYXdhaXQgdG9hc3QucHJlc2VudCgpO1xuXG4gICAgaWYgKGlzRW1wdHlBcnJheShvcHRzLmJ1dHRvbnMpKSB7XG4gICAgICAvLyBOb3QgbmVlZCB0byB3YWl0IGRpc21pc3MgKG5vICdhd2FpdCcpXG4gICAgICB0b2FzdC5vbkRpZERpc21pc3MoKS50aGVuKHVwZGF0ZUNvdW50ZXJzKTtcbiAgICAgIHJldHVybiBudWxsOyAvLyBubyByZXN1bHRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2FpdCBmb3IgYnV0dG9uIHJlc3VsdFxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdG9hc3Qub25EaWREaXNtaXNzKCk7XG5cbiAgICAgIHVwZGF0ZUNvdW50ZXJzKCk7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUVudGVyQW5pbWF0aW9uKGFuaW1hdGlvbkN0cmw6IEFuaW1hdGlvbkNvbnRyb2xsZXIsIGN1cnJlbnRPZmZzZXQ6IG51bWJlciwgb3B0czogU2hvd1RvYXN0T3B0aW9ucyk6IEFuaW1hdGlvbkJ1aWxkZXIge1xuICAgIGlmIChvcHRzLnBvc2l0aW9uID09PSAnbWlkZGxlJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgZGlyZWN0aW9uID0gb3B0cy5wb3NpdGlvbiA9PT0gJ3RvcCcgPyAxIDogLTE7XG4gICAgY29uc3Qgc3RhcnQgPSBjdXJyZW50T2Zmc2V0ICogVE9BU1RfTUFYX0hFSUdIVF9QWCAtIGRpcmVjdGlvbiAqIFRPQVNUX01BWF9IRUlHSFRfUFg7XG4gICAgY29uc3QgZW5kID0gZGlyZWN0aW9uICogY3VycmVudE9mZnNldCAqIFRPQVNUX01BWF9IRUlHSFRfUFg7XG4gICAgcmV0dXJuIChiYXNlRWw6IEhUTUxFbGVtZW50LCBvcHRzKSA9PiB7XG4gICAgICAvLyBGSVhNRTogd3JhcHBlciBpcyBhbHdheXMgbnVsbFxuICAgICAgY29uc3Qgd3JhcHBlciA9IGJhc2VFbC5xdWVyeVNlbGVjdG9yKCcudG9hc3Qtd3JhcHBlcicpO1xuICAgICAgcmV0dXJuIGNyZWF0ZUFuaW1hdGlvbigpXG4gICAgICAgIC5hZGRFbGVtZW50KHdyYXBwZXIpXG4gICAgICAgIC5kdXJhdGlvbigyNTApXG4gICAgICAgIC5mcm9tVG8oJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGVZKCR7c3RhcnR9cHgpYCwgYHRyYW5zbGF0ZVkoJHtlbmR9cHgpYClcbiAgICAgICAgLmZyb21Ubygnb3BhY2l0eScsICcwJywgJzEnKTtcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvdG9hc3QvdG9hc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHdkQsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFdkQsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFDL0IsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFTL0IsTUFBTSxPQUFPLE1BQU07SUFDakIsTUFBTSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDbkIsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFFckIsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQVUsUUFBa0IsRUFBRSxJQUFzQjtRQUN6RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDOUUsaUVBQWlFO1lBQ2pFLHlEQUF5RDtZQUN6RCxHQUFHLElBQUk7U0FDUixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQVUsZUFBZ0MsRUFBRSxTQUEyQixFQUFFLElBQXNCO1FBQzlHLFFBQVE7UUFDUix1Q0FBdUM7UUFFdkMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsNERBQTRELENBQUMsQ0FBQztZQUM1RSxJQUFJLElBQUks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aEUsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsYUFBYTtZQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFbEQsTUFBTSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFdEIsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDL0Isd0NBQXdDO1lBQ3hDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDMUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxZQUFZO1FBQzNCLENBQUM7YUFBTSxDQUFDO1lBQ04seUJBQXlCO1lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRTFDLGNBQWMsRUFBRSxDQUFDO1lBRWpCLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7SUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW9uaWNTYWZlU3RyaW5nLCBUb2FzdENvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBPdmVybGF5RXZlbnREZXRhaWwsIFRvYXN0T3B0aW9ucyB9IGZyb20gJ0Bpb25pYy9jb3JlJztcbmltcG9ydCB7IFRvYXN0QnV0dG9uIH0gZnJvbSAnQGlvbmljL2NvcmUvZGlzdC90eXBlcy9jb21wb25lbnRzL3RvYXN0L3RvYXN0LWludGVyZmFjZSc7XG5pbXBvcnQgeyBpc0VtcHR5QXJyYXksIGlzTm90TmlsIH0gZnJvbSAnLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IEluamVjdG9yIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUT09MQkFSX0hFQURFUl9JRCB9IGZyb20gJy4uL3Rvb2xiYXIvdG9vbGJhcic7XG5cbmNvbnN0IFRPQVNUX01BWF9IRUlHSFRfUFggPSA3NTtcbmNvbnN0IFRPQVNUX01BWF9TVEFDS19TSVpFID0gNDtcblxuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIFNob3dUb2FzdE9wdGlvbnMgZXh0ZW5kcyBUb2FzdE9wdGlvbnMge1xuICB0eXBlPzogJ2Vycm9yJyB8ICd3YXJuaW5nJyB8ICdpbmZvJztcbiAgbWVzc2FnZVBhcmFtcz86IGFueTtcbiAgc2hvd0Nsb3NlQnV0dG9uPzogYm9vbGVhbjtcbiAgb25XaWxsUHJlc2VudD86ICh0b2FzdDogSFRNTElvblRvYXN0RWxlbWVudCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIFRvYXN0cyB7XG4gIHN0YXRpYyBjb3VudGVyID0gMDtcbiAgc3RhdGljIHN0YWNrU2l6ZSA9IDA7XG5cbiAgc3RhdGljIGFzeW5jIHNob3dTaW1wbGU8VCA9IGFueT4oaW5qZWN0b3I6IEluamVjdG9yLCBvcHRzOiBTaG93VG9hc3RPcHRpb25zKTogUHJvbWlzZTxPdmVybGF5RXZlbnREZXRhaWw8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5zaG93KGluamVjdG9yLmdldChUb2FzdENvbnRyb2xsZXIpLCBpbmplY3Rvci5nZXQoVHJhbnNsYXRlU2VydmljZSksIHtcbiAgICAgIC8vIEZJWE1FOiAnaW9zJyBtb2RlIHVzZSBib3R0b20gcG9zaXRpb24sIGJ1dCB0aGlzIGlzIG5vdCB3b3JraW5nXG4gICAgICAvL21vZGU6IGluamVjdG9yLmdldChQbGF0Zm9ybSk/LmlzKCdpb3MnKSA/ICdpb3MnIDogJ21kJyxcbiAgICAgIC4uLm9wdHMsXG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgc2hvdzxUID0gYW55Pih0b2FzdENvbnRyb2xsZXI6IFRvYXN0Q29udHJvbGxlciwgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLCBvcHRzOiBTaG93VG9hc3RPcHRpb25zKTogUHJvbWlzZTxPdmVybGF5RXZlbnREZXRhaWw8VD4+IHtcbiAgICAvLyBERUJVR1xuICAgIC8vY29uc29sZS5kZWJ1ZygnW1RvYXN0cy5zaG93XScsIG9wdHMpO1xuXG4gICAgaWYgKCF0b2FzdENvbnRyb2xsZXIgfHwgIXRyYW5zbGF0ZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcIk1pc3NpbmcgcmVxdWlyZWQgYXJndW1lbnQgJ3RvYXN0Q29udHJvbGxlcicgb3IgJ3RyYW5zbGF0ZSdcIik7XG4gICAgICBpZiAob3B0cy5tZXNzYWdlIGluc3RhbmNlb2YgSW9uaWNTYWZlU3RyaW5nKVxuICAgICAgICBjb25zb2xlLmluZm8oJ1t0b2FzdHNdIG1lc3NhZ2U6ICcgKyAoKHRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUuaW5zdGFudChvcHRzLm1lc3NhZ2UudmFsdWUpKSB8fCBvcHRzLm1lc3NhZ2UudmFsdWUpKTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBvcHRzLm1lc3NhZ2UgPT09ICdzdHJpbmcnKVxuICAgICAgICBjb25zb2xlLmluZm8oJ1t0b2FzdHNdIG1lc3NhZ2U6ICcgKyAoKHRyYW5zbGF0ZSAmJiB0cmFuc2xhdGUuaW5zdGFudChvcHRzLm1lc3NhZ2UsIG9wdHMubWVzc2FnZVBhcmFtcykpIHx8IG9wdHMubWVzc2FnZSkpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfVxuXG4gICAgdGhpcy5jb3VudGVyKys7IC8vIEluY3JlbWVudCB0b2FzdCBjb3VudGVyXG4gICAgbGV0IGN1cnJlbnRPZmZzZXQgPSB0aGlzLnN0YWNrU2l6ZTtcbiAgICBpZiAodGhpcy5zdGFja1NpemUgPCBUT0FTVF9NQVhfU1RBQ0tfU0laRSkge1xuICAgICAgdGhpcy5zdGFja1NpemUrKzsgLy8gSW5jcmVtZW50IHN0YWNrIG9mZnNldFxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YWNrU2l6ZSA9IDE7IC8vIFJlc2V0IHRoZSBzdGFja1xuICAgICAgY3VycmVudE9mZnNldCA9IDA7XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZUNvdW50ZXJzID0gKCkgPT4ge1xuICAgICAgLy8gRGVjcmVhc2UgY291bnRlclxuICAgICAgdGhpcy5jb3VudGVyLS07XG4gICAgICAvLyBJZiBhbGwgdG9hc3QgY2xvc2VkOiByZXNldCB0aGUgc3RhY2sgb2Zmc2V0XG4gICAgICBpZiAodGhpcy5jb3VudGVyID09PSAwKSB7XG4gICAgICAgIHRoaXMuc3RhY2tTaXplID0gMDtcbiAgICAgIH1cbiAgICAgIC8vIElmIGN1cnJlbnQgdG9hc3QgaXMgdGhlIGxhc3Qgb25lLCBkZWNyZWFzZSB0aGUgb2Zmc2V0XG4gICAgICBlbHNlIGlmICh0aGlzLnN0YWNrU2l6ZSA9PT0gY3VycmVudE9mZnNldCArIDEpIHtcbiAgICAgICAgdGhpcy5zdGFja1NpemUtLTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgbWVzc2FnZSA9IG9wdHMubWVzc2FnZSAmJiBvcHRzLm1lc3NhZ2UgaW5zdGFuY2VvZiBJb25pY1NhZmVTdHJpbmcgPyBvcHRzLm1lc3NhZ2UudmFsdWUgOiAob3B0cy5tZXNzYWdlIGFzIHN0cmluZyk7XG4gICAgY29uc3QgaTE4bktleXMgPSBbbWVzc2FnZV07XG4gICAgaWYgKG9wdHMuaGVhZGVyKSBpMThuS2V5cy5wdXNoKG9wdHMuaGVhZGVyKTtcblxuICAgIGxldCBjbG9zZUJ1dHRvbjogVG9hc3RCdXR0b247XG4gICAgaWYgKG9wdHMuc2hvd0Nsb3NlQnV0dG9uKSB7XG4gICAgICBvcHRzLmJ1dHRvbnMgPSBvcHRzLmJ1dHRvbnMgfHwgW107XG4gICAgICBjb25zdCBidXR0b25JbmRleCA9IG9wdHMuYnV0dG9uc1xuICAgICAgICAubWFwKChiKSA9PiAodHlwZW9mIGIgPT09ICdvYmplY3QnICYmIChiIGFzIFRvYXN0QnV0dG9uKSkgfHwgdW5kZWZpbmVkKVxuICAgICAgICAuZmlsdGVyKGlzTm90TmlsKVxuICAgICAgICAuZmluZEluZGV4KChiKSA9PiBiLnJvbGUgPT09ICdjbG9zZScpO1xuICAgICAgaWYgKGJ1dHRvbkluZGV4ICE9PSAtMSkge1xuICAgICAgICBjbG9zZUJ1dHRvbiA9IG9wdHMuYnV0dG9uc1tidXR0b25JbmRleF0gYXMgVG9hc3RCdXR0b247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9zZUJ1dHRvbiA9IHsgcm9sZTogJ2Nsb3NlJyB9O1xuICAgICAgICBvcHRzLmJ1dHRvbnMucHVzaChjbG9zZUJ1dHRvbik7XG4gICAgICB9XG4gICAgICBjbG9zZUJ1dHRvbi50ZXh0ID0gY2xvc2VCdXR0b24udGV4dCB8fCAnQ09NTU9OLkJUTl9PSyc7XG4gICAgICBpMThuS2V5cy5wdXNoKGNsb3NlQnV0dG9uLnRleHQpO1xuICAgIH1cblxuICAgIC8vIFJlYWQgQ1NTXG4gICAgY29uc3QgY3NzQXJyYXkgPSAob3B0cy5jc3NDbGFzcyAmJiB0eXBlb2Ygb3B0cy5jc3NDbGFzcyA9PT0gJ3N0cmluZycgJiYgb3B0cy5jc3NDbGFzcy5zcGxpdCgnLCcpKSB8fCAob3B0cy5jc3NDbGFzcyBhcyBBcnJheTxzdHJpbmc+KSB8fCBbXTtcblxuICAgIC8vIEFkZCAnZXJyb3InIGNsYXNzLCBpZiBuZWVkXG4gICAgaWYgKG9wdHMudHlwZSkge1xuICAgICAgc3dpdGNoIChvcHRzLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgIGNzc0FycmF5LnB1c2goJ2RhbmdlcicpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd3YXJuaW5nJzpcbiAgICAgICAgICBjc3NBcnJheS5wdXNoKCdhY2NlbnQnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnaW5mbyc6XG4gICAgICAgICAgY3NzQXJyYXkucHVzaCgnc2Vjb25kYXJ5Jyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNsYXRpb25zID0gdHJhbnNsYXRlLmluc3RhbnQoaTE4bktleXMpO1xuICAgIGlmIChvcHRzLm1lc3NhZ2VQYXJhbXMpIHtcbiAgICAgIHRyYW5zbGF0aW9uc1ttZXNzYWdlXSA9IHRyYW5zbGF0ZS5pbnN0YW50KG1lc3NhZ2UsIG9wdHMubWVzc2FnZVBhcmFtcyk7XG4gICAgfVxuXG4gICAgaWYgKGNsb3NlQnV0dG9uKSB7XG4gICAgICBjbG9zZUJ1dHRvbi50ZXh0ID0gdHJhbnNsYXRpb25zW2Nsb3NlQnV0dG9uLnRleHRdO1xuICAgIH1cblxuICAgIC8vIFJldHJpZXZlIHRoZSB0b2FzdCBwb3NpdGlvblxuICAgIGNvbnN0IHBvc2l0aW9uID0gb3B0cy5wb3NpdGlvbiB8fCAob3B0cy5tb2RlID09PSAnaW9zJyA/ICdib3R0b20nIDogJ3RvcCcpO1xuXG4gICAgaWYgKFxuICAgICAgIW9wdHMuZW50ZXJBbmltYXRpb24gJiZcbiAgICAgIHBvc2l0aW9uICE9PSAnbWlkZGxlJyAmJlxuICAgICAgLy8gRklYTUU6IGlnbm9yZSBib3R0b20gcG9zaXRpb24gKHN0YWNrZWQgbm90IHdvcmtpbmcpXG4gICAgICBwb3NpdGlvbiAhPT0gJ2JvdHRvbSdcbiAgICApIHtcbiAgICAgIC8vIEFzIHdvcmthcm91bmQsIHdlIGFkZCBhbiBvZmZzZXQgdXNpbmcgYSBDU1MgY2xhc3NcbiAgICAgIGNzc0FycmF5LnB1c2goJ3RvYXN0LXN0YWNrZWQtJyArIHBvc2l0aW9uKTtcbiAgICAgIGNzc0FycmF5LnB1c2goJ3RvYXN0LXN0YWNrLW9mZnNldC0nICsgY3VycmVudE9mZnNldCk7XG4gICAgfVxuXG4gICAgb3B0cy5jc3NDbGFzcyA9IGNzc0FycmF5O1xuXG4gICAgY29uc3QgdG9hc3QgPSBhd2FpdCB0b2FzdENvbnRyb2xsZXIuY3JlYXRlKHtcbiAgICAgIC8vIERlZmF1bHQgdmFsdWVzXG4gICAgICBwb3NpdGlvbixcbiAgICAgIGR1cmF0aW9uOiBvcHRzLnNob3dDbG9zZUJ1dHRvbiA/IDEwMDAwIDogNDAwMCxcbiAgICAgIHBvc2l0aW9uQW5jaG9yOiBwb3NpdGlvbiA9PT0gJ3RvcCcgPyBUT09MQkFSX0hFQURFUl9JRCA6IHVuZGVmaW5lZCwgLy8gSWYgZGlzcGxheSBvbiB0b3AsIGF2b2lkIHRvIG92ZXJyaWRlIHRoZSBhcHAtdG9vbGJhciAoaWYgYW55KVxuICAgICAgc3dpcGVHZXN0dXJlOiBpc0VtcHR5QXJyYXkob3B0cy5idXR0b25zKSA/ICd2ZXJ0aWNhbCcgOiB1bmRlZmluZWQsIC8vIEFsbG93IHRvIHN3aXBlIHRvIGRpc21pc3MsIGlmIG5vIGJ1dHRvblxuICAgICAgLi4ub3B0cyxcbiAgICAgIG1lc3NhZ2U6IHRyYW5zbGF0aW9uc1ttZXNzYWdlXSxcbiAgICAgIGhlYWRlcjogKG9wdHMuaGVhZGVyICYmIHRyYW5zbGF0aW9uc1tvcHRzLmhlYWRlcl0pIHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIGlmIChvcHRzLm9uV2lsbFByZXNlbnQpIG9wdHMub25XaWxsUHJlc2VudCh0b2FzdCk7XG5cbiAgICBhd2FpdCB0b2FzdC5wcmVzZW50KCk7XG5cbiAgICBpZiAoaXNFbXB0eUFycmF5KG9wdHMuYnV0dG9ucykpIHtcbiAgICAgIC8vIE5vdCBuZWVkIHRvIHdhaXQgZGlzbWlzcyAobm8gJ2F3YWl0JylcbiAgICAgIHRvYXN0Lm9uRGlkRGlzbWlzcygpLnRoZW4odXBkYXRlQ291bnRlcnMpO1xuICAgICAgcmV0dXJuIG51bGw7IC8vIG5vIHJlc3VsdFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXYWl0IGZvciBidXR0b24gcmVzdWx0XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0b2FzdC5vbkRpZERpc21pc3MoKTtcblxuICAgICAgdXBkYXRlQ291bnRlcnMoKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|