@acorex/platform 21.0.0-next.89 → 21.0.0-next.91
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/fesm2022/acorex-platform-auth.mjs +1 -1
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/acorex-platform-common-common-settings.provider-DilV4dql.mjs.map +1 -1
- package/fesm2022/acorex-platform-common.mjs +3 -10
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-contracts.mjs +1737 -27
- package/fesm2022/acorex-platform-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +28 -1712
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +3 -3
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-attachments-page.component-CwG6n_Yb.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs +27 -1
- package/fesm2022/acorex-platform-layout-entity-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-file-list-popup.component--IeMZLIr.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +355 -122
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +77 -16
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +89 -11
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-CFyfix31.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-CZc2zFlg.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-BvFykMTH.mjs} +2 -2
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-BvFykMTH.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-XWRUVoL4.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-CntopmDS.mjs} +2 -2
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-XWRUVoL4.mjs.map → acorex-platform-layout-widgets-tabular-data-view-popup.component-CntopmDS.mjs.map} +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +5 -7
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CWLfNqV0.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-C7cT82K2.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DrUwqKKA.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +15 -5
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs → acorex-platform-themes-shared-settings.provider-DxtfyNGS.mjs} +2 -2
- package/fesm2022/acorex-platform-themes-shared-settings.provider-DxtfyNGS.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +2 -2
- package/fesm2022/acorex-platform-workflow.mjs +2 -2
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-common.d.ts +3 -5
- package/types/acorex-platform-contracts.d.ts +863 -7
- package/types/acorex-platform-core.d.ts +65 -922
- package/types/acorex-platform-layout-builder.d.ts +3 -3
- package/types/acorex-platform-layout-components.d.ts +6 -6
- package/types/acorex-platform-layout-designer.d.ts +4 -5
- package/types/acorex-platform-layout-entity-contracts.d.ts +94 -3
- package/types/acorex-platform-layout-entity.d.ts +72 -103
- package/types/acorex-platform-layout-views.d.ts +19 -12
- package/types/acorex-platform-layout-widget-core.d.ts +89 -77
- package/types/acorex-platform-layout-widgets.d.ts +9 -8
- package/types/acorex-platform-themes-default.d.ts +4 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-CZc2zFlg.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-UyKdkeyk.mjs.map +0 -1
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
|
|
1
|
+
import { mergeForeignKeyFieldIntoCreateActions, collectNestedCreateHiddenProperties, AXPEntityCommandScope, normalizeEntityDisplayTemplate, sanitizeResolvedEntityDisplayTitle, isUnresolvedEntityDisplayTemplate, AXPEntityDataSourceKeys, isCardFieldBadgeDisplay, resolveCardFieldBadgeColor, getEntityInfo, resolveEnabledMasterListLayouts, resolveDefaultMasterListLayout, AXPEntityEventsKeys, collectEntityListSortableFields, collectEntityListFilterDefinitions, parseDottedFieldPath, ENTITY_ROW_POPUP_TITLE_OPTION, resolveLookupWidgetCreateOptions, AXPEntityQueryType, buildEntitySearchTitleContext } from '@acorex/platform/layout/entity-contracts';
|
|
2
2
|
export * from '@acorex/platform/layout/entity-contracts';
|
|
3
3
|
export { collectNestedCreateHiddenProperties, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, mergeForeignKeyFieldIntoCreateActions } from '@acorex/platform/layout/entity-contracts';
|
|
4
4
|
import { AXToastService } from '@acorex/components/toast';
|
|
5
5
|
import * as i3$1 from '@acorex/core/translation';
|
|
6
6
|
import { AXTranslationService, resolveMultiLanguageString, AXTranslationModule, translateSync } from '@acorex/core/translation';
|
|
7
7
|
import * as i4$2 from '@acorex/platform/common';
|
|
8
|
-
import { AXPNotFoundError,
|
|
8
|
+
import { AXPNotFoundError, axpNavigateAppPath, AXPSettingsService, AXPCommonSettings, resolveEntityCreateListBehavior, AXPRefreshEvent, resolveEntityModifyPopupTitle, resolveSearchableText, evaluateEntityDisplayTemplate, AXPFilterOperatorMiddlewareService, AXPReloadEvent, axpRedirectToNotFound, AXP_ENTITY_DELETED_WORKFLOW_EVENT_TYPE, AXPCleanNestedFilters, AXPFileTypeProviderService, AXPFileStorageService, resolveEntityRowDisplayTitle, AXPFileActionsService, axpIsEntityRecordNotFound, AXPDefaultMultiLanguageConfigService, withDefaultMultiLanguageOnWidgetNodeTree, AXPWorkflowNavigateAction, AXP_NOT_FOUND_ROUTE, AXP_PROTECTED_ROUTE_GUARDS, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXPMenuItemsDataSourceDefinition } from '@acorex/platform/common';
|
|
9
9
|
import * as i1$3 from '@acorex/platform/workflow';
|
|
10
10
|
import { AXPWorkflowEventService, AXPWorkflowService, ofType, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
|
|
11
11
|
import * as i0 from '@angular/core';
|
|
12
12
|
import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, ChangeDetectorRef, input, signal, computed, effect, ChangeDetectionStrategy, Component, ElementRef, NgModule, viewChild, Input, afterNextRender, untracked, ViewEncapsulation, viewChildren, linkedSignal, HostBinding, output, EnvironmentInjector, makeEnvironmentProviders } from '@angular/core';
|
|
13
|
-
import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual
|
|
13
|
+
import { cloneDeep, merge, get, castArray, set, orderBy, isNil, isEmpty, isEqual, isObjectLike, isArray, has, isString } from 'lodash-es';
|
|
14
14
|
import { Subject, filter, takeUntil } from 'rxjs';
|
|
15
|
+
import { AXPWidgetsCatalog, resolveActionLook, AXPPlatformScope, extractValue, setSmart, getChangedPaths, isSelectionValueEqual, AXPDataGenerator, AXPSystemActionType } from '@acorex/platform/contracts';
|
|
15
16
|
import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex/platform/layout/builder';
|
|
16
|
-
import {
|
|
17
|
-
import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXHighlightService, extractValue, setSmart, getChangedPaths, AXPContextStore, isSelectionValueEqual, AXPDebugService, FORM_DIRTY_TRACE_NS, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPHookService, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
18
|
-
import { transform, isEqual } from 'lodash';
|
|
17
|
+
import { AXPDeviceService, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPBroadcastEventService, applyFilterArray, applySortArray, AXPDistributedEventListenerService, AXHighlightService, AXPDebugService, AXPContextStore, FORM_DIRTY_TRACE_NS, objectKeyValueTransforms, setupPopupFooterKeyboardShortcuts, AXPHookService, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
19
18
|
import { AXPSessionService, AXPPermissionDefinitionsDataSourceDefinition } from '@acorex/platform/auth';
|
|
20
19
|
import { Router, NavigationStart, ActivatedRoute, RouterModule, ROUTES } from '@angular/router';
|
|
21
20
|
import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_ENTITY, AXPCommandService, AXPQueryService, AXPQueryExecutor, AXPCommandExecutor, provideCommandSetups, provideQuerySetups, AXPCommandRegistry, AXPQueryRegistry } from '@acorex/platform/runtime';
|
|
@@ -25,7 +24,7 @@ import { AXButtonModule } from '@acorex/components/button';
|
|
|
25
24
|
import * as i3 from '@acorex/components/skeleton';
|
|
26
25
|
import { AXSkeletonModule } from '@acorex/components/skeleton';
|
|
27
26
|
import * as i2 from '@acorex/platform/layout/widget-core';
|
|
28
|
-
import { AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, createBooleanProperty, AXPWidgetRendererDirective, AXPBaseWidgetComponent, AXPWidgetStatus, createStringProperty, createNumberProperty, AXP_WIDGETS_ADVANCE_SUB_MEDIA, AXP_WIDGETS_ADVANCE_CATEGORY, createSelectProperty, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
|
|
27
|
+
import { AXPWidgetCoreModule, AXPPageStatus, AXPWidgetRegistryService, AXPColumnWidgetComponent, AXPValueWidgetComponent, AXPWidgetGroupEnum, createBooleanProperty, AXPWidgetRendererDirective, AXPBaseWidgetComponent, AXPWidgetStatus, WIDGET_CASCADE_TRACE_NS, createStringProperty, createNumberProperty, AXP_WIDGETS_ADVANCE_SUB_MEDIA, AXP_WIDGETS_ADVANCE_CATEGORY, createSelectProperty, AXP_WIDGETS_EDITOR_CATEGORY, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
|
|
29
28
|
import * as i5 from '@angular/common';
|
|
30
29
|
import { CommonModule, DOCUMENT, AsyncPipe, NgClass } from '@angular/common';
|
|
31
30
|
import { AXOverlayService } from '@acorex/cdk/overlay';
|
|
@@ -79,6 +78,7 @@ import { AXUploaderZoneDirective } from '@acorex/cdk/uploader';
|
|
|
79
78
|
import { AXUploaderModule } from '@acorex/components/uploader';
|
|
80
79
|
import * as i4$1 from '@acorex/components/collapse';
|
|
81
80
|
import { AXCollapseModule } from '@acorex/components/collapse';
|
|
81
|
+
import { transform, isEqual as isEqual$1 } from 'lodash';
|
|
82
82
|
|
|
83
83
|
function ensureListActions(ctx) {
|
|
84
84
|
ctx.interfaces.update((i) => {
|
|
@@ -100,6 +100,10 @@ function actionExists(actions, commandName, name) {
|
|
|
100
100
|
return cmd === commandName;
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
+
/** Layout order for the shared appearance section (after entity-defined groups). */
|
|
104
|
+
const AXP_APPEARANCE_SECTION_ORDER = 900;
|
|
105
|
+
/** Layout order for the shared classification section (after appearance). */
|
|
106
|
+
const AXP_CLASSIFICATION_SECTION_ORDER = 910;
|
|
103
107
|
/**
|
|
104
108
|
* Clones `sections` and `properties` arrays to prevent accidental cross-interface mutations.
|
|
105
109
|
* Many entity definitions reuse the same array instances across create/update/single interfaces.
|
|
@@ -112,9 +116,19 @@ function cloneLayoutArrays(layout) {
|
|
|
112
116
|
};
|
|
113
117
|
}
|
|
114
118
|
function ensureLayoutSection(layout, section) {
|
|
115
|
-
|
|
119
|
+
const existingIndex = layout.sections.findIndex((s) => s.id === section.id);
|
|
120
|
+
if (existingIndex === -1) {
|
|
116
121
|
layout.sections = [...layout.sections, section];
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const incomingOrder = section.order;
|
|
125
|
+
if (incomingOrder == null) {
|
|
126
|
+
return;
|
|
117
127
|
}
|
|
128
|
+
const existing = layout.sections[existingIndex];
|
|
129
|
+
const mergedOrder = Math.max(existing.order ?? 0, incomingOrder);
|
|
130
|
+
layout.sections = [...layout.sections];
|
|
131
|
+
layout.sections[existingIndex] = { ...existing, ...section, order: mergedOrder };
|
|
118
132
|
}
|
|
119
133
|
function ensureLayoutPropertyView(layout, prop) {
|
|
120
134
|
if (!layout.properties.some((p) => p.name === prop.name)) {
|
|
@@ -858,39 +872,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
858
872
|
}]
|
|
859
873
|
}] });
|
|
860
874
|
|
|
861
|
-
/**
|
|
862
|
-
* Computes a diff between two plain objects with array-aware semantics.
|
|
863
|
-
* - For arrays of objects with an id field, computes added/removed by id.
|
|
864
|
-
* - For arrays of primitives or objects without id, uses deep equality.
|
|
865
|
-
* - For scalars/objects, reports oldValue/newValue when changed.
|
|
866
|
-
*/
|
|
867
|
-
function detectEntityChanges(oldObj, newObj) {
|
|
868
|
-
return transform(newObj, (result, value, key) => {
|
|
869
|
-
if (!isEqual(value, oldObj[key])) {
|
|
870
|
-
const oldValue = oldObj[key];
|
|
871
|
-
if (Array.isArray(value) || Array.isArray(oldValue)) {
|
|
872
|
-
const oldArray = Array.isArray(oldValue) ? oldValue : [];
|
|
873
|
-
const newArray = Array.isArray(value) ? value : [];
|
|
874
|
-
const hasId = newArray.length > 0 && typeof newArray[0] === 'object' && newArray[0] !== null && 'id' in newArray[0];
|
|
875
|
-
if (hasId) {
|
|
876
|
-
const added = newArray.filter((item) => !oldArray.some((oldItem) => oldItem.id === item.id));
|
|
877
|
-
const removed = oldArray.filter((item) => !newArray.some((newItem) => newItem.id === item.id));
|
|
878
|
-
result[key] = { oldValue, newValue: value, added, removed };
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
const added = newArray.filter((item) => !oldArray.some((oldItem) => isEqual(item, oldItem)));
|
|
882
|
-
const removed = oldArray.filter((item) => !newArray.some((newItem) => isEqual(item, newItem)));
|
|
883
|
-
result[key] = { oldValue, newValue: value, added, removed };
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
else {
|
|
887
|
-
result[key] = { oldValue, newValue: value };
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
}, {});
|
|
891
|
-
}
|
|
892
|
-
//#endregion
|
|
893
|
-
|
|
894
875
|
/**
|
|
895
876
|
* Maps entity property `description` (or any i18n key / multi-language payload) to `form-field`
|
|
896
877
|
* widget options. Returns `undefined` when there is nothing to show.
|
|
@@ -4220,7 +4201,6 @@ class AXPEntitiesListDataSourceDefinition {
|
|
|
4220
4201
|
}
|
|
4221
4202
|
}
|
|
4222
4203
|
|
|
4223
|
-
//#region ---- Imports ----
|
|
4224
4204
|
//#endregion
|
|
4225
4205
|
//#region ---- Constants ----
|
|
4226
4206
|
const DEFAULT_RELATED_ORDER_STEP = 10;
|
|
@@ -4356,7 +4336,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
4356
4336
|
|
|
4357
4337
|
class AXPEntityCommandTriggerViewModel {
|
|
4358
4338
|
constructor(entity, action, isChild = false) {
|
|
4359
|
-
this.name =
|
|
4339
|
+
this.name = AXPEntityCommandTriggerViewModel.buildTriggerName(action);
|
|
4360
4340
|
this.options = typeof action.command === 'object' ? action.command.options : undefined;
|
|
4361
4341
|
this.metadata = typeof action.command === 'object' ? action.command.metadata : undefined;
|
|
4362
4342
|
const resolvedLook = resolveActionLook(action.type);
|
|
@@ -4374,6 +4354,15 @@ class AXPEntityCommandTriggerViewModel {
|
|
|
4374
4354
|
this.isChild = isChild;
|
|
4375
4355
|
this.items = action.items?.map((child) => new AXPEntityCommandTriggerViewModel(entity, child, true));
|
|
4376
4356
|
}
|
|
4357
|
+
/** Stable trigger id for command lookup and list tracking when {@link AXPEntityAction.name} is omitted. */
|
|
4358
|
+
static buildTriggerName(action) {
|
|
4359
|
+
const commandName = typeof action.command === 'string' ? action.command : action.command.name;
|
|
4360
|
+
if (action.name) {
|
|
4361
|
+
return `${commandName}&${action.name}`;
|
|
4362
|
+
}
|
|
4363
|
+
const suffix = [action.scope, action.priority, String(action.order ?? 0), action.type].join(':');
|
|
4364
|
+
return `${commandName}&${suffix}`;
|
|
4365
|
+
}
|
|
4377
4366
|
}
|
|
4378
4367
|
class AXPEntityListViewColumnViewModel {
|
|
4379
4368
|
constructor(property, column) {
|
|
@@ -5332,6 +5321,48 @@ class AXPEntityMasterListViewModel {
|
|
|
5332
5321
|
const resolved = String(result).trim();
|
|
5333
5322
|
return resolved !== '' ? resolved : 'default';
|
|
5334
5323
|
}
|
|
5324
|
+
/**
|
|
5325
|
+
* Resolves table row CSS classes from `layouts.table.cssClass.row` for the given row.
|
|
5326
|
+
*/
|
|
5327
|
+
async resolveTableRowCssClass(rowData) {
|
|
5328
|
+
return this.resolveTableCssClassValue(this.tableLayout()?.cssClass?.row, rowData);
|
|
5329
|
+
}
|
|
5330
|
+
/**
|
|
5331
|
+
* Resolves table cell CSS classes from `layouts.table.cssClass.cell` for the given row and column.
|
|
5332
|
+
*/
|
|
5333
|
+
async resolveTableCellCssClass(rowData, columnName) {
|
|
5334
|
+
return this.resolveTableCssClassValue(this.tableLayout()?.cssClass?.cell, rowData, columnName);
|
|
5335
|
+
}
|
|
5336
|
+
createTableCssClassExpressionScope(data, columnName) {
|
|
5337
|
+
const scope = this.createLogicExpressionScope(data);
|
|
5338
|
+
if (!columnName) {
|
|
5339
|
+
return scope;
|
|
5340
|
+
}
|
|
5341
|
+
const columnContext = { name: columnName };
|
|
5342
|
+
return {
|
|
5343
|
+
...scope,
|
|
5344
|
+
table: {
|
|
5345
|
+
getColumn: (field) => {
|
|
5346
|
+
return get(columnContext, field);
|
|
5347
|
+
},
|
|
5348
|
+
},
|
|
5349
|
+
};
|
|
5350
|
+
}
|
|
5351
|
+
async resolveTableCssClassValue(expression, rowData, columnName) {
|
|
5352
|
+
if (!expression) {
|
|
5353
|
+
return undefined;
|
|
5354
|
+
}
|
|
5355
|
+
const scope = this.createTableCssClassExpressionScope(rowData, columnName);
|
|
5356
|
+
const result = await this.expressionEvaluator.evaluate(expression, scope);
|
|
5357
|
+
return this.normalizeTableCssClassValue(result);
|
|
5358
|
+
}
|
|
5359
|
+
normalizeTableCssClassValue(value) {
|
|
5360
|
+
if (value === false || value == null) {
|
|
5361
|
+
return undefined;
|
|
5362
|
+
}
|
|
5363
|
+
const resolved = String(value).trim();
|
|
5364
|
+
return resolved !== '' ? resolved : undefined;
|
|
5365
|
+
}
|
|
5335
5366
|
async resolveTriggerName(triggerName, data) {
|
|
5336
5367
|
if (!triggerName) {
|
|
5337
5368
|
return triggerName;
|
|
@@ -5495,6 +5526,8 @@ class AXPEntityMasterListViewModel {
|
|
|
5495
5526
|
this.hasInlineFilters = computed(() => {
|
|
5496
5527
|
return this.inlineFiltersPlaceholders().length > 0;
|
|
5497
5528
|
}, ...(ngDevMode ? [{ debugName: "hasInlineFilters" }] : /* istanbul ignore next */ []));
|
|
5529
|
+
/** Text for data-table cell highlighting (set only after filters are applied). */
|
|
5530
|
+
this.inlineFilterHighlightText = signal('', ...(ngDevMode ? [{ debugName: "inlineFilterHighlightText" }] : /* istanbul ignore next */ []));
|
|
5498
5531
|
//****************** Beardcrumbs ******************//
|
|
5499
5532
|
this.beardcrumbs = computed(() => {
|
|
5500
5533
|
return [
|
|
@@ -5508,7 +5541,7 @@ class AXPEntityMasterListViewModel {
|
|
|
5508
5541
|
const list = this.entityDef.interfaces?.master?.list?.actions ?? [];
|
|
5509
5542
|
const actions = list.map((tr) => new AXPEntityCommandTriggerViewModel(this.entityDef, tr)) ?? [];
|
|
5510
5543
|
const orderedActions = orderBy(actions, 'order', 'asc');
|
|
5511
|
-
return orderedActions;
|
|
5544
|
+
return this.dedupeActionsByName(orderedActions);
|
|
5512
5545
|
}, ...(ngDevMode ? [{ debugName: "allActions" }] : /* istanbul ignore next */ []));
|
|
5513
5546
|
/** Flattened actions including children for execute lookup */
|
|
5514
5547
|
this.flattenedActions = computed(() => {
|
|
@@ -5986,6 +6019,17 @@ class AXPEntityMasterListViewModel {
|
|
|
5986
6019
|
setSelectedCategory(category) {
|
|
5987
6020
|
this.selectedCategory.set(category);
|
|
5988
6021
|
}
|
|
6022
|
+
/** Keeps the first action when list definitions repeat the same trigger name. */
|
|
6023
|
+
dedupeActionsByName(actions) {
|
|
6024
|
+
const seen = new Set();
|
|
6025
|
+
return actions.filter((action) => {
|
|
6026
|
+
if (seen.has(action.name)) {
|
|
6027
|
+
return false;
|
|
6028
|
+
}
|
|
6029
|
+
seen.add(action.name);
|
|
6030
|
+
return true;
|
|
6031
|
+
});
|
|
6032
|
+
}
|
|
5989
6033
|
async getPrimaryActions() {
|
|
5990
6034
|
const scope = this.createLogicExpressionScope(null);
|
|
5991
6035
|
const actions = await Promise.all(this.allActions()
|
|
@@ -6242,6 +6286,7 @@ class AXPEntityMasterListViewModel {
|
|
|
6242
6286
|
if (sortKey === this.lastAppliedSortKey && filterKey === this.lastAppliedFilterKey) {
|
|
6243
6287
|
return; // No effective change; avoid redundant refresh
|
|
6244
6288
|
}
|
|
6289
|
+
this.updateAppliedInlineFilterHighlightText(filters);
|
|
6245
6290
|
const filtersChanged = this.lastAppliedFilterKey != null && filterKey !== this.lastAppliedFilterKey;
|
|
6246
6291
|
this.lastAppliedSortKey = sortKey;
|
|
6247
6292
|
this.lastAppliedFilterKey = filterKey;
|
|
@@ -6253,6 +6298,11 @@ class AXPEntityMasterListViewModel {
|
|
|
6253
6298
|
this.dataSource.filter(transformedFilter);
|
|
6254
6299
|
this.events$.next({ action: 'refresh', meta: { resetPagination: filtersChanged } });
|
|
6255
6300
|
}
|
|
6301
|
+
updateAppliedInlineFilterHighlightText(filters) {
|
|
6302
|
+
const allFilter = filters.find((f) => f.field === 'all');
|
|
6303
|
+
const value = allFilter?.value;
|
|
6304
|
+
this.inlineFilterHighlightText.set(typeof value === 'string' ? value.trim() : '');
|
|
6305
|
+
}
|
|
6256
6306
|
//****************** Columns ******************//
|
|
6257
6307
|
resolveMergeDetailProperty(columnName) {
|
|
6258
6308
|
const parsed = parseDottedFieldPath(columnName);
|
|
@@ -7684,10 +7734,11 @@ async function calculateChildrenCounts(items, entityName, getDirectChildCount) {
|
|
|
7684
7734
|
* Loads raw rows for an entity and applies the same sorting and filtering as {@link runEntityQuery},
|
|
7685
7735
|
* without pagination.
|
|
7686
7736
|
*/
|
|
7687
|
-
async function filterSortEntityRows(entityName, request, adapters) {
|
|
7737
|
+
async function filterSortEntityRows(entityName, request, adapters, sortLocale) {
|
|
7688
7738
|
let result = await adapters.getRawAll(entityName);
|
|
7689
7739
|
if (request.sort && request.sort.length) {
|
|
7690
|
-
|
|
7740
|
+
const locale = sortLocale ?? request.params?.['locale'] ?? 'en-US';
|
|
7741
|
+
result = applySortArray(result, request.sort, locale);
|
|
7691
7742
|
}
|
|
7692
7743
|
if (request.filter && isCategoryFilter(request.filter)) {
|
|
7693
7744
|
result = await applyRecursiveCategoryFilter(result, request.filter, entityName, adapters.getAllChildCategoryIds);
|
|
@@ -7703,8 +7754,8 @@ async function filterSortEntityRows(entityName, request, adapters) {
|
|
|
7703
7754
|
/**
|
|
7704
7755
|
* Shared entity query logic: sort, filter (including recursive category filter), childrenCount, pagination.
|
|
7705
7756
|
*/
|
|
7706
|
-
async function runEntityQuery(entityName, request, adapters) {
|
|
7707
|
-
const rows = await filterSortEntityRows(entityName, request, adapters);
|
|
7757
|
+
async function runEntityQuery(entityName, request, adapters, sortLocale) {
|
|
7758
|
+
const rows = await filterSortEntityRows(entityName, request, adapters, sortLocale);
|
|
7708
7759
|
const skip = request.skip ?? 0;
|
|
7709
7760
|
const take = request.take ?? 0;
|
|
7710
7761
|
return {
|
|
@@ -12753,7 +12804,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
12753
12804
|
async reapplyScopedFiltersToDataSource() {
|
|
12754
12805
|
const merged = this.getMergedToolbarFilters();
|
|
12755
12806
|
const current = this.getValue();
|
|
12756
|
-
if (!isEqual
|
|
12807
|
+
if (!isEqual(current?.toolbar?.filters, merged)) {
|
|
12757
12808
|
this.setValue({
|
|
12758
12809
|
...current,
|
|
12759
12810
|
toolbar: { ...(current?.toolbar ?? {}), filters: merged },
|
|
@@ -12800,7 +12851,7 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
12800
12851
|
return;
|
|
12801
12852
|
}
|
|
12802
12853
|
const current = this.getValue();
|
|
12803
|
-
if (isEqual
|
|
12854
|
+
if (isEqual(current?.toolbar?.filters, filters)) {
|
|
12804
12855
|
return;
|
|
12805
12856
|
}
|
|
12806
12857
|
this.setValue({
|
|
@@ -13897,31 +13948,6 @@ function compactLookupCreateContext(data) {
|
|
|
13897
13948
|
}
|
|
13898
13949
|
//#endregion
|
|
13899
13950
|
|
|
13900
|
-
//#endregion
|
|
13901
|
-
//#region ---- Resolution ----
|
|
13902
|
-
/**
|
|
13903
|
-
* Resolves lookup create options from `create` and legacy `allowCreate` (mode).
|
|
13904
|
-
*/
|
|
13905
|
-
function resolveLookupWidgetCreateOptions(options) {
|
|
13906
|
-
const create = options.create;
|
|
13907
|
-
const legacyMode = options.allowCreate;
|
|
13908
|
-
const context = create?.context;
|
|
13909
|
-
if (create?.enable !== undefined) {
|
|
13910
|
-
if (!create.enable) {
|
|
13911
|
-
return { enabled: false, mode: 'none', context };
|
|
13912
|
-
}
|
|
13913
|
-
const mode = legacyMode && legacyMode !== 'none' ? legacyMode : 'quick';
|
|
13914
|
-
return { enabled: true, mode, context };
|
|
13915
|
-
}
|
|
13916
|
-
const mode = legacyMode ?? 'none';
|
|
13917
|
-
return {
|
|
13918
|
-
enabled: mode !== 'none',
|
|
13919
|
-
mode,
|
|
13920
|
-
context,
|
|
13921
|
-
};
|
|
13922
|
-
}
|
|
13923
|
-
//#endregion
|
|
13924
|
-
|
|
13925
13951
|
//#endregion
|
|
13926
13952
|
class AXPEntityDataSelectorRowActionsService {
|
|
13927
13953
|
constructor() {
|
|
@@ -14934,10 +14960,20 @@ class AXPLookupWidgetSelectComponent extends LookupWidgetLookBase {
|
|
|
14934
14960
|
}
|
|
14935
14961
|
//#endregion
|
|
14936
14962
|
clear() {
|
|
14963
|
+
AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-select', 'clear() — value cleared', () => ({
|
|
14964
|
+
entity: this.entityDef()()?.name,
|
|
14965
|
+
}));
|
|
14937
14966
|
this.valueChanged.emit(null);
|
|
14938
14967
|
}
|
|
14939
14968
|
refresh() {
|
|
14940
|
-
|
|
14969
|
+
AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-select', 'refresh()', () => ({
|
|
14970
|
+
entity: this.entityDef()()?.name,
|
|
14971
|
+
filter: this.customFilter()(),
|
|
14972
|
+
hasSelection: !isEmpty(this.selectedItemsValue()),
|
|
14973
|
+
}));
|
|
14974
|
+
if (!isEmpty(this.selectedItemsValue())) {
|
|
14975
|
+
this.clear();
|
|
14976
|
+
}
|
|
14941
14977
|
this.dataSource()?.refresh();
|
|
14942
14978
|
}
|
|
14943
14979
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -15519,7 +15555,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15519
15555
|
const prevValue = this.previousValue();
|
|
15520
15556
|
const isInitialized = this.initialized();
|
|
15521
15557
|
// Check if value has actually changed
|
|
15522
|
-
const valueChanged = !isEqual
|
|
15558
|
+
const valueChanged = !isEqual(currentValue, prevValue);
|
|
15523
15559
|
// Determine if we should update:
|
|
15524
15560
|
// 1. First initialization with a value
|
|
15525
15561
|
// 2. Value becomes empty after initialization
|
|
@@ -15795,6 +15831,12 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15795
15831
|
}
|
|
15796
15832
|
//#region ---- Component Methods ----
|
|
15797
15833
|
refresh() {
|
|
15834
|
+
AXPDebugService.instance?.trace(WIDGET_CASCADE_TRACE_NS, 'lookup-widget', 'refresh()', () => ({
|
|
15835
|
+
path: this.fullPath(),
|
|
15836
|
+
entity: this.entity(),
|
|
15837
|
+
look: this.look(),
|
|
15838
|
+
customerPartyId: this.contextService.getValue('customer.partyId'),
|
|
15839
|
+
}));
|
|
15798
15840
|
this.componentLook()?.refresh();
|
|
15799
15841
|
}
|
|
15800
15842
|
clear() {
|
|
@@ -16860,8 +16902,6 @@ const AXPLookupWidget = {
|
|
|
16860
16902
|
},
|
|
16861
16903
|
};
|
|
16862
16904
|
|
|
16863
|
-
//#endregion
|
|
16864
|
-
|
|
16865
16905
|
/**
|
|
16866
16906
|
* Source type
|
|
16867
16907
|
*/
|
|
@@ -18927,7 +18967,7 @@ class AXPFileListComponent {
|
|
|
18927
18967
|
return action.color ?? 'primary';
|
|
18928
18968
|
}
|
|
18929
18969
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
18930
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileListComponent, isStandalone: true, selector: "axp-file-list", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fileEditable: { classPropertyName: "fileEditable", publicName: "fileEditable", isSignal: true, isRequired: false, transformFunction: null }, enableTitleDescription: { classPropertyName: "enableTitleDescription", publicName: "enableTitleDescription", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, titleKey: { classPropertyName: "titleKey", publicName: "titleKey", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, linksLayout: { classPropertyName: "linksLayout", publicName: "linksLayout", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null }, excludePlugins: { classPropertyName: "excludePlugins", publicName: "excludePlugins", isSignal: true, isRequired: false, transformFunction: null }, capabilities: { classPropertyName: "capabilities", publicName: "capabilities", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRemove: "onRemove", onRevert: "onRevert", onRename: "onRename" }, host: { properties: { "class.--look-rows": "look() === \"rows\"", "class.--look-links": "look() === \"links\"", "class.--links-inline": "look() === \"links\" && linksLayout() === \"inline\"" } }, providers: [], ngImport: i0, template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{
|
|
18970
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileListComponent, isStandalone: true, selector: "axp-file-list", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fileEditable: { classPropertyName: "fileEditable", publicName: "fileEditable", isSignal: true, isRequired: false, transformFunction: null }, enableTitleDescription: { classPropertyName: "enableTitleDescription", publicName: "enableTitleDescription", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, titleKey: { classPropertyName: "titleKey", publicName: "titleKey", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, linksLayout: { classPropertyName: "linksLayout", publicName: "linksLayout", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, plugins: { classPropertyName: "plugins", publicName: "plugins", isSignal: true, isRequired: false, transformFunction: null }, excludePlugins: { classPropertyName: "excludePlugins", publicName: "excludePlugins", isSignal: true, isRequired: false, transformFunction: null }, capabilities: { classPropertyName: "capabilities", publicName: "capabilities", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRemove: "onRemove", onRevert: "onRevert", onRename: "onRename" }, host: { properties: { "class.--look-rows": "look() === \"rows\"", "class.--look-links": "look() === \"links\"", "class.--links-inline": "look() === \"links\" && linksLayout() === \"inline\"" } }, providers: [], ngImport: i0, template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n } @else {\n <div class=\"__empty-state __empty-state--links\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n look=\"minimal\"\n />\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}.__empty-state--links{padding-top:.5rem;padding-bottom:.5rem}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type:
|
|
18931
18971
|
// ACoreX
|
|
18932
18972
|
AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
|
|
18933
18973
|
// Platform
|
|
@@ -18955,7 +18995,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18955
18995
|
AXTranslationModule,
|
|
18956
18996
|
// Platform
|
|
18957
18997
|
AXPStateMessageComponent,
|
|
18958
|
-
], providers: [], template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{
|
|
18998
|
+
], providers: [], template: "@if (look() === 'links') {\n @if (displayFiles().length > 0) {\n <div class=\"__links\">\n @if (showLabel()) {\n <span class=\"__links-label\">{{ titleKey() | translate | async }}:</span>\n }\n <ul class=\"__links-list\">\n @for (file of displayFiles(); track file.id ?? $index) {\n <li>\n <button\n type=\"button\"\n class=\"__link-item\"\n (click)=\"handleFileDownload($event, file)\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <i class=\"fa-light fa-paperclip ax-flex-shrink-0\"></i>\n <span class=\"ax-min-w-0 ax-break-all\">{{ file.name }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n } @else {\n <div class=\"__empty-state __empty-state--links\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n look=\"minimal\"\n />\n </div>\n }\n} @else {\n @for (file of displayFiles(); track $index) {\n <div\n class=\"__item\"\n [ngClass]=\"{\n '--removed': file.status === 'deleted',\n '--attached': file.status === 'attached',\n '--with-meta': enableTitleDescription(),\n '--item-readonly': file.readOnly === true,\n '--downloadable': file.status !== 'deleted',\n }\"\n (dblclick)=\"handleFileRowActivate($event, file)\"\n >\n <div class=\"__icon\">\n <i class=\"fa-fw {{ getFileInfo(file.name).icon }} fa-solid\"></i>\n </div>\n @if (enableTitleDescription()) {\n <div class=\"__content\">\n <div class=\"__primary\">{{ file.name }}{{ file.title?.trim() ? ' - ' + file.title : '' }}</div>\n @if (file.description?.trim()) {\n <div class=\"__secondary\">{{ file.description }}</div>\n }\n </div>\n } @else {\n <div class=\"__name\">{{ file.name }}</div>\n }\n <div class=\"__actions\" (dblclick)=\"$event.stopPropagation()\">\n @if (file.status === 'deleted' && multiple() && !isItemInteractionLocked(file)) {\n <ax-button [look]=\"'blank'\" class=\"ax-sm\" color=\"warning\" (onClick)=\"handleFileRevert($event, file)\">\n <ax-icon class=\"fa-light fa-rotate-left\"></ax-icon>\n </ax-button>\n } @else if (file.status !== 'deleted') {\n @for (action of actionsFor(file, $index); track action.id ?? action.textKey ?? action.text ?? $index) {\n <ax-button\n [look]=\"'blank'\"\n class=\"ax-sm\"\n [color]=\"getActionColor(action)\"\n (onClick)=\"runAction(action)\"\n >\n @if (action.icon) {\n <ax-icon class=\"{{ action.icon }}\"></ax-icon>\n }\n </ax-button>\n }\n }\n </div>\n </div>\n } @empty {\n <div class=\"__empty-state\">\n <axp-state-message\n icon=\"fa-light fa-folder-open\"\n [title]=\"'@general:widgets.file-uploader.empty-state.title'\"\n [description]=\"'@general:widgets.file-uploader.empty-state.description'\"\n >\n </axp-state-message>\n </div>\n }\n}\n", styles: [":host{display:flex;width:100%;flex-direction:column;gap:.125rem}:host.--look-rows{padding-top:.5rem;padding-bottom:.5rem}:host.--look-links{padding-top:0;padding-bottom:0}:host.--look-links .__links .__links-label{margin-inline-end:.5rem;font-size:.875rem;line-height:1.25rem;font-weight:500;color:rgb(var(--ax-sys-color-on-surface-variant))}:host.--look-links .__links .__links-list{margin:0;margin-top:.25rem;list-style-type:none;padding:0}:host.--look-links .__links .__links-list li{margin:0;padding:0}:host.--look-links .__links .__links-list .__link-item{display:inline-flex;width:100%;cursor:pointer;align-items:center;gap:.75rem;border-radius:.375rem;border-width:0px;background-color:transparent;padding:.625rem .75rem;text-align:start;font-size:.875rem;line-height:1.25rem;text-decoration-line:none;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;color:rgb(var(--ax-sys-color-primary))}:host.--look-links .__links .__links-list .__link-item:hover{background:rgb(var(--ax-sys-color-lighter-surface))}:host.--look-links.--links-inline .__links{margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1));padding-bottom:1rem}:host.--look-links:not(.--links-inline) .__links-list{margin-top:0;display:flex;flex-direction:column;gap:.5rem}:host .__item{display:flex;align-items:center;gap:.75rem;border-left-width:4px;border-color:transparent;padding:.5rem}:host .__item.--downloadable{cursor:pointer}:host .__item.--downloadable:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}:host .__item:not(.--downloadable){cursor:default}:host .__item.--removed{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-danger-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-50),var(--tw-bg-opacity, 1))}:host .__item.--attached{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));animation:attached-flash 1s ease-out forwards}:host .__item.--item-readonly:not(.--removed){opacity:.85}:host .__item .__icon{width:1.5rem;flex-shrink:0}:host .__item .__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__content{display:flex;min-width:0px;flex:1 1 0%;flex-direction:column;gap:.125rem}:host .__item .__primary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:start;font-size:.875rem;line-height:1.25rem;font-weight:500}:host .__item .__secondary{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:.75rem;line-height:1rem;color:var(--ax-sys-color-text-secondary)}:host .__item.--with-meta .__content{justify-content:center}:host .__item .__actions{margin-left:auto;display:flex;flex-shrink:0}@keyframes attached-flash{0%{background-color:rgb(var(--ax-sys-color-success-50))}to{background-color:transparent}}.__empty-state{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.__empty-state:hover{opacity:.8}.__empty-state--links{padding-top:.5rem;padding-bottom:.5rem}\n"] }]
|
|
18959
18999
|
}], propDecorators: { onRemove: [{ type: i0.Output, args: ["onRemove"] }], onRevert: [{ type: i0.Output, args: ["onRevert"] }], onRename: [{ type: i0.Output, args: ["onRename"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], fileEditable: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileEditable", required: false }] }], enableTitleDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableTitleDescription", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], titleKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleKey", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], linksLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "linksLayout", required: false }] }], files: [{ type: i0.Input, args: [{ isSignal: true, alias: "files", required: false }] }], plugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "plugins", required: false }] }], excludePlugins: [{ type: i0.Input, args: [{ isSignal: true, alias: "excludePlugins", required: false }] }], capabilities: [{ type: i0.Input, args: [{ isSignal: true, alias: "capabilities", required: false }] }] } });
|
|
18960
19000
|
|
|
18961
19001
|
//#region ---- Attachment fingerprint (no blob comparison) ----
|
|
@@ -19038,6 +19078,9 @@ function persistedAttachments(value) {
|
|
|
19038
19078
|
}
|
|
19039
19079
|
//#endregion
|
|
19040
19080
|
|
|
19081
|
+
const FILE_PREFIX = 'file:';
|
|
19082
|
+
const DOCUMENT_PREFIX = 'document:';
|
|
19083
|
+
const REFERENCE_PREFIX = 'reference:';
|
|
19041
19084
|
//#endregion
|
|
19042
19085
|
//#region ---- Helpers ----
|
|
19043
19086
|
function isFileListItem(value) {
|
|
@@ -19095,6 +19138,120 @@ function attachmentFieldCount(fieldValue) {
|
|
|
19095
19138
|
function normalizeEntityFieldToFileList(fieldValue) {
|
|
19096
19139
|
return parseAttachmentFieldEntries(fieldValue).filter(isFileListItem);
|
|
19097
19140
|
}
|
|
19141
|
+
/** Whether a stored value is a persisted file/document/reference token. */
|
|
19142
|
+
function isAttachmentStorageRef(value) {
|
|
19143
|
+
return (isString(value) &&
|
|
19144
|
+
(value.startsWith(FILE_PREFIX) ||
|
|
19145
|
+
value.startsWith(DOCUMENT_PREFIX) ||
|
|
19146
|
+
value.startsWith(REFERENCE_PREFIX)));
|
|
19147
|
+
}
|
|
19148
|
+
/** True when the field has entries that cannot be shown without hydration (e.g. mixed `file:` refs + objects). */
|
|
19149
|
+
function attachmentNeedsHydration(fieldValue) {
|
|
19150
|
+
const entries = parseAttachmentFieldEntries(fieldValue);
|
|
19151
|
+
const count = entries.filter(isAttachmentListEntry).length;
|
|
19152
|
+
if (count === 0) {
|
|
19153
|
+
return false;
|
|
19154
|
+
}
|
|
19155
|
+
const normalizedCount = entries.filter(isFileListItem).length;
|
|
19156
|
+
if (normalizedCount < count) {
|
|
19157
|
+
return true;
|
|
19158
|
+
}
|
|
19159
|
+
return entries.some(isAttachmentStorageRef);
|
|
19160
|
+
}
|
|
19161
|
+
function removeFilePrefix(prefixedId) {
|
|
19162
|
+
return prefixedId.startsWith(FILE_PREFIX) ? prefixedId.substring(FILE_PREFIX.length) : prefixedId;
|
|
19163
|
+
}
|
|
19164
|
+
function storageInfoToFileListItem(info) {
|
|
19165
|
+
const item = {
|
|
19166
|
+
id: info.fileId,
|
|
19167
|
+
name: info.name || 'Unknown',
|
|
19168
|
+
size: info.size,
|
|
19169
|
+
status: 'uploaded',
|
|
19170
|
+
source: { kind: 'fileId', value: info.fileId },
|
|
19171
|
+
};
|
|
19172
|
+
if (info.title !== undefined) {
|
|
19173
|
+
item.title = info.title;
|
|
19174
|
+
}
|
|
19175
|
+
if (info.description !== undefined) {
|
|
19176
|
+
item.description = info.description;
|
|
19177
|
+
}
|
|
19178
|
+
if (info.readOnly === true) {
|
|
19179
|
+
item.readOnly = true;
|
|
19180
|
+
}
|
|
19181
|
+
return item;
|
|
19182
|
+
}
|
|
19183
|
+
/**
|
|
19184
|
+
* Resolves inline attachment field values to displayable file list items.
|
|
19185
|
+
* Handles mixed arrays of `file:` refs and already-hydrated AXPFileListItem objects.
|
|
19186
|
+
*/
|
|
19187
|
+
async function hydrateAttachmentFieldToFileList(fieldValue, fileStorage) {
|
|
19188
|
+
const entries = parseAttachmentFieldEntries(fieldValue).filter(isAttachmentListEntry);
|
|
19189
|
+
if (entries.length === 0) {
|
|
19190
|
+
return [];
|
|
19191
|
+
}
|
|
19192
|
+
const fileIds = entries
|
|
19193
|
+
.filter(isAttachmentStorageRef)
|
|
19194
|
+
.filter((ref) => ref.startsWith(FILE_PREFIX))
|
|
19195
|
+
.map(removeFilePrefix);
|
|
19196
|
+
const infoMap = new Map();
|
|
19197
|
+
if (fileIds.length > 0) {
|
|
19198
|
+
const infos = await fileStorage.findMany(fileIds);
|
|
19199
|
+
for (const info of infos) {
|
|
19200
|
+
infoMap.set(info.fileId, info);
|
|
19201
|
+
}
|
|
19202
|
+
}
|
|
19203
|
+
const result = [];
|
|
19204
|
+
for (const entry of entries) {
|
|
19205
|
+
if (isFileListItem(entry)) {
|
|
19206
|
+
result.push(entry);
|
|
19207
|
+
continue;
|
|
19208
|
+
}
|
|
19209
|
+
if (isAttachmentStorageRef(entry) && entry.startsWith(FILE_PREFIX)) {
|
|
19210
|
+
const id = removeFilePrefix(entry);
|
|
19211
|
+
const info = infoMap.get(id);
|
|
19212
|
+
if (info) {
|
|
19213
|
+
result.push(storageInfoToFileListItem(info));
|
|
19214
|
+
}
|
|
19215
|
+
else {
|
|
19216
|
+
result.push({
|
|
19217
|
+
id,
|
|
19218
|
+
name: 'Unknown File',
|
|
19219
|
+
status: 'remote',
|
|
19220
|
+
source: { kind: 'fileId', value: id },
|
|
19221
|
+
});
|
|
19222
|
+
}
|
|
19223
|
+
continue;
|
|
19224
|
+
}
|
|
19225
|
+
if (isAttachmentStorageRef(entry)) {
|
|
19226
|
+
result.push({
|
|
19227
|
+
id: entry,
|
|
19228
|
+
name: 'File',
|
|
19229
|
+
status: 'remote',
|
|
19230
|
+
source: { kind: 'fileId', value: entry },
|
|
19231
|
+
});
|
|
19232
|
+
}
|
|
19233
|
+
}
|
|
19234
|
+
return result;
|
|
19235
|
+
}
|
|
19236
|
+
/** Attachment field path from widget options or column path fallback. */
|
|
19237
|
+
function resolveAttachmentFieldPath(options, fieldFallback) {
|
|
19238
|
+
const entityBlock = get(options, 'entity');
|
|
19239
|
+
const fromEntityBlock = entityBlock != null && typeof entityBlock === 'object'
|
|
19240
|
+
? get(entityBlock, 'field')
|
|
19241
|
+
: undefined;
|
|
19242
|
+
const field = get(options, 'entityField') ?? fromEntityBlock ?? fieldFallback;
|
|
19243
|
+
if (typeof field !== 'string' || !field.trim()) {
|
|
19244
|
+
return undefined;
|
|
19245
|
+
}
|
|
19246
|
+
return field.trim();
|
|
19247
|
+
}
|
|
19248
|
+
/** True when the list row includes the attachment field (even when empty). */
|
|
19249
|
+
function isAttachmentFieldPresentOnRow(rowData, fieldPath) {
|
|
19250
|
+
if (!fieldPath || !rowData) {
|
|
19251
|
+
return false;
|
|
19252
|
+
}
|
|
19253
|
+
return has(rowData, fieldPath);
|
|
19254
|
+
}
|
|
19098
19255
|
/** Resolve entity scope for column popup / load when widget options carry list-row expressions. */
|
|
19099
19256
|
function resolveEntityId(entityIdOption, rowData) {
|
|
19100
19257
|
if (isString(entityIdOption) && entityIdOption.trim() && !entityIdOption.includes('{{')) {
|
|
@@ -19134,10 +19291,14 @@ function resolveFileUploaderEntityScope(options, rowData, fieldFallback) {
|
|
|
19134
19291
|
}
|
|
19135
19292
|
//#endregion
|
|
19136
19293
|
|
|
19294
|
+
/** Trace namespace for file-uploader attachment column, load/save, and hydration. */
|
|
19295
|
+
const FILE_UPLOADER_TRACE_NS = 'file-uploader-attachments';
|
|
19296
|
+
|
|
19137
19297
|
class AXPFileUploaderLoadFilesQuery {
|
|
19138
19298
|
constructor() {
|
|
19139
19299
|
//#region ---- Services & Dependencies ----
|
|
19140
19300
|
this.injector = inject(Injector);
|
|
19301
|
+
this.debug = inject(AXPDebugService);
|
|
19141
19302
|
}
|
|
19142
19303
|
//#endregion
|
|
19143
19304
|
//#region ---- Query Execution ----
|
|
@@ -19151,8 +19312,28 @@ class AXPFileUploaderLoadFilesQuery {
|
|
|
19151
19312
|
return dataService.getOne(entityId);
|
|
19152
19313
|
});
|
|
19153
19314
|
const fieldValue = get(record, field);
|
|
19154
|
-
const files = normalizeEntityFieldToFileList(fieldValue);
|
|
19155
19315
|
const count = attachmentFieldCount(fieldValue);
|
|
19316
|
+
const inlineFiles = normalizeEntityFieldToFileList(fieldValue);
|
|
19317
|
+
const needsHydration = attachmentNeedsHydration(fieldValue);
|
|
19318
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'load-files', 'Fetched entity attachment field', () => ({
|
|
19319
|
+
entityRef,
|
|
19320
|
+
entityId,
|
|
19321
|
+
field,
|
|
19322
|
+
count,
|
|
19323
|
+
inlineFiles: inlineFiles.length,
|
|
19324
|
+
needsHydration,
|
|
19325
|
+
}));
|
|
19326
|
+
let files = inlineFiles;
|
|
19327
|
+
if (needsHydration) {
|
|
19328
|
+
const fileStorage = runInInjectionContext(this.injector, () => inject(AXPFileStorageService));
|
|
19329
|
+
files = await hydrateAttachmentFieldToFileList(fieldValue, fileStorage);
|
|
19330
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'load-files', 'Hydrated attachment refs', () => ({
|
|
19331
|
+
entityId,
|
|
19332
|
+
field,
|
|
19333
|
+
hydratedCount: files.length,
|
|
19334
|
+
fileNames: files.map((f) => f.name),
|
|
19335
|
+
}));
|
|
19336
|
+
}
|
|
19156
19337
|
return { files, count };
|
|
19157
19338
|
}
|
|
19158
19339
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderLoadFilesQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
@@ -19167,6 +19348,7 @@ class AXPFileUploaderSaveFilesCommand {
|
|
|
19167
19348
|
constructor() {
|
|
19168
19349
|
//#region ---- Services & Dependencies ----
|
|
19169
19350
|
this.injector = inject(Injector);
|
|
19351
|
+
this.debug = inject(AXPDebugService);
|
|
19170
19352
|
//#endregion
|
|
19171
19353
|
}
|
|
19172
19354
|
//#endregion
|
|
@@ -19174,6 +19356,14 @@ class AXPFileUploaderSaveFilesCommand {
|
|
|
19174
19356
|
async execute(input) {
|
|
19175
19357
|
const { name: entityRef, id: entityId, field } = input;
|
|
19176
19358
|
const files = (input.files ?? []).filter(isFileListItem);
|
|
19359
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'save-files', 'Saving attachment field', () => ({
|
|
19360
|
+
entityRef,
|
|
19361
|
+
entityId,
|
|
19362
|
+
field,
|
|
19363
|
+
inputCount: input.files?.length ?? 0,
|
|
19364
|
+
savingCount: files.length,
|
|
19365
|
+
attachmentCount: attachmentFieldCount(files),
|
|
19366
|
+
}));
|
|
19177
19367
|
if (!entityRef?.trim() || !entityId?.trim() || !field?.trim()) {
|
|
19178
19368
|
return {
|
|
19179
19369
|
success: false,
|
|
@@ -19213,7 +19403,6 @@ function hasFileUploaderTitleOrDescriptionFields(editDialog) {
|
|
|
19213
19403
|
}
|
|
19214
19404
|
//#endregion
|
|
19215
19405
|
|
|
19216
|
-
//#region ---- Imports ----
|
|
19217
19406
|
//#endregion
|
|
19218
19407
|
//#region ---- Component ----
|
|
19219
19408
|
class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
@@ -19226,23 +19415,32 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19226
19415
|
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
19227
19416
|
this.formatService = inject(AXFormatService);
|
|
19228
19417
|
this.translation = inject(AXTranslationService);
|
|
19418
|
+
this.debug = inject(AXPDebugService);
|
|
19229
19419
|
//#endregion
|
|
19230
19420
|
//#region ---- View Children ----
|
|
19231
19421
|
this.fileListTrigger = viewChild('fileListTrigger', ...(ngDevMode ? [{ debugName: "fileListTrigger" }] : /* istanbul ignore next */ []));
|
|
19232
19422
|
this.fileListPopover = viewChild('fileListPopover', ...(ngDevMode ? [{ debugName: "fileListPopover" }] : /* istanbul ignore next */ []));
|
|
19233
19423
|
//#endregion
|
|
19234
19424
|
//#region ---- State ----
|
|
19235
|
-
this.fileCount = signal(0, ...(ngDevMode ? [{ debugName: "fileCount" }] : /* istanbul ignore next */ []));
|
|
19236
19425
|
this.popoverFiles = signal([], ...(ngDevMode ? [{ debugName: "popoverFiles" }] : /* istanbul ignore next */ []));
|
|
19237
19426
|
this.loadStatus = signal('idle', ...(ngDevMode ? [{ debugName: "loadStatus" }] : /* istanbul ignore next */ []));
|
|
19238
19427
|
this.loadError = signal(null, ...(ngDevMode ? [{ debugName: "loadError" }] : /* istanbul ignore next */ []));
|
|
19239
19428
|
this.isPopoverOpen = signal(false, ...(ngDevMode ? [{ debugName: "isPopoverOpen" }] : /* istanbul ignore next */ []));
|
|
19240
19429
|
this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : /* istanbul ignore next */ []));
|
|
19241
|
-
this.loadRequestId = 0;
|
|
19242
19430
|
this.popoverLoadRequestId = 0;
|
|
19243
19431
|
//#endregion
|
|
19244
19432
|
//#region ---- Computed ----
|
|
19245
19433
|
this.entityScope = computed(() => resolveFileUploaderEntityScope(this.options ?? {}, this.rowData, this.path), ...(ngDevMode ? [{ debugName: "entityScope" }] : /* istanbul ignore next */ []));
|
|
19434
|
+
this.attachmentFieldPath = computed(() => resolveAttachmentFieldPath(this.options ?? {}, this.path), ...(ngDevMode ? [{ debugName: "attachmentFieldPath" }] : /* istanbul ignore next */ []));
|
|
19435
|
+
this.inlineFieldPresent = computed(() => isAttachmentFieldPresentOnRow(this.rowData, this.attachmentFieldPath()), ...(ngDevMode ? [{ debugName: "inlineFieldPresent" }] : /* istanbul ignore next */ []));
|
|
19436
|
+
this.fileCount = computed(() => {
|
|
19437
|
+
if (!this.inlineFieldPresent()) {
|
|
19438
|
+
return 0;
|
|
19439
|
+
}
|
|
19440
|
+
return attachmentFieldCount(this.rawValue);
|
|
19441
|
+
}, ...(ngDevMode ? [{ debugName: "fileCount" }] : /* istanbul ignore next */ []));
|
|
19442
|
+
/** Clickable when count is unknown or zero — opens popover (lazy load or inline empty). */
|
|
19443
|
+
this.showAttachmentsLink = computed(() => this.fileCount() === 0 && this.entityScope() != null, ...(ngDevMode ? [{ debugName: "showAttachmentsLink" }] : /* istanbul ignore next */ []));
|
|
19246
19444
|
this.popoverTitle = computed(() => {
|
|
19247
19445
|
const row = this.rowData;
|
|
19248
19446
|
const lang = this.translation.getActiveLang();
|
|
@@ -19259,10 +19457,7 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19259
19457
|
return '@document-management:terms.common.file';
|
|
19260
19458
|
}, ...(ngDevMode ? [{ debugName: "popoverTitle" }] : /* istanbul ignore next */ []));
|
|
19261
19459
|
effect(() => {
|
|
19262
|
-
const raw = this.rawValue;
|
|
19263
19460
|
const row = this.rowData;
|
|
19264
|
-
const opts = this.options ?? {};
|
|
19265
|
-
const path = this.path;
|
|
19266
19461
|
const rowId = row?.['id'] != null ? String(row['id']) : undefined;
|
|
19267
19462
|
if (rowId !== this.previousRowId) {
|
|
19268
19463
|
this.previousRowId = rowId;
|
|
@@ -19273,33 +19468,6 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19273
19468
|
this.popoverLoadRequestId++;
|
|
19274
19469
|
});
|
|
19275
19470
|
}
|
|
19276
|
-
const inlineCount = attachmentFieldCount(raw);
|
|
19277
|
-
if (inlineCount > 0) {
|
|
19278
|
-
untracked(() => this.fileCount.set(inlineCount));
|
|
19279
|
-
return;
|
|
19280
|
-
}
|
|
19281
|
-
const entity = resolveFileUploaderEntityScope(opts, row, path);
|
|
19282
|
-
if (!entity) {
|
|
19283
|
-
untracked(() => this.fileCount.set(0));
|
|
19284
|
-
return;
|
|
19285
|
-
}
|
|
19286
|
-
const requestId = ++this.loadRequestId;
|
|
19287
|
-
untracked(() => {
|
|
19288
|
-
void this.queryExecutor
|
|
19289
|
-
.fetch('FileUploader:LoadFiles', entity)
|
|
19290
|
-
.then((result) => {
|
|
19291
|
-
if (requestId !== this.loadRequestId) {
|
|
19292
|
-
return;
|
|
19293
|
-
}
|
|
19294
|
-
const count = result?.count ?? result?.files?.length ?? 0;
|
|
19295
|
-
this.fileCount.set(count);
|
|
19296
|
-
})
|
|
19297
|
-
.catch(() => {
|
|
19298
|
-
if (requestId === this.loadRequestId) {
|
|
19299
|
-
this.fileCount.set(0);
|
|
19300
|
-
}
|
|
19301
|
-
});
|
|
19302
|
-
});
|
|
19303
19471
|
});
|
|
19304
19472
|
effect(() => {
|
|
19305
19473
|
const scope = this.entityScope();
|
|
@@ -19338,25 +19506,45 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19338
19506
|
if (this.loadStatus() === 'loading') {
|
|
19339
19507
|
return;
|
|
19340
19508
|
}
|
|
19509
|
+
const count = attachmentFieldCount(this.rawValue);
|
|
19341
19510
|
const inline = normalizeEntityFieldToFileList(this.rawValue);
|
|
19342
|
-
|
|
19511
|
+
const needsHydration = attachmentNeedsHydration(this.rawValue);
|
|
19512
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Ensure popover files', () => ({
|
|
19513
|
+
rowId: this.previousRowId,
|
|
19514
|
+
inlineFieldPresent: this.inlineFieldPresent(),
|
|
19515
|
+
count,
|
|
19516
|
+
inlineFiles: inline.length,
|
|
19517
|
+
needsHydration,
|
|
19518
|
+
loadStatus: this.loadStatus(),
|
|
19519
|
+
}));
|
|
19520
|
+
if (inline.length > 0 && !needsHydration) {
|
|
19343
19521
|
this.popoverFiles.set(inline);
|
|
19344
19522
|
this.loadStatus.set('ready');
|
|
19345
19523
|
this.loadError.set(null);
|
|
19346
19524
|
return;
|
|
19347
19525
|
}
|
|
19526
|
+
if (this.inlineFieldPresent() && count === 0) {
|
|
19527
|
+
this.popoverFiles.set([]);
|
|
19528
|
+
this.loadStatus.set('ready');
|
|
19529
|
+
this.loadError.set(null);
|
|
19530
|
+
return;
|
|
19531
|
+
}
|
|
19348
19532
|
const entity = this.entityScope();
|
|
19349
19533
|
if (!entity) {
|
|
19350
19534
|
this.popoverFiles.set([]);
|
|
19351
19535
|
this.loadStatus.set('ready');
|
|
19352
19536
|
return;
|
|
19353
19537
|
}
|
|
19354
|
-
if (this.loadStatus() === 'ready' && this.popoverFiles().length > 0) {
|
|
19538
|
+
if (this.loadStatus() === 'ready' && this.popoverFiles().length > 0 && !needsHydration) {
|
|
19355
19539
|
return;
|
|
19356
19540
|
}
|
|
19357
19541
|
const requestId = ++this.popoverLoadRequestId;
|
|
19358
19542
|
this.loadStatus.set('loading');
|
|
19359
19543
|
this.loadError.set(null);
|
|
19544
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Loading files via FileUploader:LoadFiles', () => ({
|
|
19545
|
+
entity,
|
|
19546
|
+
reason: needsHydration ? 'hydration-required' : 'lazy-or-empty',
|
|
19547
|
+
}));
|
|
19360
19548
|
try {
|
|
19361
19549
|
const result = await this.queryExecutor.fetch('FileUploader:LoadFiles', entity);
|
|
19362
19550
|
if (requestId !== this.popoverLoadRequestId) {
|
|
@@ -19364,11 +19552,19 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19364
19552
|
}
|
|
19365
19553
|
this.popoverFiles.set(result?.files ?? []);
|
|
19366
19554
|
this.loadStatus.set('ready');
|
|
19555
|
+
this.debug.trace(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Popover files loaded', () => ({
|
|
19556
|
+
loadedCount: result?.files?.length ?? 0,
|
|
19557
|
+
expectedCount: result?.count ?? 0,
|
|
19558
|
+
}));
|
|
19367
19559
|
}
|
|
19368
|
-
catch {
|
|
19560
|
+
catch (error) {
|
|
19369
19561
|
if (requestId !== this.popoverLoadRequestId) {
|
|
19370
19562
|
return;
|
|
19371
19563
|
}
|
|
19564
|
+
this.debug.warn(FILE_UPLOADER_TRACE_NS, 'column-popover', 'Failed to load popover files', () => ({
|
|
19565
|
+
entity,
|
|
19566
|
+
error: error instanceof Error ? error.message : String(error),
|
|
19567
|
+
}));
|
|
19372
19568
|
const msg = await this.translation.translateAsync('@general:widgets.lookup.column.load-failed');
|
|
19373
19569
|
this.loadError.set(msg);
|
|
19374
19570
|
this.loadStatus.set('error');
|
|
@@ -19391,11 +19587,11 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19391
19587
|
return false;
|
|
19392
19588
|
}
|
|
19393
19589
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19394
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileUploaderWidgetColumnComponent, isStandalone: true, selector: "axp-file-uploader-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "fileListTrigger", first: true, predicate: ["fileListTrigger"], descendants: true, isSignal: true }, { propertyName: "fileListPopover", first: true, predicate: ["fileListPopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (fileCount() > 0) {\n<span
|
|
19590
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPFileUploaderWidgetColumnComponent, isStandalone: true, selector: "axp-file-uploader-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "fileListTrigger", first: true, predicate: ["fileListTrigger"], descendants: true, isSignal: true }, { propertyName: "fileListPopover", first: true, predicate: ["fileListPopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (fileCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n </span>\n} @else if (showAttachmentsLink()) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{ '@general:widgets.file-uploader.attachments.title' | translate | async }}\n </span>\n} @else {\n <span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else if (popoverFiles().length === 0) {\n <p class=\"axp-file-uploader-column-popover__empty\">\n {{ '@general:widgets.file-uploader.empty-state.title' | translate | async }}\n </p>\n } @else {\n <axp-file-list\n [files]=\"popoverFiles()\"\n look=\"links\"\n linksLayout=\"menu\"\n [showLabel]=\"false\"\n [readonly]=\"true\"\n />\n }\n </div>\n </div>\n</ax-popover>\n", styles: [".axp-file-uploader-column-popover__empty{margin:0;padding-top:.5rem;padding-bottom:.5rem;text-align:center;font-size:.875rem;line-height:1.25rem;line-height:1.375;color:rgb(var(--ax-sys-color-on-lighter-surface))}\n"], dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "look", "titleKey", "showLabel", "linksLayout", "files", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i3$1.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19395
19591
|
}
|
|
19396
19592
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, decorators: [{
|
|
19397
19593
|
type: Component,
|
|
19398
|
-
args: [{ selector: 'axp-file-uploader-widget-column', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXTranslationModule, AsyncPipe, AXPopoverModule, AXLoadingModule, AXPFileListComponent], inputs: ['rawValue', 'rowData'], template: "@if (fileCount() > 0) {\n<span
|
|
19594
|
+
args: [{ selector: 'axp-file-uploader-widget-column', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXTranslationModule, AsyncPipe, AXPopoverModule, AXLoadingModule, AXPFileListComponent], inputs: ['rawValue', 'rowData'], template: "@if (fileCount() > 0) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\n </span>\n} @else if (showAttachmentsLink()) {\n <span\n class=\"ax-cursor-pointer ax-text-primary ax-underline\"\n (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger\n >\n {{ '@general:widgets.file-uploader.attachments.title' | translate | async }}\n </span>\n} @else {\n <span class=\"ax-text-muted\">---</span>\n}\n\n<ax-popover [openOn]=\"'manual'\" #fileListPopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[17.5rem] ax-max-w-[26rem] ax-overflow-hidden\">\n <div class=\"ax-border-b ax-border-surface ax-px-4 ax-py-3\">\n <h3 class=\"ax-m-0 ax-text-sm ax-font-semibold ax-leading-normal ax-text-on-lightest-surface\">\n {{ popoverTitle() | translate | async }}\n </h3>\n </div>\n <div class=\"ax-max-h-64 ax-overflow-y-auto ax-px-3 ax-py-3\" style=\"max-height: max(30dvh, 12rem)\">\n @if (loadStatus() === 'loading') {\n <div class=\"ax-flex ax-min-h-[120px] ax-items-center ax-justify-center\">\n <ax-loading></ax-loading>\n </div>\n } @else if (loadStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ loadError() }}</div>\n } @else if (popoverFiles().length === 0) {\n <p class=\"axp-file-uploader-column-popover__empty\">\n {{ '@general:widgets.file-uploader.empty-state.title' | translate | async }}\n </p>\n } @else {\n <axp-file-list\n [files]=\"popoverFiles()\"\n look=\"links\"\n linksLayout=\"menu\"\n [showLabel]=\"false\"\n [readonly]=\"true\"\n />\n }\n </div>\n </div>\n</ax-popover>\n", styles: [".axp-file-uploader-column-popover__empty{margin:0;padding-top:.5rem;padding-bottom:.5rem;text-align:center;font-size:.875rem;line-height:1.25rem;line-height:1.375;color:rgb(var(--ax-sys-color-on-lighter-surface))}\n"] }]
|
|
19399
19595
|
}], ctorParameters: () => [], propDecorators: { fileListTrigger: [{ type: i0.ViewChild, args: ['fileListTrigger', { isSignal: true }] }], fileListPopover: [{ type: i0.ViewChild, args: ['fileListPopover', { isSignal: true }] }] } });
|
|
19400
19596
|
|
|
19401
19597
|
var fileUploaderWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
@@ -20124,16 +20320,21 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
20124
20320
|
AXPFileUploaderWidgetService: AXPFileUploaderWidgetService,
|
|
20125
20321
|
AXPFileUploaderWidgetViewComponent: AXPFileUploaderWidgetViewComponent,
|
|
20126
20322
|
attachmentFieldCount: attachmentFieldCount,
|
|
20323
|
+
attachmentNeedsHydration: attachmentNeedsHydration,
|
|
20127
20324
|
attachmentsSemanticallyEqual: attachmentsSemanticallyEqual,
|
|
20128
20325
|
committedAttachments: committedAttachments,
|
|
20129
20326
|
fingerprintAttachmentItem: fingerprintAttachmentItem,
|
|
20130
20327
|
fingerprintAttachments: fingerprintAttachments,
|
|
20131
20328
|
hasFileUploaderTitleOrDescriptionFields: hasFileUploaderTitleOrDescriptionFields,
|
|
20329
|
+
hydrateAttachmentFieldToFileList: hydrateAttachmentFieldToFileList,
|
|
20330
|
+
isAttachmentFieldPresentOnRow: isAttachmentFieldPresentOnRow,
|
|
20132
20331
|
isAttachmentListEntry: isAttachmentListEntry,
|
|
20332
|
+
isAttachmentStorageRef: isAttachmentStorageRef,
|
|
20133
20333
|
isFileListItem: isFileListItem,
|
|
20134
20334
|
isFileUploaderEditDialogAuto: isFileUploaderEditDialogAuto,
|
|
20135
20335
|
normalizeEntityFieldToFileList: normalizeEntityFieldToFileList,
|
|
20136
20336
|
persistedAttachments: persistedAttachments,
|
|
20337
|
+
resolveAttachmentFieldPath: resolveAttachmentFieldPath,
|
|
20137
20338
|
resolveFileUploaderEditDialog: resolveFileUploaderEditDialog,
|
|
20138
20339
|
resolveFileUploaderEntityScope: resolveFileUploaderEntityScope
|
|
20139
20340
|
});
|
|
@@ -20196,7 +20397,6 @@ var selectorStructureWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
|
20196
20397
|
AXPSelectorStructureWidgetColumnComponent: AXPSelectorStructureWidgetColumnComponent
|
|
20197
20398
|
});
|
|
20198
20399
|
|
|
20199
|
-
//#region ---- Imports ----
|
|
20200
20400
|
/** Internal key for stable row tracking before a selector value is committed (persisted with the row). */
|
|
20201
20401
|
const SELECTOR_STRUCTURE_ROW_UID = '__rowUid';
|
|
20202
20402
|
//#endregion
|
|
@@ -25805,9 +26005,42 @@ var getEntityDetails_query = /*#__PURE__*/Object.freeze({
|
|
|
25805
26005
|
AXPGetEntityDetailsQuery: AXPGetEntityDetailsQuery
|
|
25806
26006
|
});
|
|
25807
26007
|
|
|
26008
|
+
/**
|
|
26009
|
+
* Computes a diff between two plain objects with array-aware semantics.
|
|
26010
|
+
* - For arrays of objects with an id field, computes added/removed by id.
|
|
26011
|
+
* - For arrays of primitives or objects without id, uses deep equality.
|
|
26012
|
+
* - For scalars/objects, reports oldValue/newValue when changed.
|
|
26013
|
+
*/
|
|
26014
|
+
function detectEntityChanges(oldObj, newObj) {
|
|
26015
|
+
return transform(newObj, (result, value, key) => {
|
|
26016
|
+
if (!isEqual$1(value, oldObj[key])) {
|
|
26017
|
+
const oldValue = oldObj[key];
|
|
26018
|
+
if (Array.isArray(value) || Array.isArray(oldValue)) {
|
|
26019
|
+
const oldArray = Array.isArray(oldValue) ? oldValue : [];
|
|
26020
|
+
const newArray = Array.isArray(value) ? value : [];
|
|
26021
|
+
const hasId = newArray.length > 0 && typeof newArray[0] === 'object' && newArray[0] !== null && 'id' in newArray[0];
|
|
26022
|
+
if (hasId) {
|
|
26023
|
+
const added = newArray.filter((item) => !oldArray.some((oldItem) => oldItem.id === item.id));
|
|
26024
|
+
const removed = oldArray.filter((item) => !newArray.some((newItem) => newItem.id === item.id));
|
|
26025
|
+
result[key] = { oldValue, newValue: value, added, removed };
|
|
26026
|
+
}
|
|
26027
|
+
else {
|
|
26028
|
+
const added = newArray.filter((item) => !oldArray.some((oldItem) => isEqual$1(item, oldItem)));
|
|
26029
|
+
const removed = oldArray.filter((item) => !newArray.some((newItem) => isEqual$1(item, newItem)));
|
|
26030
|
+
result[key] = { oldValue, newValue: value, added, removed };
|
|
26031
|
+
}
|
|
26032
|
+
}
|
|
26033
|
+
else {
|
|
26034
|
+
result[key] = { oldValue, newValue: value };
|
|
26035
|
+
}
|
|
26036
|
+
}
|
|
26037
|
+
}, {});
|
|
26038
|
+
}
|
|
26039
|
+
//#endregion
|
|
26040
|
+
|
|
25808
26041
|
/**
|
|
25809
26042
|
* Generated bundle index. Do not edit.
|
|
25810
26043
|
*/
|
|
25811
26044
|
|
|
25812
|
-
export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService, AXPEntityDefinitionProviderWidget, AXPEntityDefinitionProviderWidgetEditComponent, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityFormBuilderService, AXPEntityListPersistenceModeDefault, AXPEntityListTableService, AXPEntityListToolbarService, AXPEntityListViewCardFieldViewModel, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListCardSelectActionName, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityPreloadFiltersContainerComponent, AXPEntityPreloadFiltersViewModel, AXPEntityPreloadFiltersViewModelResolver, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPFileListComponent, AXPFileUploaderLoadFilesQuery, AXPFileUploaderSaveFilesCommand, AXPFileUploaderWidget, AXPFileUploaderWidgetColumnComponent, AXPFileUploaderWidgetEditComponent, AXPFileUploaderWidgetService, AXPFileUploaderWidgetViewComponent, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPRelatedColumnEnrichmentService, AXPRelatedColumnMetadataResolver, AXPSelectorStructureWidget, AXPSelectorStructureWidgetColumnComponent, AXPSelectorStructureWidgetEditComponent, AXPSelectorStructureWidgetViewComponent, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_COLUMN_ORDER, DEFAULT_PAIR_SPAN_RULES, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY, EntityBuilder, EntityDataAccessor, actionExists, applyDataSourcePagingWithoutLoad, attachmentFieldCount, attachmentsPlugin, attachmentsSemanticallyEqual, axpCreateEntityAiToolInputDefaults, axpCreateEntityCommandDefinition, canPersistEntityListState, cloneLayoutArrays, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, formatLookupItemDisplayAsync, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, hasFileUploaderTitleOrDescriptionFields, isAXPMiddlewareAbortError, isAttachmentListEntry, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, persistedAttachments, provideEntity, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
|
|
26045
|
+
export { ATTACHMENTS_PAGE_COMPONENT_KEY, AXMEntityCrudService, AXMEntityCrudServiceImpl, AXPCategoryTreeService, AXPCreateEntityCommand, AXPCreateEntityWorkflow, AXPDataSeederService, AXPDeleteEntityWorkflow, AXPEditFileUploaderCommand, AXPEntitiesListDataSourceDefinition, AXPEntityApplyUpdatesAction, AXPEntityCategoryTreeSelectorComponent, AXPEntityCategoryWidget, AXPEntityCategoryWidgetColumnComponent, AXPEntityCategoryWidgetEditComponent, AXPEntityCategoryWidgetViewComponent, AXPEntityCommandTriggerViewModel, AXPEntityCreateEvent, AXPEntityCreatePopupAction, AXPEntityCreateSubmittedAction, AXPEntityCreateViewElementViewModel, AXPEntityCreateViewModelFactory, AXPEntityCreateViewSectionViewModel, AXPEntityDataProvider, AXPEntityDataProviderImpl, AXPEntityDataSelectorRowActionsService, AXPEntityDataSelectorService, AXPEntityDefinitionProviderWidget, AXPEntityDefinitionProviderWidgetEditComponent, AXPEntityDefinitionRegistryService, AXPEntityDeletedEvent, AXPEntityDetailListViewModel, AXPEntityDetailPopoverComponent, AXPEntityDetailPopoverService, AXPEntityDetailViewModelFactory, AXPEntityDetailViewModelResolver, AXPEntityEventDispatcherService, AXPEntityFormBuilderService, AXPEntityListPersistenceModeDefault, AXPEntityListTableService, AXPEntityListToolbarService, AXPEntityListViewCardFieldViewModel, AXPEntityListViewColumnViewModel, AXPEntityListViewModelFactory, AXPEntityListViewModelResolver, AXPEntityListWidget, AXPEntityListWidgetViewComponent, AXPEntityMasterCreateViewModel, AXPEntityMasterListCardSelectActionName, AXPEntityMasterListViewModel, AXPEntityMasterListViewQueryViewModel, AXPEntityMasterSingleElementViewModel, AXPEntityMasterSingleViewGroupViewModel, AXPEntityMasterSingleViewModel, AXPEntityMasterUpdateElementViewModel, AXPEntityMasterUpdateViewModel, AXPEntityMasterUpdateViewModelFactory, AXPEntityMiddleware, AXPEntityModifyConfirmedAction, AXPEntityModifyEvent, AXPEntityModifySectionPopupAction, AXPEntityModule, AXPEntityPerformDeleteAction, AXPEntityPreloadFiltersContainerComponent, AXPEntityPreloadFiltersViewModel, AXPEntityPreloadFiltersViewModelResolver, AXPEntityResolver, AXPEntityService, AXPEntityStorageService, AXPEntityUpdateViewSectionViewModel, AXPFileListComponent, AXPFileUploaderLoadFilesQuery, AXPFileUploaderSaveFilesCommand, AXPFileUploaderWidget, AXPFileUploaderWidgetColumnComponent, AXPFileUploaderWidgetEditComponent, AXPFileUploaderWidgetService, AXPFileUploaderWidgetViewComponent, AXPGetEntityDetailsQuery, AXPLayoutOrderingConfigService, AXPLookupWidget, AXPLookupWidgetColumnComponent, AXPLookupWidgetEditComponent, AXPLookupWidgetViewComponent, AXPMiddlewareAbortError, AXPMiddlewareEntityStorageService, AXPModifyEntitySectionWorkflow, AXPMultiSourceDefinitionProviderContext, AXPMultiSourceDefinitionProviderService, AXPMultiSourceFederatedSearchService, AXPMultiSourceSelectorComponent, AXPMultiSourceSelectorService, AXPMultiSourceSelectorWidget, AXPMultiSourceSelectorWidgetColumnComponent, AXPMultiSourceSelectorWidgetEditComponent, AXPMultiSourceSelectorWidgetViewComponent, AXPMultiSourceType, AXPOpenEntityDetailsCommand, AXPQuickEntityModifyPopupAction, AXPQuickModifyEntityWorkflow, AXPRelatedColumnEnrichmentService, AXPRelatedColumnMetadataResolver, AXPSelectorStructureWidget, AXPSelectorStructureWidgetColumnComponent, AXPSelectorStructureWidgetEditComponent, AXPSelectorStructureWidgetViewComponent, AXPShowDetailViewAction, AXPShowDetailsViewWorkflow, AXPShowListViewAction, AXPShowListViewWorkflow, AXPTruncatedBreadcrumbComponent, AXPUpdateEntityCommand, AXPViewEntityDetailsCommand, AXP_APPEARANCE_SECTION_ORDER, AXP_CATEGORY_TREE_ROOT_TITLE_I18N_KEY, AXP_CLASSIFICATION_SECTION_ORDER, AXP_DATA_SEEDER_TOKEN, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_MODIFIER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_MULTI_SOURCE_DEFINITION_PROVIDER, DEFAULT_COLUMN_ORDER, DEFAULT_PAIR_SPAN_RULES, DEFAULT_PROPERTY_ORDER, DEFAULT_SECTION_ORDER, ENTITY_LIST_ROUTE_CONTEXT_SESSION_KEY, EntityBuilder, EntityDataAccessor, actionExists, applyDataSourcePagingWithoutLoad, attachmentFieldCount, attachmentNeedsHydration, attachmentsPlugin, attachmentsSemanticallyEqual, axpCreateEntityAiToolInputDefaults, axpCreateEntityCommandDefinition, canPersistEntityListState, cloneLayoutArrays, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, formatLookupItemDisplayAsync, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, hasFileUploaderTitleOrDescriptionFields, hydrateAttachmentFieldToFileList, isAXPMiddlewareAbortError, isAttachmentFieldPresentOnRow, isAttachmentListEntry, isAttachmentStorageRef, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, persistedAttachments, provideEntity, resolveAttachmentFieldPath, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
|
|
25813
26046
|
//# sourceMappingURL=acorex-platform-layout-entity.mjs.map
|