@acorex/platform 21.0.0-next.70 → 21.0.0-next.71
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-common.mjs +11 -0
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +332 -76
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +563 -44
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +83 -67
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +543 -237
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +319 -66
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +54 -6
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +198 -91
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +13 -14
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-shared.mjs +50 -30
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-common.d.ts +11 -0
- package/types/acorex-platform-core.d.ts +137 -47
- package/types/acorex-platform-layout-builder.d.ts +90 -13
- package/types/acorex-platform-layout-components.d.ts +21 -17
- package/types/acorex-platform-layout-entity.d.ts +63 -10
- package/types/acorex-platform-layout-views.d.ts +68 -6
- package/types/acorex-platform-layout-widget-core.d.ts +43 -8
- package/types/acorex-platform-layout-widgets.d.ts +21 -6
- package/types/acorex-platform-themes-default.d.ts +24 -4
- package/types/acorex-platform-themes-shared.d.ts +6 -0
- package/types/acorex-platform-workflow.d.ts +1 -1
|
@@ -9,7 +9,7 @@ import { Subject, takeUntil } from 'rxjs';
|
|
|
9
9
|
import { AXPLayoutBuilderService, LayoutBuilderModule } from '@acorex/platform/layout/builder';
|
|
10
10
|
import * as i3 from '@acorex/platform/layout/widget-core';
|
|
11
11
|
import { AXPWidgetsCatalog, 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';
|
|
12
|
-
import { AXPSystemActionType, AXPDeviceService, AXPExpressionEvaluatorService, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXPPlatformScope, AXHighlightService, extractValue, setSmart, getChangedPaths, objectKeyValueTransforms, AXPHookService, AXPDataGenerator, AXPComponentSlotModule, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
12
|
+
import { AXPSystemActionType, AXPDeviceService, AXPExpressionEvaluatorService, AXPBroadcastEventService, applyFilterArray, applySortArray, resolveActionLook, AXPDistributedEventListenerService, AXPPlatformScope, AXHighlightService, extractValue, setSmart, getChangedPaths, objectKeyValueTransforms, AXPHookService, AXPDataGenerator, AXPComponentSlotModule, AXPContextStore, AXPColumnWidthService, AXPModuleManifestRegistry, defaultColumnWidthProvider, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXPModuleManifestsDataSourceDefinition } from '@acorex/platform/core';
|
|
13
13
|
import { cloneDeep, merge, get, castArray, set, orderBy, omit, isNil, isEmpty, isEqual as isEqual$1, isArray, isString } from 'lodash-es';
|
|
14
14
|
import { transform, isEqual } from 'lodash';
|
|
15
15
|
import { AXPSessionService, AXPAuthGuard, AXPPermissionDefinitionsDataSourceDefinition } from '@acorex/platform/auth';
|
|
@@ -23,7 +23,7 @@ import * as i2 from '@acorex/components/popover';
|
|
|
23
23
|
import { AXPopoverModule } from '@acorex/components/popover';
|
|
24
24
|
import { AXFormatService } from '@acorex/core/format';
|
|
25
25
|
import * as i5 from '@angular/common';
|
|
26
|
-
import { CommonModule, AsyncPipe } from '@angular/common';
|
|
26
|
+
import { CommonModule, AsyncPipe, NgClass } from '@angular/common';
|
|
27
27
|
import { AXPThemeLayoutBlockComponent, AXPPreloadFiltersComponent, AXP_PAGE_COMPONENT_PROVIDER, AXPStateMessageComponent, AXPColumnItemListComponent, AXPDataSelectorService, AXPPageComponentRegistryService } from '@acorex/platform/layout/components';
|
|
28
28
|
import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageComponentRendererDirective, AXPPageComponentInstanceRegistryService } from '@acorex/platform/layout/views';
|
|
29
29
|
import { AXDataSource } from '@acorex/cdk/common';
|
|
@@ -1686,13 +1686,14 @@ class PropertyFilter {
|
|
|
1686
1686
|
d.setTitle(title);
|
|
1687
1687
|
d.setSize(this.externalSize ?? (useFormWizard ? 'lg' : calculatedSize));
|
|
1688
1688
|
d.setCloseButton(true);
|
|
1689
|
+
d.confirmCloseWhenDirty();
|
|
1689
1690
|
d.content((layout) => {
|
|
1690
1691
|
const defaultMode = this.kind === 'single' ? 'view' : 'edit';
|
|
1691
1692
|
layout.mode(this.externalMode ?? defaultMode);
|
|
1692
1693
|
if (useFormWizard) {
|
|
1693
1694
|
layout.stepWizard((w) => {
|
|
1694
1695
|
w.name(ENTITY_FORM_STEP_WIZARD_NAME);
|
|
1695
|
-
w.setLook('arrow-minimal');
|
|
1696
|
+
w.setLook('rectangular-arrow-minimal');
|
|
1696
1697
|
w.setShowActions(false);
|
|
1697
1698
|
const mainStepTitle = (entity.formats?.individual ||
|
|
1698
1699
|
entity.title ||
|
|
@@ -2554,7 +2555,9 @@ class AXPCreateEntityCommand {
|
|
|
2554
2555
|
const entityRef = await this.entityService.resolve(moduleName, entityName);
|
|
2555
2556
|
let chain = this.entityForm.entity(`${moduleName}.${entityName}`).create(data);
|
|
2556
2557
|
chain.actions((actions) => {
|
|
2557
|
-
actions
|
|
2558
|
+
actions
|
|
2559
|
+
.cancel('@general:actions.cancel.title')
|
|
2560
|
+
.submit('@general:actions.create.title', { shortcuts: ['Enter', 'ctrl+s'] });
|
|
2558
2561
|
});
|
|
2559
2562
|
if (excludeProperties && excludeProperties.length > 0) {
|
|
2560
2563
|
chain = chain.exclude(...excludeProperties);
|
|
@@ -3382,11 +3385,11 @@ class AXPEntityDetailPopoverComponent {
|
|
|
3382
3385
|
return prop.name;
|
|
3383
3386
|
}
|
|
3384
3387
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3385
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, displayTitle: { classPropertyName: "displayTitle", publicName: "displayTitle", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-p-4 ax-w-[min(600px,calc(100vw-2rem))]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n {{ headerTitle() }}\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-space-y-2 ax-mb-4\">\n @for (row of loadingSkeletonRows; track row) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-items-start\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-2/3 ax-rounded\"></ax-skeleton>\n @if (row === 2) {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-16 ax-w-full ax-rounded\"></ax-skeleton>\n } @else {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-full ax-rounded\"></ax-skeleton>\n }\n </div>\n }\n </div>\n <div class=\"ax-flex ax-justify-end\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-9 ax-w-28 ax-rounded\"></ax-skeleton>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of entityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-gap-y-1 ax-items-start\">\n <span class=\"ax-text-sm ax-font-medium
|
|
3388
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPEntityDetailPopoverComponent, isStandalone: true, selector: "axp-entity-detail-popover", inputs: { entity: { classPropertyName: "entity", publicName: "entity", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, displayTitle: { classPropertyName: "displayTitle", publicName: "displayTitle", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, breadcrumb: { classPropertyName: "breadcrumb", publicName: "breadcrumb", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "detailPopover", first: true, predicate: ["detailPopover"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-p-4 ax-w-[min(600px,calc(100vw-2rem))]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n {{ headerTitle() }}\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-space-y-2 ax-mb-4\">\n @for (row of loadingSkeletonRows; track row) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-items-start\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-2/3 ax-rounded\"></ax-skeleton>\n @if (row === 2) {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-16 ax-w-full ax-rounded\"></ax-skeleton>\n } @else {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-full ax-rounded\"></ax-skeleton>\n }\n </div>\n }\n </div>\n <div class=\"ax-flex ax-justify-end\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-9 ax-w-28 ax-rounded\"></ax-skeleton>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of entityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-gap-y-1 ax-items-start\">\n <span class=\"ax-text-sm ax-font-medium ax-shrink-0\">{{ item.title | translate | async\n }}:</span>\n <div class=\"ax-min-w-0 ax-text-sm\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" [text]=\"'@general:actions.open-details.title' | translate | async\"\n (click)=\"navigateToDetails()\">\n </ax-button>\n </div>\n }\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: AXPopoverModule }, { kind: "component", type: i2.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: AXPWidgetCoreModule }, { kind: "component", type: i3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i4.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3386
3389
|
}
|
|
3387
3390
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPEntityDetailPopoverComponent, decorators: [{
|
|
3388
3391
|
type: Component,
|
|
3389
|
-
args: [{ selector: 'axp-entity-detail-popover', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXButtonModule, AXPopoverModule, AXPWidgetCoreModule, AXTranslationModule, AXSkeletonModule], template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface ax-p-4 ax-w-[min(600px,calc(100vw-2rem))]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n {{ headerTitle() }}\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-space-y-2 ax-mb-4\">\n @for (row of loadingSkeletonRows; track row) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-items-start\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-2/3 ax-rounded\"></ax-skeleton>\n @if (row === 2) {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-16 ax-w-full ax-rounded\"></ax-skeleton>\n } @else {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-full ax-rounded\"></ax-skeleton>\n }\n </div>\n }\n </div>\n <div class=\"ax-flex ax-justify-end\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-9 ax-w-28 ax-rounded\"></ax-skeleton>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of entityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-gap-y-1 ax-items-start\">\n <span class=\"ax-text-sm ax-font-medium
|
|
3392
|
+
args: [{ selector: 'axp-entity-detail-popover', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXButtonModule, AXPopoverModule, AXPWidgetCoreModule, AXTranslationModule, AXSkeletonModule], template: "<ax-popover [openOn]=\"'manual'\" #detailPopover (openChange)=\"onDetailPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-p-4 ax-w-[min(600px,calc(100vw-2rem))]\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold ax-text-on-lightest-surface\">\n {{ headerTitle() }}\n </h3>\n @if (breadcrumb()) {\n <div class=\"ax-text-xs ax-text-neutral-500 ax-mt-1\">{{ breadcrumb() }}</div>\n }\n </div>\n @if (isLoadingDetails()) {\n <div class=\"ax-space-y-2 ax-mb-4\">\n @for (row of loadingSkeletonRows; track row) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-items-start\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-2/3 ax-rounded\"></ax-skeleton>\n @if (row === 2) {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-16 ax-w-full ax-rounded\"></ax-skeleton>\n } @else {\n <ax-skeleton [animated]=\"true\" class=\"ax-h-4 ax-w-full ax-rounded\"></ax-skeleton>\n }\n </div>\n }\n </div>\n <div class=\"ax-flex ax-justify-end\">\n <ax-skeleton [animated]=\"true\" class=\"ax-h-9 ax-w-28 ax-rounded\"></ax-skeleton>\n </div>\n } @else if (entityDetails()) {\n <div class=\"ax-space-y-3 ax-mb-4\">\n <!-- Important Entity Data -->\n @if (entityDetails()?.entityData) {\n <axp-widgets-container [context]=\"entityDetails()?.entityData\">\n <div class=\"ax-space-y-2\">\n @for (item of entityPropertiesWithWidgets(); track item.name) {\n <div class=\"ax-grid ax-grid-cols-[minmax(7rem,35%)_1fr] ax-gap-x-4 ax-gap-y-1 ax-items-start\">\n <span class=\"ax-text-sm ax-font-medium ax-shrink-0\">{{ item.title | translate | async\n }}:</span>\n <div class=\"ax-min-w-0 ax-text-sm\">\n <ng-container axp-widget-renderer [node]=\"item.node\" [mode]=\"'view'\"></ng-container>\n </div>\n </div>\n }\n </div>\n </axp-widgets-container>\n }\n </div>\n <div class=\"ax-flex ax-gap-2 ax-justify-end ax-sm\">\n <ax-button [color]=\"'primary'\" [look]=\"'solid'\" [text]=\"'@general:actions.open-details.title' | translate | async\"\n (click)=\"navigateToDetails()\">\n </ax-button>\n </div>\n }\n </div>\n</ax-popover>" }]
|
|
3390
3393
|
}], propDecorators: { entity: [{ type: i0.Input, args: [{ isSignal: true, alias: "entity", required: true }] }], entityId: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityId", required: true }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], displayTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayTitle", required: false }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], breadcrumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumb", required: false }] }], detailPopover: [{ type: i0.ViewChild, args: ['detailPopover', { isSignal: true }] }] } });
|
|
3391
3394
|
|
|
3392
3395
|
class AXPEntityDetailPopoverService {
|
|
@@ -3624,6 +3627,58 @@ class AXMEntityCrudServiceImpl {
|
|
|
3624
3627
|
async custom(request) { }
|
|
3625
3628
|
}
|
|
3626
3629
|
|
|
3630
|
+
/**
|
|
3631
|
+
* Error type that can be thrown by middlewares to abort the chain with a structured payload.
|
|
3632
|
+
*/
|
|
3633
|
+
class AXPMiddlewareAbortError extends Error {
|
|
3634
|
+
constructor(message, options = {}) {
|
|
3635
|
+
super(message);
|
|
3636
|
+
this.message = message;
|
|
3637
|
+
this.options = options;
|
|
3638
|
+
this.name = 'AXPMiddlewareAbortError';
|
|
3639
|
+
}
|
|
3640
|
+
toResponse() {
|
|
3641
|
+
return {
|
|
3642
|
+
success: false,
|
|
3643
|
+
error: {
|
|
3644
|
+
code: this.options.code,
|
|
3645
|
+
message: this.message,
|
|
3646
|
+
status: this.options.status,
|
|
3647
|
+
details: this.options.details,
|
|
3648
|
+
},
|
|
3649
|
+
};
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
/** Type guard for AXPMiddlewareAbortError */
|
|
3653
|
+
function isAXPMiddlewareAbortError(error) {
|
|
3654
|
+
return error instanceof AXPMiddlewareAbortError;
|
|
3655
|
+
}
|
|
3656
|
+
//#endregion
|
|
3657
|
+
|
|
3658
|
+
/**
|
|
3659
|
+
* Maps storage middleware failures to a command result the details view can surface.
|
|
3660
|
+
*/
|
|
3661
|
+
function mapEntityStorageErrorToCommandResult(error, fallback = 'Failed to update entity') {
|
|
3662
|
+
if (isAXPMiddlewareAbortError(error)) {
|
|
3663
|
+
return {
|
|
3664
|
+
success: false,
|
|
3665
|
+
message: {
|
|
3666
|
+
type: 'error',
|
|
3667
|
+
code: error.options.code,
|
|
3668
|
+
text: error.message,
|
|
3669
|
+
details: error.options.details,
|
|
3670
|
+
},
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
const text = error instanceof Error ? error.message : typeof error === 'string' ? error : fallback;
|
|
3674
|
+
return {
|
|
3675
|
+
success: false,
|
|
3676
|
+
message: {
|
|
3677
|
+
type: 'error',
|
|
3678
|
+
text,
|
|
3679
|
+
},
|
|
3680
|
+
};
|
|
3681
|
+
}
|
|
3627
3682
|
/**
|
|
3628
3683
|
* Best-effort plain string for thrown {@link Error} messages from command results (no i18n lookup).
|
|
3629
3684
|
*/
|
|
@@ -11426,12 +11481,11 @@ class AXPEntityCategoryWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
11426
11481
|
setSmart(itemToExpose, i.target, this.singleOrMultiple(values));
|
|
11427
11482
|
}
|
|
11428
11483
|
});
|
|
11429
|
-
this.contextService.
|
|
11430
|
-
|
|
11431
|
-
this.setValue(this.singleOrMultiple(keys));
|
|
11484
|
+
this.contextService.applyObjectPaths(itemToExpose, { origin: 'user' });
|
|
11485
|
+
this.setUserValue(this.singleOrMultiple(keys));
|
|
11432
11486
|
}
|
|
11433
11487
|
else {
|
|
11434
|
-
this.
|
|
11488
|
+
this.setUserValue(this.singleOrMultiple(keys));
|
|
11435
11489
|
}
|
|
11436
11490
|
// Trigger change detection
|
|
11437
11491
|
this.cdr.markForCheck();
|
|
@@ -13072,6 +13126,14 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
13072
13126
|
hasAnyChange: changes.length > 0,
|
|
13073
13127
|
};
|
|
13074
13128
|
}
|
|
13129
|
+
/**
|
|
13130
|
+
* Maps toolbar sort queries ({ name, dir }) to AXDataSource sort options ({ field, dir }).
|
|
13131
|
+
*/
|
|
13132
|
+
toDataSourceSortOptions(sorts) {
|
|
13133
|
+
return (sorts ?? [])
|
|
13134
|
+
.filter((s) => s.dir)
|
|
13135
|
+
.map((s) => ({ field: s.name, dir: s.dir }));
|
|
13136
|
+
}
|
|
13075
13137
|
/**
|
|
13076
13138
|
* Applies filter and sort changes to the data source
|
|
13077
13139
|
*/
|
|
@@ -13082,7 +13144,8 @@ class AXPEntityListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
13082
13144
|
});
|
|
13083
13145
|
}
|
|
13084
13146
|
if (changeTracker.isSortChanged) {
|
|
13085
|
-
|
|
13147
|
+
const sortOptions = this.toDataSourceSortOptions(queries.sorts);
|
|
13148
|
+
dataSource.sort(...sortOptions);
|
|
13086
13149
|
}
|
|
13087
13150
|
}
|
|
13088
13151
|
/**
|
|
@@ -15534,7 +15597,8 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15534
15597
|
this.setLoading = (loading) => {
|
|
15535
15598
|
this.isLoading.set(loading);
|
|
15536
15599
|
};
|
|
15537
|
-
this.setItems = (items) => {
|
|
15600
|
+
this.setItems = (items, options) => {
|
|
15601
|
+
const origin = options?.origin ?? 'system';
|
|
15538
15602
|
// Ensure items is always an array
|
|
15539
15603
|
items = castArray(items);
|
|
15540
15604
|
// Filter out null/undefined items
|
|
@@ -15556,7 +15620,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15556
15620
|
//
|
|
15557
15621
|
// extract data from valueField and set context by expose path
|
|
15558
15622
|
if (this.expose()) {
|
|
15559
|
-
this.expoesItems();
|
|
15623
|
+
this.expoesItems(origin);
|
|
15560
15624
|
}
|
|
15561
15625
|
const newValue = this.singleOrMultiple(keys);
|
|
15562
15626
|
if (this.filterMode()) {
|
|
@@ -15566,10 +15630,10 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15566
15630
|
operation: {
|
|
15567
15631
|
type: this.multiple() ? 'in' : 'equal',
|
|
15568
15632
|
},
|
|
15569
|
-
});
|
|
15633
|
+
}, { origin });
|
|
15570
15634
|
}
|
|
15571
15635
|
else {
|
|
15572
|
-
this.setValue(newValue);
|
|
15636
|
+
this.setValue(newValue, { origin });
|
|
15573
15637
|
}
|
|
15574
15638
|
};
|
|
15575
15639
|
}
|
|
@@ -15621,7 +15685,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15621
15685
|
}
|
|
15622
15686
|
//#region ---- Event Handlers from Dumb Components ----
|
|
15623
15687
|
handleComponentValueChanged(items) {
|
|
15624
|
-
this.setItems(items ?? []);
|
|
15688
|
+
this.setItems(items ?? [], { origin: 'user' });
|
|
15625
15689
|
}
|
|
15626
15690
|
async handleCreateClick(_e) {
|
|
15627
15691
|
const entity = this.entityDef();
|
|
@@ -15646,10 +15710,10 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15646
15710
|
if (this.multiple()) {
|
|
15647
15711
|
const exists = currentItems.some((item) => get(item, valueField) === newId);
|
|
15648
15712
|
const newItems = exists ? currentItems : [...currentItems, createdItem];
|
|
15649
|
-
this.setItems(newItems);
|
|
15713
|
+
this.setItems(newItems, { origin: 'user' });
|
|
15650
15714
|
}
|
|
15651
15715
|
else {
|
|
15652
|
-
this.setItems([createdItem]);
|
|
15716
|
+
this.setItems([createdItem], { origin: 'user' });
|
|
15653
15717
|
}
|
|
15654
15718
|
}
|
|
15655
15719
|
}
|
|
@@ -15666,7 +15730,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15666
15730
|
* so e.g. `{ person: { educationLevel: { id, title } } }` would replace the entire `person`
|
|
15667
15731
|
* object and drop sibling fields like `person.educationLevelId`, causing a value/effect loop.
|
|
15668
15732
|
*/
|
|
15669
|
-
expoesItems() {
|
|
15733
|
+
expoesItems(origin = 'system') {
|
|
15670
15734
|
const exposeValue = castArray(this.expose());
|
|
15671
15735
|
const items = this.selectedItems();
|
|
15672
15736
|
const isEmpty = !items || items.length === 0;
|
|
@@ -15679,7 +15743,7 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15679
15743
|
parentPaths.add(pathParts.slice(0, -1).join('.'));
|
|
15680
15744
|
}
|
|
15681
15745
|
else {
|
|
15682
|
-
this.contextService.update(i, null);
|
|
15746
|
+
this.contextService.update(i, null, { origin });
|
|
15683
15747
|
}
|
|
15684
15748
|
}
|
|
15685
15749
|
else {
|
|
@@ -15688,25 +15752,25 @@ class AXPLookupWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
15688
15752
|
parentPaths.add(pathParts.slice(0, -1).join('.'));
|
|
15689
15753
|
}
|
|
15690
15754
|
else {
|
|
15691
|
-
this.contextService.update(i.target, null);
|
|
15755
|
+
this.contextService.update(i.target, null, { origin });
|
|
15692
15756
|
}
|
|
15693
15757
|
}
|
|
15694
15758
|
});
|
|
15695
15759
|
parentPaths.forEach((parentPath) => {
|
|
15696
|
-
this.contextService.update(parentPath, null);
|
|
15760
|
+
this.contextService.update(parentPath, null, { origin });
|
|
15697
15761
|
});
|
|
15698
15762
|
return;
|
|
15699
15763
|
}
|
|
15700
15764
|
exposeValue.forEach((i) => {
|
|
15701
15765
|
if (typeof i === 'string') {
|
|
15702
15766
|
const values = items.map((item) => set({}, i, get(item, i)));
|
|
15703
|
-
this.contextService.update(i, this.singleOrMultiple(values));
|
|
15767
|
+
this.contextService.update(i, this.singleOrMultiple(values), { origin });
|
|
15704
15768
|
}
|
|
15705
15769
|
else {
|
|
15706
15770
|
const values = this.multiple()
|
|
15707
15771
|
? items.map((item) => set({}, i.source, get(item, i.source)))
|
|
15708
15772
|
: items.map((item) => get(item, i.source));
|
|
15709
|
-
this.contextService.update(i.target, this.singleOrMultiple(values));
|
|
15773
|
+
this.contextService.update(i.target, this.singleOrMultiple(values), { origin });
|
|
15710
15774
|
}
|
|
15711
15775
|
});
|
|
15712
15776
|
}
|
|
@@ -16516,11 +16580,11 @@ class AXPLookupWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
16516
16580
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) || /^\d+$/.test(value);
|
|
16517
16581
|
}
|
|
16518
16582
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
16519
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span
|
|
16583
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLookupWidgetColumnComponent, isStandalone: true, selector: "ng-component", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "lazyTrigger", first: true, predicate: ["lazyTrigger"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span [class.ax-cursor-pointer]=\"detailPopoverEnabled()\" [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\" (click)=\"handleItemClick($index)\">\n {{ label }}\n </span>\n @if ($index < visibleItems().length - 1) { <span class=\"ax-text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-end-0 ax-flex ax-h-full ax-cursor-pointer ax-items-center ax-px-1 hover:ax-primary-lighter\"\n (click)=\"showMoreItems(); $event.stopPropagation()\" #moreButton>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n</div>\n} @else {\n<div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @if (displayCount() > 0) {\n <span class=\"ax-cursor-pointer ax-text-primary hover:ax-underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\" #lazyTrigger>\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n</div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[280px] ax-rounded-lg ax-border ax-p-4 ax-shadow-lg\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === '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 (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"ax-flex ax-max-h-64 ax-flex-col ax-gap-3\">\n @for (item of popoverListItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span [class.ax-cursor-pointer]=\"detailPopoverEnabled()\" [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\" (click)=\"handlePopoverItemClick($index)\">\n {{ label }}\n </span>\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i1$2.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
16520
16584
|
}
|
|
16521
16585
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLookupWidgetColumnComponent, decorators: [{
|
|
16522
16586
|
type: Component,
|
|
16523
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXLoadingModule, AXPopoverModule], inputs: ['rawValue', 'rowData'], template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span
|
|
16587
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXLoadingModule, AXPopoverModule], inputs: ['rawValue', 'rowData'], template: "@if (isHydratedStrategy()) {\n<div class=\"ax-relative ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @for (item of visibleItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span [class.ax-cursor-pointer]=\"detailPopoverEnabled()\" [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\" (click)=\"handleItemClick($index)\">\n {{ label }}\n </span>\n @if ($index < visibleItems().length - 1) { <span class=\"ax-text-muted\">\u2022</span>\n }\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n @if (hasMoreItems()) {\n <span\n class=\"ax-absolute ax-end-0 ax-flex ax-h-full ax-cursor-pointer ax-items-center ax-px-1 hover:ax-primary-lighter\"\n (click)=\"showMoreItems(); $event.stopPropagation()\" #moreButton>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </span>\n }\n</div>\n} @else {\n<div class=\"ax-flex ax-min-w-0 ax-items-center ax-gap-1\">\n @if (displayCount() > 0) {\n <span class=\"ax-cursor-pointer ax-text-primary hover:ax-underline\"\n (click)=\"openLazyPopover(); $event.stopPropagation()\" #lazyTrigger>\n {{ summaryLabel() }}\n </span>\n } @else {\n <span class=\"ax-text-muted\">---</span>\n }\n</div>\n}\n\n<ax-popover [openOn]=\"'manual'\" #morePopover (openChange)=\"onPopoverOpenChange($event)\">\n <div class=\"ax-lightest-surface dark:ax-dark-surface ax-min-w-[280px] ax-rounded-lg ax-border ax-p-4 ax-shadow-lg\">\n <div class=\"ax-mb-4 ax-border-b ax-pb-2\">\n <h3 class=\"ax-text-base ax-font-semibold\">{{ popoverHeader() }}</h3>\n </div>\n\n @if (!isHydratedStrategy() && resolveStatus() === '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 (!isHydratedStrategy() && resolveStatus() === 'error') {\n <div class=\"ax-text-danger ax-text-sm\">{{ resolveError() }}</div>\n } @else {\n <div class=\"ax-flex ax-max-h-64 ax-flex-col ax-gap-3\">\n @for (item of popoverListItems(); track $index) {\n @let label = getDisplayRaw(item);\n <span [class.ax-cursor-pointer]=\"detailPopoverEnabled()\" [class.hover:ax-text-primary]=\"detailPopoverEnabled()\"\n [class.hover:ax-underline]=\"detailPopoverEnabled()\" (click)=\"handlePopoverItemClick($index)\">\n {{ label }}\n </span>\n } @empty {\n <span class=\"ax-text-muted\">---</span>\n }\n </div>\n }\n </div>\n</ax-popover>" }]
|
|
16524
16588
|
}], ctorParameters: () => [], propDecorators: { moreButton: [{ type: i0.ViewChild, args: ['moreButton', { isSignal: true }] }], lazyTrigger: [{ type: i0.ViewChild, args: ['lazyTrigger', { isSignal: true }] }], morePopover: [{ type: i0.ViewChild, args: ['morePopover', { isSignal: true }] }] } });
|
|
16525
16589
|
|
|
16526
16590
|
var lookupWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
@@ -18320,6 +18384,14 @@ class AXPFileListComponent {
|
|
|
18320
18384
|
/** When true, edit dialog shows name, title and description fields. Default false. */
|
|
18321
18385
|
this.enableTitleDescription = input(false, ...(ngDevMode ? [{ debugName: "enableTitleDescription" }] : /* istanbul ignore next */ []));
|
|
18322
18386
|
this.multiple = input(true, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
18387
|
+
/** `rows`: file-type icons and action buttons; `links`: compact paperclip links (download on click). */
|
|
18388
|
+
this.look = input('rows', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
|
|
18389
|
+
/** i18n key for links look label (template adds trailing colon). */
|
|
18390
|
+
this.titleKey = input('@general:widgets.file-uploader.attachments.title', ...(ngDevMode ? [{ debugName: "titleKey" }] : /* istanbul ignore next */ []));
|
|
18391
|
+
/** When false, links look omits the label (e.g. popover body). */
|
|
18392
|
+
this.showLabel = input(true, ...(ngDevMode ? [{ debugName: "showLabel" }] : /* istanbul ignore next */ []));
|
|
18393
|
+
/** `inline`: label + divider; `menu`: compact list for popovers/panels. */
|
|
18394
|
+
this.linksLayout = input('inline', ...(ngDevMode ? [{ debugName: "linksLayout" }] : /* istanbul ignore next */ []));
|
|
18323
18395
|
this.files = input([], ...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
|
|
18324
18396
|
// Plugin context (passed from parent widget)
|
|
18325
18397
|
this.plugins = input(undefined, ...(ngDevMode ? [{ debugName: "plugins" }] : /* istanbul ignore next */ []));
|
|
@@ -18330,11 +18402,19 @@ class AXPFileListComponent {
|
|
|
18330
18402
|
* All files should be displayed, even those with `deleted` status.
|
|
18331
18403
|
* The template will handle the visual differences based on the status.
|
|
18332
18404
|
*/
|
|
18333
|
-
this.displayFiles = computed(() =>
|
|
18405
|
+
this.displayFiles = computed(() => {
|
|
18406
|
+
const list = this.files();
|
|
18407
|
+
if (this.look() === 'links') {
|
|
18408
|
+
return list.filter((file) => file.status !== 'deleted');
|
|
18409
|
+
}
|
|
18410
|
+
return list;
|
|
18411
|
+
}, ...(ngDevMode ? [{ debugName: "displayFiles" }] : /* istanbul ignore next */ []));
|
|
18334
18412
|
// Cache for per-file actions provided by hooks
|
|
18335
18413
|
this.fileIdToActions = signal({}, ...(ngDevMode ? [{ debugName: "fileIdToActions" }] : /* istanbul ignore next */ []));
|
|
18336
18414
|
// Global actions from FileUploaderWebhookKeys.Actions hook
|
|
18337
18415
|
this.globalActions = signal([], ...(ngDevMode ? [{ debugName: "globalActions" }] : /* istanbul ignore next */ []));
|
|
18416
|
+
/** Suppress duplicate downloads from double-click (two click events). */
|
|
18417
|
+
this.recentDownloadAtByKey = new Map();
|
|
18338
18418
|
// Clear cache when files change to reload actions
|
|
18339
18419
|
this.filesChangeEffect = effect(() => {
|
|
18340
18420
|
// Track files changes to clear cache
|
|
@@ -18342,6 +18422,7 @@ class AXPFileListComponent {
|
|
|
18342
18422
|
this.fileIdToActions.set({});
|
|
18343
18423
|
}, ...(ngDevMode ? [{ debugName: "filesChangeEffect" }] : /* istanbul ignore next */ []));
|
|
18344
18424
|
}
|
|
18425
|
+
static { this.DOWNLOAD_DEBOUNCE_MS = 500; }
|
|
18345
18426
|
// Default actions that can be removed via hooks
|
|
18346
18427
|
getDefaultActions(file) {
|
|
18347
18428
|
const defaultActions = [];
|
|
@@ -18438,6 +18519,10 @@ class AXPFileListComponent {
|
|
|
18438
18519
|
this.fileIdToActions.set(next);
|
|
18439
18520
|
}
|
|
18440
18521
|
async ngOnInit() {
|
|
18522
|
+
if (this.look() === 'links') {
|
|
18523
|
+
this.isLoading.set(false);
|
|
18524
|
+
return;
|
|
18525
|
+
}
|
|
18441
18526
|
this.fileTypes.set(await this.fileTypeService.items());
|
|
18442
18527
|
await this.loadGlobalActions();
|
|
18443
18528
|
this.isLoading.set(false);
|
|
@@ -18457,6 +18542,36 @@ class AXPFileListComponent {
|
|
|
18457
18542
|
this.globalActions.set([]);
|
|
18458
18543
|
}
|
|
18459
18544
|
}
|
|
18545
|
+
shouldSkipDuplicateDownload(file) {
|
|
18546
|
+
const key = this.downloadDedupeKey(file);
|
|
18547
|
+
const now = Date.now();
|
|
18548
|
+
const last = this.recentDownloadAtByKey.get(key);
|
|
18549
|
+
if (last != null && now - last < AXPFileListComponent.DOWNLOAD_DEBOUNCE_MS) {
|
|
18550
|
+
return true;
|
|
18551
|
+
}
|
|
18552
|
+
this.recentDownloadAtByKey.set(key, now);
|
|
18553
|
+
return false;
|
|
18554
|
+
}
|
|
18555
|
+
downloadDedupeKey(file) {
|
|
18556
|
+
if (typeof file.id === 'string' && file.id.trim()) {
|
|
18557
|
+
return file.id;
|
|
18558
|
+
}
|
|
18559
|
+
const src = file.source;
|
|
18560
|
+
if (src?.kind === 'fileId' && typeof src.value === 'string' && src.value.trim()) {
|
|
18561
|
+
return src.value;
|
|
18562
|
+
}
|
|
18563
|
+
return file.name;
|
|
18564
|
+
}
|
|
18565
|
+
/** Ensures `source` is set for links look and legacy rows that only carry storage id on `id`. */
|
|
18566
|
+
resolveFileForDownload(file) {
|
|
18567
|
+
if (file.source) {
|
|
18568
|
+
return file;
|
|
18569
|
+
}
|
|
18570
|
+
if (typeof file.id === 'string' && file.id.trim()) {
|
|
18571
|
+
return { ...file, source: { kind: 'fileId', value: file.id } };
|
|
18572
|
+
}
|
|
18573
|
+
return file;
|
|
18574
|
+
}
|
|
18460
18575
|
getFileInfo(fileName) {
|
|
18461
18576
|
const extension = fileName.split('.').pop()?.toLowerCase() || '';
|
|
18462
18577
|
const extensions = this.fileTypes().flatMap((t) => t.extensions);
|
|
@@ -18466,9 +18581,22 @@ class AXPFileListComponent {
|
|
|
18466
18581
|
type: fileType?.name || 'Unknown',
|
|
18467
18582
|
};
|
|
18468
18583
|
}
|
|
18584
|
+
/**
|
|
18585
|
+
* Double-click on a file row (rows look) or link row triggers download.
|
|
18586
|
+
*/
|
|
18587
|
+
handleFileRowActivate(event, file) {
|
|
18588
|
+
if (file.status === 'deleted') {
|
|
18589
|
+
return;
|
|
18590
|
+
}
|
|
18591
|
+
void this.handleFileDownload(event, file);
|
|
18592
|
+
}
|
|
18469
18593
|
async handleFileDownload(event, file) {
|
|
18470
|
-
event.nativeEvent
|
|
18471
|
-
|
|
18594
|
+
const nativeEvent = event instanceof Event ? event : event.nativeEvent;
|
|
18595
|
+
nativeEvent.preventDefault();
|
|
18596
|
+
nativeEvent.stopPropagation();
|
|
18597
|
+
if (this.shouldSkipDuplicateDownload(file)) {
|
|
18598
|
+
return;
|
|
18599
|
+
}
|
|
18472
18600
|
try {
|
|
18473
18601
|
await this.hooks.runAsync(FileUploaderWebhookKeys.FileItem.BeforeDownload, {
|
|
18474
18602
|
file,
|
|
@@ -18478,7 +18606,9 @@ class AXPFileListComponent {
|
|
|
18478
18606
|
});
|
|
18479
18607
|
}
|
|
18480
18608
|
catch { }
|
|
18481
|
-
|
|
18609
|
+
const resolved = this.resolveFileForDownload(file);
|
|
18610
|
+
const source = resolved.source;
|
|
18611
|
+
if (!source) {
|
|
18482
18612
|
console.error('File source is undefined, cannot download.', file);
|
|
18483
18613
|
return;
|
|
18484
18614
|
}
|
|
@@ -18492,37 +18622,37 @@ class AXPFileListComponent {
|
|
|
18492
18622
|
document.body.removeChild(link);
|
|
18493
18623
|
URL.revokeObjectURL(url);
|
|
18494
18624
|
};
|
|
18495
|
-
switch (
|
|
18625
|
+
switch (source.kind) {
|
|
18496
18626
|
case 'blob':
|
|
18497
|
-
if (
|
|
18498
|
-
triggerDownload(
|
|
18627
|
+
if (source.value instanceof Blob) {
|
|
18628
|
+
triggerDownload(source.value, resolved.name ?? 'download');
|
|
18499
18629
|
}
|
|
18500
18630
|
else {
|
|
18501
18631
|
console.error('Source kind is blob, but value is not a Blob.', file);
|
|
18502
18632
|
}
|
|
18503
18633
|
break;
|
|
18504
18634
|
case 'fileId':
|
|
18505
|
-
if (typeof
|
|
18635
|
+
if (typeof source.value === 'string') {
|
|
18506
18636
|
try {
|
|
18507
|
-
const fileInfo = await this.fileStorageService.getInfo(
|
|
18637
|
+
const fileInfo = await this.fileStorageService.getInfo(source.value);
|
|
18508
18638
|
if (fileInfo && fileInfo.url) {
|
|
18509
18639
|
const link = document.createElement('a');
|
|
18510
18640
|
link.href = fileInfo.url;
|
|
18511
|
-
link.download =
|
|
18641
|
+
link.download = resolved.name ?? fileInfo.name ?? 'download';
|
|
18512
18642
|
link.target = '_blank';
|
|
18513
18643
|
document.body.appendChild(link);
|
|
18514
18644
|
link.click();
|
|
18515
18645
|
document.body.removeChild(link);
|
|
18516
18646
|
}
|
|
18517
18647
|
else if (fileInfo && fileInfo.binary instanceof Blob) {
|
|
18518
|
-
triggerDownload(fileInfo.binary,
|
|
18648
|
+
triggerDownload(fileInfo.binary, resolved.name ?? fileInfo.name ?? 'download');
|
|
18519
18649
|
}
|
|
18520
18650
|
else {
|
|
18521
18651
|
console.error('Could not retrieve file for download from fileId:', fileInfo);
|
|
18522
18652
|
}
|
|
18523
18653
|
}
|
|
18524
18654
|
catch (error) {
|
|
18525
|
-
console.error('Error downloading file by fileId:',
|
|
18655
|
+
console.error('Error downloading file by fileId:', source.value, error);
|
|
18526
18656
|
}
|
|
18527
18657
|
}
|
|
18528
18658
|
else {
|
|
@@ -18530,10 +18660,10 @@ class AXPFileListComponent {
|
|
|
18530
18660
|
}
|
|
18531
18661
|
break;
|
|
18532
18662
|
case 'url':
|
|
18533
|
-
if (typeof
|
|
18663
|
+
if (typeof source.value === 'string') {
|
|
18534
18664
|
const link = document.createElement('a');
|
|
18535
|
-
link.href =
|
|
18536
|
-
link.download =
|
|
18665
|
+
link.href = source.value;
|
|
18666
|
+
link.download = resolved.name ?? 'download';
|
|
18537
18667
|
link.target = '_blank';
|
|
18538
18668
|
document.body.appendChild(link);
|
|
18539
18669
|
link.click();
|
|
@@ -18544,14 +18674,14 @@ class AXPFileListComponent {
|
|
|
18544
18674
|
}
|
|
18545
18675
|
break;
|
|
18546
18676
|
case 'reference':
|
|
18547
|
-
if (
|
|
18548
|
-
typeof
|
|
18549
|
-
'id' in
|
|
18550
|
-
'type' in
|
|
18677
|
+
if (source.value &&
|
|
18678
|
+
typeof source.value === 'object' &&
|
|
18679
|
+
'id' in source.value &&
|
|
18680
|
+
'type' in source.value) {
|
|
18551
18681
|
try {
|
|
18552
18682
|
const result = await this.hooks.runAsync(FileUploaderWebhookKeys.FileItem.DownloadReference, {
|
|
18553
|
-
file,
|
|
18554
|
-
reference:
|
|
18683
|
+
file: resolved,
|
|
18684
|
+
reference: source.value,
|
|
18555
18685
|
plugins: this.plugins() ?? [],
|
|
18556
18686
|
excludePlugins: this.excludePlugins() ?? [],
|
|
18557
18687
|
capabilities: this.capabilities(),
|
|
@@ -18561,14 +18691,14 @@ class AXPFileListComponent {
|
|
|
18561
18691
|
if (result.fileInfo.url) {
|
|
18562
18692
|
const link = document.createElement('a');
|
|
18563
18693
|
link.href = result.fileInfo.url;
|
|
18564
|
-
link.download =
|
|
18694
|
+
link.download = resolved.name ?? result.fileInfo.name ?? 'download';
|
|
18565
18695
|
link.target = '_blank';
|
|
18566
18696
|
document.body.appendChild(link);
|
|
18567
18697
|
link.click();
|
|
18568
18698
|
document.body.removeChild(link);
|
|
18569
18699
|
}
|
|
18570
18700
|
else if (result.fileInfo.binary instanceof Blob) {
|
|
18571
|
-
triggerDownload(result.fileInfo.binary,
|
|
18701
|
+
triggerDownload(result.fileInfo.binary, resolved.name ?? result.fileInfo.name ?? 'download');
|
|
18572
18702
|
}
|
|
18573
18703
|
else {
|
|
18574
18704
|
console.error('Could not retrieve file for download from reference:', result.fileInfo);
|
|
@@ -18579,7 +18709,7 @@ class AXPFileListComponent {
|
|
|
18579
18709
|
}
|
|
18580
18710
|
}
|
|
18581
18711
|
catch (error) {
|
|
18582
|
-
console.error('Error downloading file by reference:',
|
|
18712
|
+
console.error('Error downloading file by reference:', source.value, error);
|
|
18583
18713
|
}
|
|
18584
18714
|
}
|
|
18585
18715
|
else {
|
|
@@ -18589,12 +18719,12 @@ class AXPFileListComponent {
|
|
|
18589
18719
|
case 'preview':
|
|
18590
18720
|
case 'none':
|
|
18591
18721
|
default:
|
|
18592
|
-
console.error(`Download not supported for source kind: ${
|
|
18722
|
+
console.error(`Download not supported for source kind: ${source.kind}`, file);
|
|
18593
18723
|
break;
|
|
18594
18724
|
}
|
|
18595
18725
|
try {
|
|
18596
18726
|
await this.hooks.runAsync(FileUploaderWebhookKeys.FileItem.AfterDownload, {
|
|
18597
|
-
file,
|
|
18727
|
+
file: resolved,
|
|
18598
18728
|
plugins: this.plugins() ?? [],
|
|
18599
18729
|
excludePlugins: this.excludePlugins() ?? [],
|
|
18600
18730
|
capabilities: this.capabilities(),
|
|
@@ -18663,7 +18793,9 @@ class AXPFileListComponent {
|
|
|
18663
18793
|
}
|
|
18664
18794
|
catch { }
|
|
18665
18795
|
}
|
|
18666
|
-
ngOnDestroy() {
|
|
18796
|
+
ngOnDestroy() {
|
|
18797
|
+
this.recentDownloadAtByKey.clear();
|
|
18798
|
+
}
|
|
18667
18799
|
async runAction(action) {
|
|
18668
18800
|
try {
|
|
18669
18801
|
await action.run(this.capabilities());
|
|
@@ -18687,19 +18819,24 @@ class AXPFileListComponent {
|
|
|
18687
18819
|
return action.color ?? 'primary';
|
|
18688
18820
|
}
|
|
18689
18821
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
18690
|
-
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 }, 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" }, providers: [], ngImport: i0, template: "@for (file of displayFiles(); track $index) {\n <div\n
|
|
18691
|
-
// Angular
|
|
18692
|
-
CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type:
|
|
18822
|
+
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{cursor:pointer;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}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type:
|
|
18693
18823
|
// ACoreX
|
|
18694
18824
|
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$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
|
|
18695
18825
|
// Platform
|
|
18696
|
-
AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "look"] }
|
|
18826
|
+
AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "look"] }, { kind: "pipe", type:
|
|
18827
|
+
// Angular
|
|
18828
|
+
AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }] }); }
|
|
18697
18829
|
}
|
|
18698
18830
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileListComponent, decorators: [{
|
|
18699
18831
|
type: Component,
|
|
18700
|
-
args: [{ selector: 'axp-file-list',
|
|
18832
|
+
args: [{ selector: 'axp-file-list', host: {
|
|
18833
|
+
'[class.--look-rows]': 'look() === "rows"',
|
|
18834
|
+
'[class.--look-links]': 'look() === "links"',
|
|
18835
|
+
'[class.--links-inline]': 'look() === "links" && linksLayout() === "inline"',
|
|
18836
|
+
}, imports: [
|
|
18701
18837
|
// Angular
|
|
18702
|
-
|
|
18838
|
+
AsyncPipe,
|
|
18839
|
+
NgClass,
|
|
18703
18840
|
// ACoreX
|
|
18704
18841
|
AXFormModule,
|
|
18705
18842
|
AXTextBoxModule,
|
|
@@ -18710,8 +18847,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
18710
18847
|
AXTranslationModule,
|
|
18711
18848
|
// Platform
|
|
18712
18849
|
AXPStateMessageComponent,
|
|
18713
|
-
], providers: [], template: "@for (file of displayFiles(); track $index) {\n <div\n
|
|
18714
|
-
}], 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 }] }], 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 }] }] } });
|
|
18850
|
+
], 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{cursor:pointer;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}\n"] }]
|
|
18851
|
+
}], 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 }] }] } });
|
|
18715
18852
|
|
|
18716
18853
|
//#region ---- Attachment fingerprint (no blob comparison) ----
|
|
18717
18854
|
/** Stable fingerprint for one file row; ignores Blob binary content. */
|
|
@@ -18968,95 +19105,146 @@ function hasFileUploaderTitleOrDescriptionFields(editDialog) {
|
|
|
18968
19105
|
}
|
|
18969
19106
|
//#endregion
|
|
18970
19107
|
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
19108
|
+
//#region ---- Imports ----
|
|
19109
|
+
//#endregion
|
|
19110
|
+
//#region ---- Title template resolution ----
|
|
19111
|
+
const INVALID_DISPLAY_TEXT = '[object Object]';
|
|
19112
|
+
/**
|
|
19113
|
+
* Row title template for entity-scoped popovers (e.g. attachment file list).
|
|
19114
|
+
* Priority: `interfaces.master.single.title` → `formats.searchResult.title` → `formats.individual`.
|
|
19115
|
+
*/
|
|
19116
|
+
function resolveEntityRowTitleTemplate(entity) {
|
|
19117
|
+
if (!entity) {
|
|
19118
|
+
return undefined;
|
|
18978
19119
|
}
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
19120
|
+
const singleTitle = entity.interfaces?.master?.single?.title?.trim();
|
|
19121
|
+
if (singleTitle) {
|
|
19122
|
+
return normalizeLookupDisplayTemplate(singleTitle);
|
|
19123
|
+
}
|
|
19124
|
+
const searchTitle = entity.formats?.searchResult?.title?.trim();
|
|
19125
|
+
if (searchTitle) {
|
|
19126
|
+
return normalizeLookupDisplayTemplate(searchTitle);
|
|
19127
|
+
}
|
|
19128
|
+
const individual = entity.formats?.individual?.trim();
|
|
19129
|
+
if (individual) {
|
|
19130
|
+
return normalizeLookupDisplayTemplate(individual);
|
|
19131
|
+
}
|
|
19132
|
+
return undefined;
|
|
19133
|
+
}
|
|
19134
|
+
/** Resolves a row field or format result to a plain display string for the active locale. */
|
|
19135
|
+
function resolveEntityRowDisplayText(value, activeLang) {
|
|
19136
|
+
if (value == null || value === '') {
|
|
19137
|
+
return '';
|
|
19138
|
+
}
|
|
19139
|
+
if (typeof value === 'string') {
|
|
19140
|
+
const text = value.trim();
|
|
19141
|
+
if (!text || text === INVALID_DISPLAY_TEXT || isUnresolvedLookupDisplayTemplate(text)) {
|
|
19142
|
+
return '';
|
|
18990
19143
|
}
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
editDialog: options?.editDialog,
|
|
19001
|
-
};
|
|
19002
|
-
const component = await import('./acorex-platform-layout-entity-file-list-popup.component-_yrP5SQe.mjs').then((m) => m.AXPFileListPopupComponent);
|
|
19003
|
-
const result = await this.popupService.open(component, {
|
|
19004
|
-
title: await this.translate.translateAsync('@document-management:terms.common.file'),
|
|
19005
|
-
data: {
|
|
19006
|
-
files: signal(resolved.files),
|
|
19007
|
-
isReadonly: signal(resolved.readonly),
|
|
19008
|
-
multiple: signal(resolved.multiple),
|
|
19009
|
-
accept: signal(resolved.accept),
|
|
19010
|
-
maxFileSize: signal(resolved.maxFileSize),
|
|
19011
|
-
fileEditable: signal(resolved.fileEditable),
|
|
19012
|
-
showAddItemButton: signal(resolved.showAddItemButton),
|
|
19013
|
-
plugins: signal(resolved.plugins),
|
|
19014
|
-
editDialog: signal(resolved.editDialog),
|
|
19015
|
-
},
|
|
19016
|
-
});
|
|
19017
|
-
const updatedFiles = result?.data?.data?.files;
|
|
19018
|
-
if (!updatedFiles) {
|
|
19019
|
-
return undefined;
|
|
19144
|
+
return text;
|
|
19145
|
+
}
|
|
19146
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
19147
|
+
return String(value);
|
|
19148
|
+
}
|
|
19149
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
19150
|
+
const text = resolveMultiLanguageString(value, activeLang).trim();
|
|
19151
|
+
if (!text || text === INVALID_DISPLAY_TEXT) {
|
|
19152
|
+
return '';
|
|
19020
19153
|
}
|
|
19021
|
-
|
|
19022
|
-
|
|
19154
|
+
return text;
|
|
19155
|
+
}
|
|
19156
|
+
return '';
|
|
19157
|
+
}
|
|
19158
|
+
/**
|
|
19159
|
+
* Formats the entity row title for display using row fields and single-view template.
|
|
19160
|
+
*/
|
|
19161
|
+
function formatEntityRowDisplayTitle(entity, rowData, formatService, activeLang) {
|
|
19162
|
+
if (!rowData) {
|
|
19163
|
+
return '';
|
|
19164
|
+
}
|
|
19165
|
+
for (const field of ['title', 'name', 'code']) {
|
|
19166
|
+
const fromField = resolveEntityRowDisplayText(get(rowData, field), activeLang);
|
|
19167
|
+
if (fromField) {
|
|
19168
|
+
return fromField;
|
|
19023
19169
|
}
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19170
|
+
}
|
|
19171
|
+
const template = resolveEntityRowTitleTemplate(entity);
|
|
19172
|
+
if (template) {
|
|
19173
|
+
const formatted = formatService.format(template, 'string', rowData);
|
|
19174
|
+
const fromTemplate = resolveEntityRowDisplayText(formatted, activeLang);
|
|
19175
|
+
if (fromTemplate) {
|
|
19176
|
+
return fromTemplate;
|
|
19030
19177
|
}
|
|
19031
|
-
return updatedFiles;
|
|
19032
19178
|
}
|
|
19033
|
-
|
|
19034
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetService, providedIn: 'root' }); }
|
|
19179
|
+
return '';
|
|
19035
19180
|
}
|
|
19036
|
-
|
|
19037
|
-
type: Injectable,
|
|
19038
|
-
args: [{
|
|
19039
|
-
providedIn: 'root',
|
|
19040
|
-
}]
|
|
19041
|
-
}] });
|
|
19181
|
+
//#endregion
|
|
19042
19182
|
|
|
19183
|
+
//#region ---- Imports ----
|
|
19184
|
+
//#endregion
|
|
19185
|
+
//#region ---- Component ----
|
|
19043
19186
|
class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
19044
19187
|
//#endregion
|
|
19045
19188
|
//#region ---- Lifecycle ----
|
|
19046
19189
|
constructor() {
|
|
19047
19190
|
super();
|
|
19191
|
+
//#region ---- Services & Dependencies ----
|
|
19192
|
+
this.queryExecutor = inject(AXPQueryExecutor);
|
|
19193
|
+
this.entityResolver = inject(AXPEntityDefinitionRegistryService);
|
|
19194
|
+
this.formatService = inject(AXFormatService);
|
|
19195
|
+
this.translation = inject(AXTranslationService);
|
|
19196
|
+
//#endregion
|
|
19197
|
+
//#region ---- View Children ----
|
|
19198
|
+
this.fileListTrigger = viewChild('fileListTrigger', ...(ngDevMode ? [{ debugName: "fileListTrigger" }] : /* istanbul ignore next */ []));
|
|
19199
|
+
this.fileListPopover = viewChild('fileListPopover', ...(ngDevMode ? [{ debugName: "fileListPopover" }] : /* istanbul ignore next */ []));
|
|
19200
|
+
//#endregion
|
|
19048
19201
|
//#region ---- State ----
|
|
19049
19202
|
this.fileCount = signal(0, ...(ngDevMode ? [{ debugName: "fileCount" }] : /* istanbul ignore next */ []));
|
|
19203
|
+
this.popoverFiles = signal([], ...(ngDevMode ? [{ debugName: "popoverFiles" }] : /* istanbul ignore next */ []));
|
|
19204
|
+
this.loadStatus = signal('idle', ...(ngDevMode ? [{ debugName: "loadStatus" }] : /* istanbul ignore next */ []));
|
|
19205
|
+
this.loadError = signal(null, ...(ngDevMode ? [{ debugName: "loadError" }] : /* istanbul ignore next */ []));
|
|
19206
|
+
this.isPopoverOpen = signal(false, ...(ngDevMode ? [{ debugName: "isPopoverOpen" }] : /* istanbul ignore next */ []));
|
|
19207
|
+
this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : /* istanbul ignore next */ []));
|
|
19050
19208
|
this.loadRequestId = 0;
|
|
19209
|
+
this.popoverLoadRequestId = 0;
|
|
19051
19210
|
//#endregion
|
|
19052
|
-
//#region ----
|
|
19053
|
-
this.
|
|
19054
|
-
this.
|
|
19211
|
+
//#region ---- Computed ----
|
|
19212
|
+
this.entityScope = computed(() => resolveFileUploaderEntityScope(this.options ?? {}, this.rowData, this.path), ...(ngDevMode ? [{ debugName: "entityScope" }] : /* istanbul ignore next */ []));
|
|
19213
|
+
this.popoverTitle = computed(() => {
|
|
19214
|
+
const row = this.rowData;
|
|
19215
|
+
const lang = this.translation.getActiveLang();
|
|
19216
|
+
const titleRaw = get(row, 'title');
|
|
19217
|
+
if (titleRaw != null &&
|
|
19218
|
+
typeof titleRaw === 'object' &&
|
|
19219
|
+
!Array.isArray(titleRaw) &&
|
|
19220
|
+
this.translation.isValidMultiLanguageObject(titleRaw)) {
|
|
19221
|
+
return titleRaw;
|
|
19222
|
+
}
|
|
19223
|
+
const resolved = formatEntityRowDisplayTitle(this.entityDef(), row, this.formatService, lang);
|
|
19224
|
+
if (resolved) {
|
|
19225
|
+
return resolved;
|
|
19226
|
+
}
|
|
19227
|
+
const fallback = this.entityDef()?.formats?.individual;
|
|
19228
|
+
if (fallback != null && fallback !== '') {
|
|
19229
|
+
return resolveEntityRowDisplayText(fallback, lang) || fallback;
|
|
19230
|
+
}
|
|
19231
|
+
return '@document-management:terms.common.file';
|
|
19232
|
+
}, ...(ngDevMode ? [{ debugName: "popoverTitle" }] : /* istanbul ignore next */ []));
|
|
19055
19233
|
effect(() => {
|
|
19056
19234
|
const raw = this.rawValue;
|
|
19057
19235
|
const row = this.rowData;
|
|
19058
19236
|
const opts = this.options ?? {};
|
|
19059
19237
|
const path = this.path;
|
|
19238
|
+
const rowId = row?.['id'] != null ? String(row['id']) : undefined;
|
|
19239
|
+
if (rowId !== this.previousRowId) {
|
|
19240
|
+
this.previousRowId = rowId;
|
|
19241
|
+
untracked(() => {
|
|
19242
|
+
this.popoverFiles.set([]);
|
|
19243
|
+
this.loadStatus.set('idle');
|
|
19244
|
+
this.loadError.set(null);
|
|
19245
|
+
this.popoverLoadRequestId++;
|
|
19246
|
+
});
|
|
19247
|
+
}
|
|
19060
19248
|
const inlineCount = attachmentFieldCount(raw);
|
|
19061
19249
|
if (inlineCount > 0) {
|
|
19062
19250
|
untracked(() => this.fileCount.set(inlineCount));
|
|
@@ -19069,7 +19257,6 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19069
19257
|
}
|
|
19070
19258
|
const requestId = ++this.loadRequestId;
|
|
19071
19259
|
untracked(() => {
|
|
19072
|
-
console.log('loadFiles for count', entity);
|
|
19073
19260
|
void this.queryExecutor
|
|
19074
19261
|
.fetch('FileUploader:LoadFiles', entity)
|
|
19075
19262
|
.then((result) => {
|
|
@@ -19086,51 +19273,102 @@ class AXPFileUploaderWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
|
19086
19273
|
});
|
|
19087
19274
|
});
|
|
19088
19275
|
});
|
|
19276
|
+
effect(() => {
|
|
19277
|
+
const scope = this.entityScope();
|
|
19278
|
+
if (!scope?.name?.includes('.')) {
|
|
19279
|
+
this.entityDef.set(null);
|
|
19280
|
+
return;
|
|
19281
|
+
}
|
|
19282
|
+
const [module, name] = scope.name.split('.');
|
|
19283
|
+
void this.entityResolver.resolve(module, name).then((def) => this.entityDef.set(def));
|
|
19284
|
+
});
|
|
19089
19285
|
}
|
|
19090
19286
|
//#endregion
|
|
19091
19287
|
//#region ---- UI Handlers ----
|
|
19092
|
-
|
|
19093
|
-
|
|
19094
|
-
|
|
19095
|
-
entity,
|
|
19096
|
-
readonly: true,
|
|
19097
|
-
});
|
|
19288
|
+
openFileListPopover() {
|
|
19289
|
+
this.openPopoverFromRef(this.fileListTrigger());
|
|
19290
|
+
void this.ensurePopoverFilesLoaded();
|
|
19098
19291
|
}
|
|
19099
|
-
|
|
19100
|
-
|
|
19101
|
-
|
|
19102
|
-
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19106
|
-
|
|
19107
|
-
|
|
19108
|
-
|
|
19109
|
-
|
|
19292
|
+
onPopoverOpenChange(event) {
|
|
19293
|
+
const open = this.coercePopoverOpenEvent(event);
|
|
19294
|
+
this.isPopoverOpen.set(open);
|
|
19295
|
+
if (open) {
|
|
19296
|
+
void this.ensurePopoverFilesLoaded();
|
|
19297
|
+
}
|
|
19298
|
+
}
|
|
19299
|
+
//#endregion
|
|
19300
|
+
//#region ---- Private Methods ----
|
|
19301
|
+
openPopoverFromRef(ref) {
|
|
19302
|
+
const popover = this.fileListPopover();
|
|
19303
|
+
if (popover && ref) {
|
|
19304
|
+
popover.target = ref.nativeElement;
|
|
19305
|
+
popover.open();
|
|
19306
|
+
this.isPopoverOpen.set(true);
|
|
19307
|
+
}
|
|
19308
|
+
}
|
|
19309
|
+
async ensurePopoverFilesLoaded() {
|
|
19310
|
+
if (this.loadStatus() === 'loading') {
|
|
19311
|
+
return;
|
|
19312
|
+
}
|
|
19313
|
+
const inline = normalizeEntityFieldToFileList(this.rawValue);
|
|
19314
|
+
if (inline.length > 0) {
|
|
19315
|
+
this.popoverFiles.set(inline);
|
|
19316
|
+
this.loadStatus.set('ready');
|
|
19317
|
+
this.loadError.set(null);
|
|
19318
|
+
return;
|
|
19319
|
+
}
|
|
19320
|
+
const entity = this.entityScope();
|
|
19321
|
+
if (!entity) {
|
|
19322
|
+
this.popoverFiles.set([]);
|
|
19323
|
+
this.loadStatus.set('ready');
|
|
19324
|
+
return;
|
|
19325
|
+
}
|
|
19326
|
+
if (this.loadStatus() === 'ready' && this.popoverFiles().length > 0) {
|
|
19327
|
+
return;
|
|
19328
|
+
}
|
|
19329
|
+
const requestId = ++this.popoverLoadRequestId;
|
|
19330
|
+
this.loadStatus.set('loading');
|
|
19331
|
+
this.loadError.set(null);
|
|
19332
|
+
try {
|
|
19333
|
+
const result = await this.queryExecutor.fetch('FileUploader:LoadFiles', entity);
|
|
19334
|
+
if (requestId !== this.popoverLoadRequestId) {
|
|
19335
|
+
return;
|
|
19336
|
+
}
|
|
19337
|
+
this.popoverFiles.set(result?.files ?? []);
|
|
19338
|
+
this.loadStatus.set('ready');
|
|
19339
|
+
}
|
|
19340
|
+
catch {
|
|
19341
|
+
if (requestId !== this.popoverLoadRequestId) {
|
|
19342
|
+
return;
|
|
19343
|
+
}
|
|
19344
|
+
const msg = await this.translation.translateAsync('@general:widgets.lookup.column.load-failed');
|
|
19345
|
+
this.loadError.set(msg);
|
|
19346
|
+
this.loadStatus.set('error');
|
|
19347
|
+
this.popoverFiles.set([]);
|
|
19348
|
+
}
|
|
19110
19349
|
}
|
|
19111
|
-
|
|
19350
|
+
coercePopoverOpenEvent(event) {
|
|
19351
|
+
if (typeof event === 'boolean') {
|
|
19352
|
+
return event;
|
|
19353
|
+
}
|
|
19354
|
+
if (event && typeof event === 'object') {
|
|
19355
|
+
const o = event;
|
|
19356
|
+
if ('detail' in o) {
|
|
19357
|
+
return Boolean(o['detail']);
|
|
19358
|
+
}
|
|
19359
|
+
if ('open' in o) {
|
|
19360
|
+
return Boolean(o['open']);
|
|
19361
|
+
}
|
|
19362
|
+
}
|
|
19363
|
+
return false;
|
|
19364
|
+
}
|
|
19365
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19366
|
+
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 class=\"ax-cursor-pointer ax-text-primary ax-underline\" (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger>\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\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 {\n <axp-file-list [files]=\"popoverFiles()\" look=\"links\" linksLayout=\"menu\" [showLabel]=\"false\" [readonly]=\"true\" />\n }\n </div>\n </div>\n</ax-popover>", dependencies: [{ kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.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: i6.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19112
19367
|
}
|
|
19113
19368
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetColumnComponent, decorators: [{
|
|
19114
19369
|
type: Component,
|
|
19115
|
-
args: [{
|
|
19116
|
-
|
|
19117
|
-
template: `
|
|
19118
|
-
@if (fileCount() > 0) {
|
|
19119
|
-
<span
|
|
19120
|
-
class="ax-cursor-pointer ax-text-primary ax-underline"
|
|
19121
|
-
(click)="openFileList()"
|
|
19122
|
-
>
|
|
19123
|
-
{{ fileCount() }} {{ '@document-management:file' | translate | async }}
|
|
19124
|
-
</span>
|
|
19125
|
-
} @else {
|
|
19126
|
-
<span class="ax-text-muted">---</span>
|
|
19127
|
-
}
|
|
19128
|
-
`,
|
|
19129
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
19130
|
-
imports: [AXTranslationModule, AsyncPipe],
|
|
19131
|
-
inputs: ['rawValue', 'rowData'],
|
|
19132
|
-
}]
|
|
19133
|
-
}], ctorParameters: () => [] });
|
|
19370
|
+
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 class=\"ax-cursor-pointer ax-text-primary ax-underline\" (click)=\"openFileListPopover(); $event.stopPropagation()\"\n #fileListTrigger>\n {{\n '@general:widgets.file-uploader.column.files-count'\n | translate: { params: { count: fileCount() } }\n | async\n }}\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 {\n <axp-file-list [files]=\"popoverFiles()\" look=\"links\" linksLayout=\"menu\" [showLabel]=\"false\" [readonly]=\"true\" />\n }\n </div>\n </div>\n</ax-popover>" }]
|
|
19371
|
+
}], ctorParameters: () => [], propDecorators: { fileListTrigger: [{ type: i0.ViewChild, args: ['fileListTrigger', { isSignal: true }] }], fileListPopover: [{ type: i0.ViewChild, args: ['fileListPopover', { isSignal: true }] }] } });
|
|
19134
19372
|
|
|
19135
19373
|
var fileUploaderWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
19136
19374
|
__proto__: null,
|
|
@@ -19341,6 +19579,7 @@ class AXPFileUploaderWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
19341
19579
|
}
|
|
19342
19580
|
this.isDirtySignal.set(dirty);
|
|
19343
19581
|
this.dirtyChangeSubject.next(dirty);
|
|
19582
|
+
this.layoutService.notifyWidgetDirtyChanged();
|
|
19344
19583
|
}
|
|
19345
19584
|
//#endregion
|
|
19346
19585
|
async loadActions() {
|
|
@@ -19574,7 +19813,7 @@ class AXPFileUploaderWidgetEditComponent extends AXPValueWidgetComponent {
|
|
|
19574
19813
|
(onRename)="handleFileRename($event)"
|
|
19575
19814
|
></axp-file-list>
|
|
19576
19815
|
</div>
|
|
19577
|
-
`, isInline: true, styles: [":host{border-color:rgba(var(--ax-comp-editor-border-color))}:host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drag-over{background-color:rgba(var(--ax-sys-color-primary-50),.1);border:2px dashed rgb(var(--ax-sys-color-primary-500));border-radius:.375rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "directive", type: AXUploaderZoneDirective, selector: "[axUploaderZone]", inputs: ["multiple", "accept", "overlayTemplate", "disableBrowse", "disableDragDrop"], outputs: ["fileChange", "onChanged", "dragEnter", "dragLeave", "dragOver", "onFileUploadComplete", "onFilesUploadComplete"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i3$3.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i6.AXTranslatorDirective, selector: "[translate]" }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "files", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19816
|
+
`, isInline: true, styles: [":host{border-color:rgba(var(--ax-comp-editor-border-color))}:host.axp-file-uploader-widget-edit--borderless{border:none!important}.__drag-over{background-color:rgba(var(--ax-sys-color-primary-50),.1);border:2px dashed rgb(var(--ax-sys-color-primary-500));border-radius:.375rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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: "component", type: i1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "directive", type: AXUploaderZoneDirective, selector: "[axUploaderZone]", inputs: ["multiple", "accept", "fileType", "overlayTemplate", "disableBrowse", "disableDragDrop"], outputs: ["fileChange", "onChanged", "dragEnter", "dragLeave", "dragOver", "onFileUploadComplete", "onFilesUploadComplete"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i3$3.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i6.AXTranslatorDirective, selector: "[translate]" }, { 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: i5.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19578
19817
|
}
|
|
19579
19818
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetEditComponent, decorators: [{
|
|
19580
19819
|
type: Component,
|
|
@@ -19666,7 +19905,7 @@ class AXPFileUploaderWidgetViewComponent extends AXPValueWidgetComponent {
|
|
|
19666
19905
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
19667
19906
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPFileUploaderWidgetViewComponent, isStandalone: true, selector: "axp-file-uploader-widget-view", host: { properties: { "class": "this.__class" } }, usesInheritance: true, ngImport: i0, template: `
|
|
19668
19907
|
<axp-file-list [files]="files()" [readonly]="true"></axp-file-list>
|
|
19669
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXUploaderModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPFileListComponent, selector: "axp-file-list", inputs: ["readonly", "fileEditable", "enableTitleDescription", "multiple", "files", "plugins", "excludePlugins", "capabilities"], outputs: ["onRemove", "onRevert", "onRename"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19908
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXUploaderModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
19670
19909
|
}
|
|
19671
19910
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetViewComponent, decorators: [{
|
|
19672
19911
|
type: Component,
|
|
@@ -19773,6 +20012,78 @@ const AXPFileUploaderWidget = {
|
|
|
19773
20012
|
},
|
|
19774
20013
|
};
|
|
19775
20014
|
|
|
20015
|
+
class AXPFileUploaderWidgetService {
|
|
20016
|
+
constructor() {
|
|
20017
|
+
//#region ---- Services & Dependencies ----
|
|
20018
|
+
this.popupService = inject(AXPopupService);
|
|
20019
|
+
this.translate = inject(AXTranslationService);
|
|
20020
|
+
this.commandExecutor = inject(AXPCommandExecutor);
|
|
20021
|
+
this.queryExecutor = inject(AXPQueryExecutor);
|
|
20022
|
+
}
|
|
20023
|
+
//#endregion
|
|
20024
|
+
//#region ---- Public API ----
|
|
20025
|
+
async showFileList(options) {
|
|
20026
|
+
const entity = options?.entity;
|
|
20027
|
+
let files = options?.files;
|
|
20028
|
+
if (entity) {
|
|
20029
|
+
const filesResult = await this.queryExecutor.fetch('FileUploader:LoadFiles', entity);
|
|
20030
|
+
if (!filesResult) {
|
|
20031
|
+
return undefined;
|
|
20032
|
+
}
|
|
20033
|
+
files = filesResult.files ?? [];
|
|
20034
|
+
}
|
|
20035
|
+
const resolved = {
|
|
20036
|
+
files: files ?? [],
|
|
20037
|
+
readonly: options?.readonly ?? false,
|
|
20038
|
+
multiple: options?.multiple ?? false,
|
|
20039
|
+
accept: options?.accept ?? '*',
|
|
20040
|
+
fileEditable: options?.fileEditable ?? true,
|
|
20041
|
+
maxFileSize: options?.maxFileSize ?? 1024 * 1024 * 10,
|
|
20042
|
+
showAddItemButton: options?.showAddItemButton ?? true,
|
|
20043
|
+
plugins: options?.plugins ?? [],
|
|
20044
|
+
editDialog: options?.editDialog,
|
|
20045
|
+
};
|
|
20046
|
+
const component = await import('./acorex-platform-layout-entity-file-list-popup.component-_yrP5SQe.mjs').then((m) => m.AXPFileListPopupComponent);
|
|
20047
|
+
const result = await this.popupService.open(component, {
|
|
20048
|
+
title: await this.translate.translateAsync('@document-management:terms.common.file'),
|
|
20049
|
+
data: {
|
|
20050
|
+
files: signal(resolved.files),
|
|
20051
|
+
isReadonly: signal(resolved.readonly),
|
|
20052
|
+
multiple: signal(resolved.multiple),
|
|
20053
|
+
accept: signal(resolved.accept),
|
|
20054
|
+
maxFileSize: signal(resolved.maxFileSize),
|
|
20055
|
+
fileEditable: signal(resolved.fileEditable),
|
|
20056
|
+
showAddItemButton: signal(resolved.showAddItemButton),
|
|
20057
|
+
plugins: signal(resolved.plugins),
|
|
20058
|
+
editDialog: signal(resolved.editDialog),
|
|
20059
|
+
},
|
|
20060
|
+
});
|
|
20061
|
+
const updatedFiles = result?.data?.data?.files;
|
|
20062
|
+
if (!updatedFiles) {
|
|
20063
|
+
return undefined;
|
|
20064
|
+
}
|
|
20065
|
+
if (!entity) {
|
|
20066
|
+
return updatedFiles;
|
|
20067
|
+
}
|
|
20068
|
+
const saveResult = await this.commandExecutor.execute('FileUploader:SaveFiles', {
|
|
20069
|
+
...entity,
|
|
20070
|
+
files: updatedFiles,
|
|
20071
|
+
});
|
|
20072
|
+
if (!saveResult?.success) {
|
|
20073
|
+
return undefined;
|
|
20074
|
+
}
|
|
20075
|
+
return updatedFiles;
|
|
20076
|
+
}
|
|
20077
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
20078
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetService, providedIn: 'root' }); }
|
|
20079
|
+
}
|
|
20080
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPFileUploaderWidgetService, decorators: [{
|
|
20081
|
+
type: Injectable,
|
|
20082
|
+
args: [{
|
|
20083
|
+
providedIn: 'root',
|
|
20084
|
+
}]
|
|
20085
|
+
}] });
|
|
20086
|
+
|
|
19776
20087
|
var index = /*#__PURE__*/Object.freeze({
|
|
19777
20088
|
__proto__: null,
|
|
19778
20089
|
AXPEditFileUploaderCommand: AXPEditFileUploaderCommand,
|
|
@@ -21556,7 +21867,7 @@ class AXPPageComponentConverter {
|
|
|
21556
21867
|
return empty;
|
|
21557
21868
|
}
|
|
21558
21869
|
const tempInjector = Injector.create({
|
|
21559
|
-
providers: [{ provide: ComponentType, useClass: ComponentType }],
|
|
21870
|
+
providers: [AXPContextStore, { provide: ComponentType, useClass: ComponentType }],
|
|
21560
21871
|
parent: this.injector,
|
|
21561
21872
|
});
|
|
21562
21873
|
const componentInstance = tempInjector.get(ComponentType);
|
|
@@ -21754,6 +22065,20 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
21754
22065
|
if (e.name === 'update-entity') {
|
|
21755
22066
|
const fn = entityDef?.commands?.update?.execute;
|
|
21756
22067
|
const result = await fn(context);
|
|
22068
|
+
if (result && typeof result === 'object' && 'success' in result) {
|
|
22069
|
+
const cmd = result;
|
|
22070
|
+
if (!cmd.success) {
|
|
22071
|
+
const errorText = commandMessageTextForError(cmd.message?.text) || 'Failed to update entity';
|
|
22072
|
+
return {
|
|
22073
|
+
success: false,
|
|
22074
|
+
message: cmd.message ?? { text: errorText },
|
|
22075
|
+
};
|
|
22076
|
+
}
|
|
22077
|
+
return {
|
|
22078
|
+
success: true,
|
|
22079
|
+
data: cmd.data ?? result,
|
|
22080
|
+
};
|
|
22081
|
+
}
|
|
21757
22082
|
return {
|
|
21758
22083
|
success: true,
|
|
21759
22084
|
data: result,
|
|
@@ -21807,12 +22132,7 @@ class AXPPageDetailsConverter extends AXPBaseRelatedEntityConverter {
|
|
|
21807
22132
|
}
|
|
21808
22133
|
}
|
|
21809
22134
|
catch (error) {
|
|
21810
|
-
return
|
|
21811
|
-
success: false,
|
|
21812
|
-
message: {
|
|
21813
|
-
text: error,
|
|
21814
|
-
},
|
|
21815
|
-
};
|
|
22135
|
+
return mapEntityStorageErrorToCommandResult(error);
|
|
21816
22136
|
}
|
|
21817
22137
|
};
|
|
21818
22138
|
}
|
|
@@ -22604,6 +22924,20 @@ class AXPMainEntityContentBuilder {
|
|
|
22604
22924
|
if (e.name == 'update-entity') {
|
|
22605
22925
|
const fn = entity?.commands?.update?.execute;
|
|
22606
22926
|
const result = await fn(context);
|
|
22927
|
+
if (result && typeof result === 'object' && 'success' in result) {
|
|
22928
|
+
const cmd = result;
|
|
22929
|
+
if (!cmd.success) {
|
|
22930
|
+
const errorText = commandMessageTextForError(cmd.message?.text) || 'Failed to update entity';
|
|
22931
|
+
return {
|
|
22932
|
+
success: false,
|
|
22933
|
+
message: cmd.message ?? { text: errorText },
|
|
22934
|
+
};
|
|
22935
|
+
}
|
|
22936
|
+
return {
|
|
22937
|
+
success: true,
|
|
22938
|
+
data: cmd.data ?? result,
|
|
22939
|
+
};
|
|
22940
|
+
}
|
|
22607
22941
|
return {
|
|
22608
22942
|
success: true,
|
|
22609
22943
|
data: result,
|
|
@@ -22657,12 +22991,7 @@ class AXPMainEntityContentBuilder {
|
|
|
22657
22991
|
}
|
|
22658
22992
|
}
|
|
22659
22993
|
catch (error) {
|
|
22660
|
-
return
|
|
22661
|
-
success: false,
|
|
22662
|
-
message: {
|
|
22663
|
-
text: error,
|
|
22664
|
-
},
|
|
22665
|
-
};
|
|
22994
|
+
return mapEntityStorageErrorToCommandResult(error);
|
|
22666
22995
|
}
|
|
22667
22996
|
},
|
|
22668
22997
|
tabs: [...tabDetailTabs, ...tabListTabs, ...nestedTabListTabs],
|
|
@@ -23218,32 +23547,33 @@ const eventDispatchMiddleware = {
|
|
|
23218
23547
|
const dispatcher = inject(AXPEntityEventDispatcherService);
|
|
23219
23548
|
const workflowEventService = inject(AXPWorkflowEventService);
|
|
23220
23549
|
await next();
|
|
23221
|
-
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
|
|
23226
|
-
|
|
23227
|
-
|
|
23228
|
-
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
|
|
23232
|
-
|
|
23233
|
-
|
|
23234
|
-
|
|
23235
|
-
|
|
23236
|
-
|
|
23237
|
-
|
|
23238
|
-
}
|
|
23550
|
+
try {
|
|
23551
|
+
if (ctx.op === 'create') {
|
|
23552
|
+
const createdData = ctx.result ? { ...ctx.data, id: ctx.result } : ctx.data;
|
|
23553
|
+
await dispatcher.dispatchInserted(ctx.entityName, { refType: ctx.entityName, data: createdData });
|
|
23554
|
+
workflowEventService.dispatch(AXPRefreshEvent({
|
|
23555
|
+
entity: ctx.entityName,
|
|
23556
|
+
}));
|
|
23557
|
+
}
|
|
23558
|
+
else if (ctx.op === 'update') {
|
|
23559
|
+
await dispatcher.dispatchUpdated(ctx.entityName, {
|
|
23560
|
+
refType: ctx.entityName,
|
|
23561
|
+
data: ctx.result,
|
|
23562
|
+
changes: ctx.locals.get('changes'),
|
|
23563
|
+
});
|
|
23564
|
+
workflowEventService.dispatch(AXPRefreshEvent({
|
|
23565
|
+
entity: ctx.entityName,
|
|
23566
|
+
}));
|
|
23567
|
+
}
|
|
23568
|
+
else if (ctx.op === 'delete') {
|
|
23569
|
+
await dispatcher.dispatchDeleted(ctx.entityName, { refType: ctx.entityName, data: ctx.result ?? ctx.previous });
|
|
23570
|
+
workflowEventService.dispatch(AXPRefreshEvent({
|
|
23571
|
+
entity: ctx.entityName,
|
|
23572
|
+
}));
|
|
23573
|
+
}
|
|
23239
23574
|
}
|
|
23240
|
-
|
|
23241
|
-
//
|
|
23242
|
-
await dispatcher.dispatchDeleted(ctx.entityName, { refType: ctx.entityName, data: ctx.result ?? ctx.previous });
|
|
23243
|
-
// Dispatch workflow refresh event to trigger entity list refresh
|
|
23244
|
-
workflowEventService.dispatch(AXPRefreshEvent({
|
|
23245
|
-
entity: ctx.entityName,
|
|
23246
|
-
}));
|
|
23575
|
+
catch {
|
|
23576
|
+
// Persist already succeeded; event dispatch must not block the write result.
|
|
23247
23577
|
}
|
|
23248
23578
|
},
|
|
23249
23579
|
};
|
|
@@ -23904,8 +24234,12 @@ const AXPCrudModifier = {
|
|
|
23904
24234
|
if (!command?.update) {
|
|
23905
24235
|
command.update = {
|
|
23906
24236
|
execute: async (data) => {
|
|
23907
|
-
|
|
23908
|
-
|
|
24237
|
+
const entityKey = ctx.module.get() + '.' + ctx.name.get();
|
|
24238
|
+
const { id, ...patch } = data ?? {};
|
|
24239
|
+
if (id == null || id === '') {
|
|
24240
|
+
throw new Error(`Update requires entity id (${entityKey})`);
|
|
24241
|
+
}
|
|
24242
|
+
return await dataService.updateOne(id, patch);
|
|
23909
24243
|
},
|
|
23910
24244
|
};
|
|
23911
24245
|
}
|
|
@@ -23989,34 +24323,6 @@ class AXPEntitySearchDefinitionProvider {
|
|
|
23989
24323
|
}
|
|
23990
24324
|
}
|
|
23991
24325
|
|
|
23992
|
-
/**
|
|
23993
|
-
* Error type that can be thrown by middlewares to abort the chain with a structured payload.
|
|
23994
|
-
*/
|
|
23995
|
-
class AXPMiddlewareAbortError extends Error {
|
|
23996
|
-
constructor(message, options = {}) {
|
|
23997
|
-
super(message);
|
|
23998
|
-
this.message = message;
|
|
23999
|
-
this.options = options;
|
|
24000
|
-
this.name = 'AXPMiddlewareAbortError';
|
|
24001
|
-
}
|
|
24002
|
-
toResponse() {
|
|
24003
|
-
return {
|
|
24004
|
-
success: false,
|
|
24005
|
-
error: {
|
|
24006
|
-
code: this.options.code,
|
|
24007
|
-
message: this.message,
|
|
24008
|
-
status: this.options.status,
|
|
24009
|
-
details: this.options.details,
|
|
24010
|
-
},
|
|
24011
|
-
};
|
|
24012
|
-
}
|
|
24013
|
-
}
|
|
24014
|
-
/** Type guard for AXPMiddlewareAbortError */
|
|
24015
|
-
function isAXPMiddlewareAbortError(error) {
|
|
24016
|
-
return error instanceof AXPMiddlewareAbortError;
|
|
24017
|
-
}
|
|
24018
|
-
//#endregion
|
|
24019
|
-
|
|
24020
24326
|
const AXP_ENTITY_STORAGE_BACKEND = new InjectionToken('AXP_ENTITY_STORAGE_BACKEND');
|
|
24021
24327
|
const AXP_ENTITY_STORAGE_MIDDLEWARE = new InjectionToken('AXP_ENTITY_STORAGE_MIDDLEWARE');
|
|
24022
24328
|
|
|
@@ -25305,5 +25611,5 @@ var getEntityDetails_query = /*#__PURE__*/Object.freeze({
|
|
|
25305
25611
|
* Generated bundle index. Do not edit.
|
|
25306
25612
|
*/
|
|
25307
25613
|
|
|
25308
|
-
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, AXPEntityEventsKeys, 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, AXP_RECORD_WORKFLOW_INFO_CORRELATION_ID_FIELD, AXP_RECORD_WORKFLOW_INFO_DEFINITION_ID_FIELD, AXP_RECORD_WORKFLOW_INFO_INSTANCE_ID_FIELD, 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, buildAXPRecordWorkflowInfo, canPersistEntityListState, cloneLayoutArrays, collectEntityQuickSearchFieldPaths, collectNestedCreateHiddenProperties, collectNestedFieldPathsFromEntityColumns, collectQuickSearchPathsFromSingleEntityDefinition, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, getRecordWorkflowCorrelationId, getRecordWorkflowInstanceId, hasFileUploaderTitleOrDescriptionFields, isAXPMiddlewareAbortError, isAttachmentListEntry, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, isUnresolvedLookupDisplayTemplate, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapLegacyEntityDataSelectorOptions, mergeForeignKeyFieldIntoCreateActions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, normalizeLookupDisplayTemplate, persistedAttachments, provideEntity, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
|
|
25614
|
+
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, AXPEntityEventsKeys, 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, AXP_RECORD_WORKFLOW_INFO_CORRELATION_ID_FIELD, AXP_RECORD_WORKFLOW_INFO_DEFINITION_ID_FIELD, AXP_RECORD_WORKFLOW_INFO_INSTANCE_ID_FIELD, 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, buildAXPRecordWorkflowInfo, canPersistEntityListState, cloneLayoutArrays, collectEntityQuickSearchFieldPaths, collectNestedCreateHiddenProperties, collectNestedFieldPathsFromEntityColumns, collectQuickSearchPathsFromSingleEntityDefinition, columnOrderingMiddleware, columnOrderingMiddlewareProvider, columnWidthMiddleware, columnWidthMiddlewareProvider, commandMessageTextForError, committedAttachments, computeEntityAggregates, createColumnOrderingMiddlewareProvider, createLayoutOrderingMiddlewareProvider, createModifierContext, defaultCardLayoutMiddleware, defaultCardLayoutMiddlewareProvider, defaultMultiLanguageMiddleware, defaultMultiLanguageMiddlewareProvider, detectEntityChanges, ensureLayoutPropertyView, ensureLayoutSection, ensureListActions, entityDetailsCreateActions, entityDetailsCreateActionsDeferredParent, entityDetailsCrudActions, entityDetailsEditAction, entityDetailsNewEditAction, entityDetailsReferenceCondition, entityDetailsReferenceCreateActions, entityDetailsSimpleCondition, entityMasterBulkDeleteAction, entityMasterCreateAction, entityMasterCrudActions, entityMasterDeleteAction, entityMasterEditAction, entityMasterRecordActions, entityMasterViewAction, entityOverrideDetailsViewAction, eventDispatchMiddleware, filterSortEntityRows, findEntityListRowDataInTree, fingerprintAttachmentItem, fingerprintAttachments, formatLookupItemDisplay, getDataSourcePageIndex, getEntityListRowId, getMasterInterfacePropertySortKey, getRecordWorkflowCorrelationId, getRecordWorkflowInstanceId, hasFileUploaderTitleOrDescriptionFields, isAXPMiddlewareAbortError, isAttachmentListEntry, isCategoryEntity, isCategoryFilter, isFileListItem, isFileUploaderEditDialogAuto, isLegacyEntityDataSelectorOptions, isUnresolvedLookupDisplayTemplate, layoutOrderingMiddlewareFactory, layoutOrderingMiddlewareProvider, mapEntityStorageErrorToCommandResult, mapLegacyEntityDataSelectorOptions, mergeForeignKeyFieldIntoCreateActions, normalizeEntityDataSelectorOptions, normalizeEntityFieldToFileList, normalizeEntityListPersistenceMode, normalizeListPaging, normalizeLookupDisplayTemplate, persistedAttachments, provideEntity, resolveEntityPluginDetailPageOrder, resolveFileUploaderEditDialog, resolveFileUploaderEntityScope, resolveLookupDisplayField, resolveLookupDisplayTemplate, restoreEntityListExpandedRows, runEntityQuery, searchResultDescriptionMiddleware, searchResultDescriptionMiddlewareProvider, shouldLoadEntityListStateFromStorage, shouldResetEntityListStateOnRouteEntry };
|
|
25309
25615
|
//# sourceMappingURL=acorex-platform-layout-entity.mjs.map
|