@sumaris-net/ngx-components 1.20.1 → 1.20.4
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/bundles/sumaris-net.ngx-components.umd.js +209 -26
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +12 -0
- package/esm2015/public_api.js +7 -3
- package/esm2015/src/app/core/install/install-upgrade-card.component.js +3 -2
- package/esm2015/src/app/core/services/platform.service.js +3 -2
- package/esm2015/src/app/shared/directives/autotitle.directive.js +27 -0
- package/esm2015/src/app/shared/directives/directives.module.js +6 -3
- package/esm2015/src/app/shared/file/csv.utils.js +90 -0
- package/esm2015/src/app/shared/file/file.utils.js +63 -0
- package/esm2015/src/app/shared/file/uri.utils.js +23 -0
- package/esm2015/src/app/shared/functions.js +3 -1
- package/esm2015/src/app/shared/material/autocomplete/material.autocomplete.js +3 -2
- package/esm2015/src/app/shared/material/chips/material.chips.js +3 -2
- package/esm2015/src/app/shared/material/swipe/material.swipe.js +3 -2
- package/esm2015/src/app/shared/pipes/pipes.module.js +7 -4
- package/esm2015/src/app/shared/pipes/property.pipes.js +74 -0
- package/esm2015/src/app/shared/upload-file/testing/upload-file.testing.js +2 -2
- package/fesm2015/sumaris-net.ngx-components.js +199 -24
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +6 -2
- package/src/app/shared/directives/autotitle.directive.d.ts +7 -0
- package/src/app/shared/file/csv.utils.d.ts +18 -0
- package/src/app/shared/{files.d.ts → file/file.utils.d.ts} +3 -9
- package/src/app/shared/file/uri.utils.d.ts +7 -0
- package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +2 -1
- package/src/app/shared/material/chips/material.chips.d.ts +2 -1
- package/src/app/shared/material/swipe/material.swipe.d.ts +2 -1
- package/src/app/shared/pipes/property.pipes.d.ts +14 -0
- package/src/theme/_mixins.scss +2 -0
- package/sumaris-net.ngx-components.metadata.json +1 -1
- package/esm2015/src/app/shared/files.js +0 -84
- package/esm2015/src/app/shared/pipes/properties.pipe.js +0 -20
- package/src/app/shared/pipes/properties.pipe.d.ts +0 -7
|
@@ -576,6 +576,8 @@
|
|
|
576
576
|
function joinPropertiesPath(obj, properties, separator) {
|
|
577
577
|
if (!obj)
|
|
578
578
|
throw new Error('Could not display an undefined entity.');
|
|
579
|
+
if (!properties)
|
|
580
|
+
throw new Error('Missing \'properties\' argument');
|
|
579
581
|
return properties
|
|
580
582
|
.map(function (path) { return getPropertyByPath(obj, path); })
|
|
581
583
|
.filter(isNotNilOrBlank)
|
|
@@ -2200,7 +2202,7 @@
|
|
|
2200
2202
|
{ type: i0.Component, args: [{
|
|
2201
2203
|
// eslint-disable-next-line @angular-eslint/component-selector
|
|
2202
2204
|
selector: 'mat-autocomplete-field',
|
|
2203
|
-
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <!-- readonly -->\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Mobile or Multiple (use <mat-select>) -->\n <mat-select #matSelect\n *ngIf=\"mobile || multiple; else desktopTemplate\"\n [disableRipple]=\"true\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [typeaheadDebounceInterval]=\"debounceTime * 10\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- Search bar -->\n <mat-option class=\"mat-select-searchbar\" *ngIf=\"showSearchBar\"\n [class.mat-select-searchbar-sticky]=\"stickySearchBar\"\n disabled>\n <ion-searchbar #ionSearchbar\n inputmode=\"search\"\n autocomplete=\"off\"\n animated=\"true\"\n showClearButton=\"true\"\n [debounce]=\"debounceTime\"\n (ionClear)=\"markAsLoading()\"\n (ionInput)=\"markAsLoading()\"\n (ionChange)=\"ionSearchBarChanged($event, $event.detail.value)\"\n [placeholder]=\"'COMMON.BTN_SEARCH'|translate\"\n ></ion-searchbar>\n </mat-option>\n\n <!-- Headers -->\n <ion-row class=\"mat-select-header column ion-no-padding\"\n [class.multiple]=\"multiple\"\n [class.mat-select-searchbar-sticky]=\"showSearchBar && stickySearchBar\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required && !multiple && !clearable\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async as items; else loadingTemplate\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <!-- Options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- footer -->\n <mat-option *ngIf=\"itemCount as count\" class=\"mat-option-footer mat-autocomplete-footer ion-no-padding\" disabled>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </mat-option>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(displayValue | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #desktopTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <!-- Headers -->\n <ion-row class=\"mat-autocomplete-header column ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- Options -->\n <ng-container *ngIf=\"$filteredItems | async as items; else loadingTemplate\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(displayValue | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n\n <!-- footer -->\n <ion-row *ngIf=\"itemCount; let count\" class=\"mat-autocomplete-footer ion-no-padding\">\n <ion-col>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"!mobile && !multiple\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #headers>\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n</ng-template>\n\n<ng-template #options>\n\n\n</ng-template>\n\n",
|
|
2205
|
+
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <!-- readonly -->\n <mat-form-field *ngIf=\"_readonly; else writable\"\n [floatLabel]=\"floatLabel\"\n [appearance]=\"appearance\"\n [title]=\"displayValue\"\n class=\"mat-form-field-disabled\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <input matInput hidden type=\"text\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\" readonly>\n <ion-text>{{displayWith(value)}}</ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n </mat-form-field>\n\n <ng-template #writable>\n <mat-form-field [floatLabel]=\"floatLabel\"\n [class.mat-form-field-disabled]=\"disabled\"\n [title]=\"displayValue\">\n\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n <!-- Mobile or Multiple (use <mat-select>) -->\n <mat-select #matSelect\n *ngIf=\"mobile || multiple; else desktopTemplate\"\n [disableRipple]=\"true\"\n [placeholder]=\"placeholder\"\n [formControl]=\"formControl\"\n [tabindex]=\"_tabindex\"\n [panelClass]=\"classList\"\n [style.width]=\"panelWidth\"\n (focus)=\"filterMatSelectFocusEvent($event)\"\n (blur)=\"filterMatSelectBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n [compareWith]=\"equals\"\n [multiple]=\"multiple\"\n [typeaheadDebounceInterval]=\"debounceTime * 10\"\n [required]=\"required\">\n <mat-select-trigger>{{ displayWith(value) }}</mat-select-trigger>\n\n <!-- Search bar -->\n <mat-option class=\"mat-select-searchbar\" *ngIf=\"showSearchBar\"\n [class.mat-select-searchbar-sticky]=\"stickySearchBar\"\n disabled>\n <ion-searchbar #ionSearchbar\n inputmode=\"search\"\n autocomplete=\"off\"\n animated=\"true\"\n showClearButton=\"true\"\n [debounce]=\"debounceTime\"\n (ionClear)=\"markAsLoading()\"\n (ionInput)=\"markAsLoading()\"\n (ionChange)=\"ionSearchBarChanged($event, $event.detail.value)\"\n [placeholder]=\"'COMMON.BTN_SEARCH'|translate\"\n ></ion-searchbar>\n </mat-option>\n\n <!-- Headers -->\n <ion-row class=\"mat-select-header column ion-no-padding\"\n [class.multiple]=\"multiple\"\n [class.mat-select-searchbar-sticky]=\"showSearchBar && stickySearchBar\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- None option -->\n <mat-option *ngIf=\"!required && !multiple && !clearable\" class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding\">\n <ion-label><i translate>COMMON.EMPTY_OPTION</i></ion-label>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <ng-container *ngIf=\"$filteredItems | async as items; else loadingTemplate\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <!-- Options -->\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initMatSelectInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- footer -->\n <mat-option *ngIf=\"itemCount as count\" class=\"mat-option-footer mat-autocomplete-footer ion-no-padding\" disabled>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </mat-option>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(displayValue | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-select>\n\n\n <!--\n NOTE :\n - \"selectInputContent($event) || onFocus.emit($event)\" : call onFocus only when to the input is empty (nothing to select)\n -->\n <ng-template #desktopTemplate>\n <input matInput #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"formControl\"\n [placeholder]=\"placeholder\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\">\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <!-- Headers -->\n <ion-row class=\"mat-autocomplete-header column ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <!-- Options -->\n <ng-container *ngIf=\"$filteredItems | async as items; else loadingTemplate\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label><i>{{noResultMessage | translate}}</i></ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: formControl.value, withAccent: highlightAccent }\"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(displayValue | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n\n <!-- footer -->\n <ion-row *ngIf=\"itemCount; let count\" class=\"mat-autocomplete-footer ion-no-padding\">\n <ion-col>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n </mat-autocomplete>\n\n </ng-template>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"!mobile && !multiple\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #headers>\n <ion-row class=\"mat-autocomplete-header ion-no-padding\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n</ng-template>\n\n<ng-template #options>\n\n\n</ng-template>\n\n",
|
|
2204
2206
|
providers: [{
|
|
2205
2207
|
provide: i1.NG_VALUE_ACCESSOR,
|
|
2206
2208
|
multi: true,
|
|
@@ -2221,6 +2223,7 @@
|
|
|
2221
2223
|
formControl: [{ type: i0.Input }],
|
|
2222
2224
|
formControlName: [{ type: i0.Input }],
|
|
2223
2225
|
floatLabel: [{ type: i0.Input }],
|
|
2226
|
+
appearance: [{ type: i0.Input }],
|
|
2224
2227
|
placeholder: [{ type: i0.Input }],
|
|
2225
2228
|
suggestFn: [{ type: i0.Input }],
|
|
2226
2229
|
required: [{ type: i0.Input }],
|
|
@@ -3343,26 +3346,6 @@
|
|
|
3343
3346
|
{ type: i0.Injectable }
|
|
3344
3347
|
];
|
|
3345
3348
|
|
|
3346
|
-
var PropertyGetPipe = /** @class */ (function () {
|
|
3347
|
-
function PropertyGetPipe() {
|
|
3348
|
-
}
|
|
3349
|
-
PropertyGetPipe.prototype.transform = function (obj, args) {
|
|
3350
|
-
return getPropertyByPath(obj,
|
|
3351
|
-
// Path
|
|
3352
|
-
args && (typeof args === 'string' ? args : args.key),
|
|
3353
|
-
// Default value
|
|
3354
|
-
args && args.defaultValue);
|
|
3355
|
-
};
|
|
3356
|
-
return PropertyGetPipe;
|
|
3357
|
-
}());
|
|
3358
|
-
PropertyGetPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function PropertyGetPipe_Factory() { return new PropertyGetPipe(); }, token: PropertyGetPipe, providedIn: "root" });
|
|
3359
|
-
PropertyGetPipe.decorators = [
|
|
3360
|
-
{ type: i0.Pipe, args: [{
|
|
3361
|
-
name: 'propertyGet'
|
|
3362
|
-
},] },
|
|
3363
|
-
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
|
|
3364
|
-
];
|
|
3365
|
-
|
|
3366
3349
|
var NgInitDirective = /** @class */ (function () {
|
|
3367
3350
|
function NgInitDirective() {
|
|
3368
3351
|
this.ngInit = new i0.EventEmitter();
|
|
@@ -4881,6 +4864,79 @@
|
|
|
4881
4864
|
{ type: i0.ChangeDetectorRef }
|
|
4882
4865
|
]; };
|
|
4883
4866
|
|
|
4867
|
+
var PropertyGetPipe = /** @class */ (function () {
|
|
4868
|
+
function PropertyGetPipe() {
|
|
4869
|
+
}
|
|
4870
|
+
PropertyGetPipe.prototype.transform = function (obj, args) {
|
|
4871
|
+
return getPropertyByPath(obj,
|
|
4872
|
+
// Path
|
|
4873
|
+
args && (typeof args === 'string' ? args : args.key),
|
|
4874
|
+
// Default value
|
|
4875
|
+
args && args.defaultValue);
|
|
4876
|
+
};
|
|
4877
|
+
return PropertyGetPipe;
|
|
4878
|
+
}());
|
|
4879
|
+
PropertyGetPipe.decorators = [
|
|
4880
|
+
{ type: i0.Pipe, args: [{
|
|
4881
|
+
name: 'propertyGet'
|
|
4882
|
+
},] }
|
|
4883
|
+
];
|
|
4884
|
+
var PropertyFormatPipe = /** @class */ (function () {
|
|
4885
|
+
function PropertyFormatPipe(dateFormat) {
|
|
4886
|
+
this.dateFormat = dateFormat;
|
|
4887
|
+
}
|
|
4888
|
+
PropertyFormatPipe.prototype.transform = function (obj, keyOrDefinition) {
|
|
4889
|
+
var _a, _b;
|
|
4890
|
+
if (!obj)
|
|
4891
|
+
return '';
|
|
4892
|
+
var definition = keyOrDefinition && (typeof keyOrDefinition === 'object') && keyOrDefinition;
|
|
4893
|
+
var key = (definition === null || definition === void 0 ? void 0 : definition.key) || keyOrDefinition;
|
|
4894
|
+
if (!key) {
|
|
4895
|
+
// Should never occur
|
|
4896
|
+
console.warn('Invalid use of pipe \'formatProperty\': missing key or definition');
|
|
4897
|
+
return '';
|
|
4898
|
+
}
|
|
4899
|
+
var value = obj[key];
|
|
4900
|
+
if (isNil(value))
|
|
4901
|
+
return value;
|
|
4902
|
+
var type = (definition === null || definition === void 0 ? void 0 : definition.type) || typeof value;
|
|
4903
|
+
switch (type) {
|
|
4904
|
+
case 'date':
|
|
4905
|
+
return this.dateFormat.transform(value);
|
|
4906
|
+
case 'dateTime':
|
|
4907
|
+
return this.dateFormat.transform(value, { time: true });
|
|
4908
|
+
case 'enum':
|
|
4909
|
+
{
|
|
4910
|
+
// DEBUG
|
|
4911
|
+
// console.debug('formatProperty by definition (type='enum', key=' +definition.key+ '):', value );
|
|
4912
|
+
var item = (definition.values || [value]).find(function (item) { return (isNotNil(item.key) ? item.key : item) === value; });
|
|
4913
|
+
return item.value || item;
|
|
4914
|
+
}
|
|
4915
|
+
case 'entity':
|
|
4916
|
+
{
|
|
4917
|
+
if ((_a = definition.autocomplete) === null || _a === void 0 ? void 0 : _a.displayWith) {
|
|
4918
|
+
return definition.autocomplete.displayWith(value);
|
|
4919
|
+
}
|
|
4920
|
+
return joinPropertiesPath(obj, ((_b = definition.autocomplete) === null || _b === void 0 ? void 0 : _b.attributes) || ['label', 'name']) || undefined;
|
|
4921
|
+
}
|
|
4922
|
+
case 'string':
|
|
4923
|
+
default:
|
|
4924
|
+
return value;
|
|
4925
|
+
}
|
|
4926
|
+
};
|
|
4927
|
+
return PropertyFormatPipe;
|
|
4928
|
+
}());
|
|
4929
|
+
PropertyFormatPipe.ɵprov = i0.ɵɵdefineInjectable({ factory: function PropertyFormatPipe_Factory() { return new PropertyFormatPipe(i0.ɵɵinject(DateFormatPipe)); }, token: PropertyFormatPipe, providedIn: "root" });
|
|
4930
|
+
PropertyFormatPipe.decorators = [
|
|
4931
|
+
{ type: i0.Pipe, args: [{
|
|
4932
|
+
name: 'propertyFormat'
|
|
4933
|
+
},] },
|
|
4934
|
+
{ type: i0.Injectable, args: [{ providedIn: 'root' },] }
|
|
4935
|
+
];
|
|
4936
|
+
PropertyFormatPipe.ctorParameters = function () { return [
|
|
4937
|
+
{ type: DateFormatPipe }
|
|
4938
|
+
]; };
|
|
4939
|
+
|
|
4884
4940
|
var SharedPipesModule = /** @class */ (function () {
|
|
4885
4941
|
function SharedPipesModule() {
|
|
4886
4942
|
}
|
|
@@ -4895,6 +4951,7 @@
|
|
|
4895
4951
|
],
|
|
4896
4952
|
declarations: [
|
|
4897
4953
|
PropertyGetPipe,
|
|
4954
|
+
PropertyFormatPipe,
|
|
4898
4955
|
DateFormatPipe,
|
|
4899
4956
|
DateDiffDurationPipe,
|
|
4900
4957
|
DurationPipe,
|
|
@@ -4931,10 +4988,12 @@
|
|
|
4931
4988
|
FormGetControlPipe,
|
|
4932
4989
|
FormGetArrayPipe,
|
|
4933
4990
|
FormGetGroupPipe,
|
|
4934
|
-
FormGetValuePipe
|
|
4991
|
+
FormGetValuePipe,
|
|
4992
|
+
PropertyFormatPipe
|
|
4935
4993
|
],
|
|
4936
4994
|
exports: [
|
|
4937
4995
|
PropertyGetPipe,
|
|
4996
|
+
PropertyFormatPipe,
|
|
4938
4997
|
DateFormatPipe,
|
|
4939
4998
|
DateFromNowPipe,
|
|
4940
4999
|
DateDiffDurationPipe,
|
|
@@ -5142,6 +5201,33 @@
|
|
|
5142
5201
|
ondrop: [{ type: i0.HostListener, args: ['drop', ['$event'],] }]
|
|
5143
5202
|
};
|
|
5144
5203
|
|
|
5204
|
+
var compatibleTagNames = ['ion-label', 'mat-label'];
|
|
5205
|
+
var AutoTitleDirective = /** @class */ (function () {
|
|
5206
|
+
function AutoTitleDirective(elementRef) {
|
|
5207
|
+
var _a;
|
|
5208
|
+
this.elementRef = elementRef;
|
|
5209
|
+
// Check compatible tag
|
|
5210
|
+
if (compatibleTagNames.includes((_a = elementRef.nativeElement.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase())) {
|
|
5211
|
+
this.element = elementRef.nativeElement;
|
|
5212
|
+
}
|
|
5213
|
+
}
|
|
5214
|
+
AutoTitleDirective.prototype.ngAfterContentChecked = function () {
|
|
5215
|
+
// Update title if different
|
|
5216
|
+
if (this.element && this.element.title !== this.element.textContent) {
|
|
5217
|
+
this.element.title = this.element.textContent;
|
|
5218
|
+
}
|
|
5219
|
+
};
|
|
5220
|
+
return AutoTitleDirective;
|
|
5221
|
+
}());
|
|
5222
|
+
AutoTitleDirective.decorators = [
|
|
5223
|
+
{ type: i0.Directive, args: [{
|
|
5224
|
+
selector: '[appAutoTitle]',
|
|
5225
|
+
},] }
|
|
5226
|
+
];
|
|
5227
|
+
AutoTitleDirective.ctorParameters = function () { return [
|
|
5228
|
+
{ type: i0.ElementRef, decorators: [{ type: i0.Inject, args: [i0.ElementRef,] }] }
|
|
5229
|
+
]; };
|
|
5230
|
+
|
|
5145
5231
|
var SharedDirectivesModule = /** @class */ (function () {
|
|
5146
5232
|
function SharedDirectivesModule() {
|
|
5147
5233
|
}
|
|
@@ -5156,12 +5242,14 @@
|
|
|
5156
5242
|
declarations: [
|
|
5157
5243
|
AutofocusDirective,
|
|
5158
5244
|
NgVarDirective,
|
|
5159
|
-
DragAndDropDirective
|
|
5245
|
+
DragAndDropDirective,
|
|
5246
|
+
AutoTitleDirective
|
|
5160
5247
|
],
|
|
5161
5248
|
exports: [
|
|
5162
5249
|
AutofocusDirective,
|
|
5163
5250
|
NgVarDirective,
|
|
5164
|
-
DragAndDropDirective
|
|
5251
|
+
DragAndDropDirective,
|
|
5252
|
+
AutoTitleDirective
|
|
5165
5253
|
]
|
|
5166
5254
|
},] }
|
|
5167
5255
|
];
|
|
@@ -8237,7 +8325,7 @@
|
|
|
8237
8325
|
MatSwipeField.decorators = [
|
|
8238
8326
|
{ type: i0.Component, args: [{
|
|
8239
8327
|
selector: 'mat-swipe-field',
|
|
8240
|
-
template: "<mat-form-field [floatLabel]=\"showSlides && (!floatLabel || floatLabel === 'auto') ? 'always': floatLabel\"\n [class]=\"classList\"\n [class.mat-form-field-disabled]=\"disabled\">\n <mat-label *ngIf=\"placeholder && floatLabel!=='never'\">\n {{placeholder}}\n </mat-label>\n <input matInput #fakeInput type=\"text\"\n [formControl]=\"formControl\"\n [readonly]=\"true\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showSlides\"\n [tabindex]=\"tabindex\">\n\n <div class=\"slides-container\" [class.hidden]=\"!showSlides\">\n <ion-slides #slides\n [options]=\"slidesOptions\"\n (ionSlidesDidLoad)=\"slidesLoaded()\"\n (ionSlideReachStart)=\"reachStart(true)\"\n (ionSlideReachEnd)=\"reachEnd(true)\"\n (ionSlideNextEnd)=\"reachStart(false)\"\n (ionSlidePrevEnd)=\"reachEnd(false)\"\n (ionSlideDidChange)=\"slideChanged()\"\n >\n <ion-slide *ngFor=\"let item of $items | async\">\n <ion-label>{{ displayWith(item) }}</ion-label>\n </ion-slide>\n\n </ion-slides>\n </div>\n\n <button #prevButton\n mat-icon-button\n type=\"button\"\n class=\"button-prev\"\n [hidden]=\"!showSlides\"\n [disabled]=\"previousDisabled\"\n (click)=\"previous()\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button #nextButton\n mat-icon-button\n type=\"button\"\n class=\"button-next\"\n [hidden]=\"!showSlides\"\n [disabled]=\"nextDisabled\"\n (click)=\"next()\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n\n</mat-form-field>\n",
|
|
8328
|
+
template: "<mat-form-field [floatLabel]=\"showSlides && (!floatLabel || floatLabel === 'auto') ? 'always': floatLabel\"\n [appearance]=\"appearance\"\n [class]=\"classList\"\n [class.mat-form-field-disabled]=\"disabled\">\n <mat-label *ngIf=\"placeholder && floatLabel!=='never'\">\n {{placeholder}}\n </mat-label>\n <input matInput #fakeInput type=\"text\"\n [formControl]=\"formControl\"\n [readonly]=\"true\"\n (focus)=\"_onFocusFakeInput($event)\"\n [required]=\"required\"\n [class.cdk-visually-hidden]=\"showSlides\"\n [tabindex]=\"tabindex\">\n\n <div class=\"slides-container\" [class.hidden]=\"!showSlides\">\n <ion-slides #slides\n [options]=\"slidesOptions\"\n (ionSlidesDidLoad)=\"slidesLoaded()\"\n (ionSlideReachStart)=\"reachStart(true)\"\n (ionSlideReachEnd)=\"reachEnd(true)\"\n (ionSlideNextEnd)=\"reachStart(false)\"\n (ionSlidePrevEnd)=\"reachEnd(false)\"\n (ionSlideDidChange)=\"slideChanged()\"\n >\n <ion-slide *ngFor=\"let item of $items | async\">\n <ion-label>{{ displayWith(item) }}</ion-label>\n </ion-slide>\n\n </ion-slides>\n </div>\n\n <button #prevButton\n mat-icon-button\n type=\"button\"\n class=\"button-prev\"\n [hidden]=\"!showSlides\"\n [disabled]=\"previousDisabled\"\n (click)=\"previous()\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button #nextButton\n mat-icon-button\n type=\"button\"\n class=\"button-next\"\n [hidden]=\"!showSlides\"\n [disabled]=\"nextDisabled\"\n (click)=\"next()\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n\n <button matSuffix mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"formControl.hasError('entity')\" translate>ERROR.FIELD_INVALID</mat-error>\n\n</mat-form-field>\n",
|
|
8241
8329
|
providers: [DEFAULT_VALUE_ACCESSOR$5],
|
|
8242
8330
|
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
8243
8331
|
styles: [":host{display:inline-block;width:100%;position:relative}input.hidden{display:none}.slides-container .swiper-slide{font-size:16px!important}.slides-container.hidden{visibility:hidden;height:0!important}.button-next,.button-prev{position:absolute;top:calc(50% - 20px);z-index:10}.button-prev{left:0;right:auto}.button-next{left:auto;right:0}"]
|
|
@@ -8252,6 +8340,7 @@
|
|
|
8252
8340
|
formControl: [{ type: i0.Input }],
|
|
8253
8341
|
formControlName: [{ type: i0.Input }],
|
|
8254
8342
|
floatLabel: [{ type: i0.Input }],
|
|
8343
|
+
appearance: [{ type: i0.Input }],
|
|
8255
8344
|
placeholder: [{ type: i0.Input }],
|
|
8256
8345
|
debug: [{ type: i0.Input }],
|
|
8257
8346
|
required: [{ type: i0.Input }],
|
|
@@ -8928,7 +9017,7 @@
|
|
|
8928
9017
|
{ type: i0.Component, args: [{
|
|
8929
9018
|
// eslint-disable-next-line @angular-eslint/component-selector
|
|
8930
9019
|
selector: 'mat-chips-field',
|
|
8931
|
-
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"
|
|
9020
|
+
template: "<ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col class=\"ion-no-padding\">\n <mat-form-field [floatLabel]=\"floatLabel\"\n [appearance]=\"appearance\"\n class=\"material-chips\" [class.mat-form-field-disabled]=\"disabled\">\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n <mat-label>{{placeholder}}</mat-label>\n <mat-chip-list #chipList\n (focus)=\"filterChipsFocusEvent($event)\" >\n <mat-chip\n *ngFor=\"let item of value\"\n [selectable]=\"false\"\n [removable]=\"!disabled\"\n (removed)=\"remove(item)\"\n [color]=\"chipColor\"\n >\n {{displayWith(item)}}\n <mat-icon matChipRemove *ngIf=\"!disabled\">cancel</mat-icon>\n </mat-chip>\n\n <input #matInputText type=\"text\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"matAutocompletePosition\"\n [formControl]=\"inputControl\"\n [appAutofocus]=\"autofocus\"\n [tabindex]=\"_tabindex\"\n [readonly]=\"disabled\"\n [hidden]=\"disabled\"\n [required]=\"required\"\n (click)=\"clicked.emit($event)\"\n (focus)=\"filterInputTextFocusEvent($event)\"\n (blur)=\"filterInputTextBlurEvent($event)\"\n (keydown.escape)=\"keydownEscape.emit($event)\"\n (keyup.enter)=\"keyupEnter.emit($event)\"\n (keyup.arrowdown)=\"!autocomplete.showPanel && dropButtonClick.emit($event)\"\n [matChipInputFor]=\"chipList\"\n >\n </mat-chip-list>\n\n <!-- autocomplete -->\n <mat-autocomplete #autocomplete=\"matAutocomplete\"\n (optionSelected)=\"add($event)\"\n autoActiveFirstOption\n [displayWith]=\"displayWith\"\n [class]=\"classList\"\n [panelWidth]=\"panelWidth\">\n <ion-row class=\"mat-autocomplete-header ion-no-padding column\">\n <ion-col *ngFor=\"let attr of displayAttributes; index as i\" [size]=\"displayColumnSizes[i]\">\n <ion-label [innerHTML]=\"displayColumnNames[i] | translate\"></ion-label>\n </ion-col>\n </ion-row>\n\n <ng-container *ngIf=\"$filteredItems | async as items; else loadingTemplate\">\n <!-- No item option -->\n <mat-option *ngIf=\"items | isEmptyArray\" class=\"ion-padding text-italic\" disabled>\n <ion-label>{{noResultMessage | translate}}</ion-label>\n </mat-option>\n\n <mat-option *ngFor=\"let item of items\" [value]=\"item\" class=\"ion-no-padding\">\n <ion-row [classList]=\"item.classList\">\n <ion-col *ngFor=\"let path of displayAttributes; index as i;\"\n [size]=\"displayColumnSizes[i]\">\n <ion-text [innerHTML]=\"item | propertyGet: path | highlight: { search: inputControl.value, withAccent: highlightAccent } \"></ion-text>\n </ion-col>\n </ion-row>\n </mat-option>\n\n <!-- More item -->\n <mat-option *ngIf=\"_moreItemsCount\" (ngInit)=\"_initAutocompleteInfiniteScroll()\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-container>\n\n <!-- footer -->\n <ion-row *ngIf=\"itemCount as count\"\n class=\"mat-autocomplete-footer ion-no-padding\">\n <ion-col>\n <ion-text class=\"ion-float-end ion-padding-end\"><i>{{'COMMON.RESULT_COUNT'|translate: {count: count} }}</i></ion-text>\n </ion-col>\n </ion-row>\n\n <!-- Loading spinner -->\n <ng-template #loadingTemplate>\n <mat-option *ngIf=\"(matInputText.value | strLength) >= suggestLengthThreshold; else waitMoreCharacterTemplate\"\n class=\"ion-padding\" disabled>\n <ion-skeleton-text [animated]=\"true\" style=\"width: 100%\"></ion-skeleton-text>\n </mat-option>\n </ng-template>\n\n <!-- Need more characters -->\n <ng-template #waitMoreCharacterTemplate>\n <mat-option class=\"ion-padding text-italic\" disabled>\n <ion-label>\n {{'INFO.PLEASE_TYPE_MORE_CHARACTERS'|translate:{minLength: suggestLengthThreshold} }}\n </ion-label>\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <mat-error *ngIf=\"formControl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <ng-content select=\"[matError]\"></ng-content>\n\n </mat-form-field>\n\n </ion-col>\n <ion-col size=\"auto\" class=\"ion-align-self-center\">\n <ng-content select=\"[matAfter]\"></ng-content>\n </ion-col>\n </ion-row>\n</ion-grid>\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n\n<ng-template #matSuffixTemplate>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n (click)=\"dropButtonClick.emit($event)\"\n [hidden]=\"disabled\">\n <mat-icon class=\"large select-arrow\">arrow_drop_down</mat-icon>\n </button>\n <button mat-icon-button tabindex=\"-1\"\n type=\"button\"\n *ngIf=\"clearable\"\n (click)=\"clearValue($event)\"\n [hidden]=\"disabled || !formControl.value\">\n <mat-icon>close</mat-icon>\n </button>\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n",
|
|
8932
9021
|
providers: [{
|
|
8933
9022
|
provide: i1.NG_VALUE_ACCESSOR,
|
|
8934
9023
|
multi: true,
|
|
@@ -8949,6 +9038,7 @@
|
|
|
8949
9038
|
formControl: [{ type: i0.Input }],
|
|
8950
9039
|
formControlName: [{ type: i0.Input }],
|
|
8951
9040
|
floatLabel: [{ type: i0.Input }],
|
|
9041
|
+
appearance: [{ type: i0.Input }],
|
|
8952
9042
|
placeholder: [{ type: i0.Input }],
|
|
8953
9043
|
suggestFn: [{ type: i0.Input }],
|
|
8954
9044
|
required: [{ type: i0.Input }],
|
|
@@ -18238,6 +18328,8 @@
|
|
|
18238
18328
|
};
|
|
18239
18329
|
return FilesUtils;
|
|
18240
18330
|
}());
|
|
18331
|
+
FilesUtils.UTF8_BOM_CHAR = new Uint8Array([0xEF, 0xBB, 0xBF]); // UTF-8 BOM
|
|
18332
|
+
|
|
18241
18333
|
var UriUtils = /** @class */ (function () {
|
|
18242
18334
|
function UriUtils() {
|
|
18243
18335
|
}
|
|
@@ -20752,6 +20844,94 @@
|
|
|
20752
20844
|
return JobUtils;
|
|
20753
20845
|
}());
|
|
20754
20846
|
|
|
20847
|
+
//@dynamic
|
|
20848
|
+
var CsvUtils = /** @class */ (function () {
|
|
20849
|
+
function CsvUtils() {
|
|
20850
|
+
}
|
|
20851
|
+
CsvUtils.exportToFile = function (rows, opts) {
|
|
20852
|
+
if (!rows || !rows.length)
|
|
20853
|
+
return; // Skip if empty
|
|
20854
|
+
var filename = (opts === null || opts === void 0 ? void 0 : opts.filename) || 'export.csv';
|
|
20855
|
+
var charset = ((opts === null || opts === void 0 ? void 0 : opts.encoding) || 'utf-8').toLowerCase();
|
|
20856
|
+
var separator = (opts === null || opts === void 0 ? void 0 : opts.separator) || ',';
|
|
20857
|
+
var protectCellRegexp = new RegExp("/(\"|" + separator + "|\n)/g");
|
|
20858
|
+
var keys = Object.keys(rows[0]);
|
|
20859
|
+
var headers = (opts === null || opts === void 0 ? void 0 : opts.headers) || keys;
|
|
20860
|
+
var csvContent =
|
|
20861
|
+
// Header row
|
|
20862
|
+
headers.join(separator) + '\n' +
|
|
20863
|
+
// Data rows
|
|
20864
|
+
rows.map(function (row) {
|
|
20865
|
+
return keys.map(function (k) {
|
|
20866
|
+
var cell = row[k] === null || row[k] === undefined ? '' : row[k];
|
|
20867
|
+
var cellStr = cell instanceof Date
|
|
20868
|
+
? cell.toLocaleString()
|
|
20869
|
+
: cell.toString().replace(/"/g, '""');
|
|
20870
|
+
if (protectCellRegexp.test(cellStr)) {
|
|
20871
|
+
cellStr = "\"" + cellStr + "\"";
|
|
20872
|
+
}
|
|
20873
|
+
return cellStr;
|
|
20874
|
+
}).join(separator);
|
|
20875
|
+
}).join('\n');
|
|
20876
|
+
var blob = new Blob((charset === 'utf-8')
|
|
20877
|
+
// Add UTF-8 BOM character
|
|
20878
|
+
? [FilesUtils.UTF8_BOM_CHAR, csvContent]
|
|
20879
|
+
// Non UTF-8 charset
|
|
20880
|
+
: [csvContent], { type: "text/csv;charset=" + charset + ";" });
|
|
20881
|
+
if (navigator.msSaveBlob) { // IE 10+
|
|
20882
|
+
navigator.msSaveBlob(blob, filename);
|
|
20883
|
+
}
|
|
20884
|
+
else {
|
|
20885
|
+
var link = document.createElement('a');
|
|
20886
|
+
if (link.download !== undefined) {
|
|
20887
|
+
// Browsers that support HTML5 download attribute
|
|
20888
|
+
var url = URL.createObjectURL(blob);
|
|
20889
|
+
link.setAttribute('href', url);
|
|
20890
|
+
link.setAttribute('download', filename);
|
|
20891
|
+
link.style.visibility = 'hidden';
|
|
20892
|
+
document.body.appendChild(link);
|
|
20893
|
+
link.click();
|
|
20894
|
+
document.body.removeChild(link);
|
|
20895
|
+
}
|
|
20896
|
+
}
|
|
20897
|
+
};
|
|
20898
|
+
CsvUtils.parseFile = function (file, opts) {
|
|
20899
|
+
return FilesUtils.readAsText(file, opts === null || opts === void 0 ? void 0 : opts.encoding)
|
|
20900
|
+
.pipe(operators.map(function (e) {
|
|
20901
|
+
if (e.type === i2$1.HttpEventType.UploadProgress) {
|
|
20902
|
+
var loaded = Math.round(e.loaded * 0.8);
|
|
20903
|
+
return Object.assign(Object.assign({}, e), { loaded: loaded });
|
|
20904
|
+
}
|
|
20905
|
+
else if (e instanceof FileResponse) {
|
|
20906
|
+
var body = e.body;
|
|
20907
|
+
var data = CsvUtils.parseCSV(body, opts);
|
|
20908
|
+
return new FileResponse({ body: data });
|
|
20909
|
+
}
|
|
20910
|
+
}), operators.filter(isNotNil));
|
|
20911
|
+
};
|
|
20912
|
+
CsvUtils.parseCSV = function (body, opts) {
|
|
20913
|
+
var separator = (opts === null || opts === void 0 ? void 0 : opts.separator) || ',';
|
|
20914
|
+
var skipEmptyLine = !opts || opts.skipEmptyLine !== false;
|
|
20915
|
+
// Protect special characters (quote and /n)
|
|
20916
|
+
body = body.replace('""', '<quote>') // Protect double quote
|
|
20917
|
+
.replace(/("[^\n"]+)\n\r?/gm, '"$1<br>') // Protect \n inside a quoted expression
|
|
20918
|
+
.replace(/\n\r/gm, '\n'); // Windows CR
|
|
20919
|
+
var headerAndRows = body.split('\n', 2);
|
|
20920
|
+
var headers = headerAndRows[0].split(separator);
|
|
20921
|
+
return body.split('\n') // split into rows
|
|
20922
|
+
.filter(function (line) { return !skipEmptyLine || line.trim().length > 0; }) // Skip empty line
|
|
20923
|
+
.map(function (line) {
|
|
20924
|
+
var cells = line.split(separator, headers.length) // split into cells
|
|
20925
|
+
.map(function (cell) { return cell.replace(/^"([^"]*)"$/, '$1'); }) // Clean trailing quotes
|
|
20926
|
+
.map(function (cell) { return cell.replace('<quote>', '"'); }) // restore protected quote
|
|
20927
|
+
.map(function (cell) { return cell.replace('<br>', '\n'); }) // restore protected br
|
|
20928
|
+
;
|
|
20929
|
+
return cells;
|
|
20930
|
+
});
|
|
20931
|
+
};
|
|
20932
|
+
return CsvUtils;
|
|
20933
|
+
}());
|
|
20934
|
+
|
|
20755
20935
|
/**
|
|
20756
20936
|
* Define here theme colors
|
|
20757
20937
|
*/
|
|
@@ -32201,6 +32381,7 @@
|
|
|
32201
32381
|
exports.AuthForm = AuthForm;
|
|
32202
32382
|
exports.AuthGuardService = AuthGuardService;
|
|
32203
32383
|
exports.AuthModal = AuthModal;
|
|
32384
|
+
exports.AutoTitleDirective = AutoTitleDirective;
|
|
32204
32385
|
exports.AutocompleteTestPage = AutocompleteTestPage;
|
|
32205
32386
|
exports.AutofocusDirective = AutofocusDirective;
|
|
32206
32387
|
exports.Base58 = Base58;
|
|
@@ -32220,6 +32401,7 @@
|
|
|
32220
32401
|
exports.CoreModule = CoreModule;
|
|
32221
32402
|
exports.CoreTestingModule = CoreTestingModule;
|
|
32222
32403
|
exports.CryptoService = CryptoService;
|
|
32404
|
+
exports.CsvUtils = CsvUtils;
|
|
32223
32405
|
exports.DATE_ISO_PATTERN = DATE_ISO_PATTERN;
|
|
32224
32406
|
exports.DATE_UNIX_MS_TIMESTAMP = DATE_UNIX_MS_TIMESTAMP;
|
|
32225
32407
|
exports.DATE_UNIX_TIMESTAMP = DATE_UNIX_TIMESTAMP;
|
|
@@ -32340,6 +32522,7 @@
|
|
|
32340
32522
|
exports.PlatformService = PlatformService;
|
|
32341
32523
|
exports.ProgressBarService = ProgressBarService;
|
|
32342
32524
|
exports.ProgressInterceptor = ProgressInterceptor;
|
|
32525
|
+
exports.PropertyFormatPipe = PropertyFormatPipe;
|
|
32343
32526
|
exports.PropertyGetPipe = PropertyGetPipe;
|
|
32344
32527
|
exports.RESERVED_END_COLUMNS = RESERVED_END_COLUMNS;
|
|
32345
32528
|
exports.RESERVED_START_COLUMNS = RESERVED_START_COLUMNS;
|