@genesislcap/foundation-workspace 14.406.0-workspaces.7

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.
Files changed (185) hide show
  1. package/api-extractor.json +5 -0
  2. package/dist/dts/index.d.ts +4 -0
  3. package/dist/dts/index.d.ts.map +1 -0
  4. package/dist/dts/tsdoc-metadata.json +11 -0
  5. package/dist/dts/workspace/filter-registry.d.ts +34 -0
  6. package/dist/dts/workspace/filter-registry.d.ts.map +1 -0
  7. package/dist/dts/workspace/grid-register/grid-register.d.ts +23 -0
  8. package/dist/dts/workspace/grid-register/grid-register.d.ts.map +1 -0
  9. package/dist/dts/workspace/grid-register/grid-register.template.d.ts +4 -0
  10. package/dist/dts/workspace/grid-register/grid-register.template.d.ts.map +1 -0
  11. package/dist/dts/workspace/grid-register/index.d.ts +2 -0
  12. package/dist/dts/workspace/grid-register/index.d.ts.map +1 -0
  13. package/dist/dts/workspace/grid-registry.d.ts +47 -0
  14. package/dist/dts/workspace/grid-registry.d.ts.map +1 -0
  15. package/dist/dts/workspace/index.d.ts +9 -0
  16. package/dist/dts/workspace/index.d.ts.map +1 -0
  17. package/dist/dts/workspace/layout-registry.d.ts +27 -0
  18. package/dist/dts/workspace/layout-registry.d.ts.map +1 -0
  19. package/dist/dts/workspace/layout-wrapper/index.d.ts +2 -0
  20. package/dist/dts/workspace/layout-wrapper/index.d.ts.map +1 -0
  21. package/dist/dts/workspace/layout-wrapper/layout-wrapper.d.ts +14 -0
  22. package/dist/dts/workspace/layout-wrapper/layout-wrapper.d.ts.map +1 -0
  23. package/dist/dts/workspace/layout-wrapper/layout-wrapper.template.d.ts +4 -0
  24. package/dist/dts/workspace/layout-wrapper/layout-wrapper.template.d.ts.map +1 -0
  25. package/dist/dts/workspace/workspace-state.d.ts +45 -0
  26. package/dist/dts/workspace/workspace-state.d.ts.map +1 -0
  27. package/dist/dts/workspace/workspace-state.types.d.ts +26 -0
  28. package/dist/dts/workspace/workspace-state.types.d.ts.map +1 -0
  29. package/dist/dts/workspace/workspace.types.d.ts +25 -0
  30. package/dist/dts/workspace/workspace.types.d.ts.map +1 -0
  31. package/dist/dts/workspace-components.d.ts +22 -0
  32. package/dist/dts/workspace-components.d.ts.map +1 -0
  33. package/dist/dts/workspace-manager/index.d.ts +2 -0
  34. package/dist/dts/workspace-manager/index.d.ts.map +1 -0
  35. package/dist/dts/workspace-manager/workspace-manager.d.ts +70 -0
  36. package/dist/dts/workspace-manager/workspace-manager.d.ts.map +1 -0
  37. package/dist/dts/workspace-manager/workspace-manager.styles.d.ts +2 -0
  38. package/dist/dts/workspace-manager/workspace-manager.styles.d.ts.map +1 -0
  39. package/dist/dts/workspace-manager/workspace-manager.template.d.ts +4 -0
  40. package/dist/dts/workspace-manager/workspace-manager.template.d.ts.map +1 -0
  41. package/dist/esm/index.js +3 -0
  42. package/dist/esm/workspace/filter-registry.js +47 -0
  43. package/dist/esm/workspace/grid-register/grid-register.js +136 -0
  44. package/dist/esm/workspace/grid-register/grid-register.template.js +4 -0
  45. package/dist/esm/workspace/grid-register/index.js +1 -0
  46. package/dist/esm/workspace/grid-registry.js +109 -0
  47. package/dist/esm/workspace/index.js +8 -0
  48. package/dist/esm/workspace/layout-registry.js +45 -0
  49. package/dist/esm/workspace/layout-wrapper/index.js +1 -0
  50. package/dist/esm/workspace/layout-wrapper/layout-wrapper.js +64 -0
  51. package/dist/esm/workspace/layout-wrapper/layout-wrapper.template.js +4 -0
  52. package/dist/esm/workspace/workspace-state.js +193 -0
  53. package/dist/esm/workspace/workspace-state.types.js +1 -0
  54. package/dist/esm/workspace/workspace.types.js +1 -0
  55. package/dist/esm/workspace-components.js +43 -0
  56. package/dist/esm/workspace-manager/index.js +1 -0
  57. package/dist/esm/workspace-manager/workspace-manager.js +436 -0
  58. package/dist/esm/workspace-manager/workspace-manager.styles.js +138 -0
  59. package/dist/esm/workspace-manager/workspace-manager.template.js +259 -0
  60. package/dist/foundation-workspace.api.json +3614 -0
  61. package/dist/foundation-workspace.d.ts +343 -0
  62. package/dist/tsconfig.tsbuildinfo +1 -0
  63. package/docs/.gitkeep +1 -0
  64. package/docs/api/foundation-workspace.defaultfilterregistry.md +17 -0
  65. package/docs/api/foundation-workspace.defaultgridregistry.md +17 -0
  66. package/docs/api/foundation-workspace.defaultlayoutregistry.md +18 -0
  67. package/docs/api/foundation-workspace.defaultworkspacestate._constructor_.md +65 -0
  68. package/docs/api/foundation-workspace.defaultworkspacestate.auth.md +14 -0
  69. package/docs/api/foundation-workspace.defaultworkspacestate.kvstorage.md +14 -0
  70. package/docs/api/foundation-workspace.defaultworkspacestate.md +115 -0
  71. package/docs/api/foundation-workspace.filterregistration.filterkey.md +14 -0
  72. package/docs/api/foundation-workspace.filterregistration.getfiltervalue.md +14 -0
  73. package/docs/api/foundation-workspace.filterregistration.md +98 -0
  74. package/docs/api/foundation-workspace.filterregistration.setfiltervalue.md +14 -0
  75. package/docs/api/foundation-workspace.filterregistry.applyfiltersvalues.md +53 -0
  76. package/docs/api/foundation-workspace.filterregistry.getallfiltersvalues.md +18 -0
  77. package/docs/api/foundation-workspace.filterregistry.md +16 -0
  78. package/docs/api/foundation-workspace.filterregistry.registerfilter.md +81 -0
  79. package/docs/api/foundation-workspace.filterregistry.unregisterfilter.md +53 -0
  80. package/docs/api/foundation-workspace.gridregister.gridkey.md +14 -0
  81. package/docs/api/foundation-workspace.gridregister.gridregistry.md +14 -0
  82. package/docs/api/foundation-workspace.gridregister.md +100 -0
  83. package/docs/api/foundation-workspace.gridregister.workspacestate.md +14 -0
  84. package/docs/api/foundation-workspace.gridregistration.columnapi.md +14 -0
  85. package/docs/api/foundation-workspace.gridregistration.gridapi.md +14 -0
  86. package/docs/api/foundation-workspace.gridregistration.gridkey.md +14 -0
  87. package/docs/api/foundation-workspace.gridregistration.md +98 -0
  88. package/docs/api/foundation-workspace.gridregistry.applyallgridssettings.md +53 -0
  89. package/docs/api/foundation-workspace.gridregistry.applygridsettings.md +72 -0
  90. package/docs/api/foundation-workspace.gridregistry.getallgridssettings.md +18 -0
  91. package/docs/api/foundation-workspace.gridregistry.getgrid.md +53 -0
  92. package/docs/api/foundation-workspace.gridregistry.md +16 -0
  93. package/docs/api/foundation-workspace.gridregistry.registergrid.md +81 -0
  94. package/docs/api/foundation-workspace.gridregistry.unregistergrid.md +53 -0
  95. package/docs/api/foundation-workspace.layoutregistry.applysavedlayouts.md +53 -0
  96. package/docs/api/foundation-workspace.layoutregistry.getlayoutsconfigs.md +18 -0
  97. package/docs/api/foundation-workspace.layoutregistry.md +16 -0
  98. package/docs/api/foundation-workspace.layoutregistry.registerlayout.md +67 -0
  99. package/docs/api/foundation-workspace.layoutregistry.unregisterlayout.md +53 -0
  100. package/docs/api/foundation-workspace.layoutwrapper.layoutkey.md +14 -0
  101. package/docs/api/foundation-workspace.layoutwrapper.layoutregistry.md +14 -0
  102. package/docs/api/foundation-workspace.layoutwrapper.md +81 -0
  103. package/docs/api/foundation-workspace.loadmode.md +16 -0
  104. package/docs/api/foundation-workspace.md +332 -0
  105. package/docs/api/foundation-workspace.savedfiltervalue.filterkey.md +14 -0
  106. package/docs/api/foundation-workspace.savedfiltervalue.md +79 -0
  107. package/docs/api/foundation-workspace.savedfiltervalue.value.md +14 -0
  108. package/docs/api/foundation-workspace.savedgridsettings.columnstate.md +14 -0
  109. package/docs/api/foundation-workspace.savedgridsettings.gridkey.md +14 -0
  110. package/docs/api/foundation-workspace.savedgridsettings.md +99 -0
  111. package/docs/api/foundation-workspace.savedgridsettings.savedat.md +14 -0
  112. package/docs/api/foundation-workspace.savedlayout.layout.md +14 -0
  113. package/docs/api/foundation-workspace.savedlayout.layoutkey.md +14 -0
  114. package/docs/api/foundation-workspace.savedlayout.md +79 -0
  115. package/docs/api/foundation-workspace.savedworkspace.description.md +14 -0
  116. package/docs/api/foundation-workspace.savedworkspace.filters.md +14 -0
  117. package/docs/api/foundation-workspace.savedworkspace.grids.md +14 -0
  118. package/docs/api/foundation-workspace.savedworkspace.layouts.md +14 -0
  119. package/docs/api/foundation-workspace.savedworkspace.md +174 -0
  120. package/docs/api/foundation-workspace.savedworkspace.name.md +14 -0
  121. package/docs/api/foundation-workspace.savedworkspace.savedat.md +14 -0
  122. package/docs/api/foundation-workspace.savedworkspace.username.md +14 -0
  123. package/docs/api/foundation-workspace.sharedworkspace.createdon.md +14 -0
  124. package/docs/api/foundation-workspace.sharedworkspace.data.md +14 -0
  125. package/docs/api/foundation-workspace.sharedworkspace.description.md +14 -0
  126. package/docs/api/foundation-workspace.sharedworkspace.id.md +14 -0
  127. package/docs/api/foundation-workspace.sharedworkspace.md +174 -0
  128. package/docs/api/foundation-workspace.sharedworkspace.modifiedon.md +14 -0
  129. package/docs/api/foundation-workspace.sharedworkspace.name.md +14 -0
  130. package/docs/api/foundation-workspace.sharedworkspace.username.md +14 -0
  131. package/docs/api/foundation-workspace.workspacecomponents.md +29 -0
  132. package/docs/api/foundation-workspace.workspacemanager.applyingworkspace.md +14 -0
  133. package/docs/api/foundation-workspace.workspacemanager.auth.md +14 -0
  134. package/docs/api/foundation-workspace.workspacemanager.canshareworkspace.md +14 -0
  135. package/docs/api/foundation-workspace.workspacemanager.connect.md +14 -0
  136. package/docs/api/foundation-workspace.workspacemanager.dialogboundary.md +14 -0
  137. package/docs/api/foundation-workspace.workspacemanager.filterregistry.md +14 -0
  138. package/docs/api/foundation-workspace.workspacemanager.gridregistry.md +14 -0
  139. package/docs/api/foundation-workspace.workspacemanager.isloading.md +14 -0
  140. package/docs/api/foundation-workspace.workspacemanager.layoutregistry.md +14 -0
  141. package/docs/api/foundation-workspace.workspacemanager.loadmodal.md +14 -0
  142. package/docs/api/foundation-workspace.workspacemanager.loadmode.md +14 -0
  143. package/docs/api/foundation-workspace.workspacemanager.md +442 -0
  144. package/docs/api/foundation-workspace.workspacemanager.savedworkspaces.md +14 -0
  145. package/docs/api/foundation-workspace.workspacemanager.savemodal.md +14 -0
  146. package/docs/api/foundation-workspace.workspacemanager.savemode.md +14 -0
  147. package/docs/api/foundation-workspace.workspacemanager.selectedworkspacetooverwrite.md +14 -0
  148. package/docs/api/foundation-workspace.workspacemanager.sharedworkspacedialogboundary.md +14 -0
  149. package/docs/api/foundation-workspace.workspacemanager.sharedworkspaces.md +14 -0
  150. package/docs/api/foundation-workspace.workspacemanager.workspacedescription.md +14 -0
  151. package/docs/api/foundation-workspace.workspacemanager.workspacename.md +14 -0
  152. package/docs/api/foundation-workspace.workspacemanager.workspacestate.md +14 -0
  153. package/docs/api/foundation-workspace.workspacemanager.workspacetoshare.md +14 -0
  154. package/docs/api/foundation-workspace.workspacestate.deleteworkspace.md +53 -0
  155. package/docs/api/foundation-workspace.workspacestate.getcurrentworkspace.md +18 -0
  156. package/docs/api/foundation-workspace.workspacestate.getsavedworkspaces.md +18 -0
  157. package/docs/api/foundation-workspace.workspacestate.loadworkspace.md +53 -0
  158. package/docs/api/foundation-workspace.workspacestate.md +16 -0
  159. package/docs/api/foundation-workspace.workspacestate.saveworkspace.md +111 -0
  160. package/docs/api/foundation-workspace.workspacestate.setcurrentworkspace.md +53 -0
  161. package/docs/api/index.md +30 -0
  162. package/docs/api-report.md.api.md +372 -0
  163. package/license.txt +46 -0
  164. package/package.json +69 -0
  165. package/src/index.ts +3 -0
  166. package/src/workspace/filter-registry.ts +80 -0
  167. package/src/workspace/grid-register/grid-register.template.ts +7 -0
  168. package/src/workspace/grid-register/grid-register.ts +142 -0
  169. package/src/workspace/grid-register/index.ts +1 -0
  170. package/src/workspace/grid-registry.ts +157 -0
  171. package/src/workspace/index.ts +8 -0
  172. package/src/workspace/layout-registry.ts +58 -0
  173. package/src/workspace/layout-wrapper/index.ts +1 -0
  174. package/src/workspace/layout-wrapper/layout-wrapper.template.ts +7 -0
  175. package/src/workspace/layout-wrapper/layout-wrapper.ts +66 -0
  176. package/src/workspace/workspace-state.ts +234 -0
  177. package/src/workspace/workspace-state.types.ts +27 -0
  178. package/src/workspace/workspace.types.ts +26 -0
  179. package/src/workspace-components.ts +51 -0
  180. package/src/workspace-manager/index.ts +1 -0
  181. package/src/workspace-manager/workspace-manager.styles.ts +139 -0
  182. package/src/workspace-manager/workspace-manager.template.ts +352 -0
  183. package/src/workspace-manager/workspace-manager.ts +420 -0
  184. package/temp/api-report.md.api.md +372 -0
  185. package/tsconfig.json +11 -0
