@memberjunction/ng-conversations 6.1.0-edge.5 → 6.1.0-edge.6
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/README.md +9 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.js +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +55 -56
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +1 -1
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +1 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts +9 -1
- package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
- package/dist/lib/components/composer/ai-composer.component.js +16 -3
- package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +2 -2
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +116 -11
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +309 -77
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +22 -23
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-mode-picker.component.js +10 -11
- package/dist/lib/components/conversation/conversation-mode-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/pinned-messages-panel.component.js +1 -1
- package/dist/lib/components/dialogs/rating-dialog.component.js +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +1 -1
- package/dist/lib/components/message/actionable-commands.component.js +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +52 -1
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +116 -24
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +39 -1
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +172 -111
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +35 -0
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +107 -23
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/message/workflow-plan-card.component.js +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +1 -1
- package/dist/lib/components/notification/notification-badge.component.js +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +2 -2
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +1 -1
- package/dist/lib/components/realtime/channels/channel-onboarding-panel.component.js +1 -1
- package/dist/lib/components/realtime/evidence-playback/realtime-evidence-playback.component.js +1 -1
- package/dist/lib/components/realtime/media/realtime-media-surface.component.js +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +2 -2
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +6 -6
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-composer.component.js +2 -2
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-thread.component.js +1 -1
- package/dist/lib/components/realtime/realtime-session-timeline-card.component.js +1 -1
- package/dist/lib/components/realtime/realtime-surface-tabs.component.js +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +1 -1
- package/dist/lib/components/search/search-panel.component.js +2 -2
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts +6 -0
- package/dist/lib/composer-plugins/base-conversation-mention.provider.d.ts.map +1 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js +7 -1
- package/dist/lib/composer-plugins/base-conversation-mention.provider.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +9 -7
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/composer-draft-store.d.ts.map +1 -1
- package/dist/lib/services/composer-draft-store.js +5 -2
- package/dist/lib/services/composer-draft-store.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +16 -2
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +38 -9
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/skill-picker-narrowing.d.ts +13 -0
- package/dist/lib/services/skill-picker-narrowing.d.ts.map +1 -0
- package/dist/lib/services/skill-picker-narrowing.js +13 -0
- package/dist/lib/services/skill-picker-narrowing.js.map +1 -0
- package/dist/lib/utils/artifact-panel-action.d.ts +89 -0
- package/dist/lib/utils/artifact-panel-action.d.ts.map +1 -0
- package/dist/lib/utils/artifact-panel-action.js +122 -0
- package/dist/lib/utils/artifact-panel-action.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +8 -0
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +12 -2
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/package.json +39 -39
package/README.md
CHANGED
|
@@ -140,6 +140,15 @@ Embedding products (white-labeled end-user apps, embedded widgets) can pare the
|
|
|
140
140
|
| `showSuggestedPrompts` | The empty-state's built-in suggested-prompt chips |
|
|
141
141
|
| `showDateNavigation` | The message list's sticky date header + jump-to-date navigation |
|
|
142
142
|
|
|
143
|
+
#### Behaviour switches
|
|
144
|
+
|
|
145
|
+
Unlike the gates above, these change *how* the surface behaves and default to today's behaviour:
|
|
146
|
+
|
|
147
|
+
| Input | Default | Effect when set |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `readReplyFromTop` | `false` | A finished turn — the reader's message plus the reply — is scrolled to the top of the pane if it is taller than the pane, so the run ends at the start of the answer instead of its end. A turn that fits stays where it is; a reader who scrolled up during the run is never moved. (Independent of this switch, an in-place message update — progress, status, streamed text — only follows the tail for a reader who is already at the bottom.) |
|
|
150
|
+
|
|
151
|
+
|
|
143
152
|
```html
|
|
144
153
|
<!-- e.g. a minimal, single-agent end-user surface -->
|
|
145
154
|
<mj-conversation-chat-area
|
|
@@ -95,7 +95,7 @@ export class ActiveTasksPanelComponent {
|
|
|
95
95
|
i0.ɵɵpipe(1, "async");
|
|
96
96
|
} if (rf & 2) {
|
|
97
97
|
i0.ɵɵconditional(i0.ɵɵpipeBind1(1, 1, ctx.taskCount$) > 0 ? 0 : -1);
|
|
98
|
-
} }, dependencies: [i2.MJAccordionPanelComponent, i2.MJAccordionTitleDirective, i2.MJAccordionBodyDirective, i3.AsyncPipe], styles: [".active-tasks-panel[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 320px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n }\n\n \n\n\n
|
|
98
|
+
} }, dependencies: [i2.MJAccordionPanelComponent, i2.MJAccordionTitleDirective, i2.MJAccordionBodyDirective, i3.AsyncPipe], styles: [".active-tasks-panel[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 320px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n z-index: 1000;\n }\n\n \n\n\n .active-tasks-title-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .panel-content[_ngcontent-%COMP%] {\n max-height: 300px;\n overflow-y: auto;\n }\n\n .task-item[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .task-item[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n }\n\n .task-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n }\n\n .task-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n }\n\n .task-agent[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n }\n\n .task-elapsed[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n }\n\n .task-status[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-muted);\n padding-left: 22px;\n }"] });
|
|
99
99
|
}
|
|
100
100
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActiveTasksPanelComponent, [{
|
|
101
101
|
type: Component,
|
|
@@ -140,7 +140,7 @@ export class ActiveAgentIndicatorComponent {
|
|
|
140
140
|
i0.ɵɵconditionalCreate(0, ActiveAgentIndicatorComponent_Conditional_0_Template, 11, 4, "div", 0);
|
|
141
141
|
} if (rf & 2) {
|
|
142
142
|
i0.ɵɵconditional(ctx.activeAgents.length > 0 ? 0 : -1);
|
|
143
|
-
} }, styles: [".active-agents-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background-color: #F4F4F4;\n border-radius: 20px;\n font-size: 12px;\n color: #6B7280;\n height: 32px;\n }\n\n .active-agents-label[_ngcontent-%COMP%] {\n font-weight: 500;\n color: #6B7280;\n }\n\n .agents-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n max-width: 200px;\n overflow: hidden;\n transition: max-width 300ms ease;\n }\n\n .agents-wrapper.expanded[_ngcontent-%COMP%] {\n max-width: 600px;\n }\n\n .agent-avatar[_ngcontent-%COMP%] {\n position: relative;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 200ms ease;\n flex-shrink: 0;\n font-size: 10px;\n font-weight: 600;\n }\n\n .agent-avatar[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n }\n\n .avatar-content[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: white;\n position: relative;\n z-index: 1;\n }\n\n \n
|
|
143
|
+
} }, styles: [".active-agents-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background-color: #F4F4F4;\n border-radius: 20px;\n font-size: 12px;\n color: #6B7280;\n height: 32px;\n }\n\n .active-agents-label[_ngcontent-%COMP%] {\n font-weight: 500;\n color: #6B7280;\n }\n\n .agents-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n max-width: 200px;\n overflow: hidden;\n transition: max-width 300ms ease;\n }\n\n .agents-wrapper.expanded[_ngcontent-%COMP%] {\n max-width: 600px;\n }\n\n .agent-avatar[_ngcontent-%COMP%] {\n position: relative;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 200ms ease;\n flex-shrink: 0;\n font-size: 10px;\n font-weight: 600;\n }\n\n .agent-avatar[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n }\n\n .avatar-content[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: white;\n position: relative;\n z-index: 1;\n }\n\n \n .status-acknowledging[_ngcontent-%COMP%] .avatar-content[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #3B82F6, #2563EB);\n }\n\n .status-working[_ngcontent-%COMP%] .avatar-content[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #F59E0B, #D97706);\n }\n\n .status-completing[_ngcontent-%COMP%] .avatar-content[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #10B981, #059669);\n }\n\n .status-completed[_ngcontent-%COMP%] .avatar-content[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #6B7280, #4B5563);\n opacity: 0.6;\n }\n\n .status-error[_ngcontent-%COMP%] .avatar-content[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #EF4444, #DC2626);\n }\n\n \n .status-indicator[_ngcontent-%COMP%] {\n position: absolute;\n top: -2px;\n right: -2px;\n width: 10px;\n height: 10px;\n z-index: 2;\n }\n\n .pulse-ring[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: currentColor;\n animation: _ngcontent-%COMP%_pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n .status-acknowledging[_ngcontent-%COMP%] .pulse-ring[_ngcontent-%COMP%] {\n background: #3B82F6;\n }\n\n .status-working[_ngcontent-%COMP%] .pulse-ring[_ngcontent-%COMP%] {\n background: #F59E0B;\n animation: _ngcontent-%COMP%_pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n .status-completing[_ngcontent-%COMP%] .pulse-ring[_ngcontent-%COMP%] {\n background: #10B981;\n animation: _ngcontent-%COMP%_pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n }\n\n @keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.5;\n transform: scale(1.5);\n }\n }\n\n \n .confidence-badge[_ngcontent-%COMP%] {\n position: absolute;\n bottom: -4px;\n right: -4px;\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 4px;\n padding: 1px 3px;\n font-size: 9px;\n font-weight: 600;\n color: #374151;\n z-index: 3;\n line-height: 1;\n }\n\n .more-agents[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #E5E7EB;\n border: none;\n color: #6B7280;\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: all 200ms ease;\n flex-shrink: 0;\n }\n\n .more-agents[_ngcontent-%COMP%]:hover {\n background: #D1D5DB;\n transform: scale(1.05);\n }\n\n .panel-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n background: #3B82F6;\n border: none;\n border-radius: 6px;\n color: white;\n font-size: 12px;\n cursor: pointer;\n transition: all 200ms ease;\n position: relative;\n }\n\n .panel-toggle[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.3);\n }\n\n .agent-count[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.2);\n padding: 2px 6px;\n border-radius: 10px;\n font-weight: 600;\n min-width: 20px;\n text-align: center;\n }"] });
|
|
144
144
|
}
|
|
145
145
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ActiveAgentIndicatorComponent, [{
|
|
146
146
|
type: Component,
|
|
@@ -260,7 +260,7 @@ export class ImageViewerComponent {
|
|
|
260
260
|
i0.ɵɵconditionalCreate(0, ImageViewerComponent_Conditional_0_Template, 34, 8, "div", 0);
|
|
261
261
|
} if (rf & 2) {
|
|
262
262
|
i0.ɵɵconditional(ctx.visible ? 0 : -1);
|
|
263
|
-
} }, styles: [".image-viewer-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n z-index: 10000;\n background: rgba(0, 0, 0, 0.92);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n
|
|
263
|
+
} }, styles: [".image-viewer-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n z-index: 10000;\n background: rgba(0, 0, 0, 0.92);\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n.viewer-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(10px);\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.toolbar-left[_ngcontent-%COMP%], \n.toolbar-center[_ngcontent-%COMP%], \n.toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toolbar-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.toolbar-right[_ngcontent-%COMP%] {\n flex: 1;\n justify-content: flex-end;\n}\n\n.file-name[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.9);\n font-size: 14px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n}\n\n.toolbar-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 8px;\n background: rgba(255, 255, 255, 0.1);\n color: rgba(255, 255, 255, 0.9);\n cursor: pointer;\n transition: background 0.2s, transform 0.15s;\n}\n\n.toolbar-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.2);\n transform: scale(1.05);\n}\n\n.toolbar-btn[_ngcontent-%COMP%]:active {\n transform: scale(0.95);\n}\n\n.toolbar-btn.close-btn[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n}\n\n.toolbar-btn.close-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n}\n\n.toolbar-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.zoom-display[_ngcontent-%COMP%] {\n color: rgba(255, 255, 255, 0.9);\n font-size: 13px;\n font-weight: 500;\n min-width: 50px;\n text-align: center;\n font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;\n}\n\n.toolbar-separator[_ngcontent-%COMP%] {\n width: 1px;\n height: 20px;\n background: rgba(255, 255, 255, 0.2);\n margin: 0 4px;\n}\n\n\n.image-container[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 20px;\n}\n\n.viewer-image[_ngcontent-%COMP%] {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n transition: transform 0.1s ease-out;\n user-select: none;\n pointer-events: none;\n border-radius: 4px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n}\n\n\n.viewer-instructions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 10px;\n color: rgba(255, 255, 255, 0.5);\n font-size: 12px;\n}\n\n.viewer-instructions[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n opacity: 0.3;\n}\n\n\n@media (max-width: 768px) {\n .viewer-toolbar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .toolbar-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n }\n\n .file-name[_ngcontent-%COMP%] {\n max-width: 150px;\n font-size: 12px;\n }\n\n .zoom-display[_ngcontent-%COMP%] {\n min-width: 40px;\n font-size: 11px;\n }\n\n .viewer-instructions[_ngcontent-%COMP%] {\n font-size: 10px;\n padding: 8px;\n }\n\n .image-container[_ngcontent-%COMP%] {\n padding: 10px;\n }\n}\n\n\n@media (hover: none) {\n .toolbar-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.1);\n transform: none;\n }\n\n .toolbar-btn.close-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, transparent);\n }\n\n .viewer-instructions[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
264
264
|
}
|
|
265
265
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ImageViewerComponent, [{
|
|
266
266
|
type: Component,
|
|
@@ -1034,7 +1034,7 @@ export class ArtifactCollectionPickerModalComponent extends BaseAngularComponent
|
|
|
1034
1034
|
} }, dependencies: [FormsModule, i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, MJDialogComponent,
|
|
1035
1035
|
MJDialogActionsComponent,
|
|
1036
1036
|
MJButtonDirective,
|
|
1037
|
-
SharedGenericModule, i4.LoadingComponent], styles: ["\n\n .picker-shell[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n min-height: 460px;\n max-height: 70vh;\n gap: 0;\n margin: -8px -4px 0;\n }\n .pane[_ngcontent-%COMP%] { display:flex; flex-direction:column; min-height: 0; }\n .pane-left[_ngcontent-%COMP%] { border-right: 1px solid var(--mj-border-subtle); }\n .pane-right[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); }\n\n \n\n .toolbar[_ngcontent-%COMP%] {\n display:flex; gap: 8px; padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-wrap: wrap;\n }\n .search[_ngcontent-%COMP%] {\n flex: 1; min-width: 200px;\n display:flex; align-items:center; gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid transparent;\n border-radius: 8px;\n transition: all .15s ease;\n }\n .search[_ngcontent-%COMP%]:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n }\n .search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 13px; }\n .search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1; border: 0; outline: 0; background: transparent;\n font-size: 13.5px; color: var(--mj-text-primary);\n min-width: 0;\n }\n .search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-disabled); }\n .search-clear[_ngcontent-%COMP%] {\n background: transparent; border: 0; cursor: pointer;\n color: var(--mj-text-muted); padding: 2px 4px; border-radius: 4px;\n }\n .search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n\n .chip-btn[_ngcontent-%COMP%] {\n display:inline-flex; align-items:center; gap: 6px;\n padding: 7px 11px; border-radius: 8px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 12.5px; font-weight: 600; cursor: pointer;\n transition: all .15s ease;\n }\n .chip-btn[_ngcontent-%COMP%]:hover:not(:disabled) { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .chip-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .chip-btn[_ngcontent-%COMP%]:disabled { opacity: .55; cursor: not-allowed; }\n\n \n\n .tree-wrap[_ngcontent-%COMP%] { flex: 1; overflow-y: auto; padding: 8px 8px 16px; }\n .tree[_ngcontent-%COMP%] { display:flex; flex-direction: column; gap: 1px; }\n .row[_ngcontent-%COMP%] {\n display:flex; align-items:center; gap: 10px;\n padding: 7px 12px; border-radius: 8px; cursor: pointer;\n user-select: none;\n border: 1px solid transparent;\n background: transparent;\n text-align: left;\n transition: background .12s ease;\n min-height: 36px;\n }\n .row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .row.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 9%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .row.already[_ngcontent-%COMP%] { cursor: default; }\n .row.already[_ngcontent-%COMP%]:hover { background: transparent; }\n .row.already[_ngcontent-%COMP%] .row-title[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n\n .caret[_ngcontent-%COMP%] {\n width: 16px; flex-shrink: 0; text-align: center;\n color: var(--mj-text-muted); font-size: 10px;\n cursor: pointer;\n }\n .caret[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n .check[_ngcontent-%COMP%] {\n width: 18px; height: 18px; border-radius: 5px;\n border: 1.5px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n display:flex; align-items:center; justify-content:center;\n color: transparent; font-size: 10px; flex-shrink: 0;\n transition: all .12s ease;\n }\n .check.checked[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: #fff;\n }\n .check.locked[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: #fff;\n }\n .check.dashed[_ngcontent-%COMP%] {\n border-style: dashed;\n color: var(--mj-text-muted);\n }\n\n .folder-icon[_ngcontent-%COMP%] { font-size: 14px; flex-shrink: 0; }\n\n .row-title[_ngcontent-%COMP%] {\n flex: 1; font-size: 13.5px; font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .row-ancestry[_ngcontent-%COMP%] {\n font-weight: 500; color: var(--mj-text-muted); font-size: 12px;\n margin-left: 2px;\n }\n .row-tag[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600; padding: 2px 8px;\n border-radius: 999px; flex-shrink: 0;\n }\n .row-tag.success[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 35%, transparent);\n }\n\n .create-row[_ngcontent-%COMP%] {\n width: 100%;\n border: 1.5px dashed var(--mj-border-strong);\n color: var(--mj-text-secondary);\n margin-top: 8px;\n background: transparent;\n }\n .create-row[_ngcontent-%COMP%] .row-title[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-weight: 600; }\n .create-row[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n }\n .create-row[_ngcontent-%COMP%]:hover .row-title[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n .create-form-row[_ngcontent-%COMP%] {\n margin-top: 8px;\n border: 1.5px solid var(--mj-border-focus);\n background: var(--mj-bg-surface);\n cursor: default;\n gap: 8px;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n .create-input[_ngcontent-%COMP%] {\n flex: 1; min-width: 0;\n padding: 7px 10px;\n font-size: 13.5px; color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: 0;\n transition: all .12s ease;\n }\n .create-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n }\n .create-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n }\n\n \n\n .state-block[_ngcontent-%COMP%] {\n display:flex; flex-direction:column; align-items:center; justify-content:center;\n padding: 48px 24px; gap: 8px; color: var(--mj-text-muted);\n text-align: center;\n }\n .state-block[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 28px; opacity: .6; }\n .state-block.error[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .state-block[_ngcontent-%COMP%] .hint[_ngcontent-%COMP%] { font-size: 12.5px; color: var(--mj-text-disabled); margin: 0; }\n .state-block[_ngcontent-%COMP%] .link-btn[_ngcontent-%COMP%] {\n background: transparent; border: 0; color: var(--mj-text-link);\n font-weight: 600; cursor: pointer; font-size: 13px; padding: 6px 12px;\n }\n .state-block[_ngcontent-%COMP%] .link-btn[_ngcontent-%COMP%]:hover { color: var(--mj-text-link-hover); text-decoration: underline; }\n .state-block[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0; font-size: 13.5px; }\n \n\n .state-block[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: inherit; opacity: 1; }\n .empty-create-form[_ngcontent-%COMP%] {\n display: flex; flex-direction: column; gap: 8px;\n width: 100%; max-width: 280px; margin-top: 4px;\n }\n .empty-create-actions[_ngcontent-%COMP%] { display: flex; gap: 8px; justify-content: center; }\n\n \n\n .preview-block[_ngcontent-%COMP%] { padding: 16px 18px; border-bottom: 1px solid var(--mj-border-subtle); }\n .block-label[_ngcontent-%COMP%] {\n font-size: 11px; text-transform: uppercase; letter-spacing: .08em;\n font-weight: 700; color: var(--mj-text-muted); margin-bottom: 8px;\n display:flex; justify-content:space-between; align-items:center;\n }\n .block-count[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary); font-size: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 8px; border-radius: 999px;\n }\n .preview-card[_ngcontent-%COMP%] {\n display:flex; gap: 12px; align-items:center;\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 10px; padding: 12px;\n box-shadow: 0 1px 2px rgba(15,23,42,.04);\n }\n .preview-thumb[_ngcontent-%COMP%] {\n width: 38px; height: 38px; border-radius: 9px; flex-shrink: 0;\n background: linear-gradient(135deg, var(--mj-color-accent-400), var(--mj-brand-primary));\n color: #fff; display:flex; align-items:center; justify-content:center;\n font-size: 14px;\n }\n .preview-meta[_ngcontent-%COMP%] { flex: 1; min-width: 0; display:flex; flex-direction: column; gap: 4px; }\n .preview-name[_ngcontent-%COMP%] {\n font-weight: 700; font-size: 13.5px; color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .badge[_ngcontent-%COMP%] {\n display:inline-flex; align-items:center; gap: 4px;\n padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;\n width: fit-content;\n }\n .badge.neutral[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n }\n\n .chips-block[_ngcontent-%COMP%] { flex: 1; min-height: 0; display:flex; flex-direction: column;\n padding: 16px 18px 8px; overflow-y: auto; }\n .chips[_ngcontent-%COMP%] { display:flex; flex-direction: column; gap: 6px; }\n .chip[_ngcontent-%COMP%] {\n display:flex; align-items:center; gap: 10px; padding: 8px 10px;\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n }\n .chip-body[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .chip-name[_ngcontent-%COMP%] {\n font-weight: 600; font-size: 13px; color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .chip-error[_ngcontent-%COMP%] {\n font-size: 11.5px; color: var(--mj-status-error-text); margin-top: 2px;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .chip-action[_ngcontent-%COMP%] {\n width: 24px; height: 24px; border-radius: 6px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--mj-text-muted); font-size: 11px;\n display:flex; align-items:center; justify-content:center;\n }\n .chip-action[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); color: var(--mj-text-primary);\n }\n .chip-action[_ngcontent-%COMP%]:disabled { opacity: .4; cursor: not-allowed; }\n .chip-status[_ngcontent-%COMP%] {\n width: 20px; flex-shrink: 0; text-align: center; font-size: 12px;\n }\n .chip.result.success[_ngcontent-%COMP%] { border-color: color-mix(in srgb, var(--mj-status-success) 35%, transparent);\n background: var(--mj-status-success-bg); }\n .chip.result.success[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-status-success-text); }\n .chip.result.error[_ngcontent-%COMP%] { border-color: color-mix(in srgb, var(--mj-status-error) 35%, transparent);\n background: var(--mj-status-error-bg); }\n .chip.result.error[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .chip.result.saving[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n .chips-empty[_ngcontent-%COMP%] {\n flex: 1; display:flex; flex-direction: column; align-items: center; justify-content: center;\n padding: 32px 16px; text-align: center; color: var(--mj-text-muted);\n border: 1.5px dashed var(--mj-border-default); border-radius: 10px;\n }\n .chips-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 22px; margin-bottom: 8px; opacity: .55; }\n .chips-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0; font-size: 12.5px; }\n\n .footnote[_ngcontent-%COMP%] {\n padding: 12px 18px;\n font-size: 11.5px; color: var(--mj-text-muted);\n display:flex; align-items:center; gap: 6px;\n border-top: 1px solid var(--mj-border-subtle);\n }\n .footnote[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 11px; }\n\n \n\n [_nghost-%COMP%] mj-dialog .k-window-content, \n [_nghost-%COMP%] mj-dialog .mj-dialog-content {\n padding: 0 !important;\n }"] });
|
|
1037
|
+
SharedGenericModule, i4.LoadingComponent], styles: ["\n .picker-shell[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n min-height: 460px;\n max-height: 70vh;\n gap: 0;\n margin: -8px -4px 0;\n }\n .pane[_ngcontent-%COMP%] { display:flex; flex-direction:column; min-height: 0; }\n .pane-left[_ngcontent-%COMP%] { border-right: 1px solid var(--mj-border-subtle); }\n .pane-right[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); }\n\n \n .toolbar[_ngcontent-%COMP%] {\n display:flex; gap: 8px; padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-wrap: wrap;\n }\n .search[_ngcontent-%COMP%] {\n flex: 1; min-width: 200px;\n display:flex; align-items:center; gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid transparent;\n border-radius: 8px;\n transition: all .15s ease;\n }\n .search[_ngcontent-%COMP%]:focus-within {\n background: var(--mj-bg-surface);\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n }\n .search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 13px; }\n .search[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1; border: 0; outline: 0; background: transparent;\n font-size: 13.5px; color: var(--mj-text-primary);\n min-width: 0;\n }\n .search[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-disabled); }\n .search-clear[_ngcontent-%COMP%] {\n background: transparent; border: 0; cursor: pointer;\n color: var(--mj-text-muted); padding: 2px 4px; border-radius: 4px;\n }\n .search-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n\n .chip-btn[_ngcontent-%COMP%] {\n display:inline-flex; align-items:center; gap: 6px;\n padding: 7px 11px; border-radius: 8px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n font-size: 12.5px; font-weight: 600; cursor: pointer;\n transition: all .15s ease;\n }\n .chip-btn[_ngcontent-%COMP%]:hover:not(:disabled) { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .chip-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .chip-btn[_ngcontent-%COMP%]:disabled { opacity: .55; cursor: not-allowed; }\n\n \n .tree-wrap[_ngcontent-%COMP%] { flex: 1; overflow-y: auto; padding: 8px 8px 16px; }\n .tree[_ngcontent-%COMP%] { display:flex; flex-direction: column; gap: 1px; }\n .row[_ngcontent-%COMP%] {\n display:flex; align-items:center; gap: 10px;\n padding: 7px 12px; border-radius: 8px; cursor: pointer;\n user-select: none;\n border: 1px solid transparent;\n background: transparent;\n text-align: left;\n transition: background .12s ease;\n min-height: 36px;\n }\n .row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .row.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 9%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n }\n .row.already[_ngcontent-%COMP%] { cursor: default; }\n .row.already[_ngcontent-%COMP%]:hover { background: transparent; }\n .row.already[_ngcontent-%COMP%] .row-title[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n\n .caret[_ngcontent-%COMP%] {\n width: 16px; flex-shrink: 0; text-align: center;\n color: var(--mj-text-muted); font-size: 10px;\n cursor: pointer;\n }\n .caret[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n\n .check[_ngcontent-%COMP%] {\n width: 18px; height: 18px; border-radius: 5px;\n border: 1.5px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n display:flex; align-items:center; justify-content:center;\n color: transparent; font-size: 10px; flex-shrink: 0;\n transition: all .12s ease;\n }\n .check.checked[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: #fff;\n }\n .check.locked[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n border-color: var(--mj-status-success);\n color: #fff;\n }\n .check.dashed[_ngcontent-%COMP%] {\n border-style: dashed;\n color: var(--mj-text-muted);\n }\n\n .folder-icon[_ngcontent-%COMP%] { font-size: 14px; flex-shrink: 0; }\n\n .row-title[_ngcontent-%COMP%] {\n flex: 1; font-size: 13.5px; font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .row-ancestry[_ngcontent-%COMP%] {\n font-weight: 500; color: var(--mj-text-muted); font-size: 12px;\n margin-left: 2px;\n }\n .row-tag[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600; padding: 2px 8px;\n border-radius: 999px; flex-shrink: 0;\n }\n .row-tag.success[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 35%, transparent);\n }\n\n .create-row[_ngcontent-%COMP%] {\n width: 100%;\n border: 1.5px dashed var(--mj-border-strong);\n color: var(--mj-text-secondary);\n margin-top: 8px;\n background: transparent;\n }\n .create-row[_ngcontent-%COMP%] .row-title[_ngcontent-%COMP%] { color: var(--mj-text-secondary); font-weight: 600; }\n .create-row[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n }\n .create-row[_ngcontent-%COMP%]:hover .row-title[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n .create-form-row[_ngcontent-%COMP%] {\n margin-top: 8px;\n border: 1.5px solid var(--mj-border-focus);\n background: var(--mj-bg-surface);\n cursor: default;\n gap: 8px;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n .create-input[_ngcontent-%COMP%] {\n flex: 1; min-width: 0;\n padding: 7px 10px;\n font-size: 13.5px; color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: 0;\n transition: all .12s ease;\n }\n .create-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n }\n .create-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n }\n\n \n .state-block[_ngcontent-%COMP%] {\n display:flex; flex-direction:column; align-items:center; justify-content:center;\n padding: 48px 24px; gap: 8px; color: var(--mj-text-muted);\n text-align: center;\n }\n .state-block[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 28px; opacity: .6; }\n .state-block.error[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .state-block[_ngcontent-%COMP%] .hint[_ngcontent-%COMP%] { font-size: 12.5px; color: var(--mj-text-disabled); margin: 0; }\n .state-block[_ngcontent-%COMP%] .link-btn[_ngcontent-%COMP%] {\n background: transparent; border: 0; color: var(--mj-text-link);\n font-weight: 600; cursor: pointer; font-size: 13px; padding: 6px 12px;\n }\n .state-block[_ngcontent-%COMP%] .link-btn[_ngcontent-%COMP%]:hover { color: var(--mj-text-link-hover); text-decoration: underline; }\n .state-block[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0; font-size: 13.5px; }\n \n .state-block[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: inherit; opacity: 1; }\n .empty-create-form[_ngcontent-%COMP%] {\n display: flex; flex-direction: column; gap: 8px;\n width: 100%; max-width: 280px; margin-top: 4px;\n }\n .empty-create-actions[_ngcontent-%COMP%] { display: flex; gap: 8px; justify-content: center; }\n\n \n .preview-block[_ngcontent-%COMP%] { padding: 16px 18px; border-bottom: 1px solid var(--mj-border-subtle); }\n .block-label[_ngcontent-%COMP%] {\n font-size: 11px; text-transform: uppercase; letter-spacing: .08em;\n font-weight: 700; color: var(--mj-text-muted); margin-bottom: 8px;\n display:flex; justify-content:space-between; align-items:center;\n }\n .block-count[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary); font-size: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n padding: 2px 8px; border-radius: 999px;\n }\n .preview-card[_ngcontent-%COMP%] {\n display:flex; gap: 12px; align-items:center;\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 10px; padding: 12px;\n box-shadow: 0 1px 2px rgba(15,23,42,.04);\n }\n .preview-thumb[_ngcontent-%COMP%] {\n width: 38px; height: 38px; border-radius: 9px; flex-shrink: 0;\n background: linear-gradient(135deg, var(--mj-color-accent-400), var(--mj-brand-primary));\n color: #fff; display:flex; align-items:center; justify-content:center;\n font-size: 14px;\n }\n .preview-meta[_ngcontent-%COMP%] { flex: 1; min-width: 0; display:flex; flex-direction: column; gap: 4px; }\n .preview-name[_ngcontent-%COMP%] {\n font-weight: 700; font-size: 13.5px; color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .badge[_ngcontent-%COMP%] {\n display:inline-flex; align-items:center; gap: 4px;\n padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;\n width: fit-content;\n }\n .badge.neutral[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n border: 1px solid var(--mj-border-default);\n }\n\n .chips-block[_ngcontent-%COMP%] { flex: 1; min-height: 0; display:flex; flex-direction: column;\n padding: 16px 18px 8px; overflow-y: auto; }\n .chips[_ngcontent-%COMP%] { display:flex; flex-direction: column; gap: 6px; }\n .chip[_ngcontent-%COMP%] {\n display:flex; align-items:center; gap: 10px; padding: 8px 10px;\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n }\n .chip-body[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .chip-name[_ngcontent-%COMP%] {\n font-weight: 600; font-size: 13px; color: var(--mj-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .chip-error[_ngcontent-%COMP%] {\n font-size: 11.5px; color: var(--mj-status-error-text); margin-top: 2px;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .chip-action[_ngcontent-%COMP%] {\n width: 24px; height: 24px; border-radius: 6px;\n background: transparent; border: 0; cursor: pointer;\n color: var(--mj-text-muted); font-size: 11px;\n display:flex; align-items:center; justify-content:center;\n }\n .chip-action[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); color: var(--mj-text-primary);\n }\n .chip-action[_ngcontent-%COMP%]:disabled { opacity: .4; cursor: not-allowed; }\n .chip-status[_ngcontent-%COMP%] {\n width: 20px; flex-shrink: 0; text-align: center; font-size: 12px;\n }\n .chip.result.success[_ngcontent-%COMP%] { border-color: color-mix(in srgb, var(--mj-status-success) 35%, transparent);\n background: var(--mj-status-success-bg); }\n .chip.result.success[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-status-success-text); }\n .chip.result.error[_ngcontent-%COMP%] { border-color: color-mix(in srgb, var(--mj-status-error) 35%, transparent);\n background: var(--mj-status-error-bg); }\n .chip.result.error[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .chip.result.saving[_ngcontent-%COMP%] .chip-status[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n\n .chips-empty[_ngcontent-%COMP%] {\n flex: 1; display:flex; flex-direction: column; align-items: center; justify-content: center;\n padding: 32px 16px; text-align: center; color: var(--mj-text-muted);\n border: 1.5px dashed var(--mj-border-default); border-radius: 10px;\n }\n .chips-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 22px; margin-bottom: 8px; opacity: .55; }\n .chips-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] { margin: 0; font-size: 12.5px; }\n\n .footnote[_ngcontent-%COMP%] {\n padding: 12px 18px;\n font-size: 11.5px; color: var(--mj-text-muted);\n display:flex; align-items:center; gap: 6px;\n border-top: 1px solid var(--mj-border-subtle);\n }\n .footnote[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 11px; }\n\n \n [_nghost-%COMP%] mj-dialog .k-window-content, \n [_nghost-%COMP%] mj-dialog .mj-dialog-content {\n padding: 0 !important;\n }"] });
|
|
1038
1038
|
}
|
|
1039
1039
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArtifactCollectionPickerModalComponent, [{
|
|
1040
1040
|
type: Component,
|
|
@@ -9,32 +9,32 @@ import * as i3 from "@angular/common";
|
|
|
9
9
|
const _c0 = a0 => ({ node: a0 });
|
|
10
10
|
const _forTrack0 = ($index, $item) => $item.collection.ID;
|
|
11
11
|
function CollectionTreeComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
12
|
-
const
|
|
12
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
13
13
|
i0.ɵɵelementStart(0, "button", 6);
|
|
14
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
14
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCreateCollection(null)); });
|
|
15
15
|
i0.ɵɵelement(1, "i", 7);
|
|
16
16
|
i0.ɵɵelementEnd();
|
|
17
17
|
} }
|
|
18
18
|
function CollectionTreeComponent_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
-
const
|
|
19
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
20
20
|
i0.ɵɵelementStart(0, "i", 15);
|
|
21
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_2_Template_i_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
21
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_2_Template_i_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleNode(node_r4, $event)); });
|
|
22
22
|
i0.ɵɵelementEnd();
|
|
23
23
|
} if (rf & 2) {
|
|
24
|
-
const
|
|
25
|
-
i0.ɵɵproperty("ngClass",
|
|
24
|
+
const node_r4 = i0.ɵɵnextContext().$implicit;
|
|
25
|
+
i0.ɵɵproperty("ngClass", node_r4.expanded ? "fa-chevron-down" : "fa-chevron-right");
|
|
26
26
|
} }
|
|
27
27
|
function CollectionTreeComponent_For_7_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
28
|
-
const
|
|
28
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
29
29
|
i0.ɵɵelementStart(0, "button", 16);
|
|
30
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
30
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCreateCollection(node_r4.collection.ID)); });
|
|
31
31
|
i0.ɵɵelement(1, "i", 7);
|
|
32
32
|
i0.ɵɵelementEnd();
|
|
33
33
|
} }
|
|
34
34
|
function CollectionTreeComponent_For_7_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
35
|
-
const
|
|
35
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
36
36
|
i0.ɵɵelementStart(0, "button", 17);
|
|
37
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
37
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDeleteCollection(node_r4.collection)); });
|
|
38
38
|
i0.ɵɵelement(1, "i", 18);
|
|
39
39
|
i0.ɵɵelementEnd();
|
|
40
40
|
} }
|
|
@@ -44,73 +44,73 @@ function CollectionTreeComponent_For_7_Conditional_9_For_1_ng_container_0_Templa
|
|
|
44
44
|
function CollectionTreeComponent_For_7_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
45
45
|
i0.ɵɵtemplate(0, CollectionTreeComponent_For_7_Conditional_9_For_1_ng_container_0_Template, 1, 0, "ng-container", 19);
|
|
46
46
|
} if (rf & 2) {
|
|
47
|
-
const
|
|
47
|
+
const child_r8 = ctx.$implicit;
|
|
48
48
|
i0.ɵɵnextContext(3);
|
|
49
|
-
const
|
|
50
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
49
|
+
const recursiveTree_r9 = i0.ɵɵreference(9);
|
|
50
|
+
i0.ɵɵproperty("ngTemplateOutlet", recursiveTree_r9)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r8));
|
|
51
51
|
} }
|
|
52
52
|
function CollectionTreeComponent_For_7_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
53
53
|
i0.ɵɵrepeaterCreate(0, CollectionTreeComponent_For_7_Conditional_9_For_1_Template, 1, 4, "ng-container", null, _forTrack0);
|
|
54
54
|
} if (rf & 2) {
|
|
55
|
-
const
|
|
56
|
-
i0.ɵɵrepeater(
|
|
55
|
+
const node_r4 = i0.ɵɵnextContext().$implicit;
|
|
56
|
+
i0.ɵɵrepeater(node_r4.children);
|
|
57
57
|
} }
|
|
58
58
|
function CollectionTreeComponent_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
59
|
-
const
|
|
59
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
60
60
|
i0.ɵɵelementStart(0, "div", 5)(1, "div", 8);
|
|
61
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Template_div_click_1_listener() { const
|
|
61
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Template_div_click_1_listener() { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSelectCollection(node_r4.collection)); })("dragstart", function CollectionTreeComponent_For_7_Template_div_dragstart_1_listener($event) { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragStart($event, node_r4)); })("dragend", function CollectionTreeComponent_For_7_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragEnd($event)); })("dragover", function CollectionTreeComponent_For_7_Template_div_dragover_1_listener($event) { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragOver($event, node_r4)); })("dragleave", function CollectionTreeComponent_For_7_Template_div_dragleave_1_listener($event) { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragLeave($event, node_r4)); })("drop", function CollectionTreeComponent_For_7_Template_div_drop_1_listener($event) { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDrop($event, node_r4)); });
|
|
62
62
|
i0.ɵɵconditionalCreate(2, CollectionTreeComponent_For_7_Conditional_2_Template, 1, 1, "i", 9);
|
|
63
63
|
i0.ɵɵelement(3, "i", 10);
|
|
64
64
|
i0.ɵɵelementStart(4, "span", 11);
|
|
65
65
|
i0.ɵɵtext(5);
|
|
66
66
|
i0.ɵɵelementEnd();
|
|
67
67
|
i0.ɵɵelementStart(6, "div", 12);
|
|
68
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Template_div_click_6_listener($event) {
|
|
68
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_For_7_Template_div_click_6_listener($event) { return $event.stopPropagation(); });
|
|
69
69
|
i0.ɵɵconditionalCreate(7, CollectionTreeComponent_For_7_Conditional_7_Template, 2, 0, "button", 13);
|
|
70
70
|
i0.ɵɵconditionalCreate(8, CollectionTreeComponent_For_7_Conditional_8_Template, 2, 0, "button", 14);
|
|
71
71
|
i0.ɵɵelementEnd()();
|
|
72
72
|
i0.ɵɵconditionalCreate(9, CollectionTreeComponent_For_7_Conditional_9_Template, 2, 0);
|
|
73
73
|
i0.ɵɵelementEnd();
|
|
74
74
|
} if (rf & 2) {
|
|
75
|
-
const
|
|
76
|
-
const
|
|
75
|
+
const node_r4 = ctx.$implicit;
|
|
76
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
77
77
|
i0.ɵɵadvance();
|
|
78
|
-
i0.ɵɵstyleProp("padding-left",
|
|
79
|
-
i0.ɵɵclassProp("selected",
|
|
78
|
+
i0.ɵɵstyleProp("padding-left", node_r4.level * 20, "px");
|
|
79
|
+
i0.ɵɵclassProp("selected", ctx_r1.IsCollectionSelected(node_r4))("drag-over", ctx_r1.dragOverNodeId === node_r4.collection.ID)("dragging", ctx_r1.IsCollectionDragging(node_r4));
|
|
80
80
|
i0.ɵɵproperty("draggable", true);
|
|
81
81
|
i0.ɵɵadvance();
|
|
82
|
-
i0.ɵɵconditional(
|
|
82
|
+
i0.ɵɵconditional(node_r4.children.length > 0 ? 2 : -1);
|
|
83
83
|
i0.ɵɵadvance();
|
|
84
|
-
i0.ɵɵstyleProp("color",
|
|
84
|
+
i0.ɵɵstyleProp("color", node_r4.collection.Color || "#0076B6");
|
|
85
85
|
i0.ɵɵadvance(2);
|
|
86
|
-
i0.ɵɵtextInterpolate(
|
|
86
|
+
i0.ɵɵtextInterpolate(node_r4.collection.Name);
|
|
87
87
|
i0.ɵɵadvance(2);
|
|
88
|
-
i0.ɵɵconditional(
|
|
88
|
+
i0.ɵɵconditional(ctx_r1.canEdit(node_r4.collection) ? 7 : -1);
|
|
89
89
|
i0.ɵɵadvance();
|
|
90
|
-
i0.ɵɵconditional(
|
|
90
|
+
i0.ɵɵconditional(ctx_r1.canDelete(node_r4.collection) ? 8 : -1);
|
|
91
91
|
i0.ɵɵadvance();
|
|
92
|
-
i0.ɵɵconditional(
|
|
92
|
+
i0.ɵɵconditional(node_r4.expanded ? 9 : -1);
|
|
93
93
|
} }
|
|
94
94
|
function CollectionTreeComponent_ng_template_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
-
const
|
|
95
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
96
96
|
i0.ɵɵelementStart(0, "i", 15);
|
|
97
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_2_Template_i_click_0_listener($event) { i0.ɵɵrestoreView(
|
|
97
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_2_Template_i_click_0_listener($event) { i0.ɵɵrestoreView(_r12); const node_r11 = i0.ɵɵnextContext().node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleNode(node_r11, $event)); });
|
|
98
98
|
i0.ɵɵelementEnd();
|
|
99
99
|
} if (rf & 2) {
|
|
100
|
-
const
|
|
101
|
-
i0.ɵɵproperty("ngClass",
|
|
100
|
+
const node_r11 = i0.ɵɵnextContext().node;
|
|
101
|
+
i0.ɵɵproperty("ngClass", node_r11.expanded ? "fa-chevron-down" : "fa-chevron-right");
|
|
102
102
|
} }
|
|
103
103
|
function CollectionTreeComponent_ng_template_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
104
|
-
const
|
|
104
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
105
105
|
i0.ɵɵelementStart(0, "button", 16);
|
|
106
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
106
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const node_r11 = i0.ɵɵnextContext().node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onCreateCollection(node_r11.collection.ID)); });
|
|
107
107
|
i0.ɵɵelement(1, "i", 7);
|
|
108
108
|
i0.ɵɵelementEnd();
|
|
109
109
|
} }
|
|
110
110
|
function CollectionTreeComponent_ng_template_8_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
111
|
-
const
|
|
111
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
112
112
|
i0.ɵɵelementStart(0, "button", 17);
|
|
113
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
113
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const node_r11 = i0.ɵɵnextContext().node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDeleteCollection(node_r11.collection)); });
|
|
114
114
|
i0.ɵɵelement(1, "i", 18);
|
|
115
115
|
i0.ɵɵelementEnd();
|
|
116
116
|
} }
|
|
@@ -120,52 +120,52 @@ function CollectionTreeComponent_ng_template_8_Conditional_9_For_1_ng_container_
|
|
|
120
120
|
function CollectionTreeComponent_ng_template_8_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
121
121
|
i0.ɵɵtemplate(0, CollectionTreeComponent_ng_template_8_Conditional_9_For_1_ng_container_0_Template, 1, 0, "ng-container", 19);
|
|
122
122
|
} if (rf & 2) {
|
|
123
|
-
const
|
|
123
|
+
const child_r15 = ctx.$implicit;
|
|
124
124
|
i0.ɵɵnextContext(3);
|
|
125
|
-
const
|
|
126
|
-
i0.ɵɵproperty("ngTemplateOutlet",
|
|
125
|
+
const recursiveTree_r9 = i0.ɵɵreference(9);
|
|
126
|
+
i0.ɵɵproperty("ngTemplateOutlet", recursiveTree_r9)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c0, child_r15));
|
|
127
127
|
} }
|
|
128
128
|
function CollectionTreeComponent_ng_template_8_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
129
129
|
i0.ɵɵrepeaterCreate(0, CollectionTreeComponent_ng_template_8_Conditional_9_For_1_Template, 1, 4, "ng-container", null, _forTrack0);
|
|
130
130
|
} if (rf & 2) {
|
|
131
|
-
const
|
|
132
|
-
i0.ɵɵrepeater(
|
|
131
|
+
const node_r11 = i0.ɵɵnextContext().node;
|
|
132
|
+
i0.ɵɵrepeater(node_r11.children);
|
|
133
133
|
} }
|
|
134
134
|
function CollectionTreeComponent_ng_template_8_Template(rf, ctx) { if (rf & 1) {
|
|
135
|
-
const
|
|
135
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
136
136
|
i0.ɵɵelementStart(0, "div", 5)(1, "div", 8);
|
|
137
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Template_div_click_1_listener() { const
|
|
137
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Template_div_click_1_listener() { const node_r11 = i0.ɵɵrestoreView(_r10).node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSelectCollection(node_r11.collection)); })("dragstart", function CollectionTreeComponent_ng_template_8_Template_div_dragstart_1_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragStart($event, node_r11)); })("dragend", function CollectionTreeComponent_ng_template_8_Template_div_dragend_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragEnd($event)); })("dragover", function CollectionTreeComponent_ng_template_8_Template_div_dragover_1_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragOver($event, node_r11)); })("dragleave", function CollectionTreeComponent_ng_template_8_Template_div_dragleave_1_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDragLeave($event, node_r11)); })("drop", function CollectionTreeComponent_ng_template_8_Template_div_drop_1_listener($event) { const node_r11 = i0.ɵɵrestoreView(_r10).node; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDrop($event, node_r11)); });
|
|
138
138
|
i0.ɵɵconditionalCreate(2, CollectionTreeComponent_ng_template_8_Conditional_2_Template, 1, 1, "i", 9);
|
|
139
139
|
i0.ɵɵelement(3, "i", 10);
|
|
140
140
|
i0.ɵɵelementStart(4, "span", 11);
|
|
141
141
|
i0.ɵɵtext(5);
|
|
142
142
|
i0.ɵɵelementEnd();
|
|
143
143
|
i0.ɵɵelementStart(6, "div", 12);
|
|
144
|
-
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Template_div_click_6_listener($event) {
|
|
144
|
+
i0.ɵɵlistener("click", function CollectionTreeComponent_ng_template_8_Template_div_click_6_listener($event) { return $event.stopPropagation(); });
|
|
145
145
|
i0.ɵɵconditionalCreate(7, CollectionTreeComponent_ng_template_8_Conditional_7_Template, 2, 0, "button", 13);
|
|
146
146
|
i0.ɵɵconditionalCreate(8, CollectionTreeComponent_ng_template_8_Conditional_8_Template, 2, 0, "button", 14);
|
|
147
147
|
i0.ɵɵelementEnd()();
|
|
148
148
|
i0.ɵɵconditionalCreate(9, CollectionTreeComponent_ng_template_8_Conditional_9_Template, 2, 0);
|
|
149
149
|
i0.ɵɵelementEnd();
|
|
150
150
|
} if (rf & 2) {
|
|
151
|
-
const
|
|
152
|
-
const
|
|
151
|
+
const node_r11 = ctx.node;
|
|
152
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
153
153
|
i0.ɵɵadvance();
|
|
154
|
-
i0.ɵɵstyleProp("padding-left",
|
|
155
|
-
i0.ɵɵclassProp("selected",
|
|
154
|
+
i0.ɵɵstyleProp("padding-left", node_r11.level * 20, "px");
|
|
155
|
+
i0.ɵɵclassProp("selected", ctx_r1.IsCollectionSelected(node_r11))("drag-over", ctx_r1.dragOverNodeId === node_r11.collection.ID)("dragging", ctx_r1.IsCollectionDragging(node_r11));
|
|
156
156
|
i0.ɵɵproperty("draggable", true);
|
|
157
157
|
i0.ɵɵadvance();
|
|
158
|
-
i0.ɵɵconditional(
|
|
158
|
+
i0.ɵɵconditional(node_r11.children.length > 0 ? 2 : -1);
|
|
159
159
|
i0.ɵɵadvance();
|
|
160
|
-
i0.ɵɵstyleProp("color",
|
|
160
|
+
i0.ɵɵstyleProp("color", node_r11.collection.Color || "#0076B6");
|
|
161
161
|
i0.ɵɵadvance(2);
|
|
162
|
-
i0.ɵɵtextInterpolate(
|
|
162
|
+
i0.ɵɵtextInterpolate(node_r11.collection.Name);
|
|
163
163
|
i0.ɵɵadvance(2);
|
|
164
|
-
i0.ɵɵconditional(
|
|
164
|
+
i0.ɵɵconditional(ctx_r1.canEdit(node_r11.collection) ? 7 : -1);
|
|
165
165
|
i0.ɵɵadvance();
|
|
166
|
-
i0.ɵɵconditional(
|
|
166
|
+
i0.ɵɵconditional(ctx_r1.canDelete(node_r11.collection) ? 8 : -1);
|
|
167
167
|
i0.ɵɵadvance();
|
|
168
|
-
i0.ɵɵconditional(
|
|
168
|
+
i0.ɵɵconditional(node_r11.expanded ? 9 : -1);
|
|
169
169
|
} }
|
|
170
170
|
export class CollectionTreeComponent extends BaseAngularComponent {
|
|
171
171
|
permissionService;
|
|
@@ -448,14 +448,13 @@ export class CollectionTreeComponent extends BaseAngularComponent {
|
|
|
448
448
|
}
|
|
449
449
|
static ɵfac = function CollectionTreeComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CollectionTreeComponent)(i0.ɵɵdirectiveInject(i1.CollectionPermissionService), i0.ɵɵdirectiveInject(i2.MJConfirmService)); };
|
|
450
450
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CollectionTreeComponent, selectors: [["mj-collection-tree"]], inputs: { environmentId: "environmentId", currentUser: "currentUser", selectedCollectionId: "selectedCollectionId", userPermissions: "userPermissions" }, outputs: { collectionSelected: "collectionSelected", collectionCreated: "collectionCreated", collectionDeleted: "collectionDeleted" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 10, vars: 3, consts: [["recursiveTree", ""], [1, "collection-tree"], [1, "tree-header"], ["title", "New Collection", 1, "btn-new"], [1, "tree-content", 3, "dragover", "drop"], [1, "tree-node-wrapper"], ["title", "New Collection", 1, "btn-new", 3, "click"], [1, "fas", "fa-plus"], [1, "tree-node", 3, "click", "dragstart", "dragend", "dragover", "dragleave", "drop", "draggable"], [1, "fas", "toggle-icon", 3, "ngClass"], [1, "fas", "fa-folder", "collection-icon"], [1, "collection-name"], [1, "node-actions", 3, "click"], ["title", "Add sub-collection", 1, "node-action-btn"], ["title", "Delete", 1, "node-action-btn"], [1, "fas", "toggle-icon", 3, "click", "ngClass"], ["title", "Add sub-collection", 1, "node-action-btn", 3, "click"], ["title", "Delete", 1, "node-action-btn", 3, "click"], [1, "fas", "fa-trash"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"]], template: function CollectionTreeComponent_Template(rf, ctx) { if (rf & 1) {
|
|
451
|
-
const _r1 = i0.ɵɵgetCurrentView();
|
|
452
451
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h3");
|
|
453
452
|
i0.ɵɵtext(3, "Collections");
|
|
454
453
|
i0.ɵɵelementEnd();
|
|
455
454
|
i0.ɵɵconditionalCreate(4, CollectionTreeComponent_Conditional_4_Template, 2, 0, "button", 3);
|
|
456
455
|
i0.ɵɵelementEnd();
|
|
457
456
|
i0.ɵɵelementStart(5, "div", 4);
|
|
458
|
-
i0.ɵɵlistener("dragover", function CollectionTreeComponent_Template_div_dragover_5_listener($event) {
|
|
457
|
+
i0.ɵɵlistener("dragover", function CollectionTreeComponent_Template_div_dragover_5_listener($event) { return ctx.onDragOverRoot($event); })("drop", function CollectionTreeComponent_Template_div_drop_5_listener($event) { return ctx.onDropRoot($event); });
|
|
459
458
|
i0.ɵɵrepeaterCreate(6, CollectionTreeComponent_For_7_Template, 10, 16, "div", 5, _forTrack0);
|
|
460
459
|
i0.ɵɵelementEnd()();
|
|
461
460
|
i0.ɵɵtemplate(8, CollectionTreeComponent_ng_template_8_Template, 10, 16, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-tree.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-tree.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJCollectionEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata, LogError } from '@memberjunction/core';\nimport { CollectionPermission, CollectionPermissionService } from '../../services/collection-permission.service';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MJConfirmService } from '@memberjunction/ng-ui-components';\n\ninterface TreeNode {\n collection: MJCollectionEntity;\n children: TreeNode[];\n expanded: boolean;\n level: number;\n}\n\ninterface DragData {\n collectionId: string;\n parentId: string | null;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-collection-tree',\n template: `\n <div class=\"collection-tree\">\n <div class=\"tree-header\">\n <h3>Collections</h3>\n @if (canCreateAtRoot()) {\n <button class=\"btn-new\" (click)=\"onCreateCollection(null)\" title=\"New Collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n </div>\n\n <div\n class=\"tree-content\"\n [class.drag-over-root]=\"dragOverNodeId === 'root'\"\n (dragover)=\"onDragOverRoot($event)\"\n (drop)=\"onDropRoot($event)\">\n @for (node of treeNodes; track node.collection.ID) {\n <div class=\"tree-node-wrapper\">\n <div\n class=\"tree-node\"\n [class.selected]=\"IsCollectionSelected(node)\"\n [class.drag-over]=\"dragOverNodeId === node.collection.ID\"\n [class.dragging]=\"IsCollectionDragging(node)\"\n [style.padding-left.px]=\"node.level * 20\"\n [draggable]=\"true\"\n (click)=\"onSelectCollection(node.collection)\"\n (dragstart)=\"onDragStart($event, node)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event, node)\"\n (dragleave)=\"onDragLeave($event, node)\"\n (drop)=\"onDrop($event, node)\">\n @if (node.children.length > 0) {\n <i\n class=\"fas toggle-icon\"\n [ngClass]=\"node.expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"\n (click)=\"toggleNode(node, $event)\">\n </i>\n }\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n <div class=\"node-actions\" (click)=\"$event.stopPropagation()\">\n @if (canEdit(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onCreateCollection(node.collection.ID)\" title=\"Add sub-collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n @if (canDelete(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onDeleteCollection(node.collection)\" title=\"Delete\">\n <i class=\"fas fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n\n @if (node.expanded) {\n @for (child of node.children; track child.collection.ID) {\n <ng-container *ngTemplateOutlet=\"recursiveTree; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n </div>\n </div>\n\n <ng-template #recursiveTree let-node=\"node\">\n <div class=\"tree-node-wrapper\">\n <div\n class=\"tree-node\"\n [class.selected]=\"IsCollectionSelected(node)\"\n [class.drag-over]=\"dragOverNodeId === node.collection.ID\"\n [class.dragging]=\"IsCollectionDragging(node)\"\n [style.padding-left.px]=\"node.level * 20\"\n [draggable]=\"true\"\n (click)=\"onSelectCollection(node.collection)\"\n (dragstart)=\"onDragStart($event, node)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event, node)\"\n (dragleave)=\"onDragLeave($event, node)\"\n (drop)=\"onDrop($event, node)\">\n @if (node.children.length > 0) {\n <i\n class=\"fas toggle-icon\"\n [ngClass]=\"node.expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"\n (click)=\"toggleNode(node, $event)\">\n </i>\n }\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n <div class=\"node-actions\" (click)=\"$event.stopPropagation()\">\n @if (canEdit(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onCreateCollection(node.collection.ID)\" title=\"Add sub-collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n @if (canDelete(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onDeleteCollection(node.collection)\" title=\"Delete\">\n <i class=\"fas fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n\n @if (node.expanded) {\n @for (child of node.children; track child.collection.ID) {\n <ng-container *ngTemplateOutlet=\"recursiveTree; context: { node: child }\"></ng-container>\n }\n }\n </div>\n </ng-template>\n `,\n styles: [`\n .collection-tree { display: flex; flex-direction: column; height: 100%; }\n .tree-header { padding: 16px; border-bottom: 1px solid var(--mj-border-default); display: flex; justify-content: space-between; align-items: center; }\n .tree-header h3 { margin: 0; font-size: 16px; }\n .btn-new { padding: 6px 10px; background: var(--mj-brand-primary); color: var(--mj-text-inverse); border: none; border-radius: 4px; cursor: pointer; }\n .btn-new:hover { background: var(--mj-brand-primary-hover); }\n .tree-content { flex: 1; overflow-y: auto; position: relative; }\n .tree-content.drag-over-root { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .tree-node {\n padding: 8px 12px;\n cursor: move;\n display: flex;\n align-items: center;\n gap: 8px;\n position: relative;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n }\n .tree-node:hover { background: var(--mj-bg-surface-sunken); }\n .tree-node.selected { background: var(--mj-brand-accent); }\n .tree-node.dragging {\n opacity: 0.4;\n cursor: grabbing;\n }\n .tree-node.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 2px dashed var(--mj-brand-primary);\n border-radius: 4px;\n }\n .toggle-icon { font-size: 10px; color: var(--mj-text-disabled); cursor: pointer; width: 12px; }\n .collection-icon { font-size: 14px; }\n .collection-name { flex: 1; font-size: 14px; user-select: none; }\n .node-actions { display: none; gap: 4px; }\n .tree-node:hover .node-actions { display: flex; }\n .node-action-btn { padding: 4px 6px; background: transparent; border: none; cursor: pointer; border-radius: 3px; color: var(--mj-text-muted); }\n .node-action-btn:hover { background: var(--mj-bg-surface-sunken); }\n `]\n})\nexport class CollectionTreeComponent extends BaseAngularComponent implements OnInit {\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() selectedCollectionId: string | null = null;\n @Input() userPermissions: Map<string, CollectionPermission> = new Map();\n\n @Output() collectionSelected = new EventEmitter<MJCollectionEntity>();\n @Output() collectionCreated = new EventEmitter<MJCollectionEntity>();\n @Output() collectionDeleted = new EventEmitter<MJCollectionEntity>();\n\n public collections: MJCollectionEntity[] = [];\n public treeNodes: TreeNode[] = [];\n public draggedNode: TreeNode | null = null;\n public dragOverNodeId: string | null = null;\n\n constructor(private permissionService: CollectionPermissionService, private confirmService: MJConfirmService) {\n super();}\n\n ngOnInit() {\n this.permissionService.Provider = this.ProviderToUse;\n this.loadCollections();\n }\n\n private async loadCollections(): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: `EnvironmentID='${this.environmentId}'`,\n OrderBy: 'Sequence ASC, Name ASC',\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (result.Success) {\n this.collections = result.Results || [];\n this.buildTree();\n }\n } catch (error) {\n console.error('Error loading collections:', error);\n }\n }\n\n private buildTree(): void {\n const rootCollections = this.collections.filter(c => !c.ParentID);\n this.treeNodes = rootCollections.map(c => this.buildNode(c, 0));\n }\n\n private buildNode(collection: MJCollectionEntity, level: number): TreeNode {\n const children = this.collections.filter(c => UUIDsEqual(c.ParentID, collection.ID));\n return {\n collection,\n children: children.map(c => this.buildNode(c, level + 1)),\n expanded: level === 0,\n level\n };\n }\n\n toggleNode(node: TreeNode, event: Event): void {\n event.stopPropagation();\n node.expanded = !node.expanded;\n }\n\n IsCollectionSelected(node: TreeNode): boolean {\n return UUIDsEqual(node.collection.ID, this.selectedCollectionId);\n }\n\n IsCollectionDragging(node: TreeNode): boolean {\n return UUIDsEqual(this.draggedNode?.collection?.ID, node.collection.ID);\n }\n\n onSelectCollection(collection: MJCollectionEntity): void {\n this.selectedCollectionId = collection.ID;\n this.collectionSelected.emit(collection);\n }\n\n async onCreateCollection(parentId: string | null): Promise<void> {\n // Validate permission if creating child collection\n if (parentId) {\n const parentCollection = this.collections.find(c => UUIDsEqual(c.ID, parentId));\n if (parentCollection) {\n // Check if user has Edit permission on parent\n if (parentCollection.OwnerID && !UUIDsEqual(parentCollection.OwnerID, this.currentUser.ID)) {\n const permission = await this.permissionService.checkPermission(\n parentId,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canEdit) {\n alert('You do not have Edit permission to create a sub-collection.');\n return;\n }\n }\n }\n }\n\n const name = prompt('Enter collection name:');\n if (!name) return;\n\n try {\n const md = this.ProviderToUse;\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n\n collection.Name = name;\n collection.EnvironmentID = this.environmentId;\n\n if (parentId) {\n // Child collection - inherit parent's owner and set parent\n const parentCollection = this.collections.find(c => UUIDsEqual(c.ID, parentId));\n collection.ParentID = parentId;\n collection.OwnerID = parentCollection?.OwnerID || this.currentUser.ID;\n } else {\n // Root collection - current user becomes owner\n collection.OwnerID = this.currentUser.ID;\n }\n\n const saved = await collection.Save();\n if (saved) {\n this.collectionCreated.emit(collection);\n await this.loadCollections();\n }\n } catch (error) {\n console.error('Error creating collection:', error);\n alert('Failed to create collection');\n }\n }\n\n async onDeleteCollection(collection: MJCollectionEntity): Promise<void> {\n // Validate Delete permission\n if (collection.OwnerID && !UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n const permission = await this.permissionService.checkPermission(\n collection.ID,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canDelete) {\n alert('You do not have Delete permission for this collection.');\n return;\n }\n }\n\n if (!(await this.confirmService.ConfirmDelete({ title: 'Delete Collection', message: `Delete collection \"${collection.Name}\"?` }))) return;\n\n try {\n const deleted = await collection.Delete();\n if (deleted) {\n this.collectionDeleted.emit(collection);\n await this.loadCollections();\n }\n } catch (error) {\n console.error('Error deleting collection:', error);\n alert('Failed to delete collection');\n }\n }\n\n onDragStart(event: DragEvent, node: TreeNode): void {\n this.draggedNode = node;\n const dragData: DragData = {\n collectionId: node.collection.ID,\n parentId: node.collection.ParentID || null\n };\n event.dataTransfer!.effectAllowed = 'move';\n event.dataTransfer!.setData('application/json', JSON.stringify(dragData));\n\n // Add visual feedback\n (event.target as HTMLElement).style.opacity = '0.4';\n }\n\n onDragEnd(event: DragEvent): void {\n // Clean up visual feedback\n (event.target as HTMLElement).style.opacity = '1';\n this.draggedNode = null;\n this.dragOverNodeId = null;\n }\n\n onDragOver(event: DragEvent, targetNode: TreeNode): void {\n event.preventDefault(); // Required to allow drop\n\n if (!this.draggedNode || UUIDsEqual(this.draggedNode.collection.ID, targetNode.collection.ID)) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n // Check if trying to drop into a descendant\n if (this.isDescendant(targetNode, this.draggedNode)) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n event.dataTransfer!.dropEffect = 'move';\n this.dragOverNodeId = targetNode.collection.ID;\n }\n\n onDragLeave(event: DragEvent, targetNode: TreeNode): void {\n if (this.dragOverNodeId === targetNode.collection.ID) {\n this.dragOverNodeId = null;\n }\n }\n\n async onDrop(event: DragEvent, targetNode: TreeNode): Promise<void> {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.draggedNode) {\n return;\n }\n\n // Don't allow dropping on itself\n if (UUIDsEqual(this.draggedNode.collection.ID, targetNode.collection.ID)) {\n this.dragOverNodeId = null;\n return;\n }\n\n // Check if trying to drop into a descendant\n if (this.isDescendant(targetNode, this.draggedNode)) {\n alert('Cannot move a collection into its own descendant');\n this.dragOverNodeId = null;\n return;\n }\n\n try {\n const collection = this.draggedNode.collection;\n const newParentId = targetNode.collection.ID;\n\n // Update the collection's parent\n collection.ParentID = newParentId;\n\n const saved = await collection.Save();\n if (saved) {\n // Reload the tree to reflect changes\n await this.loadCollections();\n } else {\n alert('Failed to move collection');\n }\n } catch (error) {\n LogError(error);\n alert('Error moving collection');\n } finally {\n this.dragOverNodeId = null;\n }\n }\n\n onDragOverRoot(event: DragEvent): void {\n event.preventDefault();\n\n if (!this.draggedNode) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n event.dataTransfer!.dropEffect = 'move';\n this.dragOverNodeId = 'root';\n }\n\n async onDropRoot(event: DragEvent): Promise<void> {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.draggedNode) {\n return;\n }\n\n try {\n const collection = this.draggedNode.collection;\n\n // Move to root level\n collection.ParentID = null;\n\n const saved = await collection.Save();\n if (saved) {\n await this.loadCollections();\n } else {\n alert('Failed to move collection to root');\n }\n } catch (error) {\n LogError(error);\n alert('Error moving collection to root');\n } finally {\n this.dragOverNodeId = null;\n }\n }\n\n private isDescendant(potentialDescendant: TreeNode, ancestor: TreeNode): boolean {\n if (UUIDsEqual(potentialDescendant.collection.ParentID, ancestor.collection.ID)) {\n return true;\n }\n\n for (const child of ancestor.children) {\n if (this.isDescendant(potentialDescendant, child)) {\n return true;\n }\n }\n\n return false;\n }\n\n // Permission checking methods\n canEdit(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canEdit || false;\n }\n\n canDelete(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canDelete || false;\n }\n\n canCreateAtRoot(): boolean {\n // Anyone can create at root level\n return true;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"collection-tree.component.js","sourceRoot":"","sources":["../../../../src/lib/components/collection/collection-tree.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJCollectionEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata, LogError } from '@memberjunction/core';\nimport { CollectionPermission, CollectionPermissionService } from '../../services/collection-permission.service';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MJConfirmService } from '@memberjunction/ng-ui-components';\n\ninterface TreeNode {\n collection: MJCollectionEntity;\n children: TreeNode[];\n expanded: boolean;\n level: number;\n}\n\ninterface DragData {\n collectionId: string;\n parentId: string | null;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-collection-tree',\n template: `\n <div class=\"collection-tree\">\n <div class=\"tree-header\">\n <h3>Collections</h3>\n @if (canCreateAtRoot()) {\n <button class=\"btn-new\" (click)=\"onCreateCollection(null)\" title=\"New Collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n </div>\n\n <div\n class=\"tree-content\"\n [class.drag-over-root]=\"dragOverNodeId === 'root'\"\n (dragover)=\"onDragOverRoot($event)\"\n (drop)=\"onDropRoot($event)\">\n @for (node of treeNodes; track node.collection.ID) {\n <div class=\"tree-node-wrapper\">\n <div\n class=\"tree-node\"\n [class.selected]=\"IsCollectionSelected(node)\"\n [class.drag-over]=\"dragOverNodeId === node.collection.ID\"\n [class.dragging]=\"IsCollectionDragging(node)\"\n [style.padding-left.px]=\"node.level * 20\"\n [draggable]=\"true\"\n (click)=\"onSelectCollection(node.collection)\"\n (dragstart)=\"onDragStart($event, node)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event, node)\"\n (dragleave)=\"onDragLeave($event, node)\"\n (drop)=\"onDrop($event, node)\">\n @if (node.children.length > 0) {\n <i\n class=\"fas toggle-icon\"\n [ngClass]=\"node.expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"\n (click)=\"toggleNode(node, $event)\">\n </i>\n }\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n <div class=\"node-actions\" (click)=\"$event.stopPropagation()\">\n @if (canEdit(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onCreateCollection(node.collection.ID)\" title=\"Add sub-collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n @if (canDelete(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onDeleteCollection(node.collection)\" title=\"Delete\">\n <i class=\"fas fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n\n @if (node.expanded) {\n @for (child of node.children; track child.collection.ID) {\n <ng-container *ngTemplateOutlet=\"recursiveTree; context: { node: child }\"></ng-container>\n }\n }\n </div>\n }\n </div>\n </div>\n\n <ng-template #recursiveTree let-node=\"node\">\n <div class=\"tree-node-wrapper\">\n <div\n class=\"tree-node\"\n [class.selected]=\"IsCollectionSelected(node)\"\n [class.drag-over]=\"dragOverNodeId === node.collection.ID\"\n [class.dragging]=\"IsCollectionDragging(node)\"\n [style.padding-left.px]=\"node.level * 20\"\n [draggable]=\"true\"\n (click)=\"onSelectCollection(node.collection)\"\n (dragstart)=\"onDragStart($event, node)\"\n (dragend)=\"onDragEnd($event)\"\n (dragover)=\"onDragOver($event, node)\"\n (dragleave)=\"onDragLeave($event, node)\"\n (drop)=\"onDrop($event, node)\">\n @if (node.children.length > 0) {\n <i\n class=\"fas toggle-icon\"\n [ngClass]=\"node.expanded ? 'fa-chevron-down' : 'fa-chevron-right'\"\n (click)=\"toggleNode(node, $event)\">\n </i>\n }\n <i class=\"fas fa-folder collection-icon\" [style.color]=\"node.collection.Color || '#0076B6'\"></i>\n <span class=\"collection-name\">{{ node.collection.Name }}</span>\n <div class=\"node-actions\" (click)=\"$event.stopPropagation()\">\n @if (canEdit(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onCreateCollection(node.collection.ID)\" title=\"Add sub-collection\">\n <i class=\"fas fa-plus\"></i>\n </button>\n }\n @if (canDelete(node.collection)) {\n <button class=\"node-action-btn\" (click)=\"onDeleteCollection(node.collection)\" title=\"Delete\">\n <i class=\"fas fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n\n @if (node.expanded) {\n @for (child of node.children; track child.collection.ID) {\n <ng-container *ngTemplateOutlet=\"recursiveTree; context: { node: child }\"></ng-container>\n }\n }\n </div>\n </ng-template>\n `,\n styles: [`\n .collection-tree { display: flex; flex-direction: column; height: 100%; }\n .tree-header { padding: 16px; border-bottom: 1px solid var(--mj-border-default); display: flex; justify-content: space-between; align-items: center; }\n .tree-header h3 { margin: 0; font-size: 16px; }\n .btn-new { padding: 6px 10px; background: var(--mj-brand-primary); color: var(--mj-text-inverse); border: none; border-radius: 4px; cursor: pointer; }\n .btn-new:hover { background: var(--mj-brand-primary-hover); }\n .tree-content { flex: 1; overflow-y: auto; position: relative; }\n .tree-content.drag-over-root { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .tree-node {\n padding: 8px 12px;\n cursor: move;\n display: flex;\n align-items: center;\n gap: 8px;\n position: relative;\n transition: all 0.2s ease;\n border: 2px solid transparent;\n }\n .tree-node:hover { background: var(--mj-bg-surface-sunken); }\n .tree-node.selected { background: var(--mj-brand-accent); }\n .tree-node.dragging {\n opacity: 0.4;\n cursor: grabbing;\n }\n .tree-node.drag-over {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border: 2px dashed var(--mj-brand-primary);\n border-radius: 4px;\n }\n .toggle-icon { font-size: 10px; color: var(--mj-text-disabled); cursor: pointer; width: 12px; }\n .collection-icon { font-size: 14px; }\n .collection-name { flex: 1; font-size: 14px; user-select: none; }\n .node-actions { display: none; gap: 4px; }\n .tree-node:hover .node-actions { display: flex; }\n .node-action-btn { padding: 4px 6px; background: transparent; border: none; cursor: pointer; border-radius: 3px; color: var(--mj-text-muted); }\n .node-action-btn:hover { background: var(--mj-bg-surface-sunken); }\n `]\n})\nexport class CollectionTreeComponent extends BaseAngularComponent implements OnInit {\n @Input() environmentId!: string;\n @Input() currentUser!: UserInfo;\n @Input() selectedCollectionId: string | null = null;\n @Input() userPermissions: Map<string, CollectionPermission> = new Map();\n\n @Output() collectionSelected = new EventEmitter<MJCollectionEntity>();\n @Output() collectionCreated = new EventEmitter<MJCollectionEntity>();\n @Output() collectionDeleted = new EventEmitter<MJCollectionEntity>();\n\n public collections: MJCollectionEntity[] = [];\n public treeNodes: TreeNode[] = [];\n public draggedNode: TreeNode | null = null;\n public dragOverNodeId: string | null = null;\n\n constructor(private permissionService: CollectionPermissionService, private confirmService: MJConfirmService) {\n super();}\n\n ngOnInit() {\n this.permissionService.Provider = this.ProviderToUse;\n this.loadCollections();\n }\n\n private async loadCollections(): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJCollectionEntity>({\n EntityName: 'MJ: Collections',\n ExtraFilter: `EnvironmentID='${this.environmentId}'`,\n OrderBy: 'Sequence ASC, Name ASC',\n ResultType: 'entity_object'\n }, this.currentUser);\n\n if (result.Success) {\n this.collections = result.Results || [];\n this.buildTree();\n }\n } catch (error) {\n console.error('Error loading collections:', error);\n }\n }\n\n private buildTree(): void {\n const rootCollections = this.collections.filter(c => !c.ParentID);\n this.treeNodes = rootCollections.map(c => this.buildNode(c, 0));\n }\n\n private buildNode(collection: MJCollectionEntity, level: number): TreeNode {\n const children = this.collections.filter(c => UUIDsEqual(c.ParentID, collection.ID));\n return {\n collection,\n children: children.map(c => this.buildNode(c, level + 1)),\n expanded: level === 0,\n level\n };\n }\n\n toggleNode(node: TreeNode, event: Event): void {\n event.stopPropagation();\n node.expanded = !node.expanded;\n }\n\n IsCollectionSelected(node: TreeNode): boolean {\n return UUIDsEqual(node.collection.ID, this.selectedCollectionId);\n }\n\n IsCollectionDragging(node: TreeNode): boolean {\n return UUIDsEqual(this.draggedNode?.collection?.ID, node.collection.ID);\n }\n\n onSelectCollection(collection: MJCollectionEntity): void {\n this.selectedCollectionId = collection.ID;\n this.collectionSelected.emit(collection);\n }\n\n async onCreateCollection(parentId: string | null): Promise<void> {\n // Validate permission if creating child collection\n if (parentId) {\n const parentCollection = this.collections.find(c => UUIDsEqual(c.ID, parentId));\n if (parentCollection) {\n // Check if user has Edit permission on parent\n if (parentCollection.OwnerID && !UUIDsEqual(parentCollection.OwnerID, this.currentUser.ID)) {\n const permission = await this.permissionService.checkPermission(\n parentId,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canEdit) {\n alert('You do not have Edit permission to create a sub-collection.');\n return;\n }\n }\n }\n }\n\n const name = prompt('Enter collection name:');\n if (!name) return;\n\n try {\n const md = this.ProviderToUse;\n const collection = await md.GetEntityObject<MJCollectionEntity>('MJ: Collections', this.currentUser);\n\n collection.Name = name;\n collection.EnvironmentID = this.environmentId;\n\n if (parentId) {\n // Child collection - inherit parent's owner and set parent\n const parentCollection = this.collections.find(c => UUIDsEqual(c.ID, parentId));\n collection.ParentID = parentId;\n collection.OwnerID = parentCollection?.OwnerID || this.currentUser.ID;\n } else {\n // Root collection - current user becomes owner\n collection.OwnerID = this.currentUser.ID;\n }\n\n const saved = await collection.Save();\n if (saved) {\n this.collectionCreated.emit(collection);\n await this.loadCollections();\n }\n } catch (error) {\n console.error('Error creating collection:', error);\n alert('Failed to create collection');\n }\n }\n\n async onDeleteCollection(collection: MJCollectionEntity): Promise<void> {\n // Validate Delete permission\n if (collection.OwnerID && !UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n const permission = await this.permissionService.checkPermission(\n collection.ID,\n this.currentUser.ID,\n this.currentUser\n );\n\n if (!permission?.canDelete) {\n alert('You do not have Delete permission for this collection.');\n return;\n }\n }\n\n if (!(await this.confirmService.ConfirmDelete({ title: 'Delete Collection', message: `Delete collection \"${collection.Name}\"?` }))) return;\n\n try {\n const deleted = await collection.Delete();\n if (deleted) {\n this.collectionDeleted.emit(collection);\n await this.loadCollections();\n }\n } catch (error) {\n console.error('Error deleting collection:', error);\n alert('Failed to delete collection');\n }\n }\n\n onDragStart(event: DragEvent, node: TreeNode): void {\n this.draggedNode = node;\n const dragData: DragData = {\n collectionId: node.collection.ID,\n parentId: node.collection.ParentID || null\n };\n event.dataTransfer!.effectAllowed = 'move';\n event.dataTransfer!.setData('application/json', JSON.stringify(dragData));\n\n // Add visual feedback\n (event.target as HTMLElement).style.opacity = '0.4';\n }\n\n onDragEnd(event: DragEvent): void {\n // Clean up visual feedback\n (event.target as HTMLElement).style.opacity = '1';\n this.draggedNode = null;\n this.dragOverNodeId = null;\n }\n\n onDragOver(event: DragEvent, targetNode: TreeNode): void {\n event.preventDefault(); // Required to allow drop\n\n if (!this.draggedNode || UUIDsEqual(this.draggedNode.collection.ID, targetNode.collection.ID)) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n // Check if trying to drop into a descendant\n if (this.isDescendant(targetNode, this.draggedNode)) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n event.dataTransfer!.dropEffect = 'move';\n this.dragOverNodeId = targetNode.collection.ID;\n }\n\n onDragLeave(event: DragEvent, targetNode: TreeNode): void {\n if (this.dragOverNodeId === targetNode.collection.ID) {\n this.dragOverNodeId = null;\n }\n }\n\n async onDrop(event: DragEvent, targetNode: TreeNode): Promise<void> {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.draggedNode) {\n return;\n }\n\n // Don't allow dropping on itself\n if (UUIDsEqual(this.draggedNode.collection.ID, targetNode.collection.ID)) {\n this.dragOverNodeId = null;\n return;\n }\n\n // Check if trying to drop into a descendant\n if (this.isDescendant(targetNode, this.draggedNode)) {\n alert('Cannot move a collection into its own descendant');\n this.dragOverNodeId = null;\n return;\n }\n\n try {\n const collection = this.draggedNode.collection;\n const newParentId = targetNode.collection.ID;\n\n // Update the collection's parent\n collection.ParentID = newParentId;\n\n const saved = await collection.Save();\n if (saved) {\n // Reload the tree to reflect changes\n await this.loadCollections();\n } else {\n alert('Failed to move collection');\n }\n } catch (error) {\n LogError(error);\n alert('Error moving collection');\n } finally {\n this.dragOverNodeId = null;\n }\n }\n\n onDragOverRoot(event: DragEvent): void {\n event.preventDefault();\n\n if (!this.draggedNode) {\n event.dataTransfer!.dropEffect = 'none';\n return;\n }\n\n event.dataTransfer!.dropEffect = 'move';\n this.dragOverNodeId = 'root';\n }\n\n async onDropRoot(event: DragEvent): Promise<void> {\n event.preventDefault();\n event.stopPropagation();\n\n if (!this.draggedNode) {\n return;\n }\n\n try {\n const collection = this.draggedNode.collection;\n\n // Move to root level\n collection.ParentID = null;\n\n const saved = await collection.Save();\n if (saved) {\n await this.loadCollections();\n } else {\n alert('Failed to move collection to root');\n }\n } catch (error) {\n LogError(error);\n alert('Error moving collection to root');\n } finally {\n this.dragOverNodeId = null;\n }\n }\n\n private isDescendant(potentialDescendant: TreeNode, ancestor: TreeNode): boolean {\n if (UUIDsEqual(potentialDescendant.collection.ParentID, ancestor.collection.ID)) {\n return true;\n }\n\n for (const child of ancestor.children) {\n if (this.isDescendant(potentialDescendant, child)) {\n return true;\n }\n }\n\n return false;\n }\n\n // Permission checking methods\n canEdit(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canEdit || false;\n }\n\n canDelete(collection: MJCollectionEntity): boolean {\n // Backwards compatibility: treat null OwnerID as owned by current user\n if (!collection.OwnerID || UUIDsEqual(collection.OwnerID, this.currentUser.ID)) {\n return true;\n }\n\n // Check permission record\n const permission = this.userPermissions.get(collection.ID);\n return permission?.canDelete || false;\n }\n\n canCreateAtRoot(): boolean {\n // Anyone can create at root level\n return true;\n }\n}"]}
|
|
@@ -50,7 +50,7 @@ function CollectionViewComponent_Conditional_18_Template(rf, ctx) { if (rf & 1)
|
|
|
50
50
|
i0.ɵɵelementStart(0, "div", 19);
|
|
51
51
|
i0.ɵɵlistener("click", function CollectionViewComponent_Conditional_18_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseArtifactViewer()); });
|
|
52
52
|
i0.ɵɵelementStart(1, "div", 20);
|
|
53
|
-
i0.ɵɵlistener("click", function CollectionViewComponent_Conditional_18_Template_div_click_1_listener($event) {
|
|
53
|
+
i0.ɵɵlistener("click", function CollectionViewComponent_Conditional_18_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
54
54
|
i0.ɵɵelementStart(2, "mj-artifact-viewer-panel", 21);
|
|
55
55
|
i0.ɵɵlistener("closed", function CollectionViewComponent_Conditional_18_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseArtifactViewer()); });
|
|
56
56
|
i0.ɵɵelementEnd()()();
|