@memberjunction/ng-dashboards 5.4.1 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/agents/agent-configuration.component.js +4 -4
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +5 -4
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +3 -3
- package/dist/AI/components/models/model-management.component.js.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +8 -7
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/system/system-configuration.component.js +4 -4
- package/dist/AI/components/system/system-configuration.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -2
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +2 -2
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.d.ts.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +4 -3
- package/dist/APIKeys/api-scopes-panel.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +3 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-action-panel.component.js +3 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.d.ts.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +3 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts +6 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +19 -6
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts +4 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +13 -4
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +13 -9
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +11 -11
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +3 -3
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +13 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +11 -11
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +4 -3
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +4 -3
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +11 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +140 -108
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +4 -1
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +9 -8
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +2 -2
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Home/home-application.js +2 -2
- package/dist/Home/home-application.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +3 -3
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.d.ts +1 -0
- package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +17 -14
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.d.ts +1 -0
- package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +15 -12
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +3 -2
- package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.d.ts.map +1 -1
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +8 -7
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +22 -22
- package/dist/MCP/mcp-dashboard.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts +2 -0
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +14 -10
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js +2 -1
- package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts +1 -0
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +22 -18
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts +1 -0
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +14 -10
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/VersionHistory/components/diff-resource.component.js +6 -6
- package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/package.json +38 -38
|
@@ -10,7 +10,7 @@ import { trigger, transition, style, animate } from '@angular/animations';
|
|
|
10
10
|
import { Subject } from 'rxjs';
|
|
11
11
|
import { takeUntil, debounceTime, distinctUntilChanged, filter } from 'rxjs/operators';
|
|
12
12
|
import { BaseDashboard } from '@memberjunction/ng-shared';
|
|
13
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
13
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
14
14
|
import { Metadata, RunView, EntityFieldTSType } from '@memberjunction/core';
|
|
15
15
|
// CompositeKey is used via buildCompositeKey from ng-entity-viewer
|
|
16
16
|
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
@@ -174,9 +174,9 @@ function DataExplorerDashboardComponent_Conditional_7_Template(rf, ctx) { if (rf
|
|
|
174
174
|
i0.ɵɵtextInterpolate1("", ctx_r1.entities.length, " entities available");
|
|
175
175
|
} }
|
|
176
176
|
function DataExplorerDashboardComponent_Conditional_9_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
177
|
-
const
|
|
177
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
178
178
|
i0.ɵɵelementStart(0, "button", 41);
|
|
179
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_9_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
179
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_9_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearRecordFilter()); });
|
|
180
180
|
i0.ɵɵelement(1, "i", 42);
|
|
181
181
|
i0.ɵɵelementEnd();
|
|
182
182
|
} }
|
|
@@ -185,21 +185,21 @@ function DataExplorerDashboardComponent_Conditional_9_Template(rf, ctx) { if (rf
|
|
|
185
185
|
i0.ɵɵelementStart(0, "div", 9);
|
|
186
186
|
i0.ɵɵelement(1, "i", 38);
|
|
187
187
|
i0.ɵɵelementStart(2, "input", 39, 0);
|
|
188
|
-
i0.ɵɵlistener("
|
|
188
|
+
i0.ɵɵlistener("input", function DataExplorerDashboardComponent_Conditional_9_Template_input_input_2_listener() { i0.ɵɵrestoreView(_r9); const filterInput_r10 = i0.ɵɵreference(3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFilterInputChanged(filterInput_r10.value)); });
|
|
189
189
|
i0.ɵɵelementEnd();
|
|
190
190
|
i0.ɵɵconditionalCreate(4, DataExplorerDashboardComponent_Conditional_9_Conditional_4_Template, 2, 0, "button", 40);
|
|
191
191
|
i0.ɵɵelementEnd();
|
|
192
192
|
} if (rf & 2) {
|
|
193
193
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
194
194
|
i0.ɵɵadvance(2);
|
|
195
|
-
i0.ɵɵproperty("
|
|
195
|
+
i0.ɵɵproperty("value", ctx_r1.liveFilterText);
|
|
196
196
|
i0.ɵɵadvance(2);
|
|
197
|
-
i0.ɵɵconditional(ctx_r1.
|
|
197
|
+
i0.ɵɵconditional(ctx_r1.liveFilterText ? 4 : -1);
|
|
198
198
|
} }
|
|
199
199
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
200
|
-
const
|
|
200
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
201
201
|
i0.ɵɵelementStart(0, "button", 49);
|
|
202
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
202
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onViewModeChanged("timeline")); });
|
|
203
203
|
i0.ɵɵelement(1, "i", 50);
|
|
204
204
|
i0.ɵɵelementEnd();
|
|
205
205
|
} if (rf & 2) {
|
|
@@ -207,9 +207,9 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_5_Template(rf
|
|
|
207
207
|
i0.ɵɵclassProp("active", ctx_r1.state.viewMode === "timeline");
|
|
208
208
|
} }
|
|
209
209
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
210
|
-
const
|
|
210
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
211
211
|
i0.ɵɵelementStart(0, "div", 62);
|
|
212
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(
|
|
212
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.closeDateFieldDropdown()); });
|
|
213
213
|
i0.ɵɵelementEnd();
|
|
214
214
|
} }
|
|
215
215
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -222,9 +222,9 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional
|
|
|
222
222
|
i0.ɵɵelement(0, "i", 68);
|
|
223
223
|
} }
|
|
224
224
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
225
|
-
const
|
|
225
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
226
226
|
i0.ɵɵelementStart(0, "div", 65);
|
|
227
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_For_2_Template_div_click_0_listener() { const
|
|
227
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_For_2_Template_div_click_0_listener() { const field_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.setTimelineDateField(field_r17.name)); });
|
|
228
228
|
i0.ɵɵelement(1, "i", 66);
|
|
229
229
|
i0.ɵɵelementStart(2, "span", 67);
|
|
230
230
|
i0.ɵɵtext(3);
|
|
@@ -232,13 +232,13 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional
|
|
|
232
232
|
i0.ɵɵconditionalCreate(4, DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_For_2_Conditional_4_Template, 1, 0, "i", 68);
|
|
233
233
|
i0.ɵɵelementEnd();
|
|
234
234
|
} if (rf & 2) {
|
|
235
|
-
const
|
|
235
|
+
const field_r17 = ctx.$implicit;
|
|
236
236
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
237
|
-
i0.ɵɵclassProp("selected",
|
|
237
|
+
i0.ɵɵclassProp("selected", field_r17.name === ctx_r1.effectiveTimelineDateField);
|
|
238
238
|
i0.ɵɵadvance(3);
|
|
239
|
-
i0.ɵɵtextInterpolate(
|
|
239
|
+
i0.ɵɵtextInterpolate(field_r17.displayName);
|
|
240
240
|
i0.ɵɵadvance();
|
|
241
|
-
i0.ɵɵconditional(
|
|
241
|
+
i0.ɵɵconditional(field_r17.name === ctx_r1.effectiveTimelineDateField ? 4 : -1);
|
|
242
242
|
} }
|
|
243
243
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
244
244
|
i0.ɵɵelementStart(0, "div", 58);
|
|
@@ -250,11 +250,11 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional
|
|
|
250
250
|
i0.ɵɵrepeater(ctx_r1.availableDateFields);
|
|
251
251
|
} }
|
|
252
252
|
function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
253
|
-
const
|
|
253
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
254
254
|
i0.ɵɵelementStart(0, "div", 51);
|
|
255
255
|
i0.ɵɵconditionalCreate(1, DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_1_Template, 1, 0, "div", 52);
|
|
256
256
|
i0.ɵɵelementStart(2, "div", 53)(3, "button", 54);
|
|
257
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(
|
|
257
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleDateFieldDropdown()); });
|
|
258
258
|
i0.ɵɵelement(4, "i", 55);
|
|
259
259
|
i0.ɵɵelementStart(5, "span", 56);
|
|
260
260
|
i0.ɵɵtext(6);
|
|
@@ -264,11 +264,11 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template(rf
|
|
|
264
264
|
i0.ɵɵconditionalCreate(8, DataExplorerDashboardComponent_Conditional_11_Conditional_6_Conditional_8_Template, 3, 0, "div", 58);
|
|
265
265
|
i0.ɵɵelementEnd()();
|
|
266
266
|
i0.ɵɵelementStart(9, "div", 59)(10, "button", 60);
|
|
267
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_10_listener() { i0.ɵɵrestoreView(
|
|
267
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleTimelineOrientation()); });
|
|
268
268
|
i0.ɵɵelement(11, "i");
|
|
269
269
|
i0.ɵɵelementEnd()();
|
|
270
270
|
i0.ɵɵelementStart(12, "div", 61)(13, "button", 60);
|
|
271
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_13_listener() { i0.ɵɵrestoreView(
|
|
271
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleTimelineSortOrder()); });
|
|
272
272
|
i0.ɵɵelement(14, "i");
|
|
273
273
|
i0.ɵɵelementEnd()();
|
|
274
274
|
} if (rf & 2) {
|
|
@@ -294,13 +294,13 @@ function DataExplorerDashboardComponent_Conditional_11_Conditional_6_Template(rf
|
|
|
294
294
|
i0.ɵɵclassMap(ctx_r1.state.timelineSortOrder === "desc" ? "fa-solid fa-arrow-down-wide-short" : "fa-solid fa-arrow-up-wide-short");
|
|
295
295
|
} }
|
|
296
296
|
function DataExplorerDashboardComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
297
|
-
const
|
|
297
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
298
298
|
i0.ɵɵelementStart(0, "div", 43)(1, "button", 44);
|
|
299
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Template_button_click_1_listener() { i0.ɵɵrestoreView(
|
|
299
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onViewModeChanged("grid")); });
|
|
300
300
|
i0.ɵɵelement(2, "i", 45);
|
|
301
301
|
i0.ɵɵelementEnd();
|
|
302
302
|
i0.ɵɵelementStart(3, "button", 46);
|
|
303
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Template_button_click_3_listener() { i0.ɵɵrestoreView(
|
|
303
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_11_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onViewModeChanged("cards")); });
|
|
304
304
|
i0.ɵɵelement(4, "i", 47);
|
|
305
305
|
i0.ɵɵelementEnd();
|
|
306
306
|
i0.ɵɵconditionalCreate(5, DataExplorerDashboardComponent_Conditional_11_Conditional_5_Template, 2, 2, "button", 48);
|
|
@@ -327,9 +327,9 @@ function DataExplorerDashboardComponent_Conditional_12_Conditional_2_Template(rf
|
|
|
327
327
|
i0.ɵɵtextInterpolate(ctx_r1.recentRecords.length + ctx_r1.favoriteRecords.length);
|
|
328
328
|
} }
|
|
329
329
|
function DataExplorerDashboardComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
330
|
-
const
|
|
330
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
331
331
|
i0.ɵɵelementStart(0, "button", 69);
|
|
332
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
332
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleQuickAccessPanel()); });
|
|
333
333
|
i0.ɵɵelement(1, "i", 70);
|
|
334
334
|
i0.ɵɵconditionalCreate(2, DataExplorerDashboardComponent_Conditional_12_Conditional_2_Template, 2, 1, "span", 71);
|
|
335
335
|
i0.ɵɵelementEnd();
|
|
@@ -345,9 +345,9 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_1_Template(rf
|
|
|
345
345
|
i0.ɵɵelementEnd();
|
|
346
346
|
} }
|
|
347
347
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
-
const
|
|
348
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
349
349
|
i0.ɵɵelementStart(0, "button", 105);
|
|
350
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(
|
|
350
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.entityFilterText = ""); });
|
|
351
351
|
i0.ɵɵelement(1, "i", 42);
|
|
352
352
|
i0.ɵɵelementEnd();
|
|
353
353
|
} }
|
|
@@ -367,14 +367,14 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
367
367
|
i0.ɵɵtext(1);
|
|
368
368
|
i0.ɵɵelementEnd();
|
|
369
369
|
} if (rf & 2) {
|
|
370
|
-
const
|
|
370
|
+
const entity_r22 = i0.ɵɵnextContext().$implicit;
|
|
371
371
|
i0.ɵɵadvance();
|
|
372
|
-
i0.ɵɵtextInterpolate(
|
|
372
|
+
i0.ɵɵtextInterpolate(entity_r22.Description);
|
|
373
373
|
} }
|
|
374
374
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
375
|
-
const
|
|
375
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
376
376
|
i0.ɵɵelementStart(0, "div", 107);
|
|
377
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Template_div_click_0_listener() { const
|
|
377
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Template_div_click_0_listener() { const entity_r22 = i0.ɵɵrestoreView(_r21).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onEntitySelected(entity_r22)); });
|
|
378
378
|
i0.ɵɵelementStart(1, "div", 108);
|
|
379
379
|
i0.ɵɵelement(2, "i");
|
|
380
380
|
i0.ɵɵelementEnd();
|
|
@@ -384,24 +384,24 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
384
384
|
i0.ɵɵconditionalCreate(6, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Conditional_6_Template, 2, 1, "span", 111);
|
|
385
385
|
i0.ɵɵelementEnd();
|
|
386
386
|
i0.ɵɵelementStart(7, "button", 112);
|
|
387
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Template_button_click_7_listener($event) { const
|
|
387
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_For_2_Template_button_click_7_listener($event) { const entity_r22 = i0.ɵɵrestoreView(_r21).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleEntityFavorite(entity_r22, $event)); });
|
|
388
388
|
i0.ɵɵelement(8, "i");
|
|
389
389
|
i0.ɵɵelementEnd()();
|
|
390
390
|
} if (rf & 2) {
|
|
391
|
-
const
|
|
391
|
+
const entity_r22 = ctx.$implicit;
|
|
392
392
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
393
|
-
i0.ɵɵproperty("title",
|
|
393
|
+
i0.ɵɵproperty("title", entity_r22.Description || entity_r22.DisplayNameOrName);
|
|
394
394
|
i0.ɵɵadvance(2);
|
|
395
|
-
i0.ɵɵclassMap(ctx_r1.getEntityIcon(
|
|
395
|
+
i0.ɵɵclassMap(ctx_r1.getEntityIcon(entity_r22));
|
|
396
396
|
i0.ɵɵadvance(3);
|
|
397
|
-
i0.ɵɵtextInterpolate(
|
|
397
|
+
i0.ɵɵtextInterpolate(entity_r22.DisplayNameOrName);
|
|
398
398
|
i0.ɵɵadvance();
|
|
399
|
-
i0.ɵɵconditional(
|
|
399
|
+
i0.ɵɵconditional(entity_r22.Description ? 6 : -1);
|
|
400
400
|
i0.ɵɵadvance();
|
|
401
|
-
i0.ɵɵclassProp("favorited", ctx_r1.isEntityFavorited(
|
|
402
|
-
i0.ɵɵproperty("title", ctx_r1.isEntityFavorited(
|
|
401
|
+
i0.ɵɵclassProp("favorited", ctx_r1.isEntityFavorited(entity_r22));
|
|
402
|
+
i0.ɵɵproperty("title", ctx_r1.isEntityFavorited(entity_r22) ? "Remove from favorites" : "Add to favorites");
|
|
403
403
|
i0.ɵɵadvance();
|
|
404
|
-
i0.ɵɵclassMap(ctx_r1.isEntityFavorited(
|
|
404
|
+
i0.ɵɵclassMap(ctx_r1.isEntityFavorited(entity_r22) ? "fa-solid fa-star" : "fa-regular fa-star");
|
|
405
405
|
} }
|
|
406
406
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
407
407
|
i0.ɵɵelementStart(0, "div", 87);
|
|
@@ -417,14 +417,14 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
417
417
|
i0.ɵɵtext(1);
|
|
418
418
|
i0.ɵɵelementEnd();
|
|
419
419
|
} if (rf & 2) {
|
|
420
|
-
const
|
|
420
|
+
const entity_r26 = i0.ɵɵnextContext().$implicit;
|
|
421
421
|
i0.ɵɵadvance();
|
|
422
|
-
i0.ɵɵtextInterpolate(
|
|
422
|
+
i0.ɵɵtextInterpolate(entity_r26.Description);
|
|
423
423
|
} }
|
|
424
424
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
425
|
-
const
|
|
425
|
+
const _r25 = i0.ɵɵgetCurrentView();
|
|
426
426
|
i0.ɵɵelementStart(0, "div", 107);
|
|
427
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template_div_click_0_listener() { const
|
|
427
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template_div_click_0_listener() { const entity_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ctx_r1 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r1.onEntitySelected(entity_r26)); });
|
|
428
428
|
i0.ɵɵelementStart(1, "div", 108);
|
|
429
429
|
i0.ɵɵelement(2, "i");
|
|
430
430
|
i0.ɵɵelementEnd();
|
|
@@ -434,38 +434,38 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
434
434
|
i0.ɵɵconditionalCreate(6, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Conditional_6_Template, 2, 1, "span", 111);
|
|
435
435
|
i0.ɵɵelementEnd();
|
|
436
436
|
i0.ɵɵelementStart(7, "button", 112);
|
|
437
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template_button_click_7_listener($event) { const
|
|
437
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template_button_click_7_listener($event) { const entity_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ctx_r1 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r1.toggleEntityFavorite(entity_r26, $event)); });
|
|
438
438
|
i0.ɵɵelement(8, "i");
|
|
439
439
|
i0.ɵɵelementEnd()();
|
|
440
440
|
} if (rf & 2) {
|
|
441
|
-
const
|
|
441
|
+
const entity_r26 = ctx.$implicit;
|
|
442
442
|
const ctx_r1 = i0.ɵɵnextContext(6);
|
|
443
|
-
i0.ɵɵproperty("title",
|
|
443
|
+
i0.ɵɵproperty("title", entity_r26.Description || entity_r26.DisplayNameOrName);
|
|
444
444
|
i0.ɵɵadvance(2);
|
|
445
|
-
i0.ɵɵclassMap(ctx_r1.getEntityIcon(
|
|
445
|
+
i0.ɵɵclassMap(ctx_r1.getEntityIcon(entity_r26));
|
|
446
446
|
i0.ɵɵadvance(3);
|
|
447
|
-
i0.ɵɵtextInterpolate(
|
|
447
|
+
i0.ɵɵtextInterpolate(entity_r26.DisplayNameOrName);
|
|
448
448
|
i0.ɵɵadvance();
|
|
449
|
-
i0.ɵɵconditional(
|
|
449
|
+
i0.ɵɵconditional(entity_r26.Description ? 6 : -1);
|
|
450
450
|
i0.ɵɵadvance();
|
|
451
|
-
i0.ɵɵclassProp("favorited", ctx_r1.isEntityFavorited(
|
|
452
|
-
i0.ɵɵproperty("title", ctx_r1.isEntityFavorited(
|
|
451
|
+
i0.ɵɵclassProp("favorited", ctx_r1.isEntityFavorited(entity_r26));
|
|
452
|
+
i0.ɵɵproperty("title", ctx_r1.isEntityFavorited(entity_r26) ? "Remove from favorites" : "Add to favorites");
|
|
453
453
|
i0.ɵɵadvance();
|
|
454
|
-
i0.ɵɵclassMap(ctx_r1.isEntityFavorited(
|
|
454
|
+
i0.ɵɵclassMap(ctx_r1.isEntityFavorited(entity_r26) ? "fa-solid fa-star" : "fa-regular fa-star");
|
|
455
455
|
} }
|
|
456
456
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
457
457
|
i0.ɵɵelementStart(0, "div", 119)(1, "div", 87);
|
|
458
458
|
i0.ɵɵrepeaterCreate(2, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_For_3_Template, 9, 10, "div", 106, _forTrack3);
|
|
459
459
|
i0.ɵɵelementEnd()();
|
|
460
460
|
} if (rf & 2) {
|
|
461
|
-
const
|
|
461
|
+
const group_r24 = i0.ɵɵnextContext().$implicit;
|
|
462
462
|
i0.ɵɵadvance(2);
|
|
463
|
-
i0.ɵɵrepeater(
|
|
463
|
+
i0.ɵɵrepeater(group_r24.entities);
|
|
464
464
|
} }
|
|
465
465
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
466
|
-
const
|
|
466
|
+
const _r23 = i0.ɵɵgetCurrentView();
|
|
467
467
|
i0.ɵɵelementStart(0, "div", 113)(1, "div", 114);
|
|
468
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Template_div_click_1_listener() { const
|
|
468
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Template_div_click_1_listener() { const group_r24 = i0.ɵɵrestoreView(_r23).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.toggleAppGroup(group_r24.applicationId)); });
|
|
469
469
|
i0.ɵɵelementStart(2, "div", 115);
|
|
470
470
|
i0.ɵɵelement(3, "i");
|
|
471
471
|
i0.ɵɵelementEnd();
|
|
@@ -480,19 +480,19 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
480
480
|
i0.ɵɵconditionalCreate(9, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Conditional_9_Template, 4, 0, "div", 119);
|
|
481
481
|
i0.ɵɵelementEnd();
|
|
482
482
|
} if (rf & 2) {
|
|
483
|
-
const
|
|
483
|
+
const group_r24 = ctx.$implicit;
|
|
484
484
|
i0.ɵɵadvance(2);
|
|
485
|
-
i0.ɵɵstyleProp("background",
|
|
485
|
+
i0.ɵɵstyleProp("background", group_r24.applicationColor ? group_r24.applicationColor + "15" : null)("color", group_r24.applicationColor || null);
|
|
486
486
|
i0.ɵɵadvance();
|
|
487
|
-
i0.ɵɵclassMap(
|
|
487
|
+
i0.ɵɵclassMap(group_r24.applicationIcon || "fa-solid fa-folder");
|
|
488
488
|
i0.ɵɵadvance(2);
|
|
489
|
-
i0.ɵɵtextInterpolate(
|
|
489
|
+
i0.ɵɵtextInterpolate(group_r24.applicationName);
|
|
490
490
|
i0.ɵɵadvance(2);
|
|
491
|
-
i0.ɵɵtextInterpolate(
|
|
491
|
+
i0.ɵɵtextInterpolate(group_r24.entities.length);
|
|
492
492
|
i0.ɵɵadvance();
|
|
493
|
-
i0.ɵɵclassProp("expanded",
|
|
493
|
+
i0.ɵɵclassProp("expanded", group_r24.isExpanded);
|
|
494
494
|
i0.ɵɵadvance();
|
|
495
|
-
i0.ɵɵconditional(
|
|
495
|
+
i0.ɵɵconditional(group_r24.isExpanded ? 9 : -1);
|
|
496
496
|
} }
|
|
497
497
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
498
498
|
i0.ɵɵrepeaterCreate(0, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_20_For_1_Template, 10, 11, "div", 113, _forTrack5);
|
|
@@ -522,9 +522,9 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
522
522
|
i0.ɵɵelementEnd()();
|
|
523
523
|
} }
|
|
524
524
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_40_Template(rf, ctx) { if (rf & 1) {
|
|
525
|
-
const
|
|
525
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
526
526
|
i0.ɵɵelementStart(0, "div", 122);
|
|
527
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_40_Template_div_click_0_listener() { const
|
|
527
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_40_Template_div_click_0_listener() { const record_r28 = i0.ɵɵrestoreView(_r27).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onRecentRecordClick(record_r28)); });
|
|
528
528
|
i0.ɵɵelementStart(1, "div", 123);
|
|
529
529
|
i0.ɵɵelement(2, "i");
|
|
530
530
|
i0.ɵɵelementEnd();
|
|
@@ -538,16 +538,16 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_40_Temp
|
|
|
538
538
|
i0.ɵɵtext(9);
|
|
539
539
|
i0.ɵɵelementEnd()();
|
|
540
540
|
} if (rf & 2) {
|
|
541
|
-
const
|
|
541
|
+
const record_r28 = ctx.$implicit;
|
|
542
542
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
543
543
|
i0.ɵɵadvance(2);
|
|
544
|
-
i0.ɵɵclassMap(ctx_r1.getEntityIconById(
|
|
544
|
+
i0.ɵɵclassMap(ctx_r1.getEntityIconById(record_r28.entityId));
|
|
545
545
|
i0.ɵɵadvance(3);
|
|
546
|
-
i0.ɵɵtextInterpolate(
|
|
546
|
+
i0.ɵɵtextInterpolate(record_r28.recordName || record_r28.recordId);
|
|
547
547
|
i0.ɵɵadvance(2);
|
|
548
|
-
i0.ɵɵtextInterpolate(
|
|
548
|
+
i0.ɵɵtextInterpolate(record_r28.entityName);
|
|
549
549
|
i0.ɵɵadvance(2);
|
|
550
|
-
i0.ɵɵtextInterpolate(ctx_r1.formatRelativeTime(
|
|
550
|
+
i0.ɵɵtextInterpolate(ctx_r1.formatRelativeTime(record_r28.latestAt));
|
|
551
551
|
} }
|
|
552
552
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_41_Template(rf, ctx) { if (rf & 1) {
|
|
553
553
|
i0.ɵɵelementStart(0, "div", 102);
|
|
@@ -555,9 +555,9 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
555
555
|
i0.ɵɵelementEnd();
|
|
556
556
|
} }
|
|
557
557
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_52_Template(rf, ctx) { if (rf & 1) {
|
|
558
|
-
const
|
|
558
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
559
559
|
i0.ɵɵelementStart(0, "div", 122);
|
|
560
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_52_Template_div_click_0_listener() { const
|
|
560
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_52_Template_div_click_0_listener() { const entity_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onEntitySelected(entity_r30)); });
|
|
561
561
|
i0.ɵɵelementStart(1, "div", 123);
|
|
562
562
|
i0.ɵɵelement(2, "i");
|
|
563
563
|
i0.ɵɵelementEnd();
|
|
@@ -565,12 +565,12 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_52_Temp
|
|
|
565
565
|
i0.ɵɵtext(5);
|
|
566
566
|
i0.ɵɵelementEnd()()();
|
|
567
567
|
} if (rf & 2) {
|
|
568
|
-
const
|
|
568
|
+
const entity_r30 = ctx.$implicit;
|
|
569
569
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
570
570
|
i0.ɵɵadvance(2);
|
|
571
|
-
i0.ɵɵclassMap(ctx_r1.getEntityIcon(
|
|
571
|
+
i0.ɵɵclassMap(ctx_r1.getEntityIcon(entity_r30));
|
|
572
572
|
i0.ɵɵadvance(3);
|
|
573
|
-
i0.ɵɵtextInterpolate(
|
|
573
|
+
i0.ɵɵtextInterpolate(entity_r30.DisplayNameOrName);
|
|
574
574
|
} }
|
|
575
575
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_53_Template(rf, ctx) { if (rf & 1) {
|
|
576
576
|
i0.ɵɵelementStart(0, "div", 102);
|
|
@@ -578,9 +578,9 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
578
578
|
i0.ɵɵelementEnd();
|
|
579
579
|
} }
|
|
580
580
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_64_Template(rf, ctx) { if (rf & 1) {
|
|
581
|
-
const
|
|
581
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
582
582
|
i0.ɵɵelementStart(0, "div", 122);
|
|
583
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_64_Template_div_click_0_listener() { const
|
|
583
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_64_Template_div_click_0_listener() { const record_r32 = i0.ɵɵrestoreView(_r31).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onFavoriteRecordClick(record_r32)); });
|
|
584
584
|
i0.ɵɵelementStart(1, "div", 123);
|
|
585
585
|
i0.ɵɵelement(2, "i");
|
|
586
586
|
i0.ɵɵelementEnd();
|
|
@@ -591,14 +591,14 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_For_64_Temp
|
|
|
591
591
|
i0.ɵɵtext(7);
|
|
592
592
|
i0.ɵɵelementEnd()()();
|
|
593
593
|
} if (rf & 2) {
|
|
594
|
-
const
|
|
594
|
+
const record_r32 = ctx.$implicit;
|
|
595
595
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
596
596
|
i0.ɵɵadvance(2);
|
|
597
|
-
i0.ɵɵclassMap(ctx_r1.getEntityIconById(
|
|
597
|
+
i0.ɵɵclassMap(ctx_r1.getEntityIconById(record_r32.entityId));
|
|
598
598
|
i0.ɵɵadvance(3);
|
|
599
|
-
i0.ɵɵtextInterpolate(
|
|
599
|
+
i0.ɵɵtextInterpolate(record_r32.recordName || record_r32.recordId);
|
|
600
600
|
i0.ɵɵadvance(2);
|
|
601
|
-
i0.ɵɵtextInterpolate(
|
|
601
|
+
i0.ɵɵtextInterpolate(record_r32.entityName);
|
|
602
602
|
} }
|
|
603
603
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_65_Template(rf, ctx) { if (rf & 1) {
|
|
604
604
|
i0.ɵɵelementStart(0, "div", 102);
|
|
@@ -606,11 +606,11 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional
|
|
|
606
606
|
i0.ɵɵelementEnd();
|
|
607
607
|
} }
|
|
608
608
|
function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
609
|
-
const
|
|
609
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
610
610
|
i0.ɵɵelementStart(0, "div", 74)(1, "div", 75)(2, "div", 76);
|
|
611
611
|
i0.ɵɵelement(3, "i", 77);
|
|
612
612
|
i0.ɵɵelementStart(4, "input", 78, 0);
|
|
613
|
-
i0.ɵɵtwoWayListener("ngModelChange", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(
|
|
613
|
+
i0.ɵɵtwoWayListener("ngModelChange", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.entityFilterText, $event) || (ctx_r1.entityFilterText = $event); return i0.ɵɵresetView($event); });
|
|
614
614
|
i0.ɵɵelementEnd();
|
|
615
615
|
i0.ɵɵconditionalCreate(6, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_6_Template, 2, 0, "button", 79)(7, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_7_Template, 2, 0, "span", 80);
|
|
616
616
|
i0.ɵɵelementEnd();
|
|
@@ -619,11 +619,11 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template(rf
|
|
|
619
619
|
i0.ɵɵconditionalCreate(11, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_11_Template, 1, 1);
|
|
620
620
|
i0.ɵɵelementEnd();
|
|
621
621
|
i0.ɵɵelementStart(12, "div", 83)(13, "button", 84);
|
|
622
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_13_listener() { i0.ɵɵrestoreView(
|
|
622
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setHomeViewMode("all")); });
|
|
623
623
|
i0.ɵɵtext(14, " All Entities ");
|
|
624
624
|
i0.ɵɵelementEnd();
|
|
625
625
|
i0.ɵɵelementStart(15, "button", 84);
|
|
626
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_15_listener() { i0.ɵɵrestoreView(
|
|
626
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setHomeViewMode("favorites")); });
|
|
627
627
|
i0.ɵɵelement(16, "i", 85);
|
|
628
628
|
i0.ɵɵtext(17, " My Favorites ");
|
|
629
629
|
i0.ɵɵelementEnd()()()();
|
|
@@ -636,11 +636,11 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template(rf
|
|
|
636
636
|
i0.ɵɵtext(26, "Quick Access");
|
|
637
637
|
i0.ɵɵelementEnd();
|
|
638
638
|
i0.ɵɵelementStart(27, "button", 92);
|
|
639
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_27_listener() { i0.ɵɵrestoreView(
|
|
639
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleQuickAccessPanel()); });
|
|
640
640
|
i0.ɵɵelement(28, "i", 93);
|
|
641
641
|
i0.ɵɵelementEnd()();
|
|
642
642
|
i0.ɵɵelementStart(29, "div", 94)(30, "div", 95)(31, "div", 96);
|
|
643
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_31_listener() { i0.ɵɵrestoreView(
|
|
643
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_31_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleQuickAccessSection("recentRecords")); });
|
|
644
644
|
i0.ɵɵelement(32, "i", 97);
|
|
645
645
|
i0.ɵɵelementStart(33, "span");
|
|
646
646
|
i0.ɵɵtext(34, "Recent Records");
|
|
@@ -655,7 +655,7 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template(rf
|
|
|
655
655
|
i0.ɵɵconditionalCreate(41, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_41_Template, 2, 0, "div", 102);
|
|
656
656
|
i0.ɵɵelementEnd()();
|
|
657
657
|
i0.ɵɵelementStart(42, "div", 95)(43, "div", 96);
|
|
658
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_43_listener() { i0.ɵɵrestoreView(
|
|
658
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_43_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleQuickAccessSection("recentEntities")); });
|
|
659
659
|
i0.ɵɵelement(44, "i", 103);
|
|
660
660
|
i0.ɵɵelementStart(45, "span");
|
|
661
661
|
i0.ɵɵtext(46, "Recent Entities");
|
|
@@ -670,7 +670,7 @@ function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template(rf
|
|
|
670
670
|
i0.ɵɵconditionalCreate(53, DataExplorerDashboardComponent_Conditional_14_Conditional_2_Conditional_53_Template, 2, 0, "div", 102);
|
|
671
671
|
i0.ɵɵelementEnd()();
|
|
672
672
|
i0.ɵɵelementStart(54, "div", 95)(55, "div", 96);
|
|
673
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_55_listener() { i0.ɵɵrestoreView(
|
|
673
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_14_Conditional_2_Template_div_click_55_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleQuickAccessSection("favoriteRecords")); });
|
|
674
674
|
i0.ɵɵelement(56, "i", 104);
|
|
675
675
|
i0.ɵɵelementStart(57, "span");
|
|
676
676
|
i0.ɵɵtext(58, "Favorite Records");
|
|
@@ -742,24 +742,24 @@ function DataExplorerDashboardComponent_Conditional_14_Template(rf, ctx) { if (r
|
|
|
742
742
|
i0.ɵɵconditional(ctx_r1.isLoadingEntities ? 1 : 2);
|
|
743
743
|
} }
|
|
744
744
|
function DataExplorerDashboardComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
745
|
-
const
|
|
745
|
+
const _r33 = i0.ɵɵgetCurrentView();
|
|
746
746
|
i0.ɵɵelementStart(0, "mj-entity-viewer", 128, 1);
|
|
747
|
-
i0.ɵɵlistener("viewModeChange", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_viewModeChange_0_listener($event) { i0.ɵɵrestoreView(
|
|
747
|
+
i0.ɵɵlistener("viewModeChange", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_viewModeChange_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onViewModeChanged($event)); })("filterTextChange", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_filterTextChange_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFilterTextChanged($event)); })("recordSelected", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_recordSelected_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onViewerRecordSelected($event)); })("recordOpened", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_recordOpened_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onViewerRecordOpened($event)); })("dataLoaded", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_dataLoaded_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDataLoaded($event)); })("filteredCountChanged", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_filteredCountChanged_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFilteredCountChanged($event)); })("gridStateChanged", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_gridStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onGridStateChanged($event)); })("selectionChanged", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_selectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onSelectionChanged($event)); })("addToListRequested", function DataExplorerDashboardComponent_Conditional_15_Template_mj_entity_viewer_addToListRequested_0_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAddToListRequested($event)); });
|
|
748
748
|
i0.ɵɵelementEnd();
|
|
749
749
|
} if (rf & 2) {
|
|
750
750
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
751
751
|
i0.ɵɵproperty("entity", ctx_r1.selectedEntity)("viewEntity", ctx_r1.selectedViewEntity)("viewMode", ctx_r1.state.viewMode)("filterText", ctx_r1.debouncedFilterText)("selectedRecordId", ctx_r1.state.selectedRecordId)("config", ctx_r1.viewerConfig)("gridState", ctx_r1.currentGridState)("timelineConfig", ctx_r1.currentTimelineConfig)("gridSelectionMode", "checkbox")("showGridToolbar", false)("showAddToListButton", false);
|
|
752
752
|
} }
|
|
753
753
|
function DataExplorerDashboardComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
754
|
-
const
|
|
754
|
+
const _r34 = i0.ɵɵgetCurrentView();
|
|
755
755
|
i0.ɵɵelementStart(0, "div", 129)(1, "div", 130)(2, "button", 131);
|
|
756
|
-
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_16_Template_button_click_2_listener() { i0.ɵɵrestoreView(
|
|
756
|
+
i0.ɵɵlistener("click", function DataExplorerDashboardComponent_Conditional_16_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openListManagementDialog()); });
|
|
757
757
|
i0.ɵɵelement(3, "i", 35);
|
|
758
758
|
i0.ɵɵelementStart(4, "span");
|
|
759
759
|
i0.ɵɵtext(5, "Add to List");
|
|
760
760
|
i0.ɵɵelementEnd()()();
|
|
761
761
|
i0.ɵɵelementStart(6, "mj-entity-record-detail-panel", 132);
|
|
762
|
-
i0.ɵɵlistener("close", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_close_6_listener() { i0.ɵɵrestoreView(
|
|
762
|
+
i0.ɵɵlistener("close", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_close_6_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onDetailPanelClosed()); })("openRecord", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_openRecord_6_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onOpenRecord($event)); })("navigateToRelated", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_navigateToRelated_6_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onNavigateToRelated($event)); })("openRelatedRecord", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_openRelatedRecord_6_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onOpenRelatedRecord($event)); })("openForeignKeyRecord", function DataExplorerDashboardComponent_Conditional_16_Template_mj_entity_record_detail_panel_openForeignKeyRecord_6_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onOpenForeignKeyRecord($event)); });
|
|
763
763
|
i0.ɵɵelementEnd()();
|
|
764
764
|
} if (rf & 2) {
|
|
765
765
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -768,9 +768,9 @@ function DataExplorerDashboardComponent_Conditional_16_Template(rf, ctx) { if (r
|
|
|
768
768
|
i0.ɵɵproperty("entity", ctx_r1.detailPanelEntity)("record", ctx_r1.selectedRecord);
|
|
769
769
|
} }
|
|
770
770
|
function DataExplorerDashboardComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
771
|
-
const
|
|
771
|
+
const _r35 = i0.ɵɵgetCurrentView();
|
|
772
772
|
i0.ɵɵelementStart(0, "mj-list-management-dialog", 133);
|
|
773
|
-
i0.ɵɵlistener("complete", function DataExplorerDashboardComponent_Conditional_20_Template_mj_list_management_dialog_complete_0_listener($event) { i0.ɵɵrestoreView(
|
|
773
|
+
i0.ɵɵlistener("complete", function DataExplorerDashboardComponent_Conditional_20_Template_mj_list_management_dialog_complete_0_listener($event) { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onListManagementComplete($event)); })("cancel", function DataExplorerDashboardComponent_Conditional_20_Template_mj_list_management_dialog_cancel_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onListManagementCancel()); });
|
|
774
774
|
i0.ɵɵelementEnd();
|
|
775
775
|
} if (rf & 2) {
|
|
776
776
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -843,7 +843,9 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
843
843
|
loadedRecords = [];
|
|
844
844
|
// Currently selected view entity (for view data loading)
|
|
845
845
|
selectedViewEntity = null;
|
|
846
|
-
//
|
|
846
|
+
// Live filter text (what the user sees in the input, updates immediately)
|
|
847
|
+
liveFilterText = '';
|
|
848
|
+
// Debounced filter text (synced with mj-entity-viewer, updates after delay)
|
|
847
849
|
debouncedFilterText = '';
|
|
848
850
|
filterInput$ = new Subject();
|
|
849
851
|
// Entity filter text for home screen
|
|
@@ -961,7 +963,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
961
963
|
get recentEntities() {
|
|
962
964
|
return this.state.recentEntityAccesses
|
|
963
965
|
.slice(0, 5)
|
|
964
|
-
.map(r => this.entities.find(e => e.ID
|
|
966
|
+
.map(r => this.entities.find(e => UUIDsEqual(e.ID, r.entityId)))
|
|
965
967
|
.filter((e) => e !== undefined);
|
|
966
968
|
}
|
|
967
969
|
/**
|
|
@@ -969,7 +971,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
969
971
|
*/
|
|
970
972
|
get favoriteEntities() {
|
|
971
973
|
return this.state.favoriteEntities
|
|
972
|
-
.map(f => this.entities.find(e => e.ID
|
|
974
|
+
.map(f => this.entities.find(e => UUIDsEqual(e.ID, f.entityId)))
|
|
973
975
|
.filter((e) => e !== undefined);
|
|
974
976
|
}
|
|
975
977
|
/**
|
|
@@ -1217,6 +1219,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
1217
1219
|
await this.stateService.setContext(this.entityFilter);
|
|
1218
1220
|
this.state = this.stateService.CurrentState;
|
|
1219
1221
|
// User search text starts empty - it's separate from smart filter
|
|
1222
|
+
this.liveFilterText = '';
|
|
1220
1223
|
this.debouncedFilterText = '';
|
|
1221
1224
|
// Load available entities (async to support applicationId filter)
|
|
1222
1225
|
// Pass urlState so we don't restore persisted entity if URL specifies one
|
|
@@ -1238,6 +1241,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
1238
1241
|
this.state = state;
|
|
1239
1242
|
// When entity changes, clear user search text
|
|
1240
1243
|
if (entityChanged) {
|
|
1244
|
+
this.liveFilterText = '';
|
|
1241
1245
|
this.debouncedFilterText = '';
|
|
1242
1246
|
}
|
|
1243
1247
|
this.onStateChanged();
|
|
@@ -1254,9 +1258,13 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
1254
1258
|
this.breadcrumbs = breadcrumbs;
|
|
1255
1259
|
this.cdr.detectChanges();
|
|
1256
1260
|
});
|
|
1257
|
-
// Setup debounced filter
|
|
1261
|
+
// Setup debounced filter - 500ms delay allows comfortable typing before triggering search
|
|
1262
|
+
// IMPORTANT: Do NOT call setSmartFilterPrompt here. Updating the state service triggers
|
|
1263
|
+
// URL updates via the shell's workspace sync, which fires NavigationEnd, which triggers
|
|
1264
|
+
// applyUrlState, which clears the filter text. The debouncedFilterText flows directly
|
|
1265
|
+
// to the entity-viewer via [filterText] binding — no state service involvement needed.
|
|
1258
1266
|
this.filterInput$
|
|
1259
|
-
.pipe(debounceTime(
|
|
1267
|
+
.pipe(debounceTime(500), distinctUntilChanged(), takeUntil(this.destroy$))
|
|
1260
1268
|
.subscribe(filterText => {
|
|
1261
1269
|
this.debouncedFilterText = filterText;
|
|
1262
1270
|
this.cdr.detectChanges();
|
|
@@ -1547,12 +1555,14 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
1547
1555
|
this.stateService.setSmartFilterPrompt('');
|
|
1548
1556
|
}
|
|
1549
1557
|
// Always clear user search text when switching views - smart filter is separate
|
|
1558
|
+
this.liveFilterText = '';
|
|
1550
1559
|
this.debouncedFilterText = '';
|
|
1551
1560
|
}
|
|
1552
1561
|
else {
|
|
1553
1562
|
// Switching to default view - load user's saved defaults from UserInfoEngine
|
|
1554
1563
|
this.currentGridState = this.loadUserDefaultGridState();
|
|
1555
1564
|
this.stateService.setSmartFilterPrompt('');
|
|
1565
|
+
this.liveFilterText = '';
|
|
1556
1566
|
this.debouncedFilterText = '';
|
|
1557
1567
|
}
|
|
1558
1568
|
// Force refresh to ensure the grid reloads with the new view configuration
|
|
@@ -2275,12 +2285,33 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
2275
2285
|
this.stateService.setSmartFilterPrompt(prompt);
|
|
2276
2286
|
this.filterInput$.next(prompt);
|
|
2277
2287
|
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Handle direct keyboard input in the filter text box.
|
|
2290
|
+
* Only updates the live display text and pushes to the debounce subject.
|
|
2291
|
+
* Does NOT trigger state changes or URL updates — those happen after the debounce.
|
|
2292
|
+
*/
|
|
2293
|
+
onFilterInputChanged(filterText) {
|
|
2294
|
+
this.liveFilterText = filterText;
|
|
2295
|
+
this.filterInput$.next(filterText);
|
|
2296
|
+
}
|
|
2297
|
+
/**
|
|
2298
|
+
* Clear the record filter (called by the X button).
|
|
2299
|
+
*/
|
|
2300
|
+
clearRecordFilter() {
|
|
2301
|
+
this.liveFilterText = '';
|
|
2302
|
+
this.debouncedFilterText = '';
|
|
2303
|
+
this.stateService.setSmartFilterPrompt('');
|
|
2304
|
+
this.filterInput$.next('');
|
|
2305
|
+
this.cdr.detectChanges();
|
|
2306
|
+
}
|
|
2278
2307
|
/**
|
|
2279
2308
|
* Handle filter text change from mj-entity-viewer (two-way binding)
|
|
2280
2309
|
*/
|
|
2281
2310
|
onFilterTextChanged(filterText) {
|
|
2311
|
+
this.liveFilterText = filterText;
|
|
2312
|
+
this.debouncedFilterText = filterText;
|
|
2282
2313
|
this.stateService.setSmartFilterPrompt(filterText);
|
|
2283
|
-
this.
|
|
2314
|
+
this.cdr.detectChanges();
|
|
2284
2315
|
}
|
|
2285
2316
|
// ========================================
|
|
2286
2317
|
// ENTITY VIEWER EVENT HANDLERS
|
|
@@ -2883,6 +2914,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
2883
2914
|
this.stateService.setSmartFilterPrompt('');
|
|
2884
2915
|
}
|
|
2885
2916
|
// User search text is always cleared when applying URL state
|
|
2917
|
+
this.liveFilterText = '';
|
|
2886
2918
|
this.debouncedFilterText = '';
|
|
2887
2919
|
// Handle record selection
|
|
2888
2920
|
if (urlState.record) {
|
|
@@ -3162,7 +3194,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
3162
3194
|
* and open the detail panel once data loads.
|
|
3163
3195
|
*/
|
|
3164
3196
|
onRecentRecordClick(record) {
|
|
3165
|
-
const entity = this.entities.find(e => e.ID
|
|
3197
|
+
const entity = this.entities.find(e => UUIDsEqual(e.ID, record.entityId));
|
|
3166
3198
|
if (entity) {
|
|
3167
3199
|
// Set pending record selection - will be resolved in onDataLoaded
|
|
3168
3200
|
this.pendingRecordSelection = record.recordId;
|
|
@@ -3175,7 +3207,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
3175
3207
|
* and open the detail panel once data loads.
|
|
3176
3208
|
*/
|
|
3177
3209
|
onFavoriteRecordClick(record) {
|
|
3178
|
-
const entity = this.entities.find(e => e.ID
|
|
3210
|
+
const entity = this.entities.find(e => UUIDsEqual(e.ID, record.entityId));
|
|
3179
3211
|
if (entity) {
|
|
3180
3212
|
// Set pending record selection - will be resolved in onDataLoaded
|
|
3181
3213
|
this.pendingRecordSelection = record.recordId;
|
|
@@ -3186,7 +3218,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
3186
3218
|
* Get the icon for an entity by ID (for recent records)
|
|
3187
3219
|
*/
|
|
3188
3220
|
getEntityIconById(entityId) {
|
|
3189
|
-
const entity = this.metadata.Entities.find(e => e.ID
|
|
3221
|
+
const entity = this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));
|
|
3190
3222
|
if (entity) {
|
|
3191
3223
|
return this.getEntityIcon(entity);
|
|
3192
3224
|
}
|
|
@@ -3416,7 +3448,7 @@ let DataExplorerDashboardComponent = class DataExplorerDashboardComponent extend
|
|
|
3416
3448
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.viewConfigPanelRef = _t.first);
|
|
3417
3449
|
} }, hostBindings: function DataExplorerDashboardComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
3418
3450
|
i0.ɵɵlistener("keydown", function DataExplorerDashboardComponent_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument);
|
|
3419
|
-
} }, inputs: { entityFilter: "entityFilter", deepLink: "deepLink", contextName: "contextName", contextIcon: "contextIcon" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 24, vars: 37, consts: [["filterInput", ""], ["entityViewer", ""], [1, "data-explorer-container"], [1, "navigation-panel", 3, "collapsed", "width"], [1, "content-area"], [1, "breadcrumb-bar"], [1, "content-header"], [1, "header-left"], [1, "header-center"], [1, "smart-filter-container"], [1, "header-right"], ["title", "Recents & Favorites", 1, "header-action-btn", 3, "active"], [1, "content-body"], [1, "home-view-concept-d"], [3, "entity", "viewEntity", "viewMode", "filterText", "selectedRecordId", "config", "gridState", "timelineConfig", "gridSelectionMode", "showGridToolbar", "showAddToListButton"], [1, "detail-panel", 3, "width"], [3, "close", "save", "saveDefaults", "delete", "duplicate", "openFilterDialogRequest", "entity", "viewEntity", "isOpen", "currentGridState", "externalFilterState", "isSaving", "DefaultSaveAsNew"], [3, "close", "apply", "isOpen", "fields", "filter", "disabled"], [3, "closed", "visible", "config"], [3, "config", "visible"], [3, "Save", "Close", "OpenAdvanced", "IsOpen", "ViewEntity", "EntityName", "Summary", "IsSaving", "DefaultSaveAsNew"], [3, "Duplicate", "Cancel", "IsOpen", "SourceViewName", "Summary"], [3, "Action", "Cancel", "IsOpen", "ViewName"], [1, "navigation-panel"], [3, "entitySelected", "toggleCollapse", "sectionToggled", "openRecord", "selectRecord", "expandAndFocus", "entities", "appEntityGroups", "selectedEntityName", "favorites", "recentItems", "collapsed", "allowedEntityNames", "favoritesSectionExpanded", "recentSectionExpanded", "entitiesSectionExpanded", "viewsSectionExpanded"], [1, "breadcrumb-item", 3, "click", "title"], [1, "breadcrumb-icon", 3, "class"], [1, "breadcrumb-label"], [1, "fa-solid", "fa-chevron-right", "breadcrumb-separator"], [1, "breadcrumb-icon"], [1, "entity-icon"], [1, "entity-title"], [1, "record-count"], [3, "viewSelected", "saveViewRequested", "manageViewsRequested", "openInTabRequested", "configureViewRequested", "createNewRecordRequested", "exportRequested", "duplicateViewRequested", "quickSaveRequested", "revertRequested", "entity", "selectedViewId", "viewModified"], [1, "header-action-btn", 3, "click", "disabled", "title"], [1, "fa-solid", "fa-list-check"], [1, "selection-badge"], [1, "entity-icon", 3, "class"], [1, "fa-solid", "fa-search", "filter-icon"], ["type", "text", "placeholder", "Filter records... (press / to focus)", 1, "smart-filter-input", 3, "
|
|
3451
|
+
} }, inputs: { entityFilter: "entityFilter", deepLink: "deepLink", contextName: "contextName", contextIcon: "contextIcon" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 24, vars: 37, consts: [["filterInput", ""], ["entityViewer", ""], [1, "data-explorer-container"], [1, "navigation-panel", 3, "collapsed", "width"], [1, "content-area"], [1, "breadcrumb-bar"], [1, "content-header"], [1, "header-left"], [1, "header-center"], [1, "smart-filter-container"], [1, "header-right"], ["title", "Recents & Favorites", 1, "header-action-btn", 3, "active"], [1, "content-body"], [1, "home-view-concept-d"], [3, "entity", "viewEntity", "viewMode", "filterText", "selectedRecordId", "config", "gridState", "timelineConfig", "gridSelectionMode", "showGridToolbar", "showAddToListButton"], [1, "detail-panel", 3, "width"], [3, "close", "save", "saveDefaults", "delete", "duplicate", "openFilterDialogRequest", "entity", "viewEntity", "isOpen", "currentGridState", "externalFilterState", "isSaving", "DefaultSaveAsNew"], [3, "close", "apply", "isOpen", "fields", "filter", "disabled"], [3, "closed", "visible", "config"], [3, "config", "visible"], [3, "Save", "Close", "OpenAdvanced", "IsOpen", "ViewEntity", "EntityName", "Summary", "IsSaving", "DefaultSaveAsNew"], [3, "Duplicate", "Cancel", "IsOpen", "SourceViewName", "Summary"], [3, "Action", "Cancel", "IsOpen", "ViewName"], [1, "navigation-panel"], [3, "entitySelected", "toggleCollapse", "sectionToggled", "openRecord", "selectRecord", "expandAndFocus", "entities", "appEntityGroups", "selectedEntityName", "favorites", "recentItems", "collapsed", "allowedEntityNames", "favoritesSectionExpanded", "recentSectionExpanded", "entitiesSectionExpanded", "viewsSectionExpanded"], [1, "breadcrumb-item", 3, "click", "title"], [1, "breadcrumb-icon", 3, "class"], [1, "breadcrumb-label"], [1, "fa-solid", "fa-chevron-right", "breadcrumb-separator"], [1, "breadcrumb-icon"], [1, "entity-icon"], [1, "entity-title"], [1, "record-count"], [3, "viewSelected", "saveViewRequested", "manageViewsRequested", "openInTabRequested", "configureViewRequested", "createNewRecordRequested", "exportRequested", "duplicateViewRequested", "quickSaveRequested", "revertRequested", "entity", "selectedViewId", "viewModified"], [1, "header-action-btn", 3, "click", "disabled", "title"], [1, "fa-solid", "fa-list-check"], [1, "selection-badge"], [1, "entity-icon", 3, "class"], [1, "fa-solid", "fa-search", "filter-icon"], ["type", "text", "placeholder", "Filter records... (press / to focus)", 1, "smart-filter-input", 3, "input", "value"], [1, "clear-filter-btn"], [1, "clear-filter-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "view-mode-toggle"], ["title", "Grid View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["title", "Cards View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-grip"], ["title", "Timeline View", 1, "toggle-btn", 3, "active"], ["title", "Timeline View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-timeline"], [1, "date-field-selector-container"], [1, "date-field-backdrop"], [1, "date-field-selector-wrapper"], [1, "date-field-selector-button", 3, "click", "disabled"], [1, "fa-solid", "fa-calendar-days", "date-field-icon"], [1, "date-field-name"], [1, "fa-solid", "fa-chevron-down", "date-field-arrow", 3, "rotated"], [1, "date-field-dropdown-panel"], [1, "timeline-orientation-toggle"], [1, "toggle-btn", 3, "click", "title"], [1, "timeline-sort-toggle"], [1, "date-field-backdrop", 3, "click"], [1, "fa-solid", "fa-chevron-down", "date-field-arrow"], [1, "date-field-dropdown-item", 3, "selected"], [1, "date-field-dropdown-item", 3, "click"], [1, "fa-regular", "fa-calendar", "item-icon"], [1, "item-name"], [1, "fa-solid", "fa-check", "selected-check"], ["title", "Recents & Favorites", 1, "header-action-btn", 3, "click"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "qa-badge"], [1, "loading-state"], ["text", "Loading entities...", "size", "medium"], [1, "home-main-area"], [1, "search-hero"], [1, "search-hero-container"], [1, "fa-solid", "fa-magnifying-glass", "search-hero-icon"], ["type", "text", "placeholder", "Search entities...", 1, "search-hero-input", 3, "ngModelChange", "ngModel"], [1, "search-hero-clear"], [1, "search-hero-shortcut"], [1, "search-meta-row"], [1, "search-entity-count"], [1, "pill-toggle"], [1, "pill-btn", 3, "click"], [1, "fa-solid", "fa-star"], [1, "entity-groups-area"], [1, "entity-item-grid"], [1, "home-no-results"], [1, "empty-state"], [1, "quick-access-panel"], [1, "qa-header"], [1, "qa-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "qa-body"], [1, "qa-section"], [1, "qa-section-header", 3, "click"], [1, "fa-solid", "fa-clock-rotate-left", "qa-section-icon"], [1, "qa-section-count"], [1, "fa-solid", "fa-chevron-down", "qa-section-chevron"], [1, "qa-section-body"], [1, "qa-item"], [1, "qa-empty"], [1, "fa-solid", "fa-table", "qa-section-icon"], [1, "fa-solid", "fa-star", "qa-section-icon", 2, "color", "#f59e0b"], [1, "search-hero-clear", 3, "click"], [1, "entity-item", 3, "title"], [1, "entity-item", 3, "click", "title"], [1, "entity-item-icon"], [1, "entity-item-text"], [1, "entity-item-name"], [1, "entity-item-desc"], [1, "entity-item-fav", 3, "click", "title"], [1, "app-group"], [1, "app-group-header", 3, "click"], [1, "app-group-icon"], [1, "app-group-name"], [1, "app-group-count"], [1, "fa-solid", "fa-chevron-right", "app-group-chevron"], [1, "app-group-entities"], [1, "fa-solid", "fa-magnifying-glass"], [1, "fa-solid", "fa-database", "empty-icon"], [1, "qa-item", 3, "click"], [1, "qa-item-icon"], [1, "qa-item-info"], [1, "qa-item-name"], [1, "qa-item-meta"], [1, "qa-item-time"], [3, "viewModeChange", "filterTextChange", "recordSelected", "recordOpened", "dataLoaded", "filteredCountChanged", "gridStateChanged", "selectionChanged", "addToListRequested", "entity", "viewEntity", "viewMode", "filterText", "selectedRecordId", "config", "gridState", "timelineConfig", "gridSelectionMode", "showGridToolbar", "showAddToListButton"], [1, "detail-panel"], [1, "detail-panel-actions"], ["title", "Add to List", 1, "detail-action-btn", 3, "click"], [3, "close", "openRecord", "navigateToRelated", "openRelatedRecord", "openForeignKeyRecord", "entity", "record"], [3, "complete", "cancel", "config", "visible"]], template: function DataExplorerDashboardComponent_Template(rf, ctx) { if (rf & 1) {
|
|
3420
3452
|
i0.ɵɵelementStart(0, "div", 2);
|
|
3421
3453
|
i0.ɵɵconditionalCreate(1, DataExplorerDashboardComponent_Conditional_1_Template, 2, 16, "div", 3);
|
|
3422
3454
|
i0.ɵɵelementStart(2, "div", 4);
|
|
@@ -3517,7 +3549,7 @@ export { DataExplorerDashboardComponent };
|
|
|
3517
3549
|
animate('200ms ease-in', style({ transform: 'translateX(-100%)', opacity: 0 }))
|
|
3518
3550
|
])
|
|
3519
3551
|
])
|
|
3520
|
-
], template: "<div class=\"data-explorer-container\">\n <!-- Navigation Panel (Left) - Hidden at home level, animated -->\n @if (!isAtHomeLevel) {\n <div\n class=\"navigation-panel\"\n [class.collapsed]=\"state.navigationPanelCollapsed\"\n [style.width.px]=\"state.navigationPanelCollapsed ? 48 : state.navigationPanelWidth\"\n [@slideInLeft]>\n\n <mj-explorer-navigation-panel\n [entities]=\"entities\"\n [appEntityGroups]=\"appEntityGroups\"\n [selectedEntityName]=\"state.selectedEntityName\"\n [favorites]=\"state.favorites\"\n [recentItems]=\"state.recentItems\"\n [collapsed]=\"state.navigationPanelCollapsed\"\n [allowedEntityNames]=\"allowedEntityNames\"\n [favoritesSectionExpanded]=\"state.favoritesSectionExpanded\"\n [recentSectionExpanded]=\"state.recentSectionExpanded\"\n [entitiesSectionExpanded]=\"state.entitiesSectionExpanded\"\n [viewsSectionExpanded]=\"state.viewsSectionExpanded\"\n (entitySelected)=\"onEntitySelected($event)\"\n (toggleCollapse)=\"toggleNavigationPanel()\"\n (sectionToggled)=\"stateService.toggleSection($event)\"\n (openRecord)=\"onOpenRecordFromNav($event)\"\n (selectRecord)=\"onSelectRecordFromNav($event)\"\n (expandAndFocus)=\"onExpandAndFocus($event)\">\n </mj-explorer-navigation-panel>\n </div>\n }\n\n <!-- Main Content Area -->\n <div class=\"content-area\">\n <!-- Breadcrumb Bar - Hidden at home level -->\n @if (!isAtHomeLevel && breadcrumbs.length > 0) {\n <div class=\"breadcrumb-bar\">\n @for (crumb of breadcrumbs; track crumb.label; let i = $index; let last = $last) {\n <span\n class=\"breadcrumb-item\"\n [class.clickable]=\"!last\"\n [class.current]=\"last\"\n (click)=\"onBreadcrumbClick(crumb, i)\"\n [title]=\"crumb.label\">\n @if (crumb.icon) {\n <i [class]=\"crumb.icon\" class=\"breadcrumb-icon\"></i>\n }\n <span class=\"breadcrumb-label\">{{ crumb.label }}</span>\n </span>\n @if (!last) {\n <i class=\"fa-solid fa-chevron-right breadcrumb-separator\"></i>\n }\n }\n </div>\n }\n\n <!-- Header -->\n <div class=\"content-header\" [class.home-header]=\"isAtHomeLevel\">\n <div class=\"header-left\">\n @if (selectedEntity) {\n <i [class]=\"getEntityIcon(selectedEntity)\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ selectedEntity.DisplayNameOrName }}</h2>\n @if (debouncedFilterText && filteredRecordCount !== totalRecordCount) {\n <span class=\"record-count\">{{ filteredRecordCount | number }} of {{ totalRecordCount | number }} records</span>\n } @else {\n <span class=\"record-count\">{{ totalRecordCount | number }} records</span>\n }\n\n <!-- View Selector -->\n <mj-view-selector\n [entity]=\"selectedEntity\"\n [selectedViewId]=\"state.selectedViewId\"\n [viewModified]=\"state.viewModified\"\n (viewSelected)=\"onViewSelected($event)\"\n (saveViewRequested)=\"onSaveViewRequested($event)\"\n (manageViewsRequested)=\"onManageViewsRequested()\"\n (openInTabRequested)=\"onOpenInTabRequested($event)\"\n (configureViewRequested)=\"onConfigureViewRequested()\"\n (createNewRecordRequested)=\"onCreateNewRecord()\"\n (exportRequested)=\"onExport()\"\n (duplicateViewRequested)=\"onDuplicateView($event)\"\n (quickSaveRequested)=\"onQuickSaveRequested($event)\"\n (revertRequested)=\"onRevertView()\">\n </mj-view-selector>\n\n <!-- Add to List Button -->\n <button\n class=\"header-action-btn\"\n [class.disabled]=\"!hasSelectedRecords\"\n [disabled]=\"!hasSelectedRecords\"\n (click)=\"onAddToListClick()\"\n [title]=\"hasSelectedRecords ? 'Add ' + selectedRecords.length + ' selected record(s) to a list' : 'Select records to add to a list'\">\n <i class=\"fa-solid fa-list-check\"></i>\n @if (hasSelectedRecords) {\n <span class=\"selection-badge\">{{ selectedRecords.length }}</span>\n }\n </button>\n } @else {\n @if (displayIcon) {\n <i [class]=\"displayIcon\" class=\"entity-icon\"></i>\n }\n <h2 class=\"entity-title\">{{ displayTitle }}</h2>\n <span class=\"record-count\">{{ entities.length }} entities available</span>\n }\n </div>\n\n <div class=\"header-center\">\n @if (selectedEntity) {\n <div class=\"smart-filter-container\">\n <i class=\"fa-solid fa-search filter-icon\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"smart-filter-input\"\n placeholder=\"Filter records... (press / to focus)\"\n [ngModel]=\"debouncedFilterText\"\n (ngModelChange)=\"onFilterTextChanged($event)\"\n />\n @if (debouncedFilterText) {\n <button class=\"clear-filter-btn\" (click)=\"onFilterTextChanged('')\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n <!-- Home-level search moved to search hero section -->\n </div>\n\n <div class=\"header-right\">\n @if (selectedEntity) {\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'grid'\"\n (click)=\"onViewModeChanged('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'cards'\"\n (click)=\"onViewModeChanged('cards')\"\n title=\"Cards View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n @if (entityHasDateFields) {\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'timeline'\"\n (click)=\"onViewModeChanged('timeline')\"\n title=\"Timeline View\">\n <i class=\"fa-solid fa-timeline\"></i>\n </button>\n }\n </div>\n\n <!-- Timeline Controls (only shown when timeline view is active) -->\n @if (state.viewMode === 'timeline' && entityHasDateFields) {\n <!-- Date Field Selector -->\n <div class=\"date-field-selector-container\">\n <!-- Backdrop for closing dropdown -->\n @if (isDateFieldDropdownOpen) {\n <div class=\"date-field-backdrop\" (click)=\"closeDateFieldDropdown()\"></div>\n }\n\n <div class=\"date-field-selector-wrapper\">\n <button\n class=\"date-field-selector-button\"\n [class.open]=\"isDateFieldDropdownOpen\"\n [disabled]=\"availableDateFields.length <= 1\"\n (click)=\"toggleDateFieldDropdown()\">\n <i class=\"fa-solid fa-calendar-days date-field-icon\"></i>\n <span class=\"date-field-name\">{{ effectiveTimelineDateFieldDisplayName }}</span>\n @if (availableDateFields.length > 1) {\n <i class=\"fa-solid fa-chevron-down date-field-arrow\" [class.rotated]=\"isDateFieldDropdownOpen\"></i>\n }\n </button>\n\n @if (isDateFieldDropdownOpen && availableDateFields.length > 1) {\n <div class=\"date-field-dropdown-panel\">\n @for (field of availableDateFields; track field.name) {\n <div\n class=\"date-field-dropdown-item\"\n [class.selected]=\"field.name === effectiveTimelineDateField\"\n (click)=\"setTimelineDateField(field.name)\">\n <i class=\"fa-regular fa-calendar item-icon\"></i>\n <span class=\"item-name\">{{ field.displayName }}</span>\n @if (field.name === effectiveTimelineDateField) {\n <i class=\"fa-solid fa-check selected-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Orientation Toggle -->\n <div class=\"timeline-orientation-toggle\">\n <button\n class=\"toggle-btn\"\n (click)=\"toggleTimelineOrientation()\"\n [title]=\"state.timelineOrientation === 'vertical' ? 'Switch to Horizontal' : 'Switch to Vertical'\">\n <i [class]=\"state.timelineOrientation === 'vertical' ? 'fa-solid fa-ellipsis-vertical' : 'fa-solid fa-ellipsis'\"></i>\n </button>\n </div>\n\n <!-- Sort Order Toggle -->\n <div class=\"timeline-sort-toggle\">\n <button\n class=\"toggle-btn\"\n (click)=\"toggleTimelineSortOrder()\"\n [title]=\"state.timelineSortOrder === 'desc' ? 'Showing Newest First (click for Oldest First)' : 'Showing Oldest First (click for Newest First)'\">\n <i [class]=\"state.timelineSortOrder === 'desc' ? 'fa-solid fa-arrow-down-wide-short' : 'fa-solid fa-arrow-up-wide-short'\"></i>\n </button>\n </div>\n }\n }\n @if (!selectedEntity) {\n <!-- Quick Access panel toggle -->\n <button\n class=\"header-action-btn\"\n [class.active]=\"state.quickAccessPanelOpen\"\n (click)=\"toggleQuickAccessPanel()\"\n title=\"Recents & Favorites\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n @if (recentRecords.length + favoriteRecords.length > 0) {\n <span class=\"qa-badge\">{{ recentRecords.length + favoriteRecords.length }}</span>\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Content Body - Using mj-entity-viewer composite -->\n <div class=\"content-body\" [class.home-content]=\"isAtHomeLevel\">\n @if (!selectedEntity) {\n <!-- Concept D: Application Groups + Search-First Home View -->\n <div class=\"home-view-concept-d\">\n @if (isLoadingEntities) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading entities...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <div class=\"home-main-area\" [class.panel-open]=\"state.quickAccessPanelOpen\">\n <!-- Search Hero -->\n <div class=\"search-hero\">\n <div class=\"search-hero-container\">\n <i class=\"fa-solid fa-magnifying-glass search-hero-icon\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"search-hero-input\"\n placeholder=\"Search entities...\"\n [(ngModel)]=\"entityFilterText\"\n />\n @if (entityFilterText) {\n <button class=\"search-hero-clear\" (click)=\"entityFilterText = ''\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n } @else {\n <span class=\"search-hero-shortcut\">/</span>\n }\n </div>\n\n <!-- Meta row: entity count + All/Favorites pills -->\n <div class=\"search-meta-row\">\n <span class=\"search-entity-count\">\n {{ filteredEntityCount }} entities\n @if (applicationCount > 0) {\n across {{ applicationCount }} applications\n }\n </span>\n <div class=\"pill-toggle\">\n <button\n class=\"pill-btn\"\n [class.active]=\"state.homeViewMode === 'all'\"\n (click)=\"setHomeViewMode('all')\">\n All Entities\n </button>\n <button\n class=\"pill-btn\"\n [class.active]=\"state.homeViewMode === 'favorites'\"\n (click)=\"setHomeViewMode('favorites')\">\n <i class=\"fa-solid fa-star\"></i> My Favorites\n </button>\n </div>\n </div>\n </div>\n\n <!-- Entity Groups Area -->\n <div class=\"entity-groups-area\">\n @if (entityFilter?.applicationId) {\n <!-- Single-app mode: flat entity grid (no grouping) -->\n <div class=\"entity-item-grid\">\n @for (entity of flatFilteredEntities; track entity.ID) {\n <div\n class=\"entity-item\"\n (click)=\"onEntitySelected(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <div class=\"entity-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"entity-item-text\">\n <span class=\"entity-item-name\">{{ entity.DisplayNameOrName }}</span>\n @if (entity.Description) {\n <span class=\"entity-item-desc\">{{ entity.Description }}</span>\n }\n </div>\n <button\n class=\"entity-item-fav\"\n [class.favorited]=\"isEntityFavorited(entity)\"\n (click)=\"toggleEntityFavorite(entity, $event)\"\n [title]=\"isEntityFavorited(entity) ? 'Remove from favorites' : 'Add to favorites'\">\n <i [class]=\"isEntityFavorited(entity) ? 'fa-solid fa-star' : 'fa-regular fa-star'\"></i>\n </button>\n </div>\n }\n </div>\n } @else {\n <!-- Multi-app mode: grouped by application -->\n @for (group of filteredAppEntityGroups; track group.applicationId) {\n <div class=\"app-group\">\n <div class=\"app-group-header\" (click)=\"toggleAppGroup(group.applicationId)\">\n <div\n class=\"app-group-icon\"\n [style.background]=\"group.applicationColor ? group.applicationColor + '15' : null\"\n [style.color]=\"group.applicationColor || null\">\n <i [class]=\"group.applicationIcon || 'fa-solid fa-folder'\"></i>\n </div>\n <span class=\"app-group-name\">{{ group.applicationName }}</span>\n <span class=\"app-group-count\">{{ group.entities.length }}</span>\n <i class=\"fa-solid fa-chevron-right app-group-chevron\"\n [class.expanded]=\"group.isExpanded\"></i>\n </div>\n @if (group.isExpanded) {\n <div class=\"app-group-entities\">\n <div class=\"entity-item-grid\">\n @for (entity of group.entities; track entity.ID) {\n <div\n class=\"entity-item\"\n (click)=\"onEntitySelected(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <div class=\"entity-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"entity-item-text\">\n <span class=\"entity-item-name\">{{ entity.DisplayNameOrName }}</span>\n @if (entity.Description) {\n <span class=\"entity-item-desc\">{{ entity.Description }}</span>\n }\n </div>\n <button\n class=\"entity-item-fav\"\n [class.favorited]=\"isEntityFavorited(entity)\"\n (click)=\"toggleEntityFavorite(entity, $event)\"\n [title]=\"isEntityFavorited(entity) ? 'Remove from favorites' : 'Add to favorites'\">\n <i [class]=\"isEntityFavorited(entity) ? 'fa-solid fa-star' : 'fa-regular fa-star'\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n\n <!-- No results -->\n @if (filteredEntityCount === 0 && entities.length > 0) {\n <div class=\"home-no-results\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <p>No entities match \"{{ entityFilterText }}\"</p>\n </div>\n }\n @if (entities.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-icon\"></i>\n <h3>No Entities Available</h3>\n <p>There are no entities configured for this application.</p>\n </div>\n }\n </div>\n </div>\n\n <!-- Quick Access Panel (right slide-in) -->\n <div class=\"quick-access-panel\" [class.open]=\"state.quickAccessPanelOpen\">\n <div class=\"qa-header\">\n <h3>Quick Access</h3>\n <button class=\"qa-close-btn\" (click)=\"toggleQuickAccessPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"qa-body\">\n <!-- Recent Records (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('recentRecords')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('recentRecords')\">\n <i class=\"fa-solid fa-clock-rotate-left qa-section-icon\"></i>\n <span>Recent Records</span>\n <span class=\"qa-section-count\">{{ quickAccessRecentRecords.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (record of quickAccessRecentRecords; track record.entityId + '|' + record.recordId) {\n <div class=\"qa-item\" (click)=\"onRecentRecordClick(record)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIconById(record.entityId)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ record.recordName || record.recordId }}</div>\n <div class=\"qa-item-meta\">{{ record.entityName }}</div>\n </div>\n <span class=\"qa-item-time\">{{ formatRelativeTime(record.latestAt) }}</span>\n </div>\n }\n @if (quickAccessRecentRecords.length === 0) {\n <div class=\"qa-empty\">No recent records</div>\n }\n </div>\n </div>\n\n <!-- Recent Entities (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('recentEntities')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('recentEntities')\">\n <i class=\"fa-solid fa-table qa-section-icon\"></i>\n <span>Recent Entities</span>\n <span class=\"qa-section-count\">{{ quickAccessRecentEntities.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (entity of quickAccessRecentEntities; track entity.ID) {\n <div class=\"qa-item\" (click)=\"onEntitySelected(entity)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ entity.DisplayNameOrName }}</div>\n </div>\n </div>\n }\n @if (quickAccessRecentEntities.length === 0) {\n <div class=\"qa-empty\">No recent entities</div>\n }\n </div>\n </div>\n\n <!-- Favorite Records (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('favoriteRecords')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('favoriteRecords')\">\n <i class=\"fa-solid fa-star qa-section-icon\" style=\"color: #f59e0b;\"></i>\n <span>Favorite Records</span>\n <span class=\"qa-section-count\">{{ quickAccessFavoriteRecords.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (record of quickAccessFavoriteRecords; track record.userFavoriteId) {\n <div class=\"qa-item\" (click)=\"onFavoriteRecordClick(record)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIconById(record.entityId)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ record.recordName || record.recordId }}</div>\n <div class=\"qa-item-meta\">{{ record.entityName }}</div>\n </div>\n </div>\n }\n @if (quickAccessFavoriteRecords.length === 0) {\n <div class=\"qa-empty\">No favorite records</div>\n }\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-entity-viewer\n #entityViewer\n [entity]=\"selectedEntity\"\n [viewEntity]=\"selectedViewEntity\"\n [viewMode]=\"state.viewMode\"\n [filterText]=\"debouncedFilterText\"\n [selectedRecordId]=\"state.selectedRecordId\"\n [config]=\"viewerConfig\"\n [gridState]=\"currentGridState\"\n [timelineConfig]=\"currentTimelineConfig\"\n [gridSelectionMode]=\"'checkbox'\"\n [showGridToolbar]=\"false\"\n [showAddToListButton]=\"false\"\n (viewModeChange)=\"onViewModeChanged($event)\"\n (filterTextChange)=\"onFilterTextChanged($event)\"\n (recordSelected)=\"onViewerRecordSelected($event)\"\n (recordOpened)=\"onViewerRecordOpened($event)\"\n (dataLoaded)=\"onDataLoaded($event)\"\n (filteredCountChanged)=\"onFilteredCountChanged($event)\"\n (gridStateChanged)=\"onGridStateChanged($event)\"\n (selectionChanged)=\"onSelectionChanged($event)\"\n (addToListRequested)=\"onAddToListRequested($event)\">\n </mj-entity-viewer>\n }\n </div>\n </div>\n\n <!-- Detail Panel (Right - Slide In) -->\n @if (state.detailPanelOpen && selectedRecord) {\n <div class=\"detail-panel\" [style.width.px]=\"state.detailPanelWidth\">\n <!-- Detail Panel Actions Bar -->\n <div class=\"detail-panel-actions\">\n <button\n class=\"detail-action-btn\"\n (click)=\"openListManagementDialog()\"\n title=\"Add to List\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>Add to List</span>\n </button>\n </div>\n <mj-entity-record-detail-panel\n [entity]=\"detailPanelEntity\"\n [record]=\"selectedRecord\"\n (close)=\"onDetailPanelClosed()\"\n (openRecord)=\"onOpenRecord($event)\"\n (navigateToRelated)=\"onNavigateToRelated($event)\"\n (openRelatedRecord)=\"onOpenRelatedRecord($event)\"\n (openForeignKeyRecord)=\"onOpenForeignKeyRecord($event)\">\n </mj-entity-record-detail-panel>\n </div>\n }\n\n <!-- View Configuration Panel -->\n <mj-view-config-panel\n [entity]=\"selectedEntity\"\n [viewEntity]=\"selectedViewEntity\"\n [isOpen]=\"state.viewConfigPanelOpen\"\n [currentGridState]=\"currentGridState\"\n [externalFilterState]=\"filterDialogState\"\n [isSaving]=\"isSavingView\"\n [DefaultSaveAsNew]=\"defaultSaveAsNew\"\n (close)=\"onCloseViewConfigPanel()\"\n (save)=\"onSaveView($event)\"\n (saveDefaults)=\"onSaveDefaultViewSettings($event)\"\n (delete)=\"onDeleteView()\"\n (duplicate)=\"onDuplicateFromPanel()\"\n (openFilterDialogRequest)=\"onOpenFilterDialogRequest($event)\">\n </mj-view-config-panel>\n\n <!-- Filter Dialog (rendered at dashboard level for full viewport width) -->\n <mj-filter-dialog\n [isOpen]=\"isFilterDialogOpen\"\n [fields]=\"filterDialogFields\"\n [filter]=\"filterDialogState\"\n [disabled]=\"filterDialogDisabled\"\n (close)=\"onCloseFilterDialog()\"\n (apply)=\"onFilterApplied($event)\">\n </mj-filter-dialog>\n\n <!-- Export Dialog -->\n <mj-export-dialog\n [visible]=\"showExportDialog\"\n [config]=\"exportDialogConfig\"\n (closed)=\"onExportDialogClosed($event)\">\n </mj-export-dialog>\n\n <!-- List Management Dialog -->\n @if (showListManagementDialog && listManagementConfig) {\n <mj-list-management-dialog\n [config]=\"listManagementConfig\"\n [visible]=\"showListManagementDialog\"\n (complete)=\"onListManagementComplete($event)\"\n (cancel)=\"onListManagementCancel()\">\n </mj-list-management-dialog>\n }\n\n <!-- Quick Save Dialog (F-001) -->\n <mj-quick-save-dialog\n [IsOpen]=\"showQuickSaveDialog\"\n [ViewEntity]=\"selectedViewEntity\"\n [EntityName]=\"selectedEntity?.DisplayNameOrName ?? ''\"\n [Summary]=\"quickSaveSummary\"\n [IsSaving]=\"isSavingView\"\n [DefaultSaveAsNew]=\"defaultSaveAsNew\"\n (Save)=\"onQuickSave($event)\"\n (Close)=\"onQuickSaveClose()\"\n (OpenAdvanced)=\"onQuickSaveOpenAdvanced()\">\n </mj-quick-save-dialog>\n\n <!-- Duplicate View Dialog (F-005) -->\n <mj-duplicate-view-dialog\n [IsOpen]=\"showDuplicateDialog\"\n [SourceViewName]=\"duplicateSourceViewName\"\n [Summary]=\"duplicateSummary\"\n (Duplicate)=\"onDuplicateConfirmed($event)\"\n (Cancel)=\"onDuplicateCancel()\">\n </mj-duplicate-view-dialog>\n\n <!-- Shared View Warning Dialog (view-creation-flow Scenario 5) -->\n <mj-shared-view-warning-dialog\n [IsOpen]=\"showSharedViewWarning\"\n [ViewName]=\"selectedViewEntity?.Name ?? ''\"\n (Action)=\"onSharedViewAction($event)\"\n (Cancel)=\"onSharedViewWarningCancel()\">\n </mj-shared-view-warning-dialog>\n</div>\n", styles: [".data-explorer-container {\n display: flex;\n height: 100%;\n width: 100%;\n background: #f5f7fa;\n overflow: hidden;\n}\n\n.navigation-panel {\n flex-shrink: 0;\n height: 100%;\n background: white;\n border-right: 1px solid #e0e0e0;\n transition: width 0.2s ease-in-out;\n overflow: hidden;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.04);\n}\n.navigation-panel.collapsed {\n width: 48px;\n}\n\n.content-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n height: 100%;\n min-width: 0;\n overflow: hidden;\n background: #f5f7fa;\n}\n\n/* Breadcrumb Bar */\n.breadcrumb-bar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: white;\n border-bottom: 1px solid #eee;\n flex-shrink: 0;\n font-size: 13px;\n min-height: 40px;\n}\n\n.breadcrumb-item {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #666;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.15s ease;\n max-width: 200px;\n}\n\n.breadcrumb-item.clickable {\n cursor: pointer;\n}\n\n.breadcrumb-item.clickable:hover {\n background: #f0f0f0;\n color: #1976d2;\n}\n\n.breadcrumb-item.current {\n color: #1a1a1a;\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-icon {\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.breadcrumb-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.breadcrumb-separator {\n font-size: 10px;\n color: #ccc;\n flex-shrink: 0;\n}\n\n.content-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n/* View Selector within header */\n.header-left ::ng-deep mj-view-selector {\n margin-left: 8px;\n}\n\n.entity-icon {\n font-size: 20px;\n color: #1976d2;\n}\n\n.entity-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.record-count {\n font-size: 13px;\n color: #666;\n font-weight: 500;\n}\n\n.header-center {\n flex: 1;\n max-width: 600px;\n}\n\n.smart-filter-container {\n position: relative;\n width: 100%;\n}\n\n.smart-filter-input {\n width: 100%;\n padding: 10px 40px 10px 16px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 14px;\n background: #fafafa;\n transition: all 0.15s ease;\n}\n.smart-filter-input:focus {\n outline: none;\n border-color: #1976d2;\n background: white;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n}\n.smart-filter-input::placeholder {\n color: #999;\n}\n\n.clear-filter-btn {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n transition: all 0.15s ease;\n}\n.clear-filter-btn:hover {\n background: #e0e0e0;\n color: #424242;\n}\n\n.header-right {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n.view-mode-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.toggle-btn:hover {\n color: #333;\n}\n.toggle-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* Header Action Button (Add to List, etc.) */\n.header-action-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n margin-left: 8px;\n}\n.header-action-btn:hover:not(.disabled) {\n border-color: #1976d2;\n color: #1976d2;\n background: #f5f9ff;\n}\n.header-action-btn.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.header-action-btn i {\n font-size: 14px;\n}\n.selection-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: #1976d2;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n/* Timeline Date Field Selector - Styled Dropdown */\n.date-field-selector-container {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.date-field-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.date-field-selector-wrapper {\n position: relative;\n}\n\n.date-field-selector-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--text-primary, #333);\n transition: all 0.15s ease;\n min-width: 120px;\n max-width: 200px;\n}\n\n.date-field-selector-button:hover:not(:disabled) {\n background: var(--background-hover, #e8e8e8);\n border-color: var(--border-color-hover, #ccc);\n}\n\n.date-field-selector-button:disabled {\n cursor: default;\n opacity: 0.8;\n}\n\n.date-field-selector-button.open {\n background: var(--background-active, #e0e0e0);\n border-color: var(--primary-color, #007bff);\n}\n\n.date-field-icon {\n color: var(--text-secondary, #666);\n font-size: 12px;\n}\n\n.date-field-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.date-field-arrow {\n color: var(--text-secondary, #666);\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.date-field-arrow.rotated {\n transform: rotate(180deg);\n}\n\n.date-field-dropdown-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 180px;\n max-width: 280px;\n max-height: 300px;\n overflow-y: auto;\n background: var(--background-panel, #fff);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n}\n\n.date-field-dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n transition: background 0.1s ease;\n font-size: 13px;\n}\n\n.date-field-dropdown-item:hover {\n background: var(--background-hover, #f5f5f5);\n}\n\n.date-field-dropdown-item.selected {\n background: var(--primary-light, #e6f0ff);\n}\n\n.date-field-dropdown-item.selected:hover {\n background: var(--primary-light-hover, #d6e4f9);\n}\n\n.date-field-dropdown-item .item-icon {\n color: var(--text-secondary, #666);\n font-size: 13px;\n width: 16px;\n text-align: center;\n}\n\n.date-field-dropdown-item .item-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.date-field-dropdown-item .selected-check {\n color: var(--primary-color, #007bff);\n font-size: 12px;\n}\n\n/* Timeline Orientation Toggle */\n.timeline-orientation-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.content-body {\n flex: 1;\n overflow: hidden;\n padding: 20px 24px;\n display: flex;\n flex-direction: column;\n}\n\n.loading-container,\n.loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 16px;\n background: white;\n border-radius: 8px;\n}\n\n.loading-spinner {\n font-size: 32px;\n color: #1976d2;\n}\n\n.loading-message {\n margin: 0;\n font-size: 14px;\n color: #666;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #757575;\n background: white;\n border-radius: 8px;\n padding: 40px;\n}\n\n.empty-icon {\n font-size: 64px;\n color: #e0e0e0;\n margin-bottom: 24px;\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #333;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n color: #666;\n}\n\n/* ============================================\n CONCEPT D: HOME VIEW LAYOUT\n ============================================ */\n\n.home-view-concept-d {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.home-main-area {\n flex: 1;\n overflow-y: auto;\n transition: margin-right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.home-main-area.panel-open {\n margin-right: 320px;\n}\n\n/* ============================================\n SEARCH HERO\n ============================================ */\n\n.search-hero {\n background: linear-gradient(180deg, white 0%, #f5f7fa 100%);\n padding: 36px 40px 24px;\n text-align: center;\n}\n\n.search-hero-container {\n position: relative;\n max-width: 600px;\n margin: 0 auto;\n}\n\n.search-hero-input {\n width: 100%;\n padding: 14px 18px 14px 44px;\n font-size: 15px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n color: #111827;\n outline: none;\n transition: all 0.2s;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);\n font-family: inherit;\n}\n\n.search-hero-input:focus {\n border-color: #1976d2;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.1), 0 0 0 4px rgba(25, 118, 210, 0.08);\n}\n\n.search-hero-input::placeholder {\n color: #9ca3af;\n}\n\n.search-hero-icon {\n position: absolute;\n left: 16px;\n top: 50%;\n transform: translateY(-50%);\n color: #9ca3af;\n font-size: 15px;\n pointer-events: none;\n}\n\n.search-hero-shortcut {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%);\n background: #f5f7fa;\n border: 1px solid #e5e7eb;\n padding: 2px 7px;\n border-radius: 5px;\n font-size: 12px;\n color: #9ca3af;\n}\n\n.search-hero-clear {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n transition: all 0.15s ease;\n}\n\n.search-hero-clear:hover {\n background: #e0e0e0;\n color: #424242;\n}\n\n/* Meta row: entity count + pills */\n.search-meta-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-top: 16px;\n}\n\n.search-entity-count {\n font-size: 13px;\n color: #9ca3af;\n}\n\n.pill-toggle {\n display: flex;\n gap: 6px;\n}\n\n.pill-btn {\n padding: 6px 16px;\n border-radius: 20px;\n border: 1px solid #e5e7eb;\n background: white;\n font-size: 13px;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pill-btn:hover {\n border-color: #1976d2;\n color: #1976d2;\n}\n\n.pill-btn.active {\n background: #1976d2;\n color: white;\n border-color: #1976d2;\n}\n\n.pill-btn i {\n font-size: 11px;\n}\n\n/* ============================================\n APPLICATION GROUPS\n ============================================ */\n\n.entity-groups-area {\n padding: 12px 40px 60px;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.app-group {\n margin-bottom: 4px;\n}\n\n.app-group-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n cursor: pointer;\n border-radius: 8px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.app-group-header:hover {\n background: rgba(0, 0, 0, 0.025);\n}\n\n.app-group-icon {\n width: 38px;\n height: 38px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 17px;\n flex-shrink: 0;\n background: #eff6ff;\n color: #2563eb;\n}\n\n.app-group-name {\n font-size: 21px;\n font-weight: 600;\n flex: 1;\n}\n\n.app-group-count {\n font-size: 12px;\n color: #9ca3af;\n background: #f5f7fa;\n padding: 2px 9px;\n border-radius: 10px;\n}\n\n.app-group-chevron {\n color: #9ca3af;\n font-size: 12px;\n transition: transform 0.2s;\n}\n\n.app-group-chevron.expanded {\n transform: rotate(90deg);\n}\n\n.app-group-entities {\n padding: 4px 14px 10px 60px;\n}\n\n/* ============================================\n ENTITY ITEM GRID (pills)\n ============================================ */\n\n.entity-item-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: 12px;\n}\n\n.entity-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px 14px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n border: 1px solid #f0f1f3;\n background: white;\n}\n\n.entity-item:hover {\n border-color: #bfdbfe;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n background: #eff6ff;\n}\n\n.entity-item-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #6b7280;\n background: #f5f7fa;\n flex-shrink: 0;\n}\n\n.entity-item:hover .entity-item-icon {\n background: #dbeafe;\n color: #2563eb;\n}\n\n.entity-item-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.entity-item-name {\n font-size: 14px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.entity-item-desc {\n font-size: 12px;\n color: #9ca3af;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n}\n\n.entity-item-fav {\n color: #9ca3af;\n opacity: 0;\n transition: opacity 0.12s;\n font-size: 11px;\n cursor: pointer;\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 4px;\n align-self: center;\n}\n\n.entity-item:hover .entity-item-fav {\n opacity: 1;\n}\n\n.entity-item-fav.favorited {\n opacity: 1;\n color: #f59e0b;\n}\n\n/* ============================================\n QUICK ACCESS PANEL (right slide-in)\n ============================================ */\n\n.quick-access-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 320px;\n height: 100%;\n background: white;\n border-left: 1px solid #e5e7eb;\n z-index: 50;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.quick-access-panel.open {\n transform: translateX(0);\n}\n\n.qa-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.qa-header h3 {\n font-size: 14px;\n font-weight: 600;\n margin: 0;\n}\n\n.qa-close-btn {\n background: none;\n border: none;\n color: #9ca3af;\n cursor: pointer;\n font-size: 14px;\n padding: 4px;\n border-radius: 4px;\n}\n\n.qa-close-btn:hover {\n background: #f5f7fa;\n}\n\n.qa-body {\n flex: 1;\n overflow-y: auto;\n}\n\n.qa-section {\n border-bottom: 1px solid #f0f1f3;\n}\n\n.qa-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: #9ca3af;\n cursor: pointer;\n user-select: none;\n}\n\n.qa-section-header .qa-section-icon {\n font-size: 12px;\n}\n\n.qa-section-header .qa-section-count {\n background: #f5f7fa;\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n margin-left: auto;\n}\n\n.qa-section-header .qa-section-chevron {\n font-size: 10px;\n transition: transform 0.15s;\n}\n\n.qa-section.collapsed .qa-section-chevron {\n transform: rotate(-90deg);\n}\n\n.qa-section-body {\n padding: 0 8px 8px;\n}\n\n.qa-section.collapsed .qa-section-body {\n display: none;\n}\n\n.qa-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.08s;\n}\n\n.qa-item:hover {\n background: #f5f7fa;\n}\n\n.qa-item-icon {\n width: 28px;\n height: 28px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n background: #f5f7fa;\n color: #6b7280;\n flex-shrink: 0;\n}\n\n.qa-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.qa-item-name {\n font-size: 13px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.qa-item-meta {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.qa-item-time {\n font-size: 11px;\n color: #9ca3af;\n white-space: nowrap;\n}\n\n.qa-empty {\n padding: 20px 16px;\n text-align: center;\n color: #9ca3af;\n font-size: 13px;\n}\n\n/* Quick Access toggle button badge */\n.qa-badge {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 0 5px;\n border-radius: 8px;\n min-width: 16px;\n text-align: center;\n}\n\n/* No results state for home view */\n.home-no-results {\n text-align: center;\n padding: 40px 20px;\n color: #9ca3af;\n}\n\n.home-no-results i {\n font-size: 28px;\n margin-bottom: 10px;\n display: block;\n}\n\n.home-no-results p {\n font-size: 14px;\n margin: 0;\n}\n\n.detail-panel {\n flex-shrink: 0;\n height: 100%;\n background: white;\n border-left: 1px solid #e0e0e0;\n box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n.detail-panel mj-entity-record-detail-panel {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n@keyframes slideIn {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n/* Detail Panel Actions Bar */\n.detail-panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n}\n\n.detail-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n background: white;\n color: #475569;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.detail-action-btn:hover {\n background: #3b82f6;\n color: white;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2);\n}\n\n.detail-action-btn i {\n font-size: 12px;\n}\n\n:host ::ng-deep mj-explorer-grid-view,\n:host ::ng-deep mj-explorer-cards-view {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n/* ============================================\n HOME SCREEN STYLES\n ============================================ */\n\n/* Home-level header adjustments */\n.content-header.home-header {\n border-bottom: none;\n background: transparent;\n box-shadow: none;\n padding: 16px 24px 8px;\n}\n\n.content-body.home-content {\n padding: 0;\n}\n\n/* Smart filter with search icon (entity-level filter) */\n.filter-icon {\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n color: #999;\n font-size: 14px;\n pointer-events: none;\n}\n\n.smart-filter-container .smart-filter-input {\n padding-left: 40px;\n}\n\n/* ============================================\n VIEW MODE TOGGLE OVERRIDES\n ============================================ */\n\n.view-mode-toggle .toggle-btn {\n width: auto;\n padding: 0 12px;\n gap: 6px;\n}\n\n.toggle-label {\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ============================================\n EMPTY STATE VARIANTS\n ============================================ */\n\n.empty-state.small {\n height: auto;\n padding: 32px;\n background: #fafafa;\n}\n\n.empty-state.small .empty-icon {\n font-size: 40px;\n margin-bottom: 16px;\n}\n\n.empty-state.small h3 {\n font-size: 16px;\n}\n\n.empty-state.small p {\n font-size: 13px;\n}\n\n/* ============================================\n RESPONSIVE STYLES\n ============================================ */\n\n@media (max-width: 1200px) {\n .entity-item-grid {\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n }\n}\n\n@media (max-width: 900px) {\n .content-header {\n flex-wrap: wrap;\n gap: 12px;\n }\n\n .header-center {\n order: 3;\n flex-basis: 100%;\n max-width: 100%;\n }\n\n .search-hero {\n padding: 24px 16px 16px;\n }\n\n .entity-groups-area {\n padding: 8px 16px 40px;\n }\n\n .app-group-entities {\n padding-left: 36px;\n }\n\n .home-main-area.panel-open {\n margin-right: 0;\n }\n\n .quick-access-panel {\n width: 100%;\n }\n}\n\n@media (max-width: 600px) {\n .data-explorer-container {\n flex-direction: column;\n }\n\n .navigation-panel {\n display: none;\n }\n\n .content-header {\n padding: 12px 16px;\n }\n\n .content-body {\n padding: 12px 16px;\n }\n\n .entity-item-grid {\n grid-template-columns: 1fr;\n }\n\n .view-mode-toggle {\n display: none;\n }\n\n .app-group-name {\n font-size: 17px;\n }\n\n .entity-item-name {\n font-size: 14px;\n }\n}\n"] }]
|
|
3552
|
+
], template: "<div class=\"data-explorer-container\">\n <!-- Navigation Panel (Left) - Hidden at home level, animated -->\n @if (!isAtHomeLevel) {\n <div\n class=\"navigation-panel\"\n [class.collapsed]=\"state.navigationPanelCollapsed\"\n [style.width.px]=\"state.navigationPanelCollapsed ? 48 : state.navigationPanelWidth\"\n [@slideInLeft]>\n\n <mj-explorer-navigation-panel\n [entities]=\"entities\"\n [appEntityGroups]=\"appEntityGroups\"\n [selectedEntityName]=\"state.selectedEntityName\"\n [favorites]=\"state.favorites\"\n [recentItems]=\"state.recentItems\"\n [collapsed]=\"state.navigationPanelCollapsed\"\n [allowedEntityNames]=\"allowedEntityNames\"\n [favoritesSectionExpanded]=\"state.favoritesSectionExpanded\"\n [recentSectionExpanded]=\"state.recentSectionExpanded\"\n [entitiesSectionExpanded]=\"state.entitiesSectionExpanded\"\n [viewsSectionExpanded]=\"state.viewsSectionExpanded\"\n (entitySelected)=\"onEntitySelected($event)\"\n (toggleCollapse)=\"toggleNavigationPanel()\"\n (sectionToggled)=\"stateService.toggleSection($event)\"\n (openRecord)=\"onOpenRecordFromNav($event)\"\n (selectRecord)=\"onSelectRecordFromNav($event)\"\n (expandAndFocus)=\"onExpandAndFocus($event)\">\n </mj-explorer-navigation-panel>\n </div>\n }\n\n <!-- Main Content Area -->\n <div class=\"content-area\">\n <!-- Breadcrumb Bar - Hidden at home level -->\n @if (!isAtHomeLevel && breadcrumbs.length > 0) {\n <div class=\"breadcrumb-bar\">\n @for (crumb of breadcrumbs; track crumb.label; let i = $index; let last = $last) {\n <span\n class=\"breadcrumb-item\"\n [class.clickable]=\"!last\"\n [class.current]=\"last\"\n (click)=\"onBreadcrumbClick(crumb, i)\"\n [title]=\"crumb.label\">\n @if (crumb.icon) {\n <i [class]=\"crumb.icon\" class=\"breadcrumb-icon\"></i>\n }\n <span class=\"breadcrumb-label\">{{ crumb.label }}</span>\n </span>\n @if (!last) {\n <i class=\"fa-solid fa-chevron-right breadcrumb-separator\"></i>\n }\n }\n </div>\n }\n\n <!-- Header -->\n <div class=\"content-header\" [class.home-header]=\"isAtHomeLevel\">\n <div class=\"header-left\">\n @if (selectedEntity) {\n <i [class]=\"getEntityIcon(selectedEntity)\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ selectedEntity.DisplayNameOrName }}</h2>\n @if (debouncedFilterText && filteredRecordCount !== totalRecordCount) {\n <span class=\"record-count\">{{ filteredRecordCount | number }} of {{ totalRecordCount | number }} records</span>\n } @else {\n <span class=\"record-count\">{{ totalRecordCount | number }} records</span>\n }\n\n <!-- View Selector -->\n <mj-view-selector\n [entity]=\"selectedEntity\"\n [selectedViewId]=\"state.selectedViewId\"\n [viewModified]=\"state.viewModified\"\n (viewSelected)=\"onViewSelected($event)\"\n (saveViewRequested)=\"onSaveViewRequested($event)\"\n (manageViewsRequested)=\"onManageViewsRequested()\"\n (openInTabRequested)=\"onOpenInTabRequested($event)\"\n (configureViewRequested)=\"onConfigureViewRequested()\"\n (createNewRecordRequested)=\"onCreateNewRecord()\"\n (exportRequested)=\"onExport()\"\n (duplicateViewRequested)=\"onDuplicateView($event)\"\n (quickSaveRequested)=\"onQuickSaveRequested($event)\"\n (revertRequested)=\"onRevertView()\">\n </mj-view-selector>\n\n <!-- Add to List Button -->\n <button\n class=\"header-action-btn\"\n [class.disabled]=\"!hasSelectedRecords\"\n [disabled]=\"!hasSelectedRecords\"\n (click)=\"onAddToListClick()\"\n [title]=\"hasSelectedRecords ? 'Add ' + selectedRecords.length + ' selected record(s) to a list' : 'Select records to add to a list'\">\n <i class=\"fa-solid fa-list-check\"></i>\n @if (hasSelectedRecords) {\n <span class=\"selection-badge\">{{ selectedRecords.length }}</span>\n }\n </button>\n } @else {\n @if (displayIcon) {\n <i [class]=\"displayIcon\" class=\"entity-icon\"></i>\n }\n <h2 class=\"entity-title\">{{ displayTitle }}</h2>\n <span class=\"record-count\">{{ entities.length }} entities available</span>\n }\n </div>\n\n <div class=\"header-center\">\n @if (selectedEntity) {\n <div class=\"smart-filter-container\">\n <i class=\"fa-solid fa-search filter-icon\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"smart-filter-input\"\n placeholder=\"Filter records... (press / to focus)\"\n [value]=\"liveFilterText\"\n (input)=\"onFilterInputChanged(filterInput.value)\"\n />\n @if (liveFilterText) {\n <button class=\"clear-filter-btn\" (click)=\"clearRecordFilter()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n <!-- Home-level search moved to search hero section -->\n </div>\n\n <div class=\"header-right\">\n @if (selectedEntity) {\n <!-- View Mode Toggle -->\n <div class=\"view-mode-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'grid'\"\n (click)=\"onViewModeChanged('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'cards'\"\n (click)=\"onViewModeChanged('cards')\"\n title=\"Cards View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n @if (entityHasDateFields) {\n <button\n class=\"toggle-btn\"\n [class.active]=\"state.viewMode === 'timeline'\"\n (click)=\"onViewModeChanged('timeline')\"\n title=\"Timeline View\">\n <i class=\"fa-solid fa-timeline\"></i>\n </button>\n }\n </div>\n\n <!-- Timeline Controls (only shown when timeline view is active) -->\n @if (state.viewMode === 'timeline' && entityHasDateFields) {\n <!-- Date Field Selector -->\n <div class=\"date-field-selector-container\">\n <!-- Backdrop for closing dropdown -->\n @if (isDateFieldDropdownOpen) {\n <div class=\"date-field-backdrop\" (click)=\"closeDateFieldDropdown()\"></div>\n }\n\n <div class=\"date-field-selector-wrapper\">\n <button\n class=\"date-field-selector-button\"\n [class.open]=\"isDateFieldDropdownOpen\"\n [disabled]=\"availableDateFields.length <= 1\"\n (click)=\"toggleDateFieldDropdown()\">\n <i class=\"fa-solid fa-calendar-days date-field-icon\"></i>\n <span class=\"date-field-name\">{{ effectiveTimelineDateFieldDisplayName }}</span>\n @if (availableDateFields.length > 1) {\n <i class=\"fa-solid fa-chevron-down date-field-arrow\" [class.rotated]=\"isDateFieldDropdownOpen\"></i>\n }\n </button>\n\n @if (isDateFieldDropdownOpen && availableDateFields.length > 1) {\n <div class=\"date-field-dropdown-panel\">\n @for (field of availableDateFields; track field.name) {\n <div\n class=\"date-field-dropdown-item\"\n [class.selected]=\"field.name === effectiveTimelineDateField\"\n (click)=\"setTimelineDateField(field.name)\">\n <i class=\"fa-regular fa-calendar item-icon\"></i>\n <span class=\"item-name\">{{ field.displayName }}</span>\n @if (field.name === effectiveTimelineDateField) {\n <i class=\"fa-solid fa-check selected-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Orientation Toggle -->\n <div class=\"timeline-orientation-toggle\">\n <button\n class=\"toggle-btn\"\n (click)=\"toggleTimelineOrientation()\"\n [title]=\"state.timelineOrientation === 'vertical' ? 'Switch to Horizontal' : 'Switch to Vertical'\">\n <i [class]=\"state.timelineOrientation === 'vertical' ? 'fa-solid fa-ellipsis-vertical' : 'fa-solid fa-ellipsis'\"></i>\n </button>\n </div>\n\n <!-- Sort Order Toggle -->\n <div class=\"timeline-sort-toggle\">\n <button\n class=\"toggle-btn\"\n (click)=\"toggleTimelineSortOrder()\"\n [title]=\"state.timelineSortOrder === 'desc' ? 'Showing Newest First (click for Oldest First)' : 'Showing Oldest First (click for Newest First)'\">\n <i [class]=\"state.timelineSortOrder === 'desc' ? 'fa-solid fa-arrow-down-wide-short' : 'fa-solid fa-arrow-up-wide-short'\"></i>\n </button>\n </div>\n }\n }\n @if (!selectedEntity) {\n <!-- Quick Access panel toggle -->\n <button\n class=\"header-action-btn\"\n [class.active]=\"state.quickAccessPanelOpen\"\n (click)=\"toggleQuickAccessPanel()\"\n title=\"Recents & Favorites\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n @if (recentRecords.length + favoriteRecords.length > 0) {\n <span class=\"qa-badge\">{{ recentRecords.length + favoriteRecords.length }}</span>\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Content Body - Using mj-entity-viewer composite -->\n <div class=\"content-body\" [class.home-content]=\"isAtHomeLevel\">\n @if (!selectedEntity) {\n <!-- Concept D: Application Groups + Search-First Home View -->\n <div class=\"home-view-concept-d\">\n @if (isLoadingEntities) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading entities...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <div class=\"home-main-area\" [class.panel-open]=\"state.quickAccessPanelOpen\">\n <!-- Search Hero -->\n <div class=\"search-hero\">\n <div class=\"search-hero-container\">\n <i class=\"fa-solid fa-magnifying-glass search-hero-icon\"></i>\n <input\n #filterInput\n type=\"text\"\n class=\"search-hero-input\"\n placeholder=\"Search entities...\"\n [(ngModel)]=\"entityFilterText\"\n />\n @if (entityFilterText) {\n <button class=\"search-hero-clear\" (click)=\"entityFilterText = ''\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n } @else {\n <span class=\"search-hero-shortcut\">/</span>\n }\n </div>\n\n <!-- Meta row: entity count + All/Favorites pills -->\n <div class=\"search-meta-row\">\n <span class=\"search-entity-count\">\n {{ filteredEntityCount }} entities\n @if (applicationCount > 0) {\n across {{ applicationCount }} applications\n }\n </span>\n <div class=\"pill-toggle\">\n <button\n class=\"pill-btn\"\n [class.active]=\"state.homeViewMode === 'all'\"\n (click)=\"setHomeViewMode('all')\">\n All Entities\n </button>\n <button\n class=\"pill-btn\"\n [class.active]=\"state.homeViewMode === 'favorites'\"\n (click)=\"setHomeViewMode('favorites')\">\n <i class=\"fa-solid fa-star\"></i> My Favorites\n </button>\n </div>\n </div>\n </div>\n\n <!-- Entity Groups Area -->\n <div class=\"entity-groups-area\">\n @if (entityFilter?.applicationId) {\n <!-- Single-app mode: flat entity grid (no grouping) -->\n <div class=\"entity-item-grid\">\n @for (entity of flatFilteredEntities; track entity.ID) {\n <div\n class=\"entity-item\"\n (click)=\"onEntitySelected(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <div class=\"entity-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"entity-item-text\">\n <span class=\"entity-item-name\">{{ entity.DisplayNameOrName }}</span>\n @if (entity.Description) {\n <span class=\"entity-item-desc\">{{ entity.Description }}</span>\n }\n </div>\n <button\n class=\"entity-item-fav\"\n [class.favorited]=\"isEntityFavorited(entity)\"\n (click)=\"toggleEntityFavorite(entity, $event)\"\n [title]=\"isEntityFavorited(entity) ? 'Remove from favorites' : 'Add to favorites'\">\n <i [class]=\"isEntityFavorited(entity) ? 'fa-solid fa-star' : 'fa-regular fa-star'\"></i>\n </button>\n </div>\n }\n </div>\n } @else {\n <!-- Multi-app mode: grouped by application -->\n @for (group of filteredAppEntityGroups; track group.applicationId) {\n <div class=\"app-group\">\n <div class=\"app-group-header\" (click)=\"toggleAppGroup(group.applicationId)\">\n <div\n class=\"app-group-icon\"\n [style.background]=\"group.applicationColor ? group.applicationColor + '15' : null\"\n [style.color]=\"group.applicationColor || null\">\n <i [class]=\"group.applicationIcon || 'fa-solid fa-folder'\"></i>\n </div>\n <span class=\"app-group-name\">{{ group.applicationName }}</span>\n <span class=\"app-group-count\">{{ group.entities.length }}</span>\n <i class=\"fa-solid fa-chevron-right app-group-chevron\"\n [class.expanded]=\"group.isExpanded\"></i>\n </div>\n @if (group.isExpanded) {\n <div class=\"app-group-entities\">\n <div class=\"entity-item-grid\">\n @for (entity of group.entities; track entity.ID) {\n <div\n class=\"entity-item\"\n (click)=\"onEntitySelected(entity)\"\n [title]=\"entity.Description || entity.DisplayNameOrName\">\n <div class=\"entity-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"entity-item-text\">\n <span class=\"entity-item-name\">{{ entity.DisplayNameOrName }}</span>\n @if (entity.Description) {\n <span class=\"entity-item-desc\">{{ entity.Description }}</span>\n }\n </div>\n <button\n class=\"entity-item-fav\"\n [class.favorited]=\"isEntityFavorited(entity)\"\n (click)=\"toggleEntityFavorite(entity, $event)\"\n [title]=\"isEntityFavorited(entity) ? 'Remove from favorites' : 'Add to favorites'\">\n <i [class]=\"isEntityFavorited(entity) ? 'fa-solid fa-star' : 'fa-regular fa-star'\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n\n <!-- No results -->\n @if (filteredEntityCount === 0 && entities.length > 0) {\n <div class=\"home-no-results\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <p>No entities match \"{{ entityFilterText }}\"</p>\n </div>\n }\n @if (entities.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-database empty-icon\"></i>\n <h3>No Entities Available</h3>\n <p>There are no entities configured for this application.</p>\n </div>\n }\n </div>\n </div>\n\n <!-- Quick Access Panel (right slide-in) -->\n <div class=\"quick-access-panel\" [class.open]=\"state.quickAccessPanelOpen\">\n <div class=\"qa-header\">\n <h3>Quick Access</h3>\n <button class=\"qa-close-btn\" (click)=\"toggleQuickAccessPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"qa-body\">\n <!-- Recent Records (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('recentRecords')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('recentRecords')\">\n <i class=\"fa-solid fa-clock-rotate-left qa-section-icon\"></i>\n <span>Recent Records</span>\n <span class=\"qa-section-count\">{{ quickAccessRecentRecords.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (record of quickAccessRecentRecords; track record.entityId + '|' + record.recordId) {\n <div class=\"qa-item\" (click)=\"onRecentRecordClick(record)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIconById(record.entityId)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ record.recordName || record.recordId }}</div>\n <div class=\"qa-item-meta\">{{ record.entityName }}</div>\n </div>\n <span class=\"qa-item-time\">{{ formatRelativeTime(record.latestAt) }}</span>\n </div>\n }\n @if (quickAccessRecentRecords.length === 0) {\n <div class=\"qa-empty\">No recent records</div>\n }\n </div>\n </div>\n\n <!-- Recent Entities (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('recentEntities')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('recentEntities')\">\n <i class=\"fa-solid fa-table qa-section-icon\"></i>\n <span>Recent Entities</span>\n <span class=\"qa-section-count\">{{ quickAccessRecentEntities.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (entity of quickAccessRecentEntities; track entity.ID) {\n <div class=\"qa-item\" (click)=\"onEntitySelected(entity)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIcon(entity)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ entity.DisplayNameOrName }}</div>\n </div>\n </div>\n }\n @if (quickAccessRecentEntities.length === 0) {\n <div class=\"qa-empty\">No recent entities</div>\n }\n </div>\n </div>\n\n <!-- Favorite Records (max 3) -->\n <div class=\"qa-section\" [class.collapsed]=\"!isQuickAccessSectionExpanded('favoriteRecords')\">\n <div class=\"qa-section-header\" (click)=\"toggleQuickAccessSection('favoriteRecords')\">\n <i class=\"fa-solid fa-star qa-section-icon\" style=\"color: #f59e0b;\"></i>\n <span>Favorite Records</span>\n <span class=\"qa-section-count\">{{ quickAccessFavoriteRecords.length }}</span>\n <i class=\"fa-solid fa-chevron-down qa-section-chevron\"></i>\n </div>\n <div class=\"qa-section-body\">\n @for (record of quickAccessFavoriteRecords; track record.userFavoriteId) {\n <div class=\"qa-item\" (click)=\"onFavoriteRecordClick(record)\">\n <div class=\"qa-item-icon\">\n <i [class]=\"getEntityIconById(record.entityId)\"></i>\n </div>\n <div class=\"qa-item-info\">\n <div class=\"qa-item-name\">{{ record.recordName || record.recordId }}</div>\n <div class=\"qa-item-meta\">{{ record.entityName }}</div>\n </div>\n </div>\n }\n @if (quickAccessFavoriteRecords.length === 0) {\n <div class=\"qa-empty\">No favorite records</div>\n }\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-entity-viewer\n #entityViewer\n [entity]=\"selectedEntity\"\n [viewEntity]=\"selectedViewEntity\"\n [viewMode]=\"state.viewMode\"\n [filterText]=\"debouncedFilterText\"\n [selectedRecordId]=\"state.selectedRecordId\"\n [config]=\"viewerConfig\"\n [gridState]=\"currentGridState\"\n [timelineConfig]=\"currentTimelineConfig\"\n [gridSelectionMode]=\"'checkbox'\"\n [showGridToolbar]=\"false\"\n [showAddToListButton]=\"false\"\n (viewModeChange)=\"onViewModeChanged($event)\"\n (filterTextChange)=\"onFilterTextChanged($event)\"\n (recordSelected)=\"onViewerRecordSelected($event)\"\n (recordOpened)=\"onViewerRecordOpened($event)\"\n (dataLoaded)=\"onDataLoaded($event)\"\n (filteredCountChanged)=\"onFilteredCountChanged($event)\"\n (gridStateChanged)=\"onGridStateChanged($event)\"\n (selectionChanged)=\"onSelectionChanged($event)\"\n (addToListRequested)=\"onAddToListRequested($event)\">\n </mj-entity-viewer>\n }\n </div>\n </div>\n\n <!-- Detail Panel (Right - Slide In) -->\n @if (state.detailPanelOpen && selectedRecord) {\n <div class=\"detail-panel\" [style.width.px]=\"state.detailPanelWidth\">\n <!-- Detail Panel Actions Bar -->\n <div class=\"detail-panel-actions\">\n <button\n class=\"detail-action-btn\"\n (click)=\"openListManagementDialog()\"\n title=\"Add to List\">\n <i class=\"fa-solid fa-list-check\"></i>\n <span>Add to List</span>\n </button>\n </div>\n <mj-entity-record-detail-panel\n [entity]=\"detailPanelEntity\"\n [record]=\"selectedRecord\"\n (close)=\"onDetailPanelClosed()\"\n (openRecord)=\"onOpenRecord($event)\"\n (navigateToRelated)=\"onNavigateToRelated($event)\"\n (openRelatedRecord)=\"onOpenRelatedRecord($event)\"\n (openForeignKeyRecord)=\"onOpenForeignKeyRecord($event)\">\n </mj-entity-record-detail-panel>\n </div>\n }\n\n <!-- View Configuration Panel -->\n <mj-view-config-panel\n [entity]=\"selectedEntity\"\n [viewEntity]=\"selectedViewEntity\"\n [isOpen]=\"state.viewConfigPanelOpen\"\n [currentGridState]=\"currentGridState\"\n [externalFilterState]=\"filterDialogState\"\n [isSaving]=\"isSavingView\"\n [DefaultSaveAsNew]=\"defaultSaveAsNew\"\n (close)=\"onCloseViewConfigPanel()\"\n (save)=\"onSaveView($event)\"\n (saveDefaults)=\"onSaveDefaultViewSettings($event)\"\n (delete)=\"onDeleteView()\"\n (duplicate)=\"onDuplicateFromPanel()\"\n (openFilterDialogRequest)=\"onOpenFilterDialogRequest($event)\">\n </mj-view-config-panel>\n\n <!-- Filter Dialog (rendered at dashboard level for full viewport width) -->\n <mj-filter-dialog\n [isOpen]=\"isFilterDialogOpen\"\n [fields]=\"filterDialogFields\"\n [filter]=\"filterDialogState\"\n [disabled]=\"filterDialogDisabled\"\n (close)=\"onCloseFilterDialog()\"\n (apply)=\"onFilterApplied($event)\">\n </mj-filter-dialog>\n\n <!-- Export Dialog -->\n <mj-export-dialog\n [visible]=\"showExportDialog\"\n [config]=\"exportDialogConfig\"\n (closed)=\"onExportDialogClosed($event)\">\n </mj-export-dialog>\n\n <!-- List Management Dialog -->\n @if (showListManagementDialog && listManagementConfig) {\n <mj-list-management-dialog\n [config]=\"listManagementConfig\"\n [visible]=\"showListManagementDialog\"\n (complete)=\"onListManagementComplete($event)\"\n (cancel)=\"onListManagementCancel()\">\n </mj-list-management-dialog>\n }\n\n <!-- Quick Save Dialog (F-001) -->\n <mj-quick-save-dialog\n [IsOpen]=\"showQuickSaveDialog\"\n [ViewEntity]=\"selectedViewEntity\"\n [EntityName]=\"selectedEntity?.DisplayNameOrName ?? ''\"\n [Summary]=\"quickSaveSummary\"\n [IsSaving]=\"isSavingView\"\n [DefaultSaveAsNew]=\"defaultSaveAsNew\"\n (Save)=\"onQuickSave($event)\"\n (Close)=\"onQuickSaveClose()\"\n (OpenAdvanced)=\"onQuickSaveOpenAdvanced()\">\n </mj-quick-save-dialog>\n\n <!-- Duplicate View Dialog (F-005) -->\n <mj-duplicate-view-dialog\n [IsOpen]=\"showDuplicateDialog\"\n [SourceViewName]=\"duplicateSourceViewName\"\n [Summary]=\"duplicateSummary\"\n (Duplicate)=\"onDuplicateConfirmed($event)\"\n (Cancel)=\"onDuplicateCancel()\">\n </mj-duplicate-view-dialog>\n\n <!-- Shared View Warning Dialog (view-creation-flow Scenario 5) -->\n <mj-shared-view-warning-dialog\n [IsOpen]=\"showSharedViewWarning\"\n [ViewName]=\"selectedViewEntity?.Name ?? ''\"\n (Action)=\"onSharedViewAction($event)\"\n (Cancel)=\"onSharedViewWarningCancel()\">\n </mj-shared-view-warning-dialog>\n</div>\n", styles: [".data-explorer-container {\n display: flex;\n height: 100%;\n width: 100%;\n background: #f5f7fa;\n overflow: hidden;\n}\n\n.navigation-panel {\n flex-shrink: 0;\n height: 100%;\n background: white;\n border-right: 1px solid #e0e0e0;\n transition: width 0.2s ease-in-out;\n overflow: hidden;\n box-shadow: 2px 0 8px rgba(0, 0, 0, 0.04);\n}\n.navigation-panel.collapsed {\n width: 48px;\n}\n\n.content-area {\n flex: 1;\n display: flex;\n flex-direction: column;\n height: 100%;\n min-width: 0;\n overflow: hidden;\n background: #f5f7fa;\n}\n\n/* Breadcrumb Bar */\n.breadcrumb-bar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 24px;\n background: white;\n border-bottom: 1px solid #eee;\n flex-shrink: 0;\n font-size: 13px;\n min-height: 40px;\n}\n\n.breadcrumb-item {\n display: flex;\n align-items: center;\n gap: 6px;\n color: #666;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.15s ease;\n max-width: 200px;\n}\n\n.breadcrumb-item.clickable {\n cursor: pointer;\n}\n\n.breadcrumb-item.clickable:hover {\n background: #f0f0f0;\n color: #1976d2;\n}\n\n.breadcrumb-item.current {\n color: #1a1a1a;\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-icon {\n font-size: 12px;\n flex-shrink: 0;\n}\n\n.breadcrumb-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.breadcrumb-separator {\n font-size: 10px;\n color: #ccc;\n flex-shrink: 0;\n}\n\n.content-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n/* View Selector within header */\n.header-left ::ng-deep mj-view-selector {\n margin-left: 8px;\n}\n\n.entity-icon {\n font-size: 20px;\n color: #1976d2;\n}\n\n.entity-title {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.record-count {\n font-size: 13px;\n color: #666;\n font-weight: 500;\n}\n\n.header-center {\n flex: 1;\n max-width: 600px;\n}\n\n.smart-filter-container {\n position: relative;\n width: 100%;\n}\n\n.smart-filter-input {\n width: 100%;\n padding: 10px 40px 10px 16px;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n font-size: 14px;\n background: #fafafa;\n transition: all 0.15s ease;\n}\n.smart-filter-input:focus {\n outline: none;\n border-color: #1976d2;\n background: white;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n}\n.smart-filter-input::placeholder {\n color: #999;\n}\n\n.clear-filter-btn {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n transition: all 0.15s ease;\n}\n.clear-filter-btn:hover {\n background: #e0e0e0;\n color: #424242;\n}\n\n.header-right {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n.view-mode-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n}\n.toggle-btn:hover {\n color: #333;\n}\n.toggle-btn.active {\n background: white;\n color: #1976d2;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* Header Action Button (Add to List, etc.) */\n.header-action-btn {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid #e0e0e0;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n transition: all 0.15s ease;\n margin-left: 8px;\n}\n.header-action-btn:hover:not(.disabled) {\n border-color: #1976d2;\n color: #1976d2;\n background: #f5f9ff;\n}\n.header-action-btn.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.header-action-btn i {\n font-size: 14px;\n}\n.selection-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: #1976d2;\n color: white;\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n/* Timeline Date Field Selector - Styled Dropdown */\n.date-field-selector-container {\n display: flex;\n align-items: center;\n position: relative;\n}\n\n.date-field-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 999;\n background: transparent;\n}\n\n.date-field-selector-wrapper {\n position: relative;\n}\n\n.date-field-selector-button {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n background: var(--background-alt, #f5f5f5);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--text-primary, #333);\n transition: all 0.15s ease;\n min-width: 120px;\n max-width: 200px;\n}\n\n.date-field-selector-button:hover:not(:disabled) {\n background: var(--background-hover, #e8e8e8);\n border-color: var(--border-color-hover, #ccc);\n}\n\n.date-field-selector-button:disabled {\n cursor: default;\n opacity: 0.8;\n}\n\n.date-field-selector-button.open {\n background: var(--background-active, #e0e0e0);\n border-color: var(--primary-color, #007bff);\n}\n\n.date-field-icon {\n color: var(--text-secondary, #666);\n font-size: 12px;\n}\n\n.date-field-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n}\n\n.date-field-arrow {\n color: var(--text-secondary, #666);\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.date-field-arrow.rotated {\n transform: rotate(180deg);\n}\n\n.date-field-dropdown-panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n min-width: 180px;\n max-width: 280px;\n max-height: 300px;\n overflow-y: auto;\n background: var(--background-panel, #fff);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n}\n\n.date-field-dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n cursor: pointer;\n transition: background 0.1s ease;\n font-size: 13px;\n}\n\n.date-field-dropdown-item:hover {\n background: var(--background-hover, #f5f5f5);\n}\n\n.date-field-dropdown-item.selected {\n background: var(--primary-light, #e6f0ff);\n}\n\n.date-field-dropdown-item.selected:hover {\n background: var(--primary-light-hover, #d6e4f9);\n}\n\n.date-field-dropdown-item .item-icon {\n color: var(--text-secondary, #666);\n font-size: 13px;\n width: 16px;\n text-align: center;\n}\n\n.date-field-dropdown-item .item-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.date-field-dropdown-item .selected-check {\n color: var(--primary-color, #007bff);\n font-size: 12px;\n}\n\n/* Timeline Orientation Toggle */\n.timeline-orientation-toggle {\n display: flex;\n background: #f0f0f0;\n border-radius: 8px;\n padding: 3px;\n}\n\n.content-body {\n flex: 1;\n overflow: hidden;\n padding: 20px 24px;\n display: flex;\n flex-direction: column;\n}\n\n.loading-container,\n.loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 16px;\n background: white;\n border-radius: 8px;\n}\n\n.loading-spinner {\n font-size: 32px;\n color: #1976d2;\n}\n\n.loading-message {\n margin: 0;\n font-size: 14px;\n color: #666;\n}\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #757575;\n background: white;\n border-radius: 8px;\n padding: 40px;\n}\n\n.empty-icon {\n font-size: 64px;\n color: #e0e0e0;\n margin-bottom: 24px;\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #333;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n color: #666;\n}\n\n/* ============================================\n CONCEPT D: HOME VIEW LAYOUT\n ============================================ */\n\n.home-view-concept-d {\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.home-main-area {\n flex: 1;\n overflow-y: auto;\n transition: margin-right 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.home-main-area.panel-open {\n margin-right: 320px;\n}\n\n/* ============================================\n SEARCH HERO\n ============================================ */\n\n.search-hero {\n background: linear-gradient(180deg, white 0%, #f5f7fa 100%);\n padding: 36px 40px 24px;\n text-align: center;\n}\n\n.search-hero-container {\n position: relative;\n max-width: 600px;\n margin: 0 auto;\n}\n\n.search-hero-input {\n width: 100%;\n padding: 14px 18px 14px 44px;\n font-size: 15px;\n border: 2px solid #e5e7eb;\n border-radius: 12px;\n background: white;\n color: #111827;\n outline: none;\n transition: all 0.2s;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);\n font-family: inherit;\n}\n\n.search-hero-input:focus {\n border-color: #1976d2;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.1), 0 0 0 4px rgba(25, 118, 210, 0.08);\n}\n\n.search-hero-input::placeholder {\n color: #9ca3af;\n}\n\n.search-hero-icon {\n position: absolute;\n left: 16px;\n top: 50%;\n transform: translateY(-50%);\n color: #9ca3af;\n font-size: 15px;\n pointer-events: none;\n}\n\n.search-hero-shortcut {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%);\n background: #f5f7fa;\n border: 1px solid #e5e7eb;\n padding: 2px 7px;\n border-radius: 5px;\n font-size: 12px;\n color: #9ca3af;\n}\n\n.search-hero-clear {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n transition: all 0.15s ease;\n}\n\n.search-hero-clear:hover {\n background: #e0e0e0;\n color: #424242;\n}\n\n/* Meta row: entity count + pills */\n.search-meta-row {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-top: 16px;\n}\n\n.search-entity-count {\n font-size: 13px;\n color: #9ca3af;\n}\n\n.pill-toggle {\n display: flex;\n gap: 6px;\n}\n\n.pill-btn {\n padding: 6px 16px;\n border-radius: 20px;\n border: 1px solid #e5e7eb;\n background: white;\n font-size: 13px;\n color: #6b7280;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pill-btn:hover {\n border-color: #1976d2;\n color: #1976d2;\n}\n\n.pill-btn.active {\n background: #1976d2;\n color: white;\n border-color: #1976d2;\n}\n\n.pill-btn i {\n font-size: 11px;\n}\n\n/* ============================================\n APPLICATION GROUPS\n ============================================ */\n\n.entity-groups-area {\n padding: 12px 40px 60px;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.app-group {\n margin-bottom: 4px;\n}\n\n.app-group-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n cursor: pointer;\n border-radius: 8px;\n transition: background 0.12s;\n user-select: none;\n}\n\n.app-group-header:hover {\n background: rgba(0, 0, 0, 0.025);\n}\n\n.app-group-icon {\n width: 38px;\n height: 38px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 17px;\n flex-shrink: 0;\n background: #eff6ff;\n color: #2563eb;\n}\n\n.app-group-name {\n font-size: 21px;\n font-weight: 600;\n flex: 1;\n}\n\n.app-group-count {\n font-size: 12px;\n color: #9ca3af;\n background: #f5f7fa;\n padding: 2px 9px;\n border-radius: 10px;\n}\n\n.app-group-chevron {\n color: #9ca3af;\n font-size: 12px;\n transition: transform 0.2s;\n}\n\n.app-group-chevron.expanded {\n transform: rotate(90deg);\n}\n\n.app-group-entities {\n padding: 4px 14px 10px 60px;\n}\n\n/* ============================================\n ENTITY ITEM GRID (pills)\n ============================================ */\n\n.entity-item-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: 12px;\n}\n\n.entity-item {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 10px 14px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n border: 1px solid #f0f1f3;\n background: white;\n}\n\n.entity-item:hover {\n border-color: #bfdbfe;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n background: #eff6ff;\n}\n\n.entity-item-icon {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: #6b7280;\n background: #f5f7fa;\n flex-shrink: 0;\n}\n\n.entity-item:hover .entity-item-icon {\n background: #dbeafe;\n color: #2563eb;\n}\n\n.entity-item-text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.entity-item-name {\n font-size: 14px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.entity-item-desc {\n font-size: 12px;\n color: #9ca3af;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: 1.3;\n}\n\n.entity-item-fav {\n color: #9ca3af;\n opacity: 0;\n transition: opacity 0.12s;\n font-size: 11px;\n cursor: pointer;\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 4px;\n align-self: center;\n}\n\n.entity-item:hover .entity-item-fav {\n opacity: 1;\n}\n\n.entity-item-fav.favorited {\n opacity: 1;\n color: #f59e0b;\n}\n\n/* ============================================\n QUICK ACCESS PANEL (right slide-in)\n ============================================ */\n\n.quick-access-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 320px;\n height: 100%;\n background: white;\n border-left: 1px solid #e5e7eb;\n z-index: 50;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.quick-access-panel.open {\n transform: translateX(0);\n}\n\n.qa-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid #e5e7eb;\n}\n\n.qa-header h3 {\n font-size: 14px;\n font-weight: 600;\n margin: 0;\n}\n\n.qa-close-btn {\n background: none;\n border: none;\n color: #9ca3af;\n cursor: pointer;\n font-size: 14px;\n padding: 4px;\n border-radius: 4px;\n}\n\n.qa-close-btn:hover {\n background: #f5f7fa;\n}\n\n.qa-body {\n flex: 1;\n overflow-y: auto;\n}\n\n.qa-section {\n border-bottom: 1px solid #f0f1f3;\n}\n\n.qa-section-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.8px;\n color: #9ca3af;\n cursor: pointer;\n user-select: none;\n}\n\n.qa-section-header .qa-section-icon {\n font-size: 12px;\n}\n\n.qa-section-header .qa-section-count {\n background: #f5f7fa;\n padding: 0 6px;\n border-radius: 8px;\n font-size: 10px;\n margin-left: auto;\n}\n\n.qa-section-header .qa-section-chevron {\n font-size: 10px;\n transition: transform 0.15s;\n}\n\n.qa-section.collapsed .qa-section-chevron {\n transform: rotate(-90deg);\n}\n\n.qa-section-body {\n padding: 0 8px 8px;\n}\n\n.qa-section.collapsed .qa-section-body {\n display: none;\n}\n\n.qa-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.08s;\n}\n\n.qa-item:hover {\n background: #f5f7fa;\n}\n\n.qa-item-icon {\n width: 28px;\n height: 28px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n background: #f5f7fa;\n color: #6b7280;\n flex-shrink: 0;\n}\n\n.qa-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.qa-item-name {\n font-size: 13px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.qa-item-meta {\n font-size: 11px;\n color: #9ca3af;\n}\n\n.qa-item-time {\n font-size: 11px;\n color: #9ca3af;\n white-space: nowrap;\n}\n\n.qa-empty {\n padding: 20px 16px;\n text-align: center;\n color: #9ca3af;\n font-size: 13px;\n}\n\n/* Quick Access toggle button badge */\n.qa-badge {\n background: #1976d2;\n color: white;\n font-size: 10px;\n font-weight: 600;\n padding: 0 5px;\n border-radius: 8px;\n min-width: 16px;\n text-align: center;\n}\n\n/* No results state for home view */\n.home-no-results {\n text-align: center;\n padding: 40px 20px;\n color: #9ca3af;\n}\n\n.home-no-results i {\n font-size: 28px;\n margin-bottom: 10px;\n display: block;\n}\n\n.home-no-results p {\n font-size: 14px;\n margin: 0;\n}\n\n.detail-panel {\n flex-shrink: 0;\n height: 100%;\n background: white;\n border-left: 1px solid #e0e0e0;\n box-shadow: -4px 0 16px rgba(0, 0, 0, 0.08);\n overflow: hidden;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n.detail-panel mj-entity-record-detail-panel {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n@keyframes slideIn {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n/* Detail Panel Actions Bar */\n.detail-panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n}\n\n.detail-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border: none;\n border-radius: 6px;\n background: white;\n color: #475569;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.detail-action-btn:hover {\n background: #3b82f6;\n color: white;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2);\n}\n\n.detail-action-btn i {\n font-size: 12px;\n}\n\n:host ::ng-deep mj-explorer-grid-view,\n:host ::ng-deep mj-explorer-cards-view {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n\n/* ============================================\n HOME SCREEN STYLES\n ============================================ */\n\n/* Home-level header adjustments */\n.content-header.home-header {\n border-bottom: none;\n background: transparent;\n box-shadow: none;\n padding: 16px 24px 8px;\n}\n\n.content-body.home-content {\n padding: 0;\n}\n\n/* Smart filter with search icon (entity-level filter) */\n.filter-icon {\n position: absolute;\n left: 14px;\n top: 50%;\n transform: translateY(-50%);\n color: #999;\n font-size: 14px;\n pointer-events: none;\n}\n\n.smart-filter-container .smart-filter-input {\n padding-left: 40px;\n}\n\n/* ============================================\n VIEW MODE TOGGLE OVERRIDES\n ============================================ */\n\n.view-mode-toggle .toggle-btn {\n width: auto;\n padding: 0 12px;\n gap: 6px;\n}\n\n.toggle-label {\n font-size: 12px;\n font-weight: 500;\n}\n\n/* ============================================\n EMPTY STATE VARIANTS\n ============================================ */\n\n.empty-state.small {\n height: auto;\n padding: 32px;\n background: #fafafa;\n}\n\n.empty-state.small .empty-icon {\n font-size: 40px;\n margin-bottom: 16px;\n}\n\n.empty-state.small h3 {\n font-size: 16px;\n}\n\n.empty-state.small p {\n font-size: 13px;\n}\n\n/* ============================================\n RESPONSIVE STYLES\n ============================================ */\n\n@media (max-width: 1200px) {\n .entity-item-grid {\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n }\n}\n\n@media (max-width: 900px) {\n .content-header {\n flex-wrap: wrap;\n gap: 12px;\n }\n\n .header-center {\n order: 3;\n flex-basis: 100%;\n max-width: 100%;\n }\n\n .search-hero {\n padding: 24px 16px 16px;\n }\n\n .entity-groups-area {\n padding: 8px 16px 40px;\n }\n\n .app-group-entities {\n padding-left: 36px;\n }\n\n .home-main-area.panel-open {\n margin-right: 0;\n }\n\n .quick-access-panel {\n width: 100%;\n }\n}\n\n@media (max-width: 600px) {\n .data-explorer-container {\n flex-direction: column;\n }\n\n .navigation-panel {\n display: none;\n }\n\n .content-header {\n padding: 12px 16px;\n }\n\n .content-body {\n padding: 12px 16px;\n }\n\n .entity-item-grid {\n grid-template-columns: 1fr;\n }\n\n .view-mode-toggle {\n display: none;\n }\n\n .app-group-name {\n font-size: 17px;\n }\n\n .entity-item-name {\n font-size: 14px;\n }\n}\n"] }]
|
|
3521
3553
|
}], () => [{ type: i1.ExplorerStateService }, { type: i0.ChangeDetectorRef }, { type: i2.Router }, { type: i3.RecentAccessService }, { type: i4.NavigationService }, { type: i5.ExportService }, { type: i0.NgZone }], { filterInputRef: [{
|
|
3522
3554
|
type: ViewChild,
|
|
3523
3555
|
args: ['filterInput']
|