@valtimo/admin-settings 13.46.0 → 13.47.0

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.
@@ -5,6 +5,7 @@ export declare class AdminSettingsComponent {
5
5
  private readonly _router;
6
6
  readonly ADMIN_SETTINGS_TABS: {
7
7
  readonly APPEARANCE: "appearance";
8
+ readonly MENU_CONFIGURATION: "menu-configuration";
8
9
  readonly FEATURE_TOGGLES: "feature-toggles";
9
10
  };
10
11
  readonly activeTabKey$: import("rxjs").Observable<any>;
@@ -0,0 +1,172 @@
1
+ import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
2
+ import { OnDestroy, OnInit } from '@angular/core';
3
+ import { FormBuilder } from '@angular/forms';
4
+ import { TranslateService } from '@ngx-translate/core';
5
+ import { AdminSettingsService } from '@valtimo/components';
6
+ import { ConfigService } from '@valtimo/shared';
7
+ import { ExternalPluginMenuPage, ExternalPluginPageService } from '@valtimo/plugin';
8
+ import { IconService } from 'carbon-components-angular';
9
+ import { BuilderNode, PaletteGroup, PaletteItem } from '../../models';
10
+ import * as i0 from "@angular/core";
11
+ export declare class AdminSettingsMenuConfigurationComponent implements OnInit, OnDestroy {
12
+ private readonly fb;
13
+ private readonly adminSettingsService;
14
+ private readonly pluginPageService;
15
+ private readonly configService;
16
+ private readonly translateService;
17
+ private readonly iconService;
18
+ protected readonly testIds: {
19
+ readonly saveButton: "menuConfigurationSaveButton";
20
+ readonly resetButton: "menuConfigurationResetButton";
21
+ readonly structureList: "menuConfigurationStructureList";
22
+ readonly editorTitleInput: "menuConfigurationEditorTitleInput";
23
+ readonly editorLinkInput: "menuConfigurationEditorLinkInput";
24
+ readonly editorSaveButton: "menuConfigurationEditorSaveButton";
25
+ readonly editorCancelButton: "menuConfigurationEditorCancelButton";
26
+ };
27
+ readonly $loading: import("@angular/core").WritableSignal<boolean>;
28
+ readonly $saving: import("@angular/core").WritableSignal<boolean>;
29
+ readonly $saved: import("@angular/core").WritableSignal<boolean>;
30
+ readonly $structure: import("@angular/core").WritableSignal<BuilderNode[]>;
31
+ /** Drives the post-save "reload now?" confirmation modal. */
32
+ private readonly _$reloadModalOpen;
33
+ readonly reloadModalOpen$: import("rxjs").Observable<boolean>;
34
+ readonly $pluginPages: import("@angular/core").WritableSignal<ExternalPluginMenuPage[]>;
35
+ /** True while a drag is in progress, so the panels can desaturate the sections that cannot receive it. */
36
+ readonly $dragging: import("@angular/core").WritableSignal<boolean>;
37
+ readonly $editorOpen: import("@angular/core").WritableSignal<boolean>;
38
+ readonly $editorKind: import("@angular/core").WritableSignal<"catalog" | "group" | "section-header" | "custom-link" | "plugin-page">;
39
+ /** True while editing a required item (Admin/Settings) — its Include-function field is suppressed. */
40
+ readonly $editorRequired: import("@angular/core").WritableSignal<boolean>;
41
+ /**
42
+ * Bumped whenever ngx-translate (re)loads, so the translated palette/section labels — resolved
43
+ * imperatively via `translateService.instant` inside computeds — recompute once translations arrive
44
+ * (a plain computed would otherwise keep the raw keys captured on first, pre-load evaluation).
45
+ */
46
+ private readonly _$translationTick;
47
+ readonly $paletteGroups: import("@angular/core").Signal<PaletteGroup[]>;
48
+ /**
49
+ * All structure drop-list ids (root + every container), so each list — including palette lists and
50
+ * the nested container lists — connects to every structure list **by id**. CDK resolves these ids
51
+ * globally, so connections work regardless of DOM/DI nesting (a `cdkDropListGroup` would not see a
52
+ * nested list whose template is declared outside the group element).
53
+ */
54
+ readonly $structureListIds: import("@angular/core").Signal<string[]>;
55
+ readonly includeFunctionKeys: string[];
56
+ readonly editorForm: import("@angular/forms").FormGroup<{
57
+ title: import("@angular/forms").FormControl<string>;
58
+ link: import("@angular/forms").FormControl<string>;
59
+ icon: import("@angular/forms").FormControl<string>;
60
+ includeFunction: import("@angular/forms").FormControl<string>;
61
+ section: import("@angular/forms").FormControl<string>;
62
+ }>;
63
+ /** Sections an item can be placed in via the editor: top level + each container present in the tree. */
64
+ readonly $sectionOptions: import("@angular/core").Signal<{
65
+ value: string;
66
+ label: string;
67
+ }[]>;
68
+ /** Kinds that can be freely placed in any section (and so get the editor's Section selector). */
69
+ private readonly SECTION_CAPABLE_KINDS;
70
+ readonly $editorShowSection: import("@angular/core").Signal<boolean>;
71
+ /** Tracks the editor's currently selected section so the icon field can react to placement changes. */
72
+ private readonly _$editorSection;
73
+ /**
74
+ * The icon only surfaces in the rendered menu for top-level entries, so the editor hides the icon
75
+ * field for section headers and for any item placed inside a section (a sub-menu item).
76
+ */
77
+ readonly $editorShowIcon: import("@angular/core").Signal<boolean>;
78
+ private _editingUid;
79
+ private _pendingPaletteItem;
80
+ private _uidCounter;
81
+ readonly topEnterPredicate: (drag: CdkDrag, drop: CdkDropList) => boolean;
82
+ readonly adminEnterPredicate: (drag: CdkDrag, drop: CdkDropList) => boolean;
83
+ readonly developmentEnterPredicate: (drag: CdkDrag, drop: CdkDropList) => boolean;
84
+ readonly groupEnterPredicate: (drag: CdkDrag, drop: CdkDropList) => boolean;
85
+ readonly paletteEnterPredicate: () => boolean;
86
+ /** Last known pointer position during a drag, used to resolve nested drop-list ambiguity. */
87
+ private _pointer;
88
+ private readonly _trackPointer;
89
+ /**
90
+ * True when a `.valtimo-drag-drop-list` nested *inside* `drop` currently sits under the pointer.
91
+ * Such a deeper list is the more specific target, so `drop` should decline the item — this keeps a
92
+ * reorder inside a section from being hijacked by the enclosing (ancestor) list.
93
+ */
94
+ private _pointerOverDeeperList;
95
+ constructor(fb: FormBuilder, adminSettingsService: AdminSettingsService, pluginPageService: ExternalPluginPageService, configService: ConfigService, translateService: TranslateService, iconService: IconService);
96
+ ngOnInit(): void;
97
+ ngOnDestroy(): void;
98
+ load(): void;
99
+ onReset(): void;
100
+ onDragStarted(): void;
101
+ onDragEnded(): void;
102
+ private _removePointerListeners;
103
+ onDrop(event: CdkDragDrop<BuilderNode[]>): void;
104
+ onAddPaletteItem(item: PaletteItem): void;
105
+ openEditor(node: BuilderNode): void;
106
+ openNewItemEditor(item: PaletteItem): void;
107
+ onEditorSave(): void;
108
+ closeEditor(): void;
109
+ /** Commits a (new or edited) node into the chosen section, moving it if its section changed. */
110
+ private _placeNode;
111
+ private _syncLinkControl;
112
+ onRemove(node: BuilderNode): void;
113
+ onSave(): void;
114
+ /** Reload the app so the freshly saved menu takes effect. */
115
+ onReloadConfirm(): void;
116
+ /** Dismiss the reload modal, leaving a persistent inline reminder that a reload is still pending. */
117
+ onReloadDismiss(): void;
118
+ /** Dismiss the persistent "menu saved" reminder. */
119
+ onDismissSavedNotification(): void;
120
+ isContainer(node: BuilderNode): boolean;
121
+ isRequired(node: BuilderNode): boolean;
122
+ hasRuntimeSubmenu(node: BuilderNode): boolean;
123
+ displayTitle(node: BuilderNode): string;
124
+ childrenOf(node: BuilderNode): BuilderNode[];
125
+ containerListId(node: BuilderNode): string;
126
+ containerEnterPredicate(node: BuilderNode): (drag: CdkDrag, drop: CdkDropList) => boolean;
127
+ iconClassOf(node: BuilderNode): string | null;
128
+ /**
129
+ * Which plugin configuration a placed page belongs to. Every configuration of one plugin
130
+ * contributes a page with the same title, so the row is otherwise indistinguishable from its
131
+ * siblings. Empty for every other kind, and for a page whose configuration no longer exists.
132
+ */
133
+ configurationTitleOf(node: BuilderNode): string;
134
+ trackByUid: (_: number, node: BuilderNode) => string;
135
+ private _displayIconClass;
136
+ private _editableTitle;
137
+ private _placementOf;
138
+ private _containerAccepts;
139
+ private _paletteItemToNode;
140
+ private _defaultTargetFor;
141
+ /** A container's stable section id: catalog `itemId` for Admin/Development, `_uid` for a custom section. */
142
+ private _sectionValue;
143
+ /** The array that backs a section id (`'root'`, a catalog `itemId`, or a group `_uid`), creating children if needed. */
144
+ private _targetForSection;
145
+ /** Which section a node currently lives in: `'root'` or the containing section's id. */
146
+ private _findSectionOf;
147
+ private _buildPaletteGroups;
148
+ private _localizedPluginTitle;
149
+ private _pluginKey;
150
+ /**
151
+ * The MDI icon selector works with the full MDI class token (e.g. `mdi-view-dashboard`) — its
152
+ * preview binds the value straight onto an element class and `POPULAR_MDI_ICONS` is `mdi-*` keyed
153
+ * — so we keep the `mdi-` prefix here (stripping it broke the preview and double-prefixed on save).
154
+ */
155
+ private _mdiKeyFromIconClass;
156
+ /** Builds the menu `iconClass` from the selector's MDI class token (`mdi-view-dashboard` → `icon mdi mdi-view-dashboard`). */
157
+ private _iconClassFromMdiKey;
158
+ /** The editable children array of a branch node (catalog group or custom section), else null. */
159
+ private _childArray;
160
+ private _withUid;
161
+ private _assignUids;
162
+ private _walk;
163
+ private _findByUid;
164
+ private _removeByUid;
165
+ /** Deep-clones array references so the OnPush drag-drop lists re-render after an in-place mutation. */
166
+ private _bump;
167
+ private _clone;
168
+ /** Produces the persisted structure without the transient `_uid` fields. */
169
+ private _stripUids;
170
+ static ɵfac: i0.ɵɵFactoryDeclaration<AdminSettingsMenuConfigurationComponent, never>;
171
+ static ɵcmp: i0.ɵɵComponentDeclaration<AdminSettingsMenuConfigurationComponent, "valtimo-admin-settings-menu-configuration", never, {}, {}, never, never, true, never>;
172
+ }
@@ -1,5 +1,6 @@
1
1
  declare const ADMIN_SETTINGS_TABS: {
2
2
  readonly APPEARANCE: "appearance";
3
+ readonly MENU_CONFIGURATION: "menu-configuration";
3
4
  readonly FEATURE_TOGGLES: "feature-toggles";
4
5
  };
5
6
  export { ADMIN_SETTINGS_TABS };
@@ -1,3 +1,4 @@
1
1
  export * from './accent-colors.constants';
2
2
  export * from './admin-settings.constants';
3
3
  export * from './feature-toggle.constants';
4
+ export * from './menu-configuration.test-ids';
@@ -0,0 +1,10 @@
1
+ declare const MENU_CONFIGURATION_TEST_IDS: {
2
+ readonly saveButton: "menuConfigurationSaveButton";
3
+ readonly resetButton: "menuConfigurationResetButton";
4
+ readonly structureList: "menuConfigurationStructureList";
5
+ readonly editorTitleInput: "menuConfigurationEditorTitleInput";
6
+ readonly editorLinkInput: "menuConfigurationEditorLinkInput";
7
+ readonly editorSaveButton: "menuConfigurationEditorSaveButton";
8
+ readonly editorCancelButton: "menuConfigurationEditorCancelButton";
9
+ };
10
+ export { MENU_CONFIGURATION_TEST_IDS };
@@ -1,4 +1,5 @@
1
1
  export * from './accent-colors.model';
2
2
  export * from './feature-toggle.model';
3
+ export * from './menu-configuration.model';
3
4
  export * from './reindex.model';
4
5
  export * from './search-engine.model';
@@ -0,0 +1,22 @@
1
+ import { MenuConfigurationItem } from '@valtimo/components';
2
+ import { ExternalPluginMenuPage } from '@valtimo/plugin';
3
+ /** A draggable entry in the right-hand "Available items" palette. */
4
+ interface PaletteItem {
5
+ paletteType: 'catalog' | 'group' | 'section-header' | 'custom-link' | 'plugin-page';
6
+ label: string;
7
+ /** Secondary line under the label, for entries whose label alone does not identify them. */
8
+ sublabel?: string;
9
+ icon?: string;
10
+ itemId?: string;
11
+ page?: ExternalPluginMenuPage;
12
+ }
13
+ interface PaletteGroup {
14
+ categoryKey: string;
15
+ items: PaletteItem[];
16
+ }
17
+ /** Builder node = a stored config node plus a transient `_uid` for stable identity across redraws. */
18
+ type BuilderNode = MenuConfigurationItem & {
19
+ _uid: string;
20
+ children?: BuilderNode[];
21
+ };
22
+ export { PaletteItem, PaletteGroup, BuilderNode };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@valtimo/admin-settings",
3
3
  "license": "EUPL-1.2",
4
- "version": "13.46.0",
4
+ "version": "13.47.0",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "19.2.25",
7
7
  "@angular/core": "19.2.25"