@@ -0,0 +1,420 @@
1
+ import { Auth, Connect } from '@genesislcap/foundation-comms';
2
+ import {
3
+ showNotificationDialog,
4
+ showNotificationToast,
5
+ } from '@genesislcap/foundation-notifications';
6
+ import { Modal } from '@genesislcap/foundation-ui';
7
+ import { customElement, observable } from '@microsoft/fast-element';
8
+ import { FoundationElement } from '@microsoft/fast-foundation';
9
+ import {
10
+ LayoutRegistry,
11
+ GridRegistry,
12
+ FilterRegistry,
13
+ WorkspaceState,
14
+ type SavedWorkspace,
15
+ type SharedWorkspace,
16
+ type SavedGridSettings,
17
+ } from '../workspace';
18
+ import { WorkspaceManagerStyles as styles } from './workspace-manager.styles';
19
+ import {
20
+ WORKSPACE_DESCRIPTION_MAX,
21
+ WorkspaceManagerTemplate as template,
22
+ } from './workspace-manager.template';
23
+
24
+ /**
25
+ * Workspace load mode.
26
+ * @alpha
27
+ */
28
+ export type LoadMode = 'MY' | 'SHARED';
29
+
30
+ /**
31
+ * Workspace persistence UI (save/load + share/delete shared workspaces).
32
+ * @alpha
33
+ */
34
+ @customElement({
35
+ name: 'workspace-manager',
36
+ template,
37
+ styles,
38
+ })
39
+ export class WorkspaceManager extends FoundationElement {
40
+ @observable workspaceName: string = '';
41
+ @observable workspaceDescription: string = '';
42
+ @observable savedWorkspaces: SavedWorkspace[] = [];
43
+ @observable sharedWorkspaces: SharedWorkspace[] = [];
44
+ @observable isLoading: boolean = false;
45
+ @observable applyingWorkspace: boolean = false;
46
+ @observable loadMode: LoadMode = 'MY';
47
+ @observable saveModal: Modal;
48
+ @observable loadModal: Modal;
49
+ @observable saveMode: 'create' | 'overwrite' | 'shared' = 'create';
50
+ @observable selectedWorkspaceToOverwrite: string = '';
51
+ @observable workspaceToShare: string = '';
52
+ @observable dialogBoundary: HTMLElement;
53
+ @observable sharedWorkspaceDialogBoundary: HTMLElement;
54
+
55
+ @LayoutRegistry layoutRegistry: LayoutRegistry;
56
+ @GridRegistry gridRegistry: GridRegistry;
57
+ @FilterRegistry filterRegistry: FilterRegistry;
58
+ @WorkspaceState workspaceState: WorkspaceState;
59
+ @Connect connect: Connect;
60
+ @Auth auth: Auth;
61
+
62
+ @observable canShareWorkspace: boolean;
63
+
64
+ private sanitizeDescription(input: string): string {
65
+ const cleaned = (input ?? '')
66
+ // allow only letters, numbers and whitespace
67
+ .replace(/[^a-zA-Z0-9\s]/g, '')
68
+ // normalise whitespace
69
+ .replace(/\s+/g, ' ')
70
+ .trim();
71
+
72
+ return cleaned.slice(0, WORKSPACE_DESCRIPTION_MAX);
73
+ }
74
+
75
+ updateWorkspaceDescription(raw: string): void {
76
+ this.workspaceDescription = this.sanitizeDescription(raw);
77
+ }
78
+
79
+ private setDescriptionFromSelectedWorkspace(): void {
80
+ const name = this.selectedWorkspaceToOverwrite?.trim();
81
+
82
+ if (!name) {
83
+ this.workspaceDescription = '';
84
+ return;
85
+ }
86
+
87
+ const existing = this.savedWorkspaces.find((w) => w.name === name);
88
+ this.workspaceDescription = this.sanitizeDescription(existing?.description ?? '');
89
+ }
90
+
91
+ async connectedCallback(): Promise<void> {
92
+ super.connectedCallback();
93
+ await this.refreshSavedWorkspaces();
94
+ await this.refreshSharedWorkspaces();
95
+ this.canShareWorkspace = this.auth.currentUser.hasPermission('SHARE_WORKSPACE');
96
+ }
97
+
98
+ async refreshSavedWorkspaces(): Promise<void> {
99
+ this.isLoading = true;
100
+ try {
101
+ this.savedWorkspaces = await this.workspaceState.getSavedWorkspaces();
102
+ } catch (error) {
103
+ console.error('Failed to load saved workspaces', error);
104
+ this.savedWorkspaces = [];
105
+ } finally {
106
+ this.isLoading = false;
107
+ }
108
+ }
109
+
110
+ async refreshSharedWorkspaces(): Promise<void> {
111
+ try {
112
+ const response: any = await this.connect.request('REQ_SHARED_WORKSPACES');
113
+ const rows: any[] = response?.REPLY || [];
114
+ this.sharedWorkspaces = rows.map((row: any) => ({
115
+ id: row.SHARED_WORKSPACE_ID,
116
+ name: row.WORKSPACE_NAME,
117
+ userName: row.USER_NAME,
118
+ description: row.DESCRIPTION ?? undefined,
119
+ createdOn: row.CREATED_ON,
120
+ modifiedOn: row.MODIFIED_ON,
121
+ data: row.WORKSPACE_DATA,
122
+ }));
123
+ } catch (error) {
124
+ this.notifyError(`REQ_SHARED_WORKSPACES ${JSON.stringify(error)}`);
125
+ console.error('Failed to load shared workspaces', error);
126
+ this.sharedWorkspaces = [];
127
+ }
128
+ }
129
+
130
+ private notifyError(body = 'Error'): void {
131
+ showNotificationToast(
132
+ { title: 'Error', body, iconName: 'bell', toast: { type: 'error', autoClose: false } },
133
+ 'rapid',
134
+ );
135
+ }
136
+
137
+ async saveWorkspace(): Promise<void> {
138
+ const workspaceName =
139
+ this.saveMode === 'overwrite'
140
+ ? this.selectedWorkspaceToOverwrite.trim()
141
+ : this.workspaceName.trim();
142
+
143
+ if (!workspaceName) {
144
+ console.error('workspace-manager: workspace name is required');
145
+ return;
146
+ }
147
+
148
+ try {
149
+ const layoutConfigs = this.layoutRegistry.getLayoutsConfigs();
150
+ const gridSettings: SavedGridSettings[] = this.gridRegistry.getAllGridsSettings();
151
+ const filterValues = this.filterRegistry.getAllFiltersValues();
152
+ await this.workspaceState.saveWorkspace(
153
+ workspaceName,
154
+ layoutConfigs,
155
+ gridSettings,
156
+ filterValues,
157
+ this.workspaceDescription.trim() || undefined,
158
+ );
159
+ this.workspaceName = '';
160
+ this.workspaceDescription = '';
161
+ this.closeSaveDialog();
162
+ await this.refreshSavedWorkspaces();
163
+ console.log('Workspace saved successfully');
164
+ } catch (error) {
165
+ console.error('Failed to save workspace', error);
166
+ }
167
+ }
168
+
169
+ private async applyWorkspace(workspace: SavedWorkspace): Promise<void> {
170
+ if (workspace.filters && workspace.filters.length > 0) {
171
+ this.filterRegistry.applyFiltersValues(workspace.filters);
172
+ }
173
+ if (workspace.layouts && workspace.layouts.length > 0) {
174
+ await this.layoutRegistry.applySavedLayouts(workspace.layouts);
175
+ }
176
+ if (workspace.grids && workspace.grids.length > 0) {
177
+ await this.gridRegistry.applyAllGridsSettings(workspace.grids);
178
+ }
179
+ }
180
+
181
+ async loadWorkspace(workspaceName: string): Promise<void> {
182
+ try {
183
+ this.applyingWorkspace = true;
184
+ const workspace = await this.workspaceState.loadWorkspace(workspaceName);
185
+ if (workspace) {
186
+ await this.applyWorkspace(workspace);
187
+ this.closeLoadDialog();
188
+ console.log('Workspace loaded successfully');
189
+ } else {
190
+ console.warn('Workspace not found:', workspaceName);
191
+ }
192
+ } catch (error) {
193
+ this.applyingWorkspace = false;
194
+ console.error('Failed to load workspace', error);
195
+ }
196
+ this.applyingWorkspace = false;
197
+ }
198
+
199
+ private async requestSharedWorkspace(SHARED_WORKSPACE_ID: string): Promise<any[]> {
200
+ try {
201
+ const response = await this.connect.request('REQ_LOAD_SHARED_WORKSPACE', {
202
+ REQUEST: { SHARED_WORKSPACE_ID },
203
+ });
204
+ return response.REPLY || [];
205
+ } catch (e) {
206
+ console.error(e);
207
+ }
208
+ }
209
+
210
+ async loadSharedWorkspace(shared: {
211
+ id: string;
212
+ name: string;
213
+ userName: string;
214
+ createdOn?: string | number;
215
+ modifiedOn?: string | number;
216
+ data: string;
217
+ }): Promise<void> {
218
+ try {
219
+ this.applyingWorkspace = true;
220
+ const sharedData = await this.requestSharedWorkspace(shared.id);
221
+ if (!sharedData?.length) {
222
+ console.warn('workspace has no data');
223
+ return;
224
+ }
225
+ const dataJoined = sharedData.map((d) => d.WORKSPACE_DATA).join('');
226
+ const workspace: SavedWorkspace = JSON.parse(dataJoined);
227
+ await this.applyWorkspace(workspace);
228
+ this.closeLoadDialog();
229
+ console.log('Shared workspace loaded successfully');
230
+ } catch (error) {
231
+ console.error('Failed to load shared workspace', error);
232
+ }
233
+ this.applyingWorkspace = false;
234
+ }
235
+
236
+ async deleteWorkspace(workspaceName: string): Promise<void> {
237
+ try {
238
+ await this.workspaceState.deleteWorkspace(workspaceName);
239
+ await this.refreshSavedWorkspaces();
240
+ console.log('Workspace deleted successfully');
241
+ } catch (error) {
242
+ console.error('Failed to delete workspace', error);
243
+ }
244
+ }
245
+
246
+ private showDeleteConfirmation(
247
+ title: string,
248
+ body: string,
249
+ actionFunction: () => void,
250
+ dialogBoundary: HTMLElement,
251
+ ): void {
252
+ showNotificationDialog(
253
+ {
254
+ title,
255
+ body,
256
+ dialog: {
257
+ confirmingActions: [{ label: 'Delete', action: actionFunction }],
258
+ dismissingAction: { label: 'Cancel' },
259
+ },
260
+ },
261
+ 'rapid',
262
+ dialogBoundary,
263
+ );
264
+ }
265
+
266
+ confirmDeleteWorkspace(workspaceName: string): void {
267
+ const trimmedName = workspaceName?.trim();
268
+ if (!trimmedName) return;
269
+ this.showDeleteConfirmation(
270
+ 'Delete workspace',
271
+ `Are you sure you want to delete the workspace "${trimmedName}"? This action cannot be undone.`,
272
+ () => this.deleteWorkspace(trimmedName),
273
+ this.dialogBoundary,
274
+ );
275
+ }
276
+
277
+ async modifySharedWorkspace(sharedWorkspace: SharedWorkspace): Promise<void> {
278
+ try {
279
+ const layouts = this.layoutRegistry.getLayoutsConfigs();
280
+ const grids: SavedGridSettings[] = this.gridRegistry.getAllGridsSettings();
281
+ const filters = this.filterRegistry.getAllFiltersValues();
282
+
283
+ const baseWorkspace = await this.workspaceState.loadWorkspace(sharedWorkspace.name);
284
+ const description =
285
+ this.sanitizeDescription(baseWorkspace?.description ?? sharedWorkspace.description ?? '') ||
286
+ undefined;
287
+
288
+ const workspace: SavedWorkspace = {
289
+ name: sharedWorkspace.name,
290
+ username: sharedWorkspace.userName,
291
+ description,
292
+ layouts,
293
+ grids,
294
+ filters,
295
+ savedAt: new Date().toISOString(),
296
+ };
297
+
298
+ const response = await this.connect.commitEvent('EVENT_SHARED_WORKSPACE_MODIFY', {
299
+ VALIDATE: false,
300
+ DETAILS: {
301
+ WORKSPACE_NAME: sharedWorkspace.name,
302
+ WORKSPACE_DATA: JSON.stringify(workspace),
303
+ WORKSPACE_DESCRIPTION: description ?? null,
304
+ },
305
+ });
306
+
307
+ if (response.MESSAGE_TYPE == 'EVENT_ACK') {
308
+ this.closeSaveDialog();
309
+ }
310
+ } catch (e) {
311
+ this.notifyError(`EVENT_SHARED_WORKSPACE_MODIFY ${JSON.stringify(e)}`);
312
+ console.error(e);
313
+ }
314
+ }
315
+
316
+ async deleteSharedWorkspace(sharedWorkspace: SharedWorkspace): Promise<void> {
317
+ try {
318
+ const response = await this.connect.commitEvent('EVENT_SHARED_WORKSPACE_DELETE', {
319
+ VALIDATE: false,
320
+ DETAILS: { WORKSPACE_NAME: sharedWorkspace.name },
321
+ });
322
+ if (response.MESSAGE_TYPE == 'EVENT_ACK') {
323
+ this.closeSaveDialog();
324
+ await this.refreshSharedWorkspaces();
325
+ }
326
+ } catch (e) {
327
+ this.notifyError(`EVENT_SHARED_WORKSPACE_DELETE ${JSON.stringify(e)}`);
328
+ console.error(e);
329
+ }
330
+ }
331
+
332
+ confirmDeleteSharedWorkspace(sharedWorkspace: SharedWorkspace): void {
333
+ if (!sharedWorkspace?.name) return;
334
+ this.showDeleteConfirmation(
335
+ 'Delete shared workspace',
336
+ `Are you sure you want to delete the shared workspace "${sharedWorkspace.name}"? This action cannot be undone.`,
337
+ () => this.deleteSharedWorkspace(sharedWorkspace),
338
+ this.sharedWorkspaceDialogBoundary,
339
+ );
340
+ }
341
+
342
+ async shareExistingWorkspace(workspaceName: string): Promise<void> {
343
+ const name = workspaceName?.trim();
344
+ if (!name) return;
345
+ try {
346
+ const workspace = await this.workspaceState.loadWorkspace(name);
347
+ if (!workspace) {
348
+ console.warn('Workspace not found for sharing:', name);
349
+ return;
350
+ }
351
+ const response = await this.connect.commitEvent('EVENT_SHARED_WORKSPACE_INSERT', {
352
+ VALIDATE: false,
353
+ DETAILS: {
354
+ WORKSPACE_NAME: workspace.name,
355
+ WORKSPACE_DATA: JSON.stringify(workspace),
356
+ WORKSPACE_DESCRIPTION: workspace.description ?? null,
357
+ },
358
+ });
359
+ if (response.MESSAGE_TYPE == 'EVENT_ACK') {
360
+ console.log('Workspace shared successfully');
361
+ this.closeSaveDialog();
362
+ await this.refreshSharedWorkspaces();
363
+ } else if (response.MESSAGE_TYPE == 'EVENT_NACK') {
364
+ console.warn('Failed to share workspace', response);
365
+ this.closeSaveDialog();
366
+ }
367
+ } catch (error) {
368
+ console.error('Failed to share workspace', error);
369
+ }
370
+ }
371
+
372
+ async openSaveDialog(): Promise<void> {
373
+ await this.refreshSavedWorkspaces();
374
+ this.saveModal.show();
375
+ this.workspaceName = '';
376
+ this.workspaceDescription = '';
377
+ this.saveMode = 'create';
378
+ this.selectedWorkspaceToOverwrite = '';
379
+ this.workspaceToShare = '';
380
+ }
381
+
382
+ isWorkspaceExisting(workspaceName: string): boolean {
383
+ return this.savedWorkspaces.some((p) => p.name.toLowerCase() === workspaceName.toLowerCase());
384
+ }
385
+
386
+ saveModeChanged(oldValue: string, newValue: string): void {
387
+ if (newValue === 'create') {
388
+ this.selectedWorkspaceToOverwrite = '';
389
+ this.workspaceDescription = '';
390
+ } else if (newValue === 'overwrite') {
391
+ this.workspaceName = '';
392
+ this.setDescriptionFromSelectedWorkspace();
393
+ } else if (newValue === 'shared') {
394
+ this.workspaceName = '';
395
+ this.selectedWorkspaceToOverwrite = '';
396
+ this.workspaceDescription = '';
397
+ }
398
+ }
399
+
400
+ selectedWorkspaceToOverwriteChanged(oldValue: string, newValue: string): void {
401
+ if (this.saveMode === 'overwrite') {
402
+ this.setDescriptionFromSelectedWorkspace();
403
+ }
404
+ }
405
+
406
+ openLoadDialog(): void {
407
+ this.refreshSharedWorkspaces();
408
+ this.loadModal.show();
409
+ }
410
+
411
+ closeSaveDialog(): void {
412
+ this.saveModal.close();
413
+ this.workspaceName = '';
414
+ this.workspaceDescription = '';
415
+ }
416
+
417
+ closeLoadDialog(): void {
418
+ this.loadModal.close();
419
+ }
420
+ }