@webiny/app-admin-ui 0.0.0-unstable.0156a4c312
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 +6 -0
- package/Dashboard/Welcome.js +120 -0
- package/Dashboard/Welcome.js.map +1 -0
- package/Dashboard/components/AssistanceWidget.d.ts +2 -0
- package/Dashboard/components/AssistanceWidget.js +54 -0
- package/Dashboard/components/AssistanceWidget.js.map +1 -0
- package/Dashboard/components/CommunityWidget.d.ts +2 -0
- package/Dashboard/components/CommunityWidget.js +58 -0
- package/Dashboard/components/CommunityWidget.js.map +1 -0
- 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/MissingPermissionsWidget.d.ts +2 -0
- package/Dashboard/components/MissingPermissionsWidget.js +16 -0
- package/Dashboard/components/MissingPermissionsWidget.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/assets/github.js +14 -0
- package/Dashboard/components/assets/github.js.map +1 -0
- package/Dashboard/components/assets/github.svg +1 -0
- package/Dashboard/components/assets/slack.js +27 -0
- package/Dashboard/components/assets/slack.js.map +1 -0
- package/Dashboard/components/assets/slack.svg +8 -0
- package/Dashboard/components/assets/x-twitter.js +18 -0
- package/Dashboard/components/assets/x-twitter.js.map +1 -0
- package/Dashboard/components/assets/x-twitter.svg +5 -0
- package/Dashboard/components/assets/youtube.js +28 -0
- package/Dashboard/components/assets/youtube.js.map +1 -0
- package/Dashboard/components/assets/youtube.svg +11 -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/index.d.ts +3 -0
- package/Dashboard/components/index.js +3 -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/Dashboard.d.ts +2 -0
- package/Dashboard.js +9 -0
- package/Dashboard.js.map +1 -0
- package/Dialog/DialogContainer.d.ts +2 -0
- package/Dialog/DialogContainer.js +59 -0
- package/Dialog/DialogContainer.js.map +1 -0
- package/Dialog/DialogProvider.d.ts +5 -0
- package/Dialog/DialogProvider.js +8 -0
- package/Dialog/DialogProvider.js.map +1 -0
- package/Dialog.d.ts +2 -0
- package/Dialog.js +9 -0
- package/Dialog.js.map +1 -0
- package/LICENSE +21 -0
- package/Layout.d.ts +2 -0
- package/Layout.js +55 -0
- package/Layout.js.map +1 -0
- package/Logo.d.ts +2 -0
- package/Logo.js +16 -0
- package/Logo.js.map +1 -0
- package/Navigation/Navigation.d.ts +2 -0
- package/Navigation/Navigation.js +34 -0
- package/Navigation/Navigation.js.map +1 -0
- package/Navigation/SidebarMenuItems.d.ts +10 -0
- package/Navigation/SidebarMenuItems.js +36 -0
- package/Navigation/SidebarMenuItems.js.map +1 -0
- package/NotFound/notFound.js +297 -0
- package/NotFound/notFound.js.map +1 -0
- package/NotFound/notFound.svg +1 -0
- package/NotFound.d.ts +2 -0
- package/NotFound.js +20 -0
- package/NotFound.js.map +1 -0
- package/README.md +11 -0
- package/UserMenu/UserMenu.d.ts +2 -0
- package/UserMenu/UserMenu.js +22 -0
- package/UserMenu/UserMenu.js.map +1 -0
- package/UserMenu/UserMenuHandle.d.ts +2 -0
- package/UserMenu/UserMenuHandle.js +36 -0
- package/UserMenu/UserMenuHandle.js.map +1 -0
- package/UserMenu/UserMenuItem.d.ts +3 -0
- package/UserMenu/UserMenuItem.js +12 -0
- package/UserMenu/UserMenuItem.js.map +1 -0
- package/UserMenu/UserMenuLink.d.ts +3 -0
- package/UserMenu/UserMenuLink.js +12 -0
- package/UserMenu/UserMenuLink.js.map +1 -0
- package/UserMenu/UserMenuSeparator.d.ts +2 -0
- package/UserMenu/UserMenuSeparator.js +12 -0
- package/UserMenu/UserMenuSeparator.js.map +1 -0
- package/UserMenu.d.ts +2 -0
- package/UserMenu.js +10 -0
- package/UserMenu.js.map +1 -0
- package/index.d.ts +2 -0
- package/index.js +35 -0
- package/index.js.map +1 -0
- package/package.json +49 -0
- package/static/svg/github.08a73b00.svg +1 -0
- package/static/svg/notFound.e8b15981.svg +1 -0
- package/static/svg/slack.1b2ba162.svg +8 -0
- package/static/svg/x-twitter.46e7218c.svg +5 -0
- package/static/svg/youtube.3c232651.svg +11 -0
- package/styles.scss +2 -0
|
@@ -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 {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { LocalStorage } from "@webiny/app/exports/admin/local-storage.js";
|
|
2
|
+
import { TenantContext } from "@webiny/app-admin/exports/admin/tenancy.js";
|
|
3
|
+
import { DashboardLayoutGateway, DashboardLayoutRepository } from "./abstractions.js";
|
|
4
|
+
const CACHE_VERSION = 1;
|
|
5
|
+
class DashboardLayoutRepositoryImpl {
|
|
6
|
+
constructor(gateway, localStorage, tenantContext){
|
|
7
|
+
this.gateway = gateway;
|
|
8
|
+
this.localStorage = localStorage;
|
|
9
|
+
this.tenantContext = tenantContext;
|
|
10
|
+
}
|
|
11
|
+
getCached(userId) {
|
|
12
|
+
const key = this.cacheKey(userId);
|
|
13
|
+
const cached = this.localStorage.get(key);
|
|
14
|
+
if (!cached || cached.version !== CACHE_VERSION) return null;
|
|
15
|
+
return cached.layout;
|
|
16
|
+
}
|
|
17
|
+
async fetch(userId) {
|
|
18
|
+
const layout = await this.gateway.get();
|
|
19
|
+
this.writeCache(userId, layout);
|
|
20
|
+
return layout;
|
|
21
|
+
}
|
|
22
|
+
async save(userId, layout) {
|
|
23
|
+
this.writeCache(userId, layout);
|
|
24
|
+
await this.gateway.save(layout);
|
|
25
|
+
}
|
|
26
|
+
writeCache(userId, layout) {
|
|
27
|
+
const key = this.cacheKey(userId);
|
|
28
|
+
if (!layout) return void this.localStorage.remove(key);
|
|
29
|
+
this.localStorage.set(key, {
|
|
30
|
+
version: CACHE_VERSION,
|
|
31
|
+
layout
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
cacheKey(userId) {
|
|
35
|
+
const tenantId = this.tenantContext.getCurrentTenant() ?? "root";
|
|
36
|
+
return `dashboard:${tenantId}:${userId}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const DashboardLayoutRepository_DashboardLayoutRepository = DashboardLayoutRepository.createImplementation({
|
|
40
|
+
implementation: DashboardLayoutRepositoryImpl,
|
|
41
|
+
dependencies: [
|
|
42
|
+
DashboardLayoutGateway,
|
|
43
|
+
LocalStorage,
|
|
44
|
+
TenantContext
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
export { DashboardLayoutRepository_DashboardLayoutRepository as DashboardLayoutRepository };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=DashboardLayoutRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/repository/DashboardLayoutRepository.js","sources":["../../../../src/Dashboard/dashboardLayout/repository/DashboardLayoutRepository.ts"],"sourcesContent":["import { LocalStorage } from \"@webiny/app/exports/admin/local-storage.js\";\nimport { TenantContext } from \"@webiny/app-admin/exports/admin/tenancy.js\";\nimport { DashboardLayoutRepository as RepositoryAbstraction } from \"./abstractions.js\";\nimport { DashboardLayoutGateway } from \"./abstractions.js\";\nimport type { DashboardLayoutData } from \"../types.js\";\n\n// Bump when the cached shape changes; older entries are then ignored and replaced on the next fetch.\nconst CACHE_VERSION = 1;\n\ninterface CachedLayout {\n version: number;\n layout: DashboardLayoutData;\n}\n\nclass DashboardLayoutRepositoryImpl implements RepositoryAbstraction.Interface {\n constructor(\n private gateway: DashboardLayoutGateway.Interface,\n private localStorage: LocalStorage.Interface,\n private tenantContext: TenantContext.Interface\n ) {}\n\n getCached(userId: string): DashboardLayoutData | null {\n const key = this.cacheKey(userId);\n const cached = this.localStorage.get<CachedLayout>(key);\n if (!cached || cached.version !== CACHE_VERSION) {\n return null;\n }\n return cached.layout;\n }\n\n async fetch(userId: string): Promise<DashboardLayoutData | null> {\n const layout = await this.gateway.get();\n this.writeCache(userId, layout);\n return layout;\n }\n\n async save(userId: string, layout: DashboardLayoutData): Promise<void> {\n // Cache first, so a reload shows the change even while the request is still in flight.\n this.writeCache(userId, layout);\n await this.gateway.save(layout);\n }\n\n private writeCache(userId: string, layout: DashboardLayoutData | null): void {\n const key = this.cacheKey(userId);\n if (!layout) {\n this.localStorage.remove(key);\n return;\n }\n this.localStorage.set<CachedLayout>(key, { version: CACHE_VERSION, layout });\n }\n\n private cacheKey(userId: string): string {\n const tenantId = this.tenantContext.getCurrentTenant() ?? \"root\";\n return `dashboard:${tenantId}:${userId}`;\n }\n}\n\nexport const DashboardLayoutRepository = RepositoryAbstraction.createImplementation({\n implementation: DashboardLayoutRepositoryImpl,\n dependencies: [DashboardLayoutGateway, LocalStorage, TenantContext]\n});\n"],"names":["CACHE_VERSION","DashboardLayoutRepositoryImpl","gateway","localStorage","tenantContext","userId","key","cached","layout","tenantId","DashboardLayoutRepository","RepositoryAbstraction","DashboardLayoutGateway","LocalStorage","TenantContext"],"mappings":";;;AAOA,MAAMA,gBAAgB;AAOtB,MAAMC;IACF,YACYC,OAAyC,EACzCC,YAAoC,EACpCC,aAAsC,CAChD;aAHUF,OAAO,GAAPA;aACAC,YAAY,GAAZA;aACAC,aAAa,GAAbA;IACT;IAEH,UAAUC,MAAc,EAA8B;QAClD,MAAMC,MAAM,IAAI,CAAC,QAAQ,CAACD;QAC1B,MAAME,SAAS,IAAI,CAAC,YAAY,CAAC,GAAG,CAAeD;QACnD,IAAI,CAACC,UAAUA,OAAO,OAAO,KAAKP,eAC9B,OAAO;QAEX,OAAOO,OAAO,MAAM;IACxB;IAEA,MAAM,MAAMF,MAAc,EAAuC;QAC7D,MAAMG,SAAS,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG;QACrC,IAAI,CAAC,UAAU,CAACH,QAAQG;QACxB,OAAOA;IACX;IAEA,MAAM,KAAKH,MAAc,EAAEG,MAA2B,EAAiB;QAEnE,IAAI,CAAC,UAAU,CAACH,QAAQG;QACxB,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAACA;IAC5B;IAEQ,WAAWH,MAAc,EAAEG,MAAkC,EAAQ;QACzE,MAAMF,MAAM,IAAI,CAAC,QAAQ,CAACD;QAC1B,IAAI,CAACG,QAAQ,YACT,IAAI,CAAC,YAAY,CAAC,MAAM,CAACF;QAG7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAeA,KAAK;YAAE,SAASN;YAAeQ;QAAO;IAC9E;IAEQ,SAASH,MAAc,EAAU;QACrC,MAAMI,WAAW,IAAI,CAAC,aAAa,CAAC,gBAAgB,MAAM;QAC1D,OAAO,CAAC,UAAU,EAAEA,SAAS,CAAC,EAAEJ,QAAQ;IAC5C;AACJ;AAEO,MAAMK,sDAA4BC,0BAAAA,oBAA0C,CAAC;IAChF,gBAAgBV;IAChB,cAAc;QAACW;QAAwBC;QAAcC;KAAc;AACvE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Talks to the API. `get` resolves to `null` when the user never customized their dashboard.
|
|
4
|
+
*/
|
|
5
|
+
export interface IDashboardLayoutGateway {
|
|
6
|
+
get(): Promise<DashboardLayoutData | null>;
|
|
7
|
+
save(layout: DashboardLayoutData): Promise<DashboardLayoutData>;
|
|
8
|
+
}
|
|
9
|
+
export declare const DashboardLayoutGateway: import("@webiny/di").Abstraction<IDashboardLayoutGateway>;
|
|
10
|
+
export declare namespace DashboardLayoutGateway {
|
|
11
|
+
type Interface = IDashboardLayoutGateway;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Keeps a copy of each user's layout in localStorage, so the dashboard renders straight away and
|
|
15
|
+
* the API request only confirms or corrects it.
|
|
16
|
+
*/
|
|
17
|
+
export interface IDashboardLayoutRepository {
|
|
18
|
+
getCached(userId: string): DashboardLayoutData | null;
|
|
19
|
+
fetch(userId: string): Promise<DashboardLayoutData | null>;
|
|
20
|
+
save(userId: string, layout: DashboardLayoutData): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare const DashboardLayoutRepository: import("@webiny/di").Abstraction<IDashboardLayoutRepository>;
|
|
23
|
+
export declare namespace DashboardLayoutRepository {
|
|
24
|
+
type Interface = IDashboardLayoutRepository;
|
|
25
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createAbstraction } from "@webiny/feature/admin";
|
|
2
|
+
const DashboardLayoutGateway = createAbstraction("DashboardLayoutGateway");
|
|
3
|
+
const DashboardLayoutRepository = createAbstraction("DashboardLayoutRepository");
|
|
4
|
+
export { DashboardLayoutGateway, DashboardLayoutRepository };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=abstractions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/repository/abstractions.js","sources":["../../../../src/Dashboard/dashboardLayout/repository/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { DashboardLayoutData } from \"../types.js\";\n\n/**\n * Talks to the API. `get` resolves to `null` when the user never customized their dashboard.\n */\nexport interface IDashboardLayoutGateway {\n get(): Promise<DashboardLayoutData | null>;\n save(layout: DashboardLayoutData): Promise<DashboardLayoutData>;\n}\n\nexport const DashboardLayoutGateway =\n createAbstraction<IDashboardLayoutGateway>(\"DashboardLayoutGateway\");\n\nexport namespace DashboardLayoutGateway {\n export type Interface = IDashboardLayoutGateway;\n}\n\n/**\n * Keeps a copy of each user's layout in localStorage, so the dashboard renders straight away and\n * the API request only confirms or corrects it.\n */\nexport interface IDashboardLayoutRepository {\n // The cached layout, or `null` if there is none for this user and tenant.\n getCached(userId: string): DashboardLayoutData | null;\n // Fetches the stored layout and refreshes the cache with it.\n fetch(userId: string): Promise<DashboardLayoutData | null>;\n save(userId: string, layout: DashboardLayoutData): Promise<void>;\n}\n\nexport const DashboardLayoutRepository = createAbstraction<IDashboardLayoutRepository>(\n \"DashboardLayoutRepository\"\n);\n\nexport namespace DashboardLayoutRepository {\n export type Interface = IDashboardLayoutRepository;\n}\n"],"names":["DashboardLayoutGateway","createAbstraction","DashboardLayoutRepository"],"mappings":";AAWO,MAAMA,yBACTC,kBAA2C;AAkBxC,MAAMC,4BAA4BD,kBACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DashboardLayoutRepositoryFeature: import("@webiny/feature/admin").FeatureDefinition<any, []>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/admin";
|
|
2
|
+
import { DashboardLayoutGateway } from "./DashboardLayoutGateway.js";
|
|
3
|
+
import { DashboardLayoutRepository } from "./DashboardLayoutRepository.js";
|
|
4
|
+
const DashboardLayoutRepositoryFeature = createFeature({
|
|
5
|
+
name: "AdminUI/DashboardLayoutRepository",
|
|
6
|
+
register (container) {
|
|
7
|
+
container.register(DashboardLayoutGateway).inSingletonScope();
|
|
8
|
+
container.register(DashboardLayoutRepository).inSingletonScope();
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
export { DashboardLayoutRepositoryFeature };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/repository/feature.js","sources":["../../../../src/Dashboard/dashboardLayout/repository/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { DashboardLayoutGateway } from \"./DashboardLayoutGateway.js\";\nimport { DashboardLayoutRepository } from \"./DashboardLayoutRepository.js\";\n\nexport const DashboardLayoutRepositoryFeature = createFeature({\n name: \"AdminUI/DashboardLayoutRepository\",\n register(container) {\n container.register(DashboardLayoutGateway).inSingletonScope();\n container.register(DashboardLayoutRepository).inSingletonScope();\n }\n});\n"],"names":["DashboardLayoutRepositoryFeature","createFeature","container","DashboardLayoutGateway","DashboardLayoutRepository"],"mappings":";;;AAIO,MAAMA,mCAAmCC,cAAc;IAC1D,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,wBAAwB,gBAAgB;QAC3DD,UAAU,QAAQ,CAACE,2BAA2B,gBAAgB;IAClE;AACJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DashboardLayoutRepository } from "../repository/abstractions.js";
|
|
2
|
+
import { SaveDashboardLayoutUseCase as UseCaseAbstraction } from "./abstractions.js";
|
|
3
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
4
|
+
declare class SaveDashboardLayoutUseCaseImpl implements UseCaseAbstraction.Interface {
|
|
5
|
+
private repository;
|
|
6
|
+
constructor(repository: DashboardLayoutRepository.Interface);
|
|
7
|
+
execute(userId: string, layout: DashboardLayoutData): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare const SaveDashboardLayoutUseCase: typeof SaveDashboardLayoutUseCaseImpl & {
|
|
10
|
+
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ISaveDashboardLayoutUseCase>;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DashboardLayoutRepository } from "../repository/abstractions.js";
|
|
2
|
+
import { SaveDashboardLayoutUseCase } from "./abstractions.js";
|
|
3
|
+
class SaveDashboardLayoutUseCaseImpl {
|
|
4
|
+
constructor(repository){
|
|
5
|
+
this.repository = repository;
|
|
6
|
+
}
|
|
7
|
+
async execute(userId, layout) {
|
|
8
|
+
await this.repository.save(userId, layout);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const SaveDashboardLayoutUseCase_SaveDashboardLayoutUseCase = SaveDashboardLayoutUseCase.createImplementation({
|
|
12
|
+
implementation: SaveDashboardLayoutUseCaseImpl,
|
|
13
|
+
dependencies: [
|
|
14
|
+
DashboardLayoutRepository
|
|
15
|
+
]
|
|
16
|
+
});
|
|
17
|
+
export { SaveDashboardLayoutUseCase_SaveDashboardLayoutUseCase as SaveDashboardLayoutUseCase };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=SaveDashboardLayoutUseCase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/saveLayout/SaveDashboardLayoutUseCase.js","sources":["../../../../src/Dashboard/dashboardLayout/saveLayout/SaveDashboardLayoutUseCase.ts"],"sourcesContent":["import { DashboardLayoutRepository } from \"../repository/abstractions.js\";\nimport { SaveDashboardLayoutUseCase as UseCaseAbstraction } from \"./abstractions.js\";\nimport type { DashboardLayoutData } from \"../types.js\";\n\nclass SaveDashboardLayoutUseCaseImpl implements UseCaseAbstraction.Interface {\n constructor(private repository: DashboardLayoutRepository.Interface) {}\n\n async execute(userId: string, layout: DashboardLayoutData): Promise<void> {\n await this.repository.save(userId, layout);\n }\n}\n\nexport const SaveDashboardLayoutUseCase = UseCaseAbstraction.createImplementation({\n implementation: SaveDashboardLayoutUseCaseImpl,\n dependencies: [DashboardLayoutRepository]\n});\n"],"names":["SaveDashboardLayoutUseCaseImpl","repository","userId","layout","SaveDashboardLayoutUseCase","UseCaseAbstraction","DashboardLayoutRepository"],"mappings":";;AAIA,MAAMA;IACF,YAAoBC,UAA+C,CAAE;aAAjDA,UAAU,GAAVA;IAAkD;IAEtE,MAAM,QAAQC,MAAc,EAAEC,MAA2B,EAAiB;QACtE,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAACD,QAAQC;IACvC;AACJ;AAEO,MAAMC,wDAA6BC,2BAAAA,oBAAuC,CAAC;IAC9E,gBAAgBL;IAChB,cAAc;QAACM;KAA0B;AAC7C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DashboardLayoutData } from "../types.js";
|
|
2
|
+
export interface ISaveDashboardLayoutUseCase {
|
|
3
|
+
execute(userId: string, layout: DashboardLayoutData): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
export declare const SaveDashboardLayoutUseCase: import("@webiny/di").Abstraction<ISaveDashboardLayoutUseCase>;
|
|
6
|
+
export declare namespace SaveDashboardLayoutUseCase {
|
|
7
|
+
type Interface = ISaveDashboardLayoutUseCase;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/saveLayout/abstractions.js","sources":["../../../../src/Dashboard/dashboardLayout/saveLayout/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { DashboardLayoutData } from \"../types.js\";\n\nexport interface ISaveDashboardLayoutUseCase {\n execute(userId: string, layout: DashboardLayoutData): Promise<void>;\n}\n\nexport const SaveDashboardLayoutUseCase = createAbstraction<ISaveDashboardLayoutUseCase>(\n \"SaveDashboardLayoutUseCase\"\n);\n\nexport namespace SaveDashboardLayoutUseCase {\n export type Interface = ISaveDashboardLayoutUseCase;\n}\n"],"names":["SaveDashboardLayoutUseCase","createAbstraction"],"mappings":";AAOO,MAAMA,6BAA6BC,kBACtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SaveDashboardLayoutFeature: import("@webiny/feature/admin").FeatureDefinition<any, []>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createFeature } from "@webiny/feature/admin";
|
|
2
|
+
import { SaveDashboardLayoutUseCase } from "./SaveDashboardLayoutUseCase.js";
|
|
3
|
+
const SaveDashboardLayoutFeature = createFeature({
|
|
4
|
+
name: "AdminUI/SaveDashboardLayout",
|
|
5
|
+
register (container) {
|
|
6
|
+
container.register(SaveDashboardLayoutUseCase);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
export { SaveDashboardLayoutFeature };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/saveLayout/feature.js","sources":["../../../../src/Dashboard/dashboardLayout/saveLayout/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/admin\";\nimport { SaveDashboardLayoutUseCase } from \"./SaveDashboardLayoutUseCase.js\";\n\nexport const SaveDashboardLayoutFeature = createFeature({\n name: \"AdminUI/SaveDashboardLayout\",\n register(container) {\n container.register(SaveDashboardLayoutUseCase);\n }\n});\n"],"names":["SaveDashboardLayoutFeature","createFeature","container","SaveDashboardLayoutUseCase"],"mappings":";;AAGO,MAAMA,6BAA6BC,cAAc;IACpD,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC;IACvB;AACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const toColumnIndex: (column: string | number | undefined) => number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/toColumnIndex.js","sources":["../../../src/Dashboard/dashboardLayout/toColumnIndex.ts"],"sourcesContent":["// Widgets register their column as a string (\"left\" or \"right\") or as a zero-based index.\nexport const toColumnIndex = (column: string | number | undefined): number => {\n if (typeof column === \"number\") {\n return column;\n }\n return column === \"right\" ? 1 : 0;\n};\n"],"names":["toColumnIndex","column"],"mappings":"AACO,MAAMA,gBAAgB,CAACC;IAC1B,IAAI,AAAkB,YAAlB,OAAOA,QACP,OAAOA;IAEX,OAAOA,AAAW,YAAXA,SAAqB,IAAI;AACpC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Default column count when a user hasn't customized their dashboard. */
|
|
2
|
+
export declare const DEFAULT_COLUMN_COUNT = 2;
|
|
3
|
+
/** Allowed range for the user-selectable column count. */
|
|
4
|
+
export declare const MIN_COLUMN_COUNT = 2;
|
|
5
|
+
export declare const MAX_COLUMN_COUNT = 4;
|
|
6
|
+
/**
|
|
7
|
+
* The persisted, per-user dashboard layout: an ordered list of widget names per column
|
|
8
|
+
* (`columns[i]` = column i), the widgets the user has removed (`hidden`), and how many
|
|
9
|
+
* columns the user has chosen.
|
|
10
|
+
*/
|
|
11
|
+
export interface DashboardLayoutData {
|
|
12
|
+
columns: string[][];
|
|
13
|
+
hidden: string[];
|
|
14
|
+
columnCount: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard/dashboardLayout/types.js","sources":["../../../src/Dashboard/dashboardLayout/types.ts"],"sourcesContent":["/** Default column count when a user hasn't customized their dashboard. */\nexport const DEFAULT_COLUMN_COUNT = 2;\n\n/** Allowed range for the user-selectable column count. */\nexport const MIN_COLUMN_COUNT = 2;\nexport const MAX_COLUMN_COUNT = 4;\n\n/**\n * The persisted, per-user dashboard layout: an ordered list of widget names per column\n * (`columns[i]` = column i), the widgets the user has removed (`hidden`), and how many\n * columns the user has chosen.\n */\nexport interface DashboardLayoutData {\n columns: string[][];\n hidden: string[];\n columnCount: number;\n}\n"],"names":["DEFAULT_COLUMN_COUNT","MIN_COLUMN_COUNT","MAX_COLUMN_COUNT"],"mappings":"AACO,MAAMA,uBAAuB;AAG7B,MAAMC,mBAAmB;AACzB,MAAMC,mBAAmB"}
|
package/Dashboard.d.ts
ADDED
package/Dashboard.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CenteredView, DashboardRenderer as app_admin_DashboardRenderer } from "@webiny/app-admin";
|
|
2
|
+
import Welcome from "./Dashboard/Welcome.js";
|
|
3
|
+
import * as __rspack_external_react from "react";
|
|
4
|
+
const Dashboard = app_admin_DashboardRenderer.createDecorator(()=>function() {
|
|
5
|
+
return /*#__PURE__*/ __rspack_external_react.createElement(CenteredView, null, /*#__PURE__*/ __rspack_external_react.createElement(Welcome, null));
|
|
6
|
+
});
|
|
7
|
+
export { Dashboard };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=Dashboard.js.map
|
package/Dashboard.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.js","sources":["../src/Dashboard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CenteredView, DashboardRenderer } from \"@webiny/app-admin\";\nimport Welcome from \"./Dashboard/Welcome.js\";\n\nexport const Dashboard = DashboardRenderer.createDecorator(() => {\n return function DashboardRenderer() {\n return (\n <CenteredView>\n <Welcome />\n </CenteredView>\n );\n };\n});\n"],"names":["Dashboard","DashboardRenderer","CenteredView","Welcome"],"mappings":";;;AAIO,MAAMA,YAAYC,4BAAAA,eAAiC,CAAC,IAChD;QACH,OAAO,WAAP,GACI,sCAACC,cAAYA,MAAAA,WAAAA,GACT,sCAACC,SAAOA;IAGpB"}
|