@webiny/app-admin-ui 0.0.0-unstable.7be00a75a9 → 0.0.0-unstable.7c2def32a7
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/Breadcrumbs/Breadcrumbs.d.ts +14 -0
- package/Breadcrumbs/Breadcrumbs.js +74 -0
- package/Breadcrumbs/Breadcrumbs.js.map +1 -0
- package/CommandPalette/CommandPalette.d.ts +6 -0
- package/CommandPalette/CommandPalette.js +202 -0
- package/CommandPalette/CommandPalette.js.map +1 -0
- package/CommandPalette/components/AiModeBadge.d.ts +3 -0
- package/CommandPalette/components/AiModeBadge.js +11 -0
- package/CommandPalette/components/AiModeBadge.js.map +1 -0
- package/CommandPalette/components/AiSuggestions.d.ts +9 -0
- package/CommandPalette/components/AiSuggestions.js +32 -0
- package/CommandPalette/components/AiSuggestions.js.map +1 -0
- package/CommandPalette/components/AiTurn.d.ts +11 -0
- package/CommandPalette/components/AiTurn.js +61 -0
- package/CommandPalette/components/AiTurn.js.map +1 -0
- package/CommandPalette/components/AnswerSkeleton.d.ts +6 -0
- package/CommandPalette/components/AnswerSkeleton.js +20 -0
- package/CommandPalette/components/AnswerSkeleton.js.map +1 -0
- package/CommandPalette/components/ApprovalPlan.d.ts +16 -0
- package/CommandPalette/components/ApprovalPlan.js +56 -0
- package/CommandPalette/components/ApprovalPlan.js.map +1 -0
- package/CommandPalette/components/CommandDetail.d.ts +13 -0
- package/CommandPalette/components/CommandDetail.js +39 -0
- package/CommandPalette/components/CommandDetail.js.map +1 -0
- package/CommandPalette/components/CommandItemRow.d.ts +5 -0
- package/CommandPalette/components/CommandItemRow.js +41 -0
- package/CommandPalette/components/CommandItemRow.js.map +1 -0
- package/CommandPalette/components/GroupHeading.d.ts +4 -0
- package/CommandPalette/components/GroupHeading.js +10 -0
- package/CommandPalette/components/GroupHeading.js.map +1 -0
- package/CommandPalette/components/HintIcon.d.ts +4 -0
- package/CommandPalette/components/HintIcon.js +11 -0
- package/CommandPalette/components/HintIcon.js.map +1 -0
- package/CommandPalette/components/Kbd.d.ts +4 -0
- package/CommandPalette/components/Kbd.js +14 -0
- package/CommandPalette/components/Kbd.js.map +1 -0
- package/CommandPalette/components/NoResults.d.ts +13 -0
- package/CommandPalette/components/NoResults.js +33 -0
- package/CommandPalette/components/NoResults.js.map +1 -0
- package/CommandPalette/components/PaletteFooter.d.ts +13 -0
- package/CommandPalette/components/PaletteFooter.js +18 -0
- package/CommandPalette/components/PaletteFooter.js.map +1 -0
- package/CommandPalette/components/ToolChip.d.ts +7 -0
- package/CommandPalette/components/ToolChip.js +32 -0
- package/CommandPalette/components/ToolChip.js.map +1 -0
- package/CommandPalette/components/index.d.ts +13 -0
- package/CommandPalette/components/index.js +13 -0
- package/CommandPalette/constants.d.ts +8 -0
- package/CommandPalette/constants.js +5 -0
- package/CommandPalette/constants.js.map +1 -0
- package/CommandPalette/deriveRows.d.ts +19 -0
- package/CommandPalette/deriveRows.js +100 -0
- package/CommandPalette/deriveRows.js.map +1 -0
- package/CommandPalette/modes/PaletteMode.d.ts +73 -0
- package/CommandPalette/modes/PaletteMode.js +0 -0
- package/CommandPalette/modes/createAiMode.d.ts +13 -0
- package/CommandPalette/modes/createAiMode.js +80 -0
- package/CommandPalette/modes/createAiMode.js.map +1 -0
- package/CommandPalette/modes/index.d.ts +2 -0
- package/CommandPalette/modes/index.js +1 -0
- package/CommandPalette/types.d.ts +15 -0
- package/CommandPalette/types.js +0 -0
- package/CommandPalette/usePaletteHotkeys.d.ts +16 -0
- package/CommandPalette/usePaletteHotkeys.js +38 -0
- package/CommandPalette/usePaletteHotkeys.js.map +1 -0
- package/Dashboard/Welcome.d.ts +4 -1
- package/Dashboard/Welcome.js +111 -24
- package/Dashboard/Welcome.js.map +1 -1
- package/Dashboard/components/DashboardToolbar.d.ts +11 -0
- package/Dashboard/components/DashboardToolbar.js +48 -0
- package/Dashboard/components/DashboardToolbar.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/AddToColumnMenu.d.ts +10 -0
- package/Dashboard/components/addWidgetDrawer/AddToColumnMenu.js +30 -0
- package/Dashboard/components/addWidgetDrawer/AddToColumnMenu.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/AddWidgetDrawer.d.ts +12 -0
- package/Dashboard/components/addWidgetDrawer/AddWidgetDrawer.js +61 -0
- package/Dashboard/components/addWidgetDrawer/AddWidgetDrawer.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/DrawerWidgetRow.d.ts +10 -0
- package/Dashboard/components/addWidgetDrawer/DrawerWidgetRow.js +38 -0
- package/Dashboard/components/addWidgetDrawer/DrawerWidgetRow.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/WidgetPreviewFrame.d.ts +7 -0
- package/Dashboard/components/addWidgetDrawer/WidgetPreviewFrame.js +44 -0
- package/Dashboard/components/addWidgetDrawer/WidgetPreviewFrame.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/WidgetSketch.d.ts +4 -0
- package/Dashboard/components/addWidgetDrawer/WidgetSketch.js +20 -0
- package/Dashboard/components/addWidgetDrawer/WidgetSketch.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/WidgetTabContent.d.ts +14 -0
- package/Dashboard/components/addWidgetDrawer/WidgetTabContent.js +76 -0
- package/Dashboard/components/addWidgetDrawer/WidgetTabContent.js.map +1 -0
- package/Dashboard/components/addWidgetDrawer/types.d.ts +10 -0
- package/Dashboard/components/addWidgetDrawer/types.js +0 -0
- package/Dashboard/components/dnd/ColumnCountControl.d.ts +9 -0
- package/Dashboard/components/dnd/ColumnCountControl.js +52 -0
- package/Dashboard/components/dnd/ColumnCountControl.js.map +1 -0
- package/Dashboard/components/dnd/ColumnEmptyState.d.ts +10 -0
- package/Dashboard/components/dnd/ColumnEmptyState.js +52 -0
- package/Dashboard/components/dnd/ColumnEmptyState.js.map +1 -0
- package/Dashboard/components/dnd/DashboardDragLayer.d.ts +6 -0
- package/Dashboard/components/dnd/DashboardDragLayer.js +28 -0
- package/Dashboard/components/dnd/DashboardDragLayer.js.map +1 -0
- package/Dashboard/components/dnd/DashboardWidgetCard.d.ts +13 -0
- package/Dashboard/components/dnd/DashboardWidgetCard.js +59 -0
- package/Dashboard/components/dnd/DashboardWidgetCard.js.map +1 -0
- package/Dashboard/components/dnd/DashboardWidgetColumn.d.ts +19 -0
- package/Dashboard/components/dnd/DashboardWidgetColumn.js +72 -0
- package/Dashboard/components/dnd/DashboardWidgetColumn.js.map +1 -0
- package/Dashboard/components/dnd/WidgetDropIndicator.d.ts +11 -0
- package/Dashboard/components/dnd/WidgetDropIndicator.js +29 -0
- package/Dashboard/components/dnd/WidgetDropIndicator.js.map +1 -0
- package/Dashboard/components/dnd/WidgetSlot.d.ts +6 -0
- package/Dashboard/components/dnd/WidgetSlot.js +9 -0
- package/Dashboard/components/dnd/WidgetSlot.js.map +1 -0
- package/Dashboard/components/dnd/dragItem.d.ts +6 -0
- package/Dashboard/components/dnd/dragItem.js +4 -0
- package/Dashboard/components/dnd/dragItem.js.map +1 -0
- package/Dashboard/components/dnd/useWidgetHosts.d.ts +1 -0
- package/Dashboard/components/dnd/useWidgetHosts.js +16 -0
- package/Dashboard/components/dnd/useWidgetHosts.js.map +1 -0
- package/Dashboard/components/layout/EditableColumns.d.ts +13 -0
- package/Dashboard/components/layout/EditableColumns.js +25 -0
- package/Dashboard/components/layout/EditableColumns.js.map +1 -0
- package/Dashboard/components/layout/StaticColumns.d.ts +8 -0
- package/Dashboard/components/layout/StaticColumns.js +20 -0
- package/Dashboard/components/layout/StaticColumns.js.map +1 -0
- package/Dashboard/components/layout/collapseColumns.d.ts +1 -0
- package/Dashboard/components/layout/collapseColumns.js +16 -0
- package/Dashboard/components/layout/collapseColumns.js.map +1 -0
- package/Dashboard/components/layout/layoutConstants.d.ts +2 -0
- package/Dashboard/components/layout/layoutConstants.js +5 -0
- package/Dashboard/components/layout/layoutConstants.js.map +1 -0
- package/Dashboard/components/layout/useColumnsThatFit.d.ts +6 -0
- package/Dashboard/components/layout/useColumnsThatFit.js +30 -0
- package/Dashboard/components/layout/useColumnsThatFit.js.map +1 -0
- package/Dashboard/components/layout/useWidgetPortals.d.ts +5 -0
- package/Dashboard/components/layout/useWidgetPortals.js +26 -0
- package/Dashboard/components/layout/useWidgetPortals.js.map +1 -0
- package/Dashboard/dashboardLayout/loadLayout/FetchDashboardLayoutUseCase.d.ts +12 -0
- package/Dashboard/dashboardLayout/loadLayout/FetchDashboardLayoutUseCase.js +19 -0
- package/Dashboard/dashboardLayout/loadLayout/FetchDashboardLayoutUseCase.js.map +1 -0
- package/Dashboard/dashboardLayout/loadLayout/GetCachedDashboardLayoutUseCase.d.ts +12 -0
- package/Dashboard/dashboardLayout/loadLayout/GetCachedDashboardLayoutUseCase.js +19 -0
- package/Dashboard/dashboardLayout/loadLayout/GetCachedDashboardLayoutUseCase.js.map +1 -0
- package/Dashboard/dashboardLayout/loadLayout/abstractions.d.ts +15 -0
- package/Dashboard/dashboardLayout/loadLayout/abstractions.js +6 -0
- package/Dashboard/dashboardLayout/loadLayout/abstractions.js.map +1 -0
- package/Dashboard/dashboardLayout/loadLayout/feature.d.ts +1 -0
- package/Dashboard/dashboardLayout/loadLayout/feature.js +13 -0
- package/Dashboard/dashboardLayout/loadLayout/feature.js.map +1 -0
- package/Dashboard/dashboardLayout/presenter/DashboardLayoutPresenter.d.ts +56 -0
- package/Dashboard/dashboardLayout/presenter/DashboardLayoutPresenter.js +308 -0
- package/Dashboard/dashboardLayout/presenter/DashboardLayoutPresenter.js.map +1 -0
- package/Dashboard/dashboardLayout/presenter/abstractions.d.ts +46 -0
- package/Dashboard/dashboardLayout/presenter/abstractions.js +5 -0
- package/Dashboard/dashboardLayout/presenter/abstractions.js.map +1 -0
- package/Dashboard/dashboardLayout/presenter/feature.d.ts +3 -0
- package/Dashboard/dashboardLayout/presenter/feature.js +23 -0
- package/Dashboard/dashboardLayout/presenter/feature.js.map +1 -0
- package/Dashboard/dashboardLayout/presenter/useDashboardLayoutPresenter.d.ts +1 -0
- package/Dashboard/dashboardLayout/presenter/useDashboardLayoutPresenter.js +6 -0
- package/Dashboard/dashboardLayout/presenter/useDashboardLayoutPresenter.js.map +1 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutGateway.d.ts +13 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutGateway.js +67 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutGateway.js.map +1 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutRepository.d.ts +20 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutRepository.js +49 -0
- package/Dashboard/dashboardLayout/repository/DashboardLayoutRepository.js.map +1 -0
- package/Dashboard/dashboardLayout/repository/abstractions.d.ts +25 -0
- package/Dashboard/dashboardLayout/repository/abstractions.js +6 -0
- package/Dashboard/dashboardLayout/repository/abstractions.js.map +1 -0
- package/Dashboard/dashboardLayout/repository/feature.d.ts +1 -0
- package/Dashboard/dashboardLayout/repository/feature.js +13 -0
- package/Dashboard/dashboardLayout/repository/feature.js.map +1 -0
- package/Dashboard/dashboardLayout/saveLayout/SaveDashboardLayoutUseCase.d.ts +12 -0
- package/Dashboard/dashboardLayout/saveLayout/SaveDashboardLayoutUseCase.js +19 -0
- package/Dashboard/dashboardLayout/saveLayout/SaveDashboardLayoutUseCase.js.map +1 -0
- package/Dashboard/dashboardLayout/saveLayout/abstractions.d.ts +8 -0
- package/Dashboard/dashboardLayout/saveLayout/abstractions.js +5 -0
- package/Dashboard/dashboardLayout/saveLayout/abstractions.js.map +1 -0
- package/Dashboard/dashboardLayout/saveLayout/feature.d.ts +1 -0
- package/Dashboard/dashboardLayout/saveLayout/feature.js +11 -0
- package/Dashboard/dashboardLayout/saveLayout/feature.js.map +1 -0
- package/Dashboard/dashboardLayout/toColumnIndex.d.ts +1 -0
- package/Dashboard/dashboardLayout/toColumnIndex.js +7 -0
- package/Dashboard/dashboardLayout/toColumnIndex.js.map +1 -0
- package/Dashboard/dashboardLayout/types.d.ts +15 -0
- package/Dashboard/dashboardLayout/types.js +6 -0
- package/Dashboard/dashboardLayout/types.js.map +1 -0
- package/Layout.js +50 -21
- package/Layout.js.map +1 -1
- package/index.js +16 -5
- package/index.js.map +1 -1
- package/package.json +15 -8
- package/Navigation/SidebarProvider.d.ts +0 -6
- package/Navigation/SidebarProvider.js +0 -26
- package/Navigation/SidebarProvider.js.map +0 -1
- package/Navigation.d.ts +0 -2
- package/Navigation.js +0 -10
- package/Navigation.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { GetCachedDashboardLayoutUseCase } from "../loadLayout/abstractions.js";
|
|
2
|
+
import { FetchDashboardLayoutUseCase } from "../loadLayout/abstractions.js";
|
|
3
|
+
import { SaveDashboardLayoutUseCase } from "../saveLayout/abstractions.js";
|
|
4
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
5
|
+
import { DashboardLayoutPresenter as Abstraction } from "./abstractions.js";
|
|
6
|
+
import type { DashboardWidgetInput } from "./abstractions.js";
|
|
7
|
+
declare class DashboardLayoutPresenterImpl implements Abstraction.Interface {
|
|
8
|
+
private getCachedDashboardLayoutUseCase;
|
|
9
|
+
private fetchDashboardLayoutUseCase;
|
|
10
|
+
private saveDashboardLayoutUseCase;
|
|
11
|
+
private _userId;
|
|
12
|
+
private _columns;
|
|
13
|
+
private _columnCount;
|
|
14
|
+
private _hidden;
|
|
15
|
+
private _draggingName;
|
|
16
|
+
private _dropColumn;
|
|
17
|
+
private _dropBeforeName;
|
|
18
|
+
private _editing;
|
|
19
|
+
private _defaultColumns;
|
|
20
|
+
private _widgets;
|
|
21
|
+
private _changed;
|
|
22
|
+
private _saving;
|
|
23
|
+
private _pendingSave;
|
|
24
|
+
constructor(getCachedDashboardLayoutUseCase: GetCachedDashboardLayoutUseCase.Interface, fetchDashboardLayoutUseCase: FetchDashboardLayoutUseCase.Interface, saveDashboardLayoutUseCase: SaveDashboardLayoutUseCase.Interface);
|
|
25
|
+
get vm(): Abstraction.ViewModel;
|
|
26
|
+
init(userId: string, widgets: DashboardWidgetInput[]): void;
|
|
27
|
+
beginDrag: (name: string) => void;
|
|
28
|
+
hoverSlot: (column: number, beforeName: string | null) => void;
|
|
29
|
+
drop: () => void;
|
|
30
|
+
endDrag: () => void;
|
|
31
|
+
removeWidget: (name: string) => void;
|
|
32
|
+
addWidget: (name: string, column?: number) => void;
|
|
33
|
+
setColumnCount: (count: number) => void;
|
|
34
|
+
removeColumn: (index: number) => void;
|
|
35
|
+
startEditing: () => void;
|
|
36
|
+
stopEditing: () => void;
|
|
37
|
+
dispose: () => void;
|
|
38
|
+
resetToDefault: () => void;
|
|
39
|
+
applyFetchedLayout: (userId: string, fetched: DashboardLayoutData | null) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Rebuild the columns and hidden list from a base state, keeping only currently registered
|
|
42
|
+
* widgets. Widgets neither placed nor hidden are treated as newly registered and appended to
|
|
43
|
+
* their default column.
|
|
44
|
+
*/
|
|
45
|
+
private applyOrder;
|
|
46
|
+
/** Pure computation of the resulting columns if `name` were dropped before `beforeName`. */
|
|
47
|
+
private computeMove;
|
|
48
|
+
private clampColumn;
|
|
49
|
+
private revalidate;
|
|
50
|
+
private persist;
|
|
51
|
+
private flushSaves;
|
|
52
|
+
}
|
|
53
|
+
export declare const DashboardLayoutPresenter: typeof DashboardLayoutPresenterImpl & {
|
|
54
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IDashboardLayoutPresenter>;
|
|
55
|
+
};
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { makeAutoObservable } from "mobx";
|
|
2
|
+
import { FetchDashboardLayoutUseCase, GetCachedDashboardLayoutUseCase } from "../loadLayout/abstractions.js";
|
|
3
|
+
import { SaveDashboardLayoutUseCase } from "../saveLayout/abstractions.js";
|
|
4
|
+
import { DEFAULT_COLUMN_COUNT, MAX_COLUMN_COUNT, MIN_COLUMN_COUNT } from "../types.js";
|
|
5
|
+
import { DashboardLayoutPresenter } from "./abstractions.js";
|
|
6
|
+
class DashboardLayoutPresenterImpl {
|
|
7
|
+
constructor(getCachedDashboardLayoutUseCase, fetchDashboardLayoutUseCase, saveDashboardLayoutUseCase){
|
|
8
|
+
this.getCachedDashboardLayoutUseCase = getCachedDashboardLayoutUseCase;
|
|
9
|
+
this.fetchDashboardLayoutUseCase = fetchDashboardLayoutUseCase;
|
|
10
|
+
this.saveDashboardLayoutUseCase = saveDashboardLayoutUseCase;
|
|
11
|
+
this._userId = null;
|
|
12
|
+
this._columns = [];
|
|
13
|
+
this._columnCount = DEFAULT_COLUMN_COUNT;
|
|
14
|
+
this._hidden = [];
|
|
15
|
+
this._draggingName = null;
|
|
16
|
+
this._dropColumn = null;
|
|
17
|
+
this._dropBeforeName = null;
|
|
18
|
+
this._editing = false;
|
|
19
|
+
this._defaultColumns = new Map();
|
|
20
|
+
this._widgets = [];
|
|
21
|
+
this._changed = false;
|
|
22
|
+
this._saving = false;
|
|
23
|
+
this._pendingSave = null;
|
|
24
|
+
this.beginDrag = (name)=>{
|
|
25
|
+
this._draggingName = name;
|
|
26
|
+
};
|
|
27
|
+
this.hoverSlot = (column, beforeName)=>{
|
|
28
|
+
if (null === this._draggingName) return;
|
|
29
|
+
const moved = this.computeMove(this._draggingName, column, beforeName);
|
|
30
|
+
if (columnsEqual(moved, this._columns)) {
|
|
31
|
+
if (null !== this._dropColumn) {
|
|
32
|
+
this._dropColumn = null;
|
|
33
|
+
this._dropBeforeName = null;
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (this._dropColumn === column && this._dropBeforeName === beforeName) return;
|
|
38
|
+
this._dropColumn = column;
|
|
39
|
+
this._dropBeforeName = beforeName;
|
|
40
|
+
};
|
|
41
|
+
this.drop = ()=>{
|
|
42
|
+
if (null !== this._draggingName && null !== this._dropColumn) {
|
|
43
|
+
this._columns = this.computeMove(this._draggingName, this._dropColumn, this._dropBeforeName);
|
|
44
|
+
this.persist();
|
|
45
|
+
}
|
|
46
|
+
this.endDrag();
|
|
47
|
+
};
|
|
48
|
+
this.endDrag = ()=>{
|
|
49
|
+
this._draggingName = null;
|
|
50
|
+
this._dropColumn = null;
|
|
51
|
+
this._dropBeforeName = null;
|
|
52
|
+
};
|
|
53
|
+
this.removeWidget = (name)=>{
|
|
54
|
+
this._columns = this._columns.map((column)=>column.filter((n)=>n !== name));
|
|
55
|
+
if (!this._hidden.includes(name)) this._hidden = [
|
|
56
|
+
...this._hidden,
|
|
57
|
+
name
|
|
58
|
+
];
|
|
59
|
+
this.persist();
|
|
60
|
+
};
|
|
61
|
+
this.addWidget = (name, column)=>{
|
|
62
|
+
if (!this._hidden.includes(name)) return;
|
|
63
|
+
this._hidden = this._hidden.filter((n)=>n !== name);
|
|
64
|
+
const requested = column ?? this._defaultColumns.get(name) ?? 0;
|
|
65
|
+
const target = this.clampColumn(requested);
|
|
66
|
+
this._columns = this._columns.map((names, index)=>{
|
|
67
|
+
if (index !== target || names.includes(name)) return names;
|
|
68
|
+
return [
|
|
69
|
+
...names,
|
|
70
|
+
name
|
|
71
|
+
];
|
|
72
|
+
});
|
|
73
|
+
this.persist();
|
|
74
|
+
};
|
|
75
|
+
this.setColumnCount = (count)=>{
|
|
76
|
+
const next = clamp(count, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);
|
|
77
|
+
if (next === this._columnCount) return;
|
|
78
|
+
this._columns = resizeColumns(this._columns, next);
|
|
79
|
+
this._columnCount = next;
|
|
80
|
+
this.persist();
|
|
81
|
+
};
|
|
82
|
+
this.removeColumn = (index)=>{
|
|
83
|
+
if (this._columnCount <= MIN_COLUMN_COUNT || index < 0 || index >= this._columns.length) return;
|
|
84
|
+
const removed = this._columns[index];
|
|
85
|
+
const columns = this._columns.filter((_, i)=>i !== index);
|
|
86
|
+
if (removed.length > 0) {
|
|
87
|
+
const target = Math.max(0, index - 1);
|
|
88
|
+
columns[target] = [
|
|
89
|
+
...columns[target],
|
|
90
|
+
...removed
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
this._columns = columns;
|
|
94
|
+
this._columnCount = columns.length;
|
|
95
|
+
this.persist();
|
|
96
|
+
};
|
|
97
|
+
this.startEditing = ()=>{
|
|
98
|
+
this._editing = true;
|
|
99
|
+
};
|
|
100
|
+
this.stopEditing = ()=>{
|
|
101
|
+
this._editing = false;
|
|
102
|
+
this.endDrag();
|
|
103
|
+
};
|
|
104
|
+
this.dispose = ()=>{
|
|
105
|
+
this.stopEditing();
|
|
106
|
+
};
|
|
107
|
+
this.resetToDefault = ()=>{
|
|
108
|
+
this._columnCount = DEFAULT_COLUMN_COUNT;
|
|
109
|
+
const columns = Array.from({
|
|
110
|
+
length: this._columnCount
|
|
111
|
+
}, ()=>[]);
|
|
112
|
+
for (const [name, column] of this._defaultColumns)columns[clamp(column, 0, this._columnCount - 1)].push(name);
|
|
113
|
+
this._columns = columns;
|
|
114
|
+
this._hidden = [];
|
|
115
|
+
this.persist();
|
|
116
|
+
};
|
|
117
|
+
this.applyFetchedLayout = (userId, fetched)=>{
|
|
118
|
+
if (this._userId !== userId || this._changed || null !== this._draggingName) return;
|
|
119
|
+
const layout = normalizeLayout(fetched);
|
|
120
|
+
this.applyOrder(this._widgets, layout);
|
|
121
|
+
};
|
|
122
|
+
makeAutoObservable(this, {
|
|
123
|
+
getCachedDashboardLayoutUseCase: false,
|
|
124
|
+
fetchDashboardLayoutUseCase: false,
|
|
125
|
+
saveDashboardLayoutUseCase: false,
|
|
126
|
+
_defaultColumns: false,
|
|
127
|
+
_widgets: false,
|
|
128
|
+
_changed: false,
|
|
129
|
+
_saving: false,
|
|
130
|
+
_pendingSave: false,
|
|
131
|
+
revalidate: false,
|
|
132
|
+
flushSaves: false
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
get vm() {
|
|
136
|
+
let dropTarget = null;
|
|
137
|
+
if (null !== this._dropColumn) dropTarget = {
|
|
138
|
+
column: this._dropColumn,
|
|
139
|
+
beforeName: this._dropBeforeName
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
columns: this._columns.map((column)=>[
|
|
143
|
+
...column
|
|
144
|
+
]),
|
|
145
|
+
columnCount: this._columnCount,
|
|
146
|
+
hidden: [
|
|
147
|
+
...this._hidden
|
|
148
|
+
],
|
|
149
|
+
draggingName: this._draggingName,
|
|
150
|
+
dropTarget,
|
|
151
|
+
editing: this._editing
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
init(userId, widgets) {
|
|
155
|
+
this._widgets = widgets;
|
|
156
|
+
if (this._userId !== userId) {
|
|
157
|
+
this._userId = userId;
|
|
158
|
+
this._pendingSave = null;
|
|
159
|
+
this._changed = false;
|
|
160
|
+
this._editing = false;
|
|
161
|
+
this.endDrag();
|
|
162
|
+
const cached = this.getCachedDashboardLayoutUseCase.execute(userId);
|
|
163
|
+
const layout = normalizeLayout(cached);
|
|
164
|
+
this.applyOrder(widgets, layout);
|
|
165
|
+
this.revalidate(userId);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.applyOrder(widgets, {
|
|
169
|
+
columns: this._columns,
|
|
170
|
+
hidden: this._hidden,
|
|
171
|
+
columnCount: this._columnCount
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
applyOrder(widgets, base) {
|
|
175
|
+
const names = widgets.map((w)=>w.name);
|
|
176
|
+
const registered = new Set(names);
|
|
177
|
+
const placed = new Set();
|
|
178
|
+
const columnCount = clamp(base.columnCount, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);
|
|
179
|
+
this._columnCount = columnCount;
|
|
180
|
+
const defaults = widgets.map((w)=>[
|
|
181
|
+
w.name,
|
|
182
|
+
clamp(w.column, 0, columnCount - 1)
|
|
183
|
+
]);
|
|
184
|
+
this._defaultColumns = new Map(defaults);
|
|
185
|
+
const columns = Array.from({
|
|
186
|
+
length: columnCount
|
|
187
|
+
}, ()=>[]);
|
|
188
|
+
base.columns.forEach((column, index)=>{
|
|
189
|
+
const target = Math.min(index, columnCount - 1);
|
|
190
|
+
for (const name of column)if (registered.has(name) && !placed.has(name)) {
|
|
191
|
+
columns[target].push(name);
|
|
192
|
+
placed.add(name);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
const hidden = [];
|
|
196
|
+
for (const name of base.hidden)if (registered.has(name) && !placed.has(name)) {
|
|
197
|
+
hidden.push(name);
|
|
198
|
+
placed.add(name);
|
|
199
|
+
}
|
|
200
|
+
for (const widget of widgets)if (!placed.has(widget.name)) {
|
|
201
|
+
columns[clamp(widget.column, 0, columnCount - 1)].push(widget.name);
|
|
202
|
+
placed.add(widget.name);
|
|
203
|
+
}
|
|
204
|
+
this._columns = columns;
|
|
205
|
+
this._hidden = hidden;
|
|
206
|
+
}
|
|
207
|
+
computeMove(name, column, beforeName) {
|
|
208
|
+
if (beforeName === name) return this._columns.map((c)=>[
|
|
209
|
+
...c
|
|
210
|
+
]);
|
|
211
|
+
const columns = this._columns.map((c)=>c.filter((n)=>n !== name));
|
|
212
|
+
const target = columns[this.clampColumn(column)];
|
|
213
|
+
if (null === beforeName) target.push(name);
|
|
214
|
+
else {
|
|
215
|
+
const index = target.indexOf(beforeName);
|
|
216
|
+
if (index < 0) target.push(name);
|
|
217
|
+
else target.splice(index, 0, name);
|
|
218
|
+
}
|
|
219
|
+
return columns;
|
|
220
|
+
}
|
|
221
|
+
clampColumn(column) {
|
|
222
|
+
return clamp(column, 0, this._columnCount - 1);
|
|
223
|
+
}
|
|
224
|
+
async revalidate(userId) {
|
|
225
|
+
let fetched;
|
|
226
|
+
try {
|
|
227
|
+
fetched = await this.fetchDashboardLayoutUseCase.execute(userId);
|
|
228
|
+
} catch {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.applyFetchedLayout(userId, fetched);
|
|
232
|
+
}
|
|
233
|
+
persist() {
|
|
234
|
+
if (null === this._userId) return;
|
|
235
|
+
this._changed = true;
|
|
236
|
+
this._pendingSave = {
|
|
237
|
+
userId: this._userId,
|
|
238
|
+
layout: {
|
|
239
|
+
columns: this._columns,
|
|
240
|
+
hidden: this._hidden,
|
|
241
|
+
columnCount: this._columnCount
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
if (!this._saving) this.flushSaves();
|
|
245
|
+
}
|
|
246
|
+
async flushSaves() {
|
|
247
|
+
this._saving = true;
|
|
248
|
+
while(this._pendingSave){
|
|
249
|
+
const { userId, layout } = this._pendingSave;
|
|
250
|
+
this._pendingSave = null;
|
|
251
|
+
try {
|
|
252
|
+
await this.saveDashboardLayoutUseCase.execute(userId, layout);
|
|
253
|
+
} catch {}
|
|
254
|
+
}
|
|
255
|
+
this._saving = false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function clamp(value, min, max) {
|
|
259
|
+
const upperBounded = Math.min(value, max);
|
|
260
|
+
return Math.max(min, upperBounded);
|
|
261
|
+
}
|
|
262
|
+
function columnsEqual(a, b) {
|
|
263
|
+
if (a.length !== b.length) return false;
|
|
264
|
+
return a.every((column, index)=>{
|
|
265
|
+
const other = b[index];
|
|
266
|
+
return column.length === other.length && column.every((v, i)=>v === other[i]);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
function resizeColumns(columns, count) {
|
|
270
|
+
if (count >= columns.length) {
|
|
271
|
+
const next = columns.map((c)=>[
|
|
272
|
+
...c
|
|
273
|
+
]);
|
|
274
|
+
while(next.length < count)next.push([]);
|
|
275
|
+
return next;
|
|
276
|
+
}
|
|
277
|
+
const next = columns.slice(0, count).map((c)=>[
|
|
278
|
+
...c
|
|
279
|
+
]);
|
|
280
|
+
for(let i = count; i < columns.length; i++)next[count - 1].push(...columns[i]);
|
|
281
|
+
return next;
|
|
282
|
+
}
|
|
283
|
+
function normalizeLayout(layout) {
|
|
284
|
+
if (!layout) return {
|
|
285
|
+
columns: [],
|
|
286
|
+
hidden: [],
|
|
287
|
+
columnCount: DEFAULT_COLUMN_COUNT
|
|
288
|
+
};
|
|
289
|
+
const columns = layout.columns ?? [];
|
|
290
|
+
const requestedCount = layout.columnCount ?? columns.length;
|
|
291
|
+
const columnCount = clamp(requestedCount, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);
|
|
292
|
+
return {
|
|
293
|
+
columns,
|
|
294
|
+
hidden: layout.hidden ?? [],
|
|
295
|
+
columnCount
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
const DashboardLayoutPresenter_DashboardLayoutPresenter = DashboardLayoutPresenter.createImplementation({
|
|
299
|
+
implementation: DashboardLayoutPresenterImpl,
|
|
300
|
+
dependencies: [
|
|
301
|
+
GetCachedDashboardLayoutUseCase,
|
|
302
|
+
FetchDashboardLayoutUseCase,
|
|
303
|
+
SaveDashboardLayoutUseCase
|
|
304
|
+
]
|
|
305
|
+
});
|
|
306
|
+
export { DashboardLayoutPresenter_DashboardLayoutPresenter as DashboardLayoutPresenter };
|
|
307
|
+
|
|
308
|
+
//# sourceMappingURL=DashboardLayoutPresenter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/presenter/DashboardLayoutPresenter.js","sources":["../../../../src/Dashboard/dashboardLayout/presenter/DashboardLayoutPresenter.ts"],"sourcesContent":["import { makeAutoObservable } from \"mobx\";\nimport { GetCachedDashboardLayoutUseCase } from \"../loadLayout/abstractions.js\";\nimport { FetchDashboardLayoutUseCase } from \"../loadLayout/abstractions.js\";\nimport { SaveDashboardLayoutUseCase } from \"../saveLayout/abstractions.js\";\nimport { DEFAULT_COLUMN_COUNT } from \"../types.js\";\nimport { MAX_COLUMN_COUNT } from \"../types.js\";\nimport { MIN_COLUMN_COUNT } from \"../types.js\";\nimport type { DashboardLayoutData } from \"../types.js\";\nimport { DashboardLayoutPresenter as Abstraction } from \"./abstractions.js\";\nimport type { DashboardDropTarget } from \"./abstractions.js\";\nimport type { DashboardWidgetInput } from \"./abstractions.js\";\n\ninterface PendingSave {\n userId: string;\n layout: DashboardLayoutData;\n}\n\nclass DashboardLayoutPresenterImpl implements Abstraction.Interface {\n // Whose layout this is. The presenter is a singleton, so a different user starts over.\n private _userId: string | null = null;\n private _columns: string[][] = [];\n private _columnCount = DEFAULT_COLUMN_COUNT;\n private _hidden: string[] = [];\n private _draggingName: string | null = null;\n private _dropColumn: number | null = null;\n private _dropBeforeName: string | null = null;\n private _editing = false;\n // Non-reactive: each registered widget's default column index, used when (re)adding a widget.\n private _defaultColumns = new Map<string, number>();\n // Non-reactive: the registered widgets, kept to apply the fetched layout when it arrives.\n private _widgets: DashboardWidgetInput[] = [];\n // Non-reactive: the user changed the layout since init, so the fetched layout is out of date.\n private _changed = false;\n // Non-reactive: saves go out one at a time, and only the newest pending layout is kept.\n private _saving = false;\n private _pendingSave: PendingSave | null = null;\n\n constructor(\n private getCachedDashboardLayoutUseCase: GetCachedDashboardLayoutUseCase.Interface,\n private fetchDashboardLayoutUseCase: FetchDashboardLayoutUseCase.Interface,\n private saveDashboardLayoutUseCase: SaveDashboardLayoutUseCase.Interface\n ) {\n makeAutoObservable<\n DashboardLayoutPresenterImpl,\n | \"getCachedDashboardLayoutUseCase\"\n | \"fetchDashboardLayoutUseCase\"\n | \"saveDashboardLayoutUseCase\"\n | \"_defaultColumns\"\n | \"_widgets\"\n | \"_changed\"\n | \"_saving\"\n | \"_pendingSave\"\n | \"revalidate\"\n | \"flushSaves\"\n >(this, {\n getCachedDashboardLayoutUseCase: false,\n fetchDashboardLayoutUseCase: false,\n saveDashboardLayoutUseCase: false,\n _defaultColumns: false,\n _widgets: false,\n _changed: false,\n _saving: false,\n _pendingSave: false,\n revalidate: false,\n flushSaves: false\n });\n }\n\n get vm(): Abstraction.ViewModel {\n let dropTarget: DashboardDropTarget | null = null;\n if (this._dropColumn !== null) {\n dropTarget = { column: this._dropColumn, beforeName: this._dropBeforeName };\n }\n\n return {\n columns: this._columns.map(column => [...column]),\n columnCount: this._columnCount,\n hidden: [...this._hidden],\n draggingName: this._draggingName,\n dropTarget,\n editing: this._editing\n };\n }\n\n init(userId: string, widgets: DashboardWidgetInput[]): void {\n this._widgets = widgets;\n\n if (this._userId !== userId) {\n // New session or another user: show their cached layout, and drop any save still\n // queued for the previous user so it can't land in this user's dashboard.\n this._userId = userId;\n this._pendingSave = null;\n this._changed = false;\n this._editing = false;\n this.endDrag();\n const cached = this.getCachedDashboardLayoutUseCase.execute(userId);\n const layout = normalizeLayout(cached);\n this.applyOrder(widgets, layout);\n void this.revalidate(userId);\n return;\n }\n\n // A widget was registered/unregistered: keep current state, reconcile. No save.\n this.applyOrder(widgets, {\n columns: this._columns,\n hidden: this._hidden,\n columnCount: this._columnCount\n });\n }\n\n beginDrag = (name: string): void => {\n this._draggingName = name;\n };\n\n hoverSlot = (column: number, beforeName: string | null): void => {\n if (this._draggingName === null) {\n return;\n }\n // Suppress no-op slots (dropping where the widget already is) — no indicator, no move.\n const moved = this.computeMove(this._draggingName, column, beforeName);\n if (columnsEqual(moved, this._columns)) {\n if (this._dropColumn !== null) {\n this._dropColumn = null;\n this._dropBeforeName = null;\n }\n return;\n }\n\n if (this._dropColumn === column && this._dropBeforeName === beforeName) {\n return;\n }\n this._dropColumn = column;\n this._dropBeforeName = beforeName;\n };\n\n drop = (): void => {\n if (this._draggingName !== null && this._dropColumn !== null) {\n this._columns = this.computeMove(\n this._draggingName,\n this._dropColumn,\n this._dropBeforeName\n );\n this.persist();\n }\n this.endDrag();\n };\n\n endDrag = (): void => {\n this._draggingName = null;\n this._dropColumn = null;\n this._dropBeforeName = null;\n };\n\n removeWidget = (name: string): void => {\n this._columns = this._columns.map(column => column.filter(n => n !== name));\n if (!this._hidden.includes(name)) {\n this._hidden = [...this._hidden, name];\n }\n this.persist();\n };\n\n addWidget = (name: string, column?: number): void => {\n if (!this._hidden.includes(name)) {\n return;\n }\n this._hidden = this._hidden.filter(n => n !== name);\n\n // Without a column, the widget goes to the column it registered with.\n const requested = column ?? this._defaultColumns.get(name) ?? 0;\n const target = this.clampColumn(requested);\n this._columns = this._columns.map((names, index) => {\n if (index !== target || names.includes(name)) {\n return names;\n }\n return [...names, name];\n });\n this.persist();\n };\n\n setColumnCount = (count: number): void => {\n const next = clamp(count, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);\n if (next === this._columnCount) {\n return;\n }\n this._columns = resizeColumns(this._columns, next);\n this._columnCount = next;\n this.persist();\n };\n\n removeColumn = (index: number): void => {\n if (this._columnCount <= MIN_COLUMN_COUNT || index < 0 || index >= this._columns.length) {\n return;\n }\n const removed = this._columns[index];\n const columns = this._columns.filter((_, i) => i !== index);\n // Fold any stray widgets into the neighboring column so nothing is lost.\n if (removed.length > 0) {\n const target = Math.max(0, index - 1);\n columns[target] = [...columns[target], ...removed];\n }\n this._columns = columns;\n this._columnCount = columns.length;\n this.persist();\n };\n\n startEditing = (): void => {\n this._editing = true;\n };\n\n stopEditing = (): void => {\n this._editing = false;\n this.endDrag();\n };\n\n // The presenter is a singleton that outlives the dashboard, so leaving the page resets what's\n // tied to that visit: the next visit opens out of Customize mode, with no drag in progress.\n // The layout stays, and so does any save still in flight.\n dispose = (): void => {\n this.stopEditing();\n };\n\n resetToDefault = (): void => {\n this._columnCount = DEFAULT_COLUMN_COUNT;\n const columns: string[][] = Array.from({ length: this._columnCount }, () => []);\n for (const [name, column] of this._defaultColumns) {\n columns[clamp(column, 0, this._columnCount - 1)].push(name);\n }\n this._columns = columns;\n this._hidden = [];\n this.persist();\n };\n\n // The stored layout replaces the cached one, unless the user already changed it on this visit.\n applyFetchedLayout = (userId: string, fetched: DashboardLayoutData | null): void => {\n if (this._userId !== userId || this._changed || this._draggingName !== null) {\n return;\n }\n const layout = normalizeLayout(fetched);\n this.applyOrder(this._widgets, layout);\n };\n\n /**\n * Rebuild the columns and hidden list from a base state, keeping only currently registered\n * widgets. Widgets neither placed nor hidden are treated as newly registered and appended to\n * their default column.\n */\n private applyOrder(widgets: DashboardWidgetInput[], base: DashboardLayoutData): void {\n const names = widgets.map(w => w.name);\n const registered = new Set(names);\n const placed = new Set<string>();\n\n const columnCount = clamp(base.columnCount, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);\n this._columnCount = columnCount;\n const defaults: [string, number][] = widgets.map(w => [\n w.name,\n clamp(w.column, 0, columnCount - 1)\n ]);\n this._defaultColumns = new Map(defaults);\n\n const columns: string[][] = Array.from({ length: columnCount }, () => []);\n\n base.columns.forEach((column, index) => {\n const target = Math.min(index, columnCount - 1);\n for (const name of column) {\n if (registered.has(name) && !placed.has(name)) {\n columns[target].push(name);\n placed.add(name);\n }\n }\n });\n\n const hidden: string[] = [];\n for (const name of base.hidden) {\n if (registered.has(name) && !placed.has(name)) {\n hidden.push(name);\n placed.add(name);\n }\n }\n\n // Newly registered widgets (in neither the order nor hidden) → their default column.\n for (const widget of widgets) {\n if (placed.has(widget.name)) {\n continue;\n }\n columns[clamp(widget.column, 0, columnCount - 1)].push(widget.name);\n placed.add(widget.name);\n }\n\n this._columns = columns;\n this._hidden = hidden;\n }\n\n /** Pure computation of the resulting columns if `name` were dropped before `beforeName`. */\n private computeMove(name: string, column: number, beforeName: string | null): string[][] {\n if (beforeName === name) {\n return this._columns.map(c => [...c]);\n }\n\n const columns = this._columns.map(c => c.filter(n => n !== name));\n const target = columns[this.clampColumn(column)];\n\n if (beforeName === null) {\n target.push(name);\n } else {\n const index = target.indexOf(beforeName);\n if (index < 0) {\n target.push(name);\n } else {\n target.splice(index, 0, name);\n }\n }\n\n return columns;\n }\n\n private clampColumn(column: number): number {\n return clamp(column, 0, this._columnCount - 1);\n }\n\n private async revalidate(userId: string): Promise<void> {\n let fetched: DashboardLayoutData | null;\n try {\n fetched = await this.fetchDashboardLayoutUseCase.execute(userId);\n } catch {\n // Ignore, the cached or default layout stays on screen.\n return;\n }\n this.applyFetchedLayout(userId, fetched);\n }\n\n private persist(): void {\n if (this._userId === null) {\n return;\n }\n this._changed = true;\n this._pendingSave = {\n userId: this._userId,\n layout: {\n columns: this._columns,\n hidden: this._hidden,\n columnCount: this._columnCount\n }\n };\n if (!this._saving) {\n void this.flushSaves();\n }\n }\n\n /*\n * Sends saves one after another. Parallel requests could finish out of order and leave an older\n * layout on the server. A layout queued while a save is in flight replaces any older queued one.\n */\n private async flushSaves(): Promise<void> {\n this._saving = true;\n while (this._pendingSave) {\n const { userId, layout } = this._pendingSave;\n this._pendingSave = null;\n try {\n await this.saveDashboardLayoutUseCase.execute(userId, layout);\n } catch {\n // Ignore, a failed save must not break the interaction. The layout still applies locally.\n }\n }\n this._saving = false;\n }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n const upperBounded = Math.min(value, max);\n return Math.max(min, upperBounded);\n}\n\nfunction columnsEqual(a: string[][], b: string[][]): boolean {\n if (a.length !== b.length) {\n return false;\n }\n return a.every((column, index) => {\n const other = b[index];\n return column.length === other.length && column.every((v, i) => v === other[i]);\n });\n}\n\n/** Grow/shrink the column list to `count`; widgets in removed columns fold into the last kept one. */\nfunction resizeColumns(columns: string[][], count: number): string[][] {\n if (count >= columns.length) {\n const next = columns.map(c => [...c]);\n while (next.length < count) {\n next.push([]);\n }\n return next;\n }\n\n const next = columns.slice(0, count).map(c => [...c]);\n for (let i = count; i < columns.length; i++) {\n next[count - 1].push(...columns[i]);\n }\n return next;\n}\n\n/** Fill in defaults for a missing layout or missing fields. */\nfunction normalizeLayout(layout: DashboardLayoutData | null): DashboardLayoutData {\n if (!layout) {\n return { columns: [], hidden: [], columnCount: DEFAULT_COLUMN_COUNT };\n }\n\n const columns = layout.columns ?? [];\n const requestedCount = layout.columnCount ?? columns.length;\n const columnCount = clamp(requestedCount, MIN_COLUMN_COUNT, MAX_COLUMN_COUNT);\n\n return {\n columns,\n hidden: layout.hidden ?? [],\n columnCount\n };\n}\n\nexport const DashboardLayoutPresenter = Abstraction.createImplementation({\n implementation: DashboardLayoutPresenterImpl,\n dependencies: [\n GetCachedDashboardLayoutUseCase,\n FetchDashboardLayoutUseCase,\n SaveDashboardLayoutUseCase\n ]\n});\n"],"names":["DashboardLayoutPresenterImpl","getCachedDashboardLayoutUseCase","fetchDashboardLayoutUseCase","saveDashboardLayoutUseCase","DEFAULT_COLUMN_COUNT","Map","name","column","beforeName","moved","columnsEqual","n","requested","target","names","index","count","next","clamp","MIN_COLUMN_COUNT","MAX_COLUMN_COUNT","resizeColumns","removed","columns","_","i","Math","Array","userId","fetched","layout","normalizeLayout","makeAutoObservable","dropTarget","widgets","cached","base","w","registered","Set","placed","columnCount","defaults","hidden","widget","c","value","min","max","upperBounded","a","b","other","v","requestedCount","DashboardLayoutPresenter","Abstraction","GetCachedDashboardLayoutUseCase","FetchDashboardLayoutUseCase","SaveDashboardLayoutUseCase"],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal description of a registered widget the presenter needs to order it.
|
|
3
|
+
* The actual React element is kept in the view — the presenter deals only in names.
|
|
4
|
+
* `column` is the widget's default column index.
|
|
5
|
+
*/
|
|
6
|
+
export interface DashboardWidgetInput {
|
|
7
|
+
name: string;
|
|
8
|
+
column: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Where a dragged widget would be dropped: into column `column`, immediately before `beforeName`.
|
|
12
|
+
* `beforeName === null` means "append to the end of the column".
|
|
13
|
+
*/
|
|
14
|
+
export interface DashboardDropTarget {
|
|
15
|
+
column: number;
|
|
16
|
+
beforeName: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface IDashboardLayoutViewModel {
|
|
19
|
+
columns: string[][];
|
|
20
|
+
columnCount: number;
|
|
21
|
+
hidden: string[];
|
|
22
|
+
draggingName: string | null;
|
|
23
|
+
dropTarget: DashboardDropTarget | null;
|
|
24
|
+
editing: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface IDashboardLayoutPresenter {
|
|
27
|
+
vm: IDashboardLayoutViewModel;
|
|
28
|
+
init(userId: string, widgets: DashboardWidgetInput[]): void;
|
|
29
|
+
beginDrag(name: string): void;
|
|
30
|
+
hoverSlot(column: number, beforeName: string | null): void;
|
|
31
|
+
drop(): void;
|
|
32
|
+
endDrag(): void;
|
|
33
|
+
removeWidget(name: string): void;
|
|
34
|
+
addWidget(name: string, column?: number): void;
|
|
35
|
+
setColumnCount(count: number): void;
|
|
36
|
+
removeColumn(index: number): void;
|
|
37
|
+
resetToDefault(): void;
|
|
38
|
+
startEditing(): void;
|
|
39
|
+
stopEditing(): void;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
}
|
|
42
|
+
export declare const DashboardLayoutPresenter: import("@webiny/di").Abstraction<IDashboardLayoutPresenter>;
|
|
43
|
+
export declare namespace DashboardLayoutPresenter {
|
|
44
|
+
type Interface = IDashboardLayoutPresenter;
|
|
45
|
+
type ViewModel = IDashboardLayoutViewModel;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/presenter/abstractions.js","sources":["../../../../src/Dashboard/dashboardLayout/presenter/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\n\n/**\n * Minimal description of a registered widget the presenter needs to order it.\n * The actual React element is kept in the view — the presenter deals only in names.\n * `column` is the widget's default column index.\n */\nexport interface DashboardWidgetInput {\n name: string;\n column: number;\n}\n\n/**\n * Where a dragged widget would be dropped: into column `column`, immediately before `beforeName`.\n * `beforeName === null` means \"append to the end of the column\".\n */\nexport interface DashboardDropTarget {\n column: number;\n beforeName: string | null;\n}\n\nexport interface IDashboardLayoutViewModel {\n columns: string[][];\n columnCount: number;\n hidden: string[];\n draggingName: string | null;\n dropTarget: DashboardDropTarget | null;\n // Customize mode: widgets can be moved, added and removed only while this is on.\n editing: boolean;\n}\n\nexport interface IDashboardLayoutPresenter {\n vm: IDashboardLayoutViewModel;\n // Renders the cached layout at once, then replaces it with the stored one when that arrives.\n init(userId: string, widgets: DashboardWidgetInput[]): void;\n beginDrag(name: string): void;\n hoverSlot(column: number, beforeName: string | null): void;\n drop(): void;\n endDrag(): void;\n removeWidget(name: string): void;\n // Appends the widget to `column`, or to its default column when none is given.\n addWidget(name: string, column?: number): void;\n setColumnCount(count: number): void;\n removeColumn(index: number): void;\n resetToDefault(): void;\n startEditing(): void;\n stopEditing(): void;\n // Called when the dashboard unmounts. Resets per-visit state such as Customize mode.\n dispose(): void;\n}\n\nexport const DashboardLayoutPresenter = createAbstraction<IDashboardLayoutPresenter>(\n \"DashboardLayoutPresenter\"\n);\n\nexport namespace DashboardLayoutPresenter {\n export type Interface = IDashboardLayoutPresenter;\n export type ViewModel = IDashboardLayoutViewModel;\n}\n"],"names":["DashboardLayoutPresenter","createAbstraction"],"mappings":";AAmDO,MAAMA,2BAA2BC,kBACpC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/admin";
|
|
2
|
+
import { DashboardLayoutPresenter } from "./abstractions.js";
|
|
3
|
+
import { DashboardLayoutPresenter as external_DashboardLayoutPresenter_js_DashboardLayoutPresenter } from "./DashboardLayoutPresenter.js";
|
|
4
|
+
import { DashboardLayoutRepositoryFeature } from "../repository/feature.js";
|
|
5
|
+
import { LoadDashboardLayoutFeature } from "../loadLayout/feature.js";
|
|
6
|
+
import { SaveDashboardLayoutFeature } from "../saveLayout/feature.js";
|
|
7
|
+
const DashboardLayoutPresenterFeature = createFeature({
|
|
8
|
+
name: "AdminUI/DashboardLayoutPresenter",
|
|
9
|
+
register (container) {
|
|
10
|
+
DashboardLayoutRepositoryFeature.register(container);
|
|
11
|
+
LoadDashboardLayoutFeature.register(container);
|
|
12
|
+
SaveDashboardLayoutFeature.register(container);
|
|
13
|
+
container.register(external_DashboardLayoutPresenter_js_DashboardLayoutPresenter).inSingletonScope();
|
|
14
|
+
},
|
|
15
|
+
resolve (container) {
|
|
16
|
+
return {
|
|
17
|
+
presenter: container.resolve(DashboardLayoutPresenter)
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
export { DashboardLayoutPresenterFeature };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/presenter/feature.js","sources":["../../../../src/Dashboard/dashboardLayout/presenter/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { DashboardLayoutPresenter as Abstraction } from \"./abstractions.js\";\nimport { DashboardLayoutPresenter } from \"./DashboardLayoutPresenter.js\";\nimport { DashboardLayoutRepositoryFeature } from \"../repository/feature.js\";\nimport { LoadDashboardLayoutFeature } from \"../loadLayout/feature.js\";\nimport { SaveDashboardLayoutFeature } from \"../saveLayout/feature.js\";\n\nexport const DashboardLayoutPresenterFeature = createFeature({\n name: \"AdminUI/DashboardLayoutPresenter\",\n register(container) {\n DashboardLayoutRepositoryFeature.register(container);\n LoadDashboardLayoutFeature.register(container);\n SaveDashboardLayoutFeature.register(container);\n container.register(DashboardLayoutPresenter).inSingletonScope();\n },\n resolve(container) {\n return {\n presenter: container.resolve(Abstraction)\n };\n }\n});\n"],"names":["DashboardLayoutPresenterFeature","createFeature","container","DashboardLayoutRepositoryFeature","LoadDashboardLayoutFeature","SaveDashboardLayoutFeature","DashboardLayoutPresenter","Abstraction"],"mappings":";;;;;;AAOO,MAAMA,kCAAkCC,cAAc;IACzD,MAAM;IACN,UAASC,SAAS;QACdC,iCAAiC,QAAQ,CAACD;QAC1CE,2BAA2B,QAAQ,CAACF;QACpCG,2BAA2B,QAAQ,CAACH;QACpCA,UAAU,QAAQ,CAACI,+DAA0B,gBAAgB;IACjE;IACA,SAAQJ,SAAS;QACb,OAAO;YACH,WAAWA,UAAU,OAAO,CAACK;QACjC;IACJ;AACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useDashboardLayoutPresenter: () => import("./abstractions.js").IDashboardLayoutPresenter;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useFeature } from "@webiny/app";
|
|
2
|
+
import { DashboardLayoutPresenterFeature } from "./feature.js";
|
|
3
|
+
const useDashboardLayoutPresenter = ()=>useFeature(DashboardLayoutPresenterFeature).presenter;
|
|
4
|
+
export { useDashboardLayoutPresenter };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=useDashboardLayoutPresenter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/presenter/useDashboardLayoutPresenter.js","sources":["../../../../src/Dashboard/dashboardLayout/presenter/useDashboardLayoutPresenter.ts"],"sourcesContent":["import { useFeature } from \"@webiny/app\";\nimport { DashboardLayoutPresenterFeature } from \"./feature.js\";\n\nexport const useDashboardLayoutPresenter = () => {\n return useFeature(DashboardLayoutPresenterFeature).presenter;\n};\n"],"names":["useDashboardLayoutPresenter","useFeature","DashboardLayoutPresenterFeature"],"mappings":";;AAGO,MAAMA,8BAA8B,IAChCC,WAAWC,iCAAiC,SAAS"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { MainGraphQLClient } from "@webiny/app/features/mainGraphQLClient/abstractions.js";
|
|
2
|
+
import { DashboardLayoutGateway as GatewayAbstraction } from "./abstractions.js";
|
|
3
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
4
|
+
declare class DashboardLayoutGatewayImpl implements GatewayAbstraction.Interface {
|
|
5
|
+
private client;
|
|
6
|
+
constructor(client: MainGraphQLClient.Interface);
|
|
7
|
+
get(): Promise<DashboardLayoutData | null>;
|
|
8
|
+
save(layout: DashboardLayoutData): Promise<DashboardLayoutData>;
|
|
9
|
+
}
|
|
10
|
+
export declare const DashboardLayoutGateway: typeof DashboardLayoutGatewayImpl & {
|
|
11
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IDashboardLayoutGateway>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MainGraphQLClient } from "@webiny/app/features/mainGraphQLClient/abstractions.js";
|
|
2
|
+
import { DashboardLayoutGateway } from "./abstractions.js";
|
|
3
|
+
const LIST_DASHBOARDS_QUERY = `
|
|
4
|
+
query ListDashboards {
|
|
5
|
+
dashboard {
|
|
6
|
+
listDashboards {
|
|
7
|
+
data {
|
|
8
|
+
columns
|
|
9
|
+
hidden
|
|
10
|
+
columnCount
|
|
11
|
+
}
|
|
12
|
+
error {
|
|
13
|
+
message
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
const UPDATE_DASHBOARD_MUTATION = `
|
|
20
|
+
mutation UpdateDashboard($data: DashboardInput!) {
|
|
21
|
+
dashboard {
|
|
22
|
+
updateDashboard(data: $data) {
|
|
23
|
+
data {
|
|
24
|
+
columns
|
|
25
|
+
hidden
|
|
26
|
+
columnCount
|
|
27
|
+
}
|
|
28
|
+
error {
|
|
29
|
+
message
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
class DashboardLayoutGatewayImpl {
|
|
36
|
+
constructor(client){
|
|
37
|
+
this.client = client;
|
|
38
|
+
}
|
|
39
|
+
async get() {
|
|
40
|
+
const response = await this.client.execute({
|
|
41
|
+
query: LIST_DASHBOARDS_QUERY
|
|
42
|
+
});
|
|
43
|
+
const { data, error } = response.dashboard.listDashboards;
|
|
44
|
+
if (error) throw new Error(error.message);
|
|
45
|
+
return data?.[0] ?? null;
|
|
46
|
+
}
|
|
47
|
+
async save(layout) {
|
|
48
|
+
const response = await this.client.execute({
|
|
49
|
+
query: UPDATE_DASHBOARD_MUTATION,
|
|
50
|
+
variables: {
|
|
51
|
+
data: layout
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
const { data, error } = response.dashboard.updateDashboard;
|
|
55
|
+
if (error) throw new Error(error.message);
|
|
56
|
+
return data ?? layout;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const DashboardLayoutGateway_DashboardLayoutGateway = DashboardLayoutGateway.createImplementation({
|
|
60
|
+
implementation: DashboardLayoutGatewayImpl,
|
|
61
|
+
dependencies: [
|
|
62
|
+
MainGraphQLClient
|
|
63
|
+
]
|
|
64
|
+
});
|
|
65
|
+
export { DashboardLayoutGateway_DashboardLayoutGateway as DashboardLayoutGateway };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=DashboardLayoutGateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/repository/DashboardLayoutGateway.js","sources":["../../../../src/Dashboard/dashboardLayout/repository/DashboardLayoutGateway.ts"],"sourcesContent":["import { MainGraphQLClient } from \"@webiny/app/features/mainGraphQLClient/abstractions.js\";\nimport { DashboardLayoutGateway as GatewayAbstraction } from \"./abstractions.js\";\nimport type { DashboardLayoutData } from \"../types.js\";\n\ninterface DashboardError {\n message: string;\n}\n\ninterface ListDashboardsResponse {\n dashboard: {\n listDashboards: { data: DashboardLayoutData[] | null; error: DashboardError | null };\n };\n}\n\ninterface UpdateDashboardResponse {\n dashboard: {\n updateDashboard: { data: DashboardLayoutData | null; error: DashboardError | null };\n };\n}\n\nconst LIST_DASHBOARDS_QUERY = /* GraphQL */ `\n query ListDashboards {\n dashboard {\n listDashboards {\n data {\n columns\n hidden\n columnCount\n }\n error {\n message\n }\n }\n }\n }\n`;\n\nconst UPDATE_DASHBOARD_MUTATION = /* GraphQL */ `\n mutation UpdateDashboard($data: DashboardInput!) {\n dashboard {\n updateDashboard(data: $data) {\n data {\n columns\n hidden\n columnCount\n }\n error {\n message\n }\n }\n }\n }\n`;\n\nclass DashboardLayoutGatewayImpl implements GatewayAbstraction.Interface {\n constructor(private client: MainGraphQLClient.Interface) {}\n\n async get(): Promise<DashboardLayoutData | null> {\n const response = await this.client.execute<ListDashboardsResponse>({\n query: LIST_DASHBOARDS_QUERY\n });\n\n const { data, error } = response.dashboard.listDashboards;\n if (error) {\n throw new Error(error.message);\n }\n\n // Each user has at most one dashboard for now.\n return data?.[0] ?? null;\n }\n\n async save(layout: DashboardLayoutData): Promise<DashboardLayoutData> {\n const response = await this.client.execute<UpdateDashboardResponse>({\n query: UPDATE_DASHBOARD_MUTATION,\n variables: { data: layout }\n });\n\n const { data, error } = response.dashboard.updateDashboard;\n if (error) {\n throw new Error(error.message);\n }\n\n return data ?? layout;\n }\n}\n\nexport const DashboardLayoutGateway = GatewayAbstraction.createImplementation({\n implementation: DashboardLayoutGatewayImpl,\n dependencies: [MainGraphQLClient]\n});\n"],"names":["LIST_DASHBOARDS_QUERY","UPDATE_DASHBOARD_MUTATION","DashboardLayoutGatewayImpl","client","response","data","error","Error","layout","DashboardLayoutGateway","GatewayAbstraction","MainGraphQLClient"],"mappings":";;AAoBA,MAAMA,wBAAsC,CAAC;;;;;;;;;;;;;;;AAe7C,CAAC;AAED,MAAMC,4BAA0C,CAAC;;;;;;;;;;;;;;;AAejD,CAAC;AAED,MAAMC;IACF,YAAoBC,MAAmC,CAAE;aAArCA,MAAM,GAANA;IAAsC;IAE1D,MAAM,MAA2C;QAC7C,MAAMC,WAAW,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAyB;YAC/D,OAAOJ;QACX;QAEA,MAAM,EAAEK,IAAI,EAAEC,KAAK,EAAE,GAAGF,SAAS,SAAS,CAAC,cAAc;QACzD,IAAIE,OACA,MAAM,IAAIC,MAAMD,MAAM,OAAO;QAIjC,OAAOD,MAAM,CAAC,EAAE,IAAI;IACxB;IAEA,MAAM,KAAKG,MAA2B,EAAgC;QAClE,MAAMJ,WAAW,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAA0B;YAChE,OAAOH;YACP,WAAW;gBAAE,MAAMO;YAAO;QAC9B;QAEA,MAAM,EAAEH,IAAI,EAAEC,KAAK,EAAE,GAAGF,SAAS,SAAS,CAAC,eAAe;QAC1D,IAAIE,OACA,MAAM,IAAIC,MAAMD,MAAM,OAAO;QAGjC,OAAOD,QAAQG;IACnB;AACJ;AAEO,MAAMC,gDAAyBC,uBAAAA,oBAAuC,CAAC;IAC1E,gBAAgBR;IAChB,cAAc;QAACS;KAAkB;AACrC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LocalStorage } from "@webiny/app/exports/admin/local-storage.js";
|
|
2
|
+
import { TenantContext } from "@webiny/app-admin/exports/admin/tenancy.js";
|
|
3
|
+
import { DashboardLayoutRepository as RepositoryAbstraction } from "./abstractions.js";
|
|
4
|
+
import { DashboardLayoutGateway } from "./abstractions.js";
|
|
5
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
6
|
+
declare class DashboardLayoutRepositoryImpl implements RepositoryAbstraction.Interface {
|
|
7
|
+
private gateway;
|
|
8
|
+
private localStorage;
|
|
9
|
+
private tenantContext;
|
|
10
|
+
constructor(gateway: DashboardLayoutGateway.Interface, localStorage: LocalStorage.Interface, tenantContext: TenantContext.Interface);
|
|
11
|
+
getCached(userId: string): DashboardLayoutData | null;
|
|
12
|
+
fetch(userId: string): Promise<DashboardLayoutData | null>;
|
|
13
|
+
save(userId: string, layout: DashboardLayoutData): Promise<void>;
|
|
14
|
+
private writeCache;
|
|
15
|
+
private cacheKey;
|
|
16
|
+
}
|
|
17
|
+
export declare const DashboardLayoutRepository: typeof DashboardLayoutRepositoryImpl & {
|
|
18
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").IDashboardLayoutRepository>;
|
|
19
|
+
};
|
|
20
|
+
export {};
|