@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
360 lines • 119 kB
JavaScript
import { __decorate } from "tslib";
/**
* Copyright (C) 2020-2024 Linagora
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU
* Affero General Public License, subsections (b), (c), and (e), pursuant to
* which these Appropriate Legal Notices must notably (i) retain the display of
* the "LinID™" trademark/logo at the top of the interface window, the display
* of the “You are using the Open Source and free version of LinID™, powered by
* Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise
* offer!” infobox and in the e-mails sent with the Program, notice appended to
* any type of outbound messages (e.g. e-mail and meeting requests) as well as
* in the LinID Directory Manager user interface, (ii) retain all hypertext
* links between LinID Directory Manager and https://linid.org/, as well as
* between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
* intellectual property rights over its trademarks and commercial brands. Other
* Additional Terms apply, see <http://www.linagora.com/licenses/> for more
* details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinID Directory Manager along with this
* program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
* General Public License version 3 and <http://www.linagora.com/licenses/> for
* the Additional Terms applicable to the LinID Directory Manager software.
*/
import { HttpErrorResponse } from '@angular/common/http';
import { Component, EventEmitter, Inject, Output, ViewChild, } from '@angular/core';
import { FormControl, Validators, } from '@angular/forms';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatTableDataSource } from '@angular/material/table';
import { Select } from '@ngxs/store';
import { Subject, catchError, defaultIfEmpty, filter, forkJoin, map, takeUntil, tap, } from 'rxjs';
import { ConfigsState, CustomValidators, Data, DataState, EEllipsisMenuActions, EResourceComponent, ETreeSelectMode, Error as ErrorActions, ResourcesTypesState, buildTree, cleanAssignDialogTree, convertDataNodeToDataItem, getClickableCellsEndpoints, getDataSourceForGenericArray, getElementIds, getFlattenTree, getFormFieldError, getNodeById, getRequestsDetails, getResponseAttributesIds, getUserActionOnResourceRequest, isDataNode, resourceRequest, toJsTable, } from '../../shared';
import * as i0 from "@angular/core";
import * as i1 from "../../shared";
import * as i2 from "@ngxs/store";
import * as i3 from "@angular/forms";
import * as i4 from "@angular/common";
import * as i5 from "@angular/flex-layout/flex";
import * as i6 from "@angular/flex-layout/extended";
import * as i7 from "@angular/material/button";
import * as i8 from "@angular/material/dialog";
import * as i9 from "@angular/material/form-field";
import * as i10 from "@angular/material/input";
import * as i11 from "../../shared/directives/omit-chars.directive";
import * as i12 from "../../ui/generic-array-header/generic-array-header.component";
import * as i13 from "../../ui/loading-spinner/loading-spinner.component";
import * as i14 from "../generic-array/generic-array.component";
import * as i15 from "../generic-list/generic-list.component";
import * as i16 from "../generic-tree/generic-tree.component";
import * as i17 from "../search-bar/search-bar.component";
var EBrowseState;
(function (EBrowseState) {
EBrowseState["PREVIOUS"] = "previous";
EBrowseState["NEXT"] = "NEXT";
})(EBrowseState || (EBrowseState = {}));
export class ConfirmDialogComponent {
constructor(data, _interactionsService, _store$, _dataService, _errorHandlerService, _fb) {
this.data = data;
this._interactionsService = _interactionsService;
this._store$ = _store$;
this._dataService = _dataService;
this._errorHandlerService = _errorHandlerService;
this._fb = _fb;
this.onDestroy$ = new Subject();
this.dataSource = new MatTableDataSource();
this.selectedElementsIdsForEdit = [];
this.selectedNodesId = [];
this.selectedElements = [];
this.selectedElementsUiIds = [];
this.isActiveSearch = false;
this.isAssignAction = false;
this.isTwoStepsAssignAction = false;
this.isReassignAction = false;
this.isRemovingAction = false;
this.isEditingAction = false;
this.isMovingNodeAction = false;
this.stepNumber = 1;
this.browseStates = EBrowseState;
this.resourcesComponents = EResourceComponent;
this.treeSelectMode = ETreeSelectMode;
this.isMovingToAnotherEntry = false;
this.action$ = new EventEmitter();
}
ngOnInit() {
this.selectedElementsUiIds = this.data.selectedElementsUiIds;
this.isAssignAction = this.data.dialogAction === 'assign';
this.isTwoStepsAssignAction =
this.isAssignAction &&
this.data.updateActionsParams.assign.isMultipleStepsAssign;
this.isReassignAction =
this.data.dialogAction === EEllipsisMenuActions.SINGLE_REASSIGN ||
this.data.dialogAction === EEllipsisMenuActions.MULTIPLE_REASSIGN;
this.isRemovingAction =
this.data.dialogAction === EEllipsisMenuActions.DELETE ||
this.data.dialogAction === EEllipsisMenuActions.DELETE_CHILD ||
this.data.dialogAction === EEllipsisMenuActions.DELETE_CHILDREN ||
this.data.dialogAction === EEllipsisMenuActions.SINGLE_DELETE ||
this.data.dialogAction === EEllipsisMenuActions.MULTIPLE_DELETE ||
this.data.dialogAction === EEllipsisMenuActions.SINGLE_UNASSIGN ||
this.data.dialogAction === EEllipsisMenuActions.MULTIPLE_UNASSIGN;
this.isEditingAction =
this.data.dialogAction === EEllipsisMenuActions.SINGLE_EDIT ||
this.data.dialogAction === EEllipsisMenuActions.MULTIPLE_EDIT;
this.isMovingNodeAction =
this.data.dialogAction === EEllipsisMenuActions.MOVE_NODE;
if (this.isReassignAction ||
this.isTwoStepsAssignAction ||
this.isEditingAction) {
this.selectedResourceTypeId = this._store$.selectSnapshot(DataState.getSelectedResourceTypeId);
}
if (this.isEditingAction || this.isTwoStepsAssignAction) {
const allAttributesConfig = this._store$.selectSnapshot(ConfigsState.getConfigsById)[this.selectedResourceTypeId]?.attributes;
this.attributeConfig = allAttributesConfig.find((attribute) => attribute.modelRef === this.data.attributeModelRef);
}
if (this.isReassignAction) {
switch (this.data.updateActionsParams.reassign.resourceTypeComponent) {
case EResourceComponent.TREE:
this._interactionsService.displayedDataTree$
.pipe(takeUntil(this.onDestroy$), tap((dataTree) => {
this.dataTree = [...dataTree];
this.flattenDataTree = getFlattenTree(this.dataTree);
}))
.subscribe();
break;
case EResourceComponent.LIST:
this._interactionsService.displayedDataList$
.pipe(takeUntil(this.onDestroy$), tap((dataList) => (this.dataList = [...dataList])))
.subscribe();
break;
}
}
else if (this.isMovingNodeAction) {
const selectedResourceTypeId = this._store$.selectSnapshot(DataState.getSelectedResourceTypeId);
this.resourceTypeComponent = this._store$.selectSnapshot(ConfigsState.getConfigsById)[selectedResourceTypeId]?.component;
this._interactionsService.displayedDataTree$
.pipe(takeUntil(this.onDestroy$), tap((dataTree) => {
this.dataTree = [...dataTree];
this.flattenDataTree = getFlattenTree(this.dataTree);
const triggerNode = this.flattenDataTree.find((node) => node.ids.id === this.data.triggerElementId);
if (triggerNode) {
this.isMovingToAnotherEntry = triggerNode.parentIds.id === 'root';
}
}))
.subscribe();
}
else if (this.isAssignAction &&
this.data.updateActionsParams.assign.resourceTypeComponent ===
EResourceComponent.TREE) {
const resourcesTypes = this._store$.selectSnapshot(ResourcesTypesState.getResourcesTypesJsTable);
const configs = this._store$.selectSnapshot(ConfigsState.getConfigsJsTable);
const treeRequestsDetails = getRequestsDetails(this.data.updateActionsParams.assign.requestedResourceTypeId, configs, resourcesTypes, this.data.updateActionsParams.assign.assignedResourceTypeId);
this._interactionsService.isProcessingRequest(true);
let areTreeRequestsIn404Error = false;
forkJoin(treeRequestsDetails.map((treeRequestDetail) => {
const responseAttributesIds = getResponseAttributesIds(configs.byId[treeRequestDetail.resourceTypeId], treeRequestDetail.resourceTypeId);
return resourceRequest(null, treeRequestDetail, responseAttributesIds, this._dataService).pipe(map((response) => 'body' in response
? response.body
: response), catchError((error) => {
if (!areTreeRequestsIn404Error) {
this._store$.dispatch([
new ErrorActions.SetErrorDetail({
error,
userActionOnError: getUserActionOnResourceRequest(this.data.updateActionsParams.assign
.resourceTypeComponent),
}),
new ErrorActions.IsHandlingError(true),
]);
}
areTreeRequestsIn404Error =
!areTreeRequestsIn404Error &&
error instanceof HttpErrorResponse &&
error.status === 404;
return this._errorHandlerService.handleError(error);
}));
}))
.pipe(takeUntil(this.onDestroy$), filter((resources) => {
this._interactionsService.isProcessingRequest(false);
const oneRequestFailed = resources.some((resource) => resource instanceof Error ||
resource instanceof HttpErrorResponse);
if (oneRequestFailed) {
this._store$.dispatch(new Data.FetchResourcesError());
this.dataTreeAssignAction = [];
}
return !oneRequestFailed;
}), defaultIfEmpty([]), tap((resources) => {
const resourcesAsJsTable = toJsTable(resources.reduce((acc, curr, index) => ({
...acc,
[treeRequestsDetails[index].resourceTypeId]: {
...curr,
Resources: curr.Resources.filter((data) => !this.data.displayedArrayRowsIds.includes(data.id)),
},
}), {}));
this.dataTreeAssignAction = cleanAssignDialogTree(buildTree(resourcesAsJsTable, configs, treeRequestsDetails), this.data.updateActionsParams.assign.assignedResourceTypeId);
this.flattenDataTree = getFlattenTree(this.dataTreeAssignAction);
}))
.subscribe();
}
else if (this.isEditingAction) {
this.selectedElementsIdsForEdit = this.data.selectedElementsUiIds;
this._setEditForm();
}
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
onSelectedNode(node) {
this.selectedNode = node;
}
onSelectedItem(item) {
this.selectedItem = item;
if (this.isMovingNodeAction) {
switch (this.resourceTypeComponent) {
case EResourceComponent.TREE:
this.selectedNode = getNodeById(this.selectedItem.ids.id, this.dataTree);
break;
default:
break;
}
}
}
onSearch(event) {
if (this.isMovingNodeAction) {
this.dataList = event.map((node) => convertDataNodeToDataItem(node, 'link'));
}
else if (this.isAssignAction) {
if (this.data.fieldForUpdate) {
event.Resources?.forEach((data) => {
data = {
...data,
meta: {
...data.meta,
isModifiable: data.meta.isModifiable &&
data.meta.modifiableAttributes.includes(this.data.fieldForUpdate),
},
};
});
}
const dataResourcesAsFlatArray = getDataSourceForGenericArray(event, this.data.assignArrayViewProperties.resourceTypeConfig, getClickableCellsEndpoints(this._store$.selectSnapshot(ResourcesTypesState.getResourcesTypesJsTable), this._store$.selectSnapshot(ConfigsState.getConfigsAllIds), this.data.assignArrayViewProperties.resourceTypeConfig), true);
this.dataSource = new MatTableDataSource(dataResourcesAsFlatArray.filter((resource) => !this.data.displayedArrayRowsIds.includes(resource.id)));
}
}
onResetSearch() {
this.dataSource.data = [];
this.dataList = [];
}
onActiveSearch(event) {
this.isActiveSearch = event;
}
selectedData(data) {
if (this.data.updateActionsParams.assign.resourceTypeComponent ===
EResourceComponent.TREE) {
this.selectedElements = data;
this.selectedNodesId = this.selectedElements
.filter((element) => isDataNode(element))
.map((node) => node.ids.id);
}
else {
this.selectedElements = data;
this.selectedElementsUiIds = this.selectedElements.map((element) => element.selectionIds);
}
}
getChildHeight() {
if (!!this.genericList) {
return this.genericList.elementRef.nativeElement.offsetHeight;
}
else if (!!(this.divArrayHeader && this.searchBar && this.divContentArray)) {
return (this.divArrayHeader.nativeElement.offsetHeight +
this.searchBar.elementRef.nativeElement.offsetHeight +
this.divContentArray.nativeElement.offsetHeight);
}
else {
return 0;
}
}
submitAction() {
this.action$.emit();
}
_setEditForm() {
this.editForm = this._fb.group(this.selectedElementsIdsForEdit.reduce((acc, ids) => {
this.formErrors = { ...this.formErrors, [ids.id]: null };
return {
...acc,
[ids.id]: new FormControl(this.data.mapSelectedElementIdEditableValue?.get(ids.id), this._getValidators(this.data.updateActionsParams.edit)),
};
}, {}));
}
changeAssignStep(state) {
if (state === EBrowseState.NEXT) {
this.selectedElementsIdsForEdit = [];
this.selectedElements.forEach((element) => {
const ids = getElementIds(element);
this.selectedElementsIdsForEdit.push(ids);
if (!!this.editForm && !this.editForm.contains(ids.id)) {
this.formErrors = { ...this.formErrors, [ids.id]: null };
this.editForm.addControl(ids.id, new FormControl(null, this._getValidators(this.data.updateActionsParams.edit)));
}
});
if (!!this.editForm) {
const selectedElementsId = this.selectedElementsIdsForEdit.map((ids) => ids.id);
Object.keys(this.editForm.controls).forEach((id) => {
if (!selectedElementsId.includes(id)) {
this.editForm.removeControl(id);
delete this.formErrors[id];
}
});
}
else {
this._setEditForm();
}
this.stepNumber++;
}
else if (state === EBrowseState.PREVIOUS) {
this.stepNumber--;
if (this.isMovingNodeAction) {
this.isMovingToAnotherEntry = false;
this.dataList = [];
}
}
}
_getValidators(editParams) {
let validators = [Validators.required];
if (editParams.props.isInteger) {
validators.push(Validators.compose([
Validators.min(editParams.props.min),
CustomValidators.validIntegerCharacters(),
]));
}
return validators;
}
checkFormValue(fieldId) {
this.formErrors[fieldId] = getFormFieldError(this.editForm.get(fieldId), this.attributeConfig);
}
moveToRoot() {
this.selectedNode = null;
this.action$.emit();
}
moveToAnotherEntry() {
this.stepNumber++;
this.isMovingToAnotherEntry = true;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.InteractionsService }, { token: i2.Store }, { token: i1.DataService }, { token: i1.ErrorsHandlerService }, { token: i3.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: ConfirmDialogComponent, selector: "dm-confirm-dialog", outputs: { action$: "action$" }, viewQueries: [{ propertyName: "searchBar", first: true, predicate: ["searchBar"], descendants: true }, { propertyName: "divArrayHeader", first: true, predicate: ["divArrayHeader"], descendants: true }, { propertyName: "divContentArray", first: true, predicate: ["divContentArray"], descendants: true }, { propertyName: "genericList", first: true, predicate: ["genericList"], descendants: true }, { propertyName: "assignTree", first: true, predicate: ["assignTree"], descendants: true }], ngImport: i0, template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<h3 mat-dialog-title [innerHTML]=\"data.title\" class=\"title\"></h3>\n<mat-dialog-content class=\"mat-dialog-content\">\n <div\n *ngIf=\"\n !isEditingAction &&\n !isMovingNodeAction &&\n !(isAssignAction && dataSource?.data?.length > 0)\n \"\n class=\"div-selected-elements\"\n >\n <span *ngFor=\"let element of selectedElementsUiIds; let i = index\">\n <span *ngIf=\"i < 10\">\n <span\n *ngIf=\"\n i < 9 && i < selectedElementsUiIds?.length - 1;\n else lastElement\n \"\n >\n {{ element.label }},\n </span>\n <ng-template #lastElement>{{ element.label }}</ng-template>\n </span>\n </span>\n <span *ngIf=\"selectedElementsUiIds?.length > 10\">\n {{ '... (+' + (selectedElementsUiIds.length - 10) + ')' }}\n </span>\n </div>\n <ng-container *ngIf=\"isReassignAction\">\n <ng-container\n *ngIf=\"\n data.updateActionsParams.reassign.resourceTypeComponent ===\n resourcesComponents.TREE;\n else genericListTemplate\n \"\n >\n <div class=\"div-content-tree\">\n <dm-generic-tree\n [isSelectOnlyModeEnabled]=\"true\"\n [selectMode]=\"treeSelectMode.SINGLE\"\n [selectedNodeId]=\"selectedEntryId$ | async\"\n [selectedResourceTypeId]=\"selectedResourceTypeId\"\n [flattenInitialDataTree]=\"flattenDataTree\"\n [initialDataTree]=\"dataTree\"\n (selectedNode)=\"onSelectedNode($event)\"\n ></dm-generic-tree>\n </div>\n </ng-container>\n <ng-template #genericListTemplate>\n <div class=\"div-content-list\">\n <dm-generic-list\n [isSelectOnlyModeEnabled]=\"true\"\n [initialDataList]=\"dataList\"\n [selectedItemId]=\"selectedEntryId$ | async\"\n (selectedItem)=\"onSelectedItem($event)\"\n #genericList\n ></dm-generic-list>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isAssignAction && stepNumber === 1\">\n <ng-container\n *ngIf=\"\n data.updateActionsParams.assign.resourceTypeComponent ===\n resourcesComponents.ARRAY;\n else genericTreeTemplate\n \"\n ><div\n [ngClass]=\"{\n 'div-assign-search-bar':\n selectedElementsUiIds?.length > 0 && dataSource?.data?.length === 0\n }\"\n >\n <dm-search-bar\n [endpoint]=\"data.endpoint\"\n [placeholder]=\"data.placeholder\"\n [config]=\"data.assignArrayViewProperties.resourceTypeConfig\"\n [searchRequestAttributes]=\"data.assignedElementsAttributes\"\n [extendedMeta]=\"data.fieldForUpdate != null\"\n (searchResult)=\"onSearch($event)\"\n (resetSearch)=\"onResetSearch()\"\n (isActiveSearch)=\"onActiveSearch($event)\"\n #searchBar\n ></dm-search-bar>\n </div>\n\n <ng-container *ngIf=\"isActiveSearch && !searchBar.isFetchingResources\">\n <div\n *ngIf=\"dataSource?.data?.length === 0; else displayArray\"\n fxLayout=\"row\"\n fxLayoutAlign=\"center start\"\n >\n <span class=\"no-search-result\">{{ data.noSearchResult }}</span>\n </div>\n <ng-template #displayArray>\n <div\n *ngIf=\"dataSource?.data?.length > 0\"\n class=\"div-generic-array-header\"\n #divArrayHeader\n >\n <dm-generic-array-header\n [dataLength]=\"dataSource.data.length\"\n [dataIcon]=\"data.assignArrayViewProperties.icon\"\n [dataName]=\"data.assignArrayViewProperties.name\"\n ></dm-generic-array-header>\n </div>\n <div class=\"div-content-array\" #divContentArray>\n <div *ngIf=\"dataSource?.data?.length > 0\" class=\"div-generic-array\">\n <dm-generic-array\n [isSelectOnlyModeEnabled]=\"true\"\n [endpoint]=\"data.endpoint\"\n [columns]=\"data.assignArrayViewProperties.columns\"\n [accessibility]=\"data.assignArrayViewProperties.accessibility\"\n [initialDisplayedColumns]=\"\n data.assignArrayViewProperties.displayedColumns\n \"\n [selectedElementsUiIds]=\"selectedElementsUiIds\"\n [isAttributeArray]=\"true\"\n [updateAffectAnotherResourceType]=\"\n data.updateActionsParams.updateAffectAnotherResourceType\n \"\n [fieldForUpdate]=\"data.fieldForUpdate\"\n [dataSource]=\"dataSource\"\n [actions]=\"{\n assign: {\n noFilterResult:\n data.assignArrayViewProperties.noFilterResult\n }\n }\"\n (selectedData)=\"selectedData($event)\"\n ></dm-generic-array>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #genericTreeTemplate>\n <div class=\"div-content-tree\">\n <dm-generic-tree\n *ngIf=\"dataTreeAssignAction; else loadingSpinner\"\n [isSelectOnlyModeEnabled]=\"true\"\n [selectMode]=\"treeSelectMode.MULTIPLE\"\n [selectedResourceTypeId]=\"\n data.updateActionsParams?.assign?.assignedResourceTypeId\n \"\n [selectedNodesId]=\"selectedNodesId\"\n [flattenInitialDataTree]=\"flattenDataTree\"\n [initialDataTree]=\"dataTreeAssignAction\"\n (selectedNodes)=\"selectedData($event)\"\n #assignTree\n ></dm-generic-tree>\n </div>\n <ng-template #loadingSpinner>\n <div class=\"div-loading-spinner\">\n <dm-loading-spinner></dm-loading-spinner>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"isEditingAction || (isTwoStepsAssignAction && stepNumber === 2)\"\n >\n <form [formGroup]=\"editForm\" (keydown.tab)=\"$event.stopPropagation()\">\n <div\n *ngFor=\"let selectedElementIds of selectedElementsIdsForEdit\"\n fxLayout=\"row\"\n fxLayoutAlign=\"center center\"\n [ngStyle.gt-xs]=\"{ 'padding-bottom.px': 4 }\"\n [ngStyle.xs]=\"{ 'padding-bottom.px': 2 }\"\n class=\"div-form-field\"\n >\n <span fxFlex class=\"edited-entry-id ellipsis\">{{\n selectedElementIds.label\n }}</span>\n <mat-form-field fxFlex color=\"accent\" class=\"custom-form-field\">\n <mat-label fxLayout=\"row\">\n {{ data.updateActionsParams.edit.props.label }}\n </mat-label>\n <input\n matInput\n appOmitChars\n [formControlName]=\"selectedElementIds.id\"\n [type]=\"data.updateActionsParams.edit.props.type\"\n [min]=\"data.updateActionsParams.edit.props.min\"\n [invalidChars]=\"\n data.updateActionsParams.edit.props.invalidCharacters\n \"\n (ngModelChange)=\"checkFormValue(selectedElementIds.id)\"\n class=\"ellipsis\"\n />\n <mat-error>{{ formErrors[selectedElementIds.id] }}</mat-error>\n </mat-form-field>\n </div>\n </form>\n </ng-container>\n <ng-container *ngIf=\"isMovingNodeAction\">\n <ng-template #moveMenu>\n <div fxLayout=\"column\">\n <button\n mat-button\n color=\"accent\"\n (click)=\"moveToRoot()\"\n class=\"move-node-menu-btn\"\n >\n {{ data.moveToRootButtonText }}\n </button>\n <button\n mat-button\n color=\"accent\"\n (click)=\"moveToAnotherEntry()\"\n class=\"move-node-menu-btn\"\n >\n {{ data.moveToAnotherEntryButtonText }}\n </button>\n </div>\n </ng-template>\n <ng-container *ngIf=\"isMovingToAnotherEntry; else moveMenu\">\n <dm-search-bar\n [placeholder]=\"data.placeholder\"\n [isLocalSearchModeEnabled]=\"true\"\n [dataToFilter]=\"dataTree\"\n [triggerElementId]=\"data.triggerElementId\"\n [resourceTypeComponent]=\"resourceTypeComponent\"\n (searchResult)=\"onSearch($event)\"\n (resetSearch)=\"onResetSearch()\"\n (isActiveSearch)=\"onActiveSearch($event)\"\n ></dm-search-bar>\n <div\n *ngIf=\"isActiveSearch && dataList?.length === 0; else displayList\"\n fxLayout=\"row\"\n fxLayoutAlign=\"center start\"\n >\n <span class=\"no-search-result\">{{ data.noSearchResult }}</span>\n </div>\n <ng-template #displayList>\n <div class=\"div-content-list\">\n <dm-generic-list\n [isSelectOnlyModeEnabled]=\"true\"\n [initialDataList]=\"dataList\"\n (selectedItem)=\"onSelectedItem($event)\"\n #genericList\n ></dm-generic-list>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n</mat-dialog-content>\n<mat-dialog-actions\n *ngIf=\"!isMovingNodeAction || isMovingToAnotherEntry\"\n [ngStyle]=\"\n (isTwoStepsAssignAction || isMovingNodeAction) && stepNumber > 1\n ? { 'justify-content': 'space-between' }\n : { 'justify-content': 'flex-end' }\n \"\n>\n <button\n *ngIf=\"(isTwoStepsAssignAction || isMovingNodeAction) && stepNumber > 1\"\n mat-raised-button\n class=\"assign-edit-unassign-move-action-confirm-btn\"\n (click)=\"changeAssignStep(browseStates.PREVIOUS)\"\n >\n {{ data.previousStepButtonText }}\n </button>\n <div>\n <button\n cdkFocusInitial\n mat-button\n color=\"accent\"\n [mat-dialog-close]=\"false\"\n class=\"btn-close-confirm-dialog\"\n >\n {{ data.cancelButtonText }}\n </button>\n <button\n *ngIf=\"\n isTwoStepsAssignAction &&\n stepNumber < data.updateActionsParams.assign.nbSteps;\n else confirmBtn\n \"\n mat-raised-button\n [disabled]=\"selectedElements.length === 0\"\n (click)=\"changeAssignStep(browseStates.NEXT)\"\n class=\"assign-edit-unassign-move-action-confirm-btn\"\n >\n {{ data.nextStepButtonText }}\n </button>\n <ng-template #confirmBtn>\n <button\n mat-raised-button\n [disabled]=\"\n ((isReassignAction || isMovingNodeAction) &&\n !selectedNode &&\n !selectedItem) ||\n (isAssignAction && selectedElements.length === 0) ||\n ((isTwoStepsAssignAction || isEditingAction) &&\n (editForm.pristine || !editForm.valid))\n \"\n [ngClass]=\"\n isRemovingAction\n ? 'delete-action-confirm-btn'\n : 'assign-edit-unassign-move-action-confirm-btn'\n \"\n (click)=\"submitAction()\"\n >\n {{ data.confirmButtonText }}\n </button>\n </ng-template>\n </div>\n</mat-dialog-actions>\n", styles: ["@charset \"UTF-8\";.title{font-weight:700}.div-generic-array-header{padding:8px 0}.mdc-dialog__content{display:flex;flex-direction:column}.div-generic-array{height:100%}.div-content-array,.div-content-tree,.div-content-list{margin-bottom:20px}.div-content-list{overflow-y:auto}.no-search-result{color:#0003;font-size:20px;padding:20px 0}.btn-close-confirm-dialog{margin-right:8px}.div-loading-spinner{height:64px}.edited-entry-id{text-align:center}.move-node-menu-btn{margin-bottom:20px}.div-assign-search-bar{margin-top:10px}.div-selected-elements{overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i5.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i5.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i6.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "directive", type: i6.DefaultStyleDirective, selector: " [ngStyle], [ngStyle.xs], [ngStyle.sm], [ngStyle.md], [ngStyle.lg], [ngStyle.xl], [ngStyle.lt-sm], [ngStyle.lt-md], [ngStyle.lt-lg], [ngStyle.lt-xl], [ngStyle.gt-xs], [ngStyle.gt-sm], [ngStyle.gt-md], [ngStyle.gt-lg]", inputs: ["ngStyle", "ngStyle.xs", "ngStyle.sm", "ngStyle.md", "ngStyle.lg", "ngStyle.xl", "ngStyle.lt-sm", "ngStyle.lt-md", "ngStyle.lt-lg", "ngStyle.lt-xl", "ngStyle.gt-xs", "ngStyle.gt-sm", "ngStyle.gt-md", "ngStyle.gt-lg"] }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i8.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i8.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i8.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i8.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.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: "directive", type: i11.OmitCharsDirective, selector: "[appOmitChars]", inputs: ["invalidChars", "validChars", "regexString"] }, { kind: "component", type: i12.GenericArrayHeaderComponent, selector: "dm-generic-array-header", inputs: ["dataLength", "dataIcon", "dataName"] }, { kind: "component", type: i13.LoadingSpinnerComponent, selector: "dm-loading-spinner" }, { kind: "component", type: i14.GenericArrayComponent, selector: "dm-generic-array", inputs: ["isClickableRow", "isSelectOnlyModeEnabled", "selectedElementsUiIds", "dataSource", "columns", "initialDisplayedColumns", "processingRequest$", "actions", "resourcesTypesProperties", "configs", "accessibility", "endpoint", "canAssignOrMoveEntries", "selectedResourceRootTypeId", "isAttributeArray", "updateAffectAnotherResourceType", "fieldForUpdate", "isEditableArray", "selectionColumnId", "actionsColumnTemplate"], outputs: ["selectedData"] }, { kind: "component", type: i15.GenericListComponent, selector: "dm-generic-list", inputs: ["selectedItemId", "initialDataList", "search", "isSelectOnlyModeEnabled", "isLargeScreen", "actionsMenuTemplate"], outputs: ["selectedItem"] }, { kind: "component", type: i16.GenericTreeComponent, selector: "dm-generic-tree", inputs: ["viewportHeight", "allNodesIdsNames", "selectedNodeId", "flattenInitialDataTree", "initialDataTree", "search", "expandedTreeNodesUuids", "actions", "selectedResourceRootTypeId", "selectedResourceTypeId", "isSelectOnlyModeEnabled", "isAdvancedSearchActivated", "selectMode", "refresh", "nodesIdsMatchingAdvancedSearch", "advancedSearch", "isLargeScreen", "selectedNodesId", "isFilteringOnExternalId", "isScrollDisable", "actionsMenuTemplate"], outputs: ["widthUpdated", "selectedNode", "selectedNodes"] }, { kind: "component", type: i17.SearchBarComponent, selector: "dm-search-bar", inputs: ["placeholder", "triggerElementId", "config", "endpoint", "searchRequestAttributes", "extendedMeta", "isLocalSearchModeEnabled", "dataToFilter", "resourceTypeComponent"], outputs: ["searchResult", "resetSearch", "isActiveSearch"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); }
}
__decorate([
Select(DataState.getSelectedEntryId)
], ConfirmDialogComponent.prototype, "selectedEntryId$", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'dm-confirm-dialog', template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<h3 mat-dialog-title [innerHTML]=\"data.title\" class=\"title\"></h3>\n<mat-dialog-content class=\"mat-dialog-content\">\n <div\n *ngIf=\"\n !isEditingAction &&\n !isMovingNodeAction &&\n !(isAssignAction && dataSource?.data?.length > 0)\n \"\n class=\"div-selected-elements\"\n >\n <span *ngFor=\"let element of selectedElementsUiIds; let i = index\">\n <span *ngIf=\"i < 10\">\n <span\n *ngIf=\"\n i < 9 && i < selectedElementsUiIds?.length - 1;\n else lastElement\n \"\n >\n {{ element.label }},\n </span>\n <ng-template #lastElement>{{ element.label }}</ng-template>\n </span>\n </span>\n <span *ngIf=\"selectedElementsUiIds?.length > 10\">\n {{ '... (+' + (selectedElementsUiIds.length - 10) + ')' }}\n </span>\n </div>\n <ng-container *ngIf=\"isReassignAction\">\n <ng-container\n *ngIf=\"\n data.updateActionsParams.reassign.resourceTypeComponent ===\n resourcesComponents.TREE;\n else genericListTemplate\n \"\n >\n <div class=\"div-content-tree\">\n <dm-generic-tree\n [isSelectOnlyModeEnabled]=\"true\"\n [selectMode]=\"treeSelectMode.SINGLE\"\n [selectedNodeId]=\"selectedEntryId$ | async\"\n [selectedResourceTypeId]=\"selectedResourceTypeId\"\n [flattenInitialDataTree]=\"flattenDataTree\"\n [initialDataTree]=\"dataTree\"\n (selectedNode)=\"onSelectedNode($event)\"\n ></dm-generic-tree>\n </div>\n </ng-container>\n <ng-template #genericListTemplate>\n <div class=\"div-content-list\">\n <dm-generic-list\n [isSelectOnlyModeEnabled]=\"true\"\n [initialDataList]=\"dataList\"\n [selectedItemId]=\"selectedEntryId$ | async\"\n (selectedItem)=\"onSelectedItem($event)\"\n #genericList\n ></dm-generic-list>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isAssignAction && stepNumber === 1\">\n <ng-container\n *ngIf=\"\n data.updateActionsParams.assign.resourceTypeComponent ===\n resourcesComponents.ARRAY;\n else genericTreeTemplate\n \"\n ><div\n [ngClass]=\"{\n 'div-assign-search-bar':\n selectedElementsUiIds?.length > 0 && dataSource?.data?.length === 0\n }\"\n >\n <dm-search-bar\n [endpoint]=\"data.endpoint\"\n [placeholder]=\"data.placeholder\"\n [config]=\"data.assignArrayViewProperties.resourceTypeConfig\"\n [searchRequestAttributes]=\"data.assignedElementsAttributes\"\n [extendedMeta]=\"data.fieldForUpdate != null\"\n (searchResult)=\"onSearch($event)\"\n (resetSearch)=\"onResetSearch()\"\n (isActiveSearch)=\"onActiveSearch($event)\"\n #searchBar\n ></dm-search-bar>\n </div>\n\n <ng-container *ngIf=\"isActiveSearch && !searchBar.isFetchingResources\">\n <div\n *ngIf=\"dataSource?.data?.length === 0; else displayArray\"\n fxLayout=\"row\"\n fxLayoutAlign=\"center start\"\n >\n <span class=\"no-search-result\">{{ data.noSearchResult }}</span>\n </div>\n <ng-template #displayArray>\n <div\n *ngIf=\"dataSource?.data?.length > 0\"\n class=\"div-generic-array-header\"\n #divArrayHeader\n >\n <dm-generic-array-header\n [dataLength]=\"dataSource.data.length\"\n [dataIcon]=\"data.assignArrayViewProperties.icon\"\n [dataName]=\"data.assignArrayViewProperties.name\"\n ></dm-generic-array-header>\n </div>\n <div class=\"div-content-array\" #divContentArray>\n <div *ngIf=\"dataSource?.data?.length > 0\" class=\"div-generic-array\">\n <dm-generic-array\n [isSelectOnlyModeEnabled]=\"true\"\n [endpoint]=\"data.endpoint\"\n [columns]=\"data.assignArrayViewProperties.columns\"\n [accessibility]=\"data.assignArrayViewProperties.accessibility\"\n [initialDisplayedColumns]=\"\n data.assignArrayViewProperties.displayedColumns\n \"\n [selectedElementsUiIds]=\"selectedElementsUiIds\"\n [isAttributeArray]=\"true\"\n [updateAffectAnotherResourceType]=\"\n data.updateActionsParams.updateAffectAnotherResourceType\n \"\n [fieldForUpdate]=\"data.fieldForUpdate\"\n [dataSource]=\"dataSource\"\n [actions]=\"{\n assign: {\n noFilterResult:\n data.assignArrayViewProperties.noFilterResult\n }\n }\"\n (selectedData)=\"selectedData($event)\"\n ></dm-generic-array>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #genericTreeTemplate>\n <div class=\"div-content-tree\">\n <dm-generic-tree\n *ngIf=\"dataTreeAssignAction; else loadingSpinner\"\n [isSelectOnlyModeEnabled]=\"true\"\n [selectMode]=\"treeSelectMode.MULTIPLE\"\n [selectedResourceTypeId]=\"\n data.updateActionsParams?.assign?.assignedResourceTypeId\n \"\n [selectedNodesId]=\"selectedNodesId\"\n [flattenInitialDataTree]=\"flattenDataTree\"\n [initialDataTree]=\"dataTreeAssignAction\"\n (selectedNodes)=\"selectedData($event)\"\n #assignTree\n ></dm-generic-tree>\n </div>\n <ng-template #loadingSpinner>\n <div class=\"div-loading-spinner\">\n <dm-loading-spinner></dm-loading-spinner>\n </div>\n </ng-template>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"isEditingAction || (isTwoStepsAssignAction && stepNumber === 2)\"\n >\n <form [formGroup]=\"editForm\" (keydown.tab)=\"$event.stopPropagation()\">\n <div\n *ngFor=\"let selectedElementIds of selectedElementsIdsForEdit\"\n fxLayout=\"row\"\n fxLayoutAlign=\"center center\"\n [ngStyle.gt-xs]=\"{ 'padding-bottom.px': 4 }\"\n [ngStyle.xs]=\"{ 'padding-bottom.px': 2 }\"\n class=\"div-form-field\"\n >\n <span fxFlex class=\"edited-entry-id ellipsis\">{{\n selectedElementIds.label\n }}</span>\n <mat-form-field fxFlex color=\"accent\" class=\"custom-form-field\">\n <mat-label fxLayout=\"row\">\n {{ data.updateActionsParams.edit.props.label }}\n </mat-label>\n <input\n matInput\n appOmitChars\n [formControlName]=\"selectedElementIds.id\"\n [type]=\"data.updateActionsParams.edit.props.type\"\n [min]=\"data.updateActionsParams.edit.props.min\"\n [invalidChars]=\"\n data.updateActionsParams.edit.props.invalidCharacters\n