@genesislcap/foundation-workspace 15.19.0 → 15.19.1
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/package.json +16 -17
- package/api-extractor.json +0 -4
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/license.txt +0 -46
- package/src/index.ts +0 -3
- package/src/workspace/filter-registry.ts +0 -79
- package/src/workspace/grid-register/grid-register.template.ts +0 -6
- package/src/workspace/grid-register/grid-register.ts +0 -142
- package/src/workspace/grid-register/index.ts +0 -1
- package/src/workspace/grid-registry.ts +0 -171
- package/src/workspace/index.ts +0 -8
- package/src/workspace/layout-registry.ts +0 -63
- package/src/workspace/layout-wrapper/index.ts +0 -1
- package/src/workspace/layout-wrapper/layout-wrapper.template.ts +0 -6
- package/src/workspace/layout-wrapper/layout-wrapper.ts +0 -69
- package/src/workspace/workspace-state.ts +0 -235
- package/src/workspace/workspace-state.types.ts +0 -27
- package/src/workspace/workspace.types.ts +0 -28
- package/src/workspace-components.ts +0 -50
- package/src/workspace-manager/index.ts +0 -1
- package/src/workspace-manager/workspace-manager.styles.ts +0 -116
- package/src/workspace-manager/workspace-manager.template.ts +0 -370
- package/src/workspace-manager/workspace-manager.ts +0 -453
- package/tsconfig.json +0 -10
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { FoundationLayout } from '@genesislcap/foundation-layout';
|
|
2
|
-
import { FoundationElement, attr, customElement } from '@genesislcap/web-core';
|
|
3
|
-
import { LayoutRegistry } from '../layout-registry';
|
|
4
|
-
import { LayoutWrapperTemplate as template } from './layout-wrapper.template';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Registers a layout instance so workspace state can apply/load it.
|
|
8
|
-
* @alpha
|
|
9
|
-
*/
|
|
10
|
-
@customElement({
|
|
11
|
-
name: 'layout-register',
|
|
12
|
-
template,
|
|
13
|
-
})
|
|
14
|
-
export class LayoutWrapper extends FoundationElement {
|
|
15
|
-
@attr({ attribute: 'layout-key' }) layoutKey: string;
|
|
16
|
-
@attr({ attribute: 'design-system-prefix' }) designSystemPrefix: string = 'rapid';
|
|
17
|
-
|
|
18
|
-
@LayoutRegistry layoutRegistry: LayoutRegistry;
|
|
19
|
-
|
|
20
|
-
private layoutElement: FoundationLayout | null = null;
|
|
21
|
-
|
|
22
|
-
connectedCallback(): void {
|
|
23
|
-
super.connectedCallback();
|
|
24
|
-
this.findAndRegisterLayout();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
disconnectedCallback(): void {
|
|
28
|
-
super.disconnectedCallback();
|
|
29
|
-
const layoutKey =
|
|
30
|
-
this.layoutElement?.autoSaveKey ??
|
|
31
|
-
this.layoutElement?.getAttribute?.('auto-save-key') ??
|
|
32
|
-
this.layoutKey;
|
|
33
|
-
|
|
34
|
-
if (layoutKey) {
|
|
35
|
-
this.layoutRegistry.unregisterLayout(layoutKey);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private findAndRegisterLayout(): void {
|
|
40
|
-
const layoutTag = `${this.designSystemPrefix}-layout`;
|
|
41
|
-
let layoutElement = this.querySelector(layoutTag) as FoundationLayout;
|
|
42
|
-
|
|
43
|
-
const registerLayout = (layout: FoundationLayout | null) => {
|
|
44
|
-
if (!layout) {
|
|
45
|
-
console.warn(`layout-register: ${layoutTag} element not found`);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
this.layoutElement = layout;
|
|
49
|
-
const layoutKeyFromLayout =
|
|
50
|
-
layout.autoSaveKey ?? layout.getAttribute?.('auto-save-key') ?? this.layoutKey;
|
|
51
|
-
|
|
52
|
-
if (!layoutKeyFromLayout) {
|
|
53
|
-
console.warn('layout-register: missing layout key (auto-save-key/layout-key)');
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
this.layoutRegistry.registerLayout(layoutKeyFromLayout, layout);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
if (layoutElement) {
|
|
61
|
-
registerLayout(layoutElement);
|
|
62
|
-
} else {
|
|
63
|
-
setTimeout(() => {
|
|
64
|
-
layoutElement = this.querySelector(layoutTag) as FoundationLayout;
|
|
65
|
-
registerLayout(layoutElement);
|
|
66
|
-
}, 100);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Auth,
|
|
3
|
-
KVStorage,
|
|
4
|
-
type KVStorage as KVStorageType,
|
|
5
|
-
type Auth as AuthType,
|
|
6
|
-
} from '@genesislcap/foundation-comms';
|
|
7
|
-
import { DI } from '@genesislcap/web-core';
|
|
8
|
-
import type { SavedWorkspace } from './workspace-state.types';
|
|
9
|
-
import type { SavedFilterValue, SavedGridSettings, SavedLayout } from './workspace.types';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @alpha
|
|
13
|
-
*/
|
|
14
|
-
export interface WorkspaceState {
|
|
15
|
-
saveWorkspace(
|
|
16
|
-
workspaceName: string,
|
|
17
|
-
layouts: SavedLayout[],
|
|
18
|
-
grids: SavedGridSettings[],
|
|
19
|
-
filters: SavedFilterValue[],
|
|
20
|
-
description?: string,
|
|
21
|
-
): Promise<void>;
|
|
22
|
-
loadWorkspace(workspaceName: string): Promise<SavedWorkspace | null>;
|
|
23
|
-
getSavedWorkspaces(): Promise<SavedWorkspace[]>;
|
|
24
|
-
deleteWorkspace(workspaceName: string): Promise<void>;
|
|
25
|
-
getCurrentWorkspace(): SavedWorkspace | null;
|
|
26
|
-
setCurrentWorkspace(workspace: SavedWorkspace | null): void;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Default workspace persistence implementation backed by KVStorage.
|
|
31
|
-
*
|
|
32
|
-
* @alpha
|
|
33
|
-
*/
|
|
34
|
-
export class DefaultWorkspaceState implements WorkspaceState {
|
|
35
|
-
private readonly STORAGE_PREFIX = 'workspace_';
|
|
36
|
-
private readonly WORKSPACES_LIST_KEY = 'workspaces_list';
|
|
37
|
-
|
|
38
|
-
private currentWorkspace: SavedWorkspace | null = null;
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
@KVStorage public kvStorage: KVStorageType,
|
|
42
|
-
@Auth public auth: AuthType,
|
|
43
|
-
) {}
|
|
44
|
-
|
|
45
|
-
private getCurrentUsername(): string {
|
|
46
|
-
return this.auth?.loggedUserResult?.username || 'anonymous';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private getWorkspaceStorageKey(workspaceName: string): string {
|
|
50
|
-
const username = this.getCurrentUsername();
|
|
51
|
-
return `${this.STORAGE_PREFIX}${username}_${workspaceName}`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private getWorkspacesListKey(): string {
|
|
55
|
-
const username = this.getCurrentUsername();
|
|
56
|
-
return `${this.STORAGE_PREFIX}${username}_${this.WORKSPACES_LIST_KEY}`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async saveWorkspace(
|
|
60
|
-
workspaceName: string,
|
|
61
|
-
layouts: SavedLayout[],
|
|
62
|
-
grids: SavedGridSettings[],
|
|
63
|
-
filters: SavedFilterValue[],
|
|
64
|
-
description?: string,
|
|
65
|
-
): Promise<void> {
|
|
66
|
-
const storageKey = this.getWorkspaceStorageKey(workspaceName);
|
|
67
|
-
const username = this.getCurrentUsername();
|
|
68
|
-
|
|
69
|
-
const workspace: SavedWorkspace = {
|
|
70
|
-
name: workspaceName,
|
|
71
|
-
username,
|
|
72
|
-
description: description?.trim() || undefined,
|
|
73
|
-
layouts,
|
|
74
|
-
grids,
|
|
75
|
-
filters,
|
|
76
|
-
savedAt: new Date().toISOString(),
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
await this.kvStorage.put([
|
|
80
|
-
{
|
|
81
|
-
key: storageKey,
|
|
82
|
-
value: JSON.stringify(workspace),
|
|
83
|
-
},
|
|
84
|
-
]);
|
|
85
|
-
|
|
86
|
-
await this.updateWorkspacesList(workspaceName);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async loadWorkspace(workspaceName: string): Promise<SavedWorkspace | null> {
|
|
90
|
-
const workspace = await this.getWorkspace(workspaceName);
|
|
91
|
-
this.currentWorkspace = workspace ?? null;
|
|
92
|
-
return this.currentWorkspace;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private async getWorkspace(workspaceName: string): Promise<SavedWorkspace | null> {
|
|
96
|
-
const storageKey = this.getWorkspaceStorageKey(workspaceName);
|
|
97
|
-
const existing = await this.kvStorage.get(storageKey);
|
|
98
|
-
|
|
99
|
-
if (!existing?.kv?.value) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const workspace =
|
|
105
|
-
typeof existing.kv.value === 'string' ? JSON.parse(existing.kv.value) : existing.kv.value;
|
|
106
|
-
|
|
107
|
-
const currentUsername = this.getCurrentUsername();
|
|
108
|
-
if (workspace.username && workspace.username !== currentUsername) {
|
|
109
|
-
console.warn(`Workspace ${workspaceName} does not belong to current user`);
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (!workspace.username) {
|
|
114
|
-
workspace.username = currentUsername;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return workspace || null;
|
|
118
|
-
} catch (e) {
|
|
119
|
-
console.warn('Failed to parse saved workspace', e);
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
getCurrentWorkspace(): SavedWorkspace | null {
|
|
125
|
-
return this.currentWorkspace;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
setCurrentWorkspace(workspace: SavedWorkspace | null): void {
|
|
129
|
-
this.currentWorkspace = workspace;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async getSavedWorkspaces(): Promise<SavedWorkspace[]> {
|
|
133
|
-
const listKey = this.getWorkspaceStorageKey(this.WORKSPACES_LIST_KEY);
|
|
134
|
-
const existing = await this.kvStorage.get(listKey);
|
|
135
|
-
|
|
136
|
-
if (!existing?.kv?.value) {
|
|
137
|
-
return [];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
const workspaceNames: string[] =
|
|
142
|
-
typeof existing.kv.value === 'string' ? JSON.parse(existing.kv.value) : existing.kv.value;
|
|
143
|
-
|
|
144
|
-
if (!Array.isArray(workspaceNames)) {
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const workspaces: SavedWorkspace[] = [];
|
|
149
|
-
const currentUsername = this.getCurrentUsername();
|
|
150
|
-
/* oxlint-disable no-await-in-loop -- load each workspace from storage */
|
|
151
|
-
for (const name of workspaceNames) {
|
|
152
|
-
const workspace = await this.getWorkspace(name);
|
|
153
|
-
if (workspace && (!workspace.username || workspace.username === currentUsername)) {
|
|
154
|
-
workspaces.push(workspace);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/* oxlint-enable no-await-in-loop */
|
|
158
|
-
|
|
159
|
-
return workspaces;
|
|
160
|
-
} catch (e) {
|
|
161
|
-
console.warn('Failed to parse saved workspaces list', e);
|
|
162
|
-
return [];
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async deleteWorkspace(workspaceName: string): Promise<void> {
|
|
167
|
-
const storageKey = this.getWorkspaceStorageKey(workspaceName);
|
|
168
|
-
await this.kvStorage.delete([storageKey]);
|
|
169
|
-
await this.removeFromWorkspacesList(workspaceName);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
private async updateWorkspacesList(workspaceName: string): Promise<void> {
|
|
173
|
-
const listKey = this.getWorkspacesListKey();
|
|
174
|
-
const existing = await this.kvStorage.get(listKey);
|
|
175
|
-
|
|
176
|
-
let workspaceNames: string[] = [];
|
|
177
|
-
if (existing?.kv?.value) {
|
|
178
|
-
try {
|
|
179
|
-
workspaceNames =
|
|
180
|
-
typeof existing.kv.value === 'string' ? JSON.parse(existing.kv.value) : existing.kv.value;
|
|
181
|
-
} catch (e) {
|
|
182
|
-
console.warn('Failed to parse workspaces list', e);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
workspaceNames = workspaceNames.filter((name) => name !== workspaceName);
|
|
187
|
-
workspaceNames.push(workspaceName);
|
|
188
|
-
|
|
189
|
-
await this.kvStorage.put([
|
|
190
|
-
{
|
|
191
|
-
key: listKey,
|
|
192
|
-
value: JSON.stringify(workspaceNames),
|
|
193
|
-
},
|
|
194
|
-
]);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private async removeFromWorkspacesList(workspaceName: string): Promise<void> {
|
|
198
|
-
const listKey = this.getWorkspacesListKey();
|
|
199
|
-
const existing = await this.kvStorage.get(listKey);
|
|
200
|
-
|
|
201
|
-
if (!existing?.kv?.value) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
let workspaceNames: string[] = [];
|
|
206
|
-
try {
|
|
207
|
-
workspaceNames =
|
|
208
|
-
typeof existing.kv.value === 'string' ? JSON.parse(existing.kv.value) : existing.kv.value;
|
|
209
|
-
} catch (e) {
|
|
210
|
-
console.warn('Failed to parse workspaces list for deletion', e);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
workspaceNames = workspaceNames.filter((name) => name !== workspaceName);
|
|
215
|
-
|
|
216
|
-
if (workspaceNames.length === 0) {
|
|
217
|
-
await this.kvStorage.delete([listKey]);
|
|
218
|
-
} else {
|
|
219
|
-
await this.kvStorage.put([
|
|
220
|
-
{
|
|
221
|
-
key: listKey,
|
|
222
|
-
value: JSON.stringify(workspaceNames),
|
|
223
|
-
},
|
|
224
|
-
]);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* DI token for workspace state.
|
|
231
|
-
* @alpha
|
|
232
|
-
*/
|
|
233
|
-
export const WorkspaceState = DI.createInterface<WorkspaceState>((x) =>
|
|
234
|
-
x.singleton(DefaultWorkspaceState),
|
|
235
|
-
);
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { SavedFilterValue, SavedGridSettings, SavedLayout } from './workspace.types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @alpha
|
|
5
|
-
*/
|
|
6
|
-
export interface SavedWorkspace {
|
|
7
|
-
name: string;
|
|
8
|
-
username: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
layouts: SavedLayout[];
|
|
11
|
-
grids: SavedGridSettings[];
|
|
12
|
-
filters: SavedFilterValue[];
|
|
13
|
-
savedAt: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @alpha
|
|
18
|
-
*/
|
|
19
|
-
export interface SharedWorkspace {
|
|
20
|
-
id: string;
|
|
21
|
-
name: string;
|
|
22
|
-
userName: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
createdOn?: string | number;
|
|
25
|
-
modifiedOn?: string | number;
|
|
26
|
-
data: string;
|
|
27
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { SerialisedLayout } from '@genesislcap/foundation-layout';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Workspace persistence types.
|
|
5
|
-
* Layout and column state use generic shapes so consumers can use foundation-layout and ag-grid types.
|
|
6
|
-
* @alpha
|
|
7
|
-
*/
|
|
8
|
-
export interface SavedGridSettings {
|
|
9
|
-
gridKey: string;
|
|
10
|
-
columnState: any[];
|
|
11
|
-
savedAt: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @alpha
|
|
16
|
-
*/
|
|
17
|
-
export interface SavedFilterValue {
|
|
18
|
-
filterKey: string;
|
|
19
|
-
value: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @alpha
|
|
24
|
-
*/
|
|
25
|
-
export interface SavedLayout {
|
|
26
|
-
layoutKey: string;
|
|
27
|
-
layout: SerialisedLayout;
|
|
28
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { Container } from '@genesislcap/web-core';
|
|
2
|
-
// Import the custom elements so their `@customElement` decorators run and define tags.
|
|
3
|
-
import { LayoutWrapper, GridRegister } from './workspace';
|
|
4
|
-
import { WorkspaceManager } from './workspace-manager';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Registration object for workspace-related components.
|
|
8
|
-
*
|
|
9
|
-
* Mirrors the shape of `rapidGridComponents` so it can be passed into
|
|
10
|
-
* `provideDesignSystem().register(...)` without additional glue code.
|
|
11
|
-
*
|
|
12
|
-
* @alpha
|
|
13
|
-
*/
|
|
14
|
-
export const workspaceComponents = {
|
|
15
|
-
workspaceManager: () => ({
|
|
16
|
-
register(_container?: Container, ..._rest: any[]) {
|
|
17
|
-
// Custom elements are defined by decorators at module import time.
|
|
18
|
-
void WorkspaceManager;
|
|
19
|
-
},
|
|
20
|
-
}),
|
|
21
|
-
|
|
22
|
-
layoutWrapper: () => ({
|
|
23
|
-
register(_container?: Container, ..._rest: any[]) {
|
|
24
|
-
void LayoutWrapper;
|
|
25
|
-
},
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
gridRegister: () => ({
|
|
29
|
-
register(_container?: Container, ..._rest: any[]) {
|
|
30
|
-
void GridRegister;
|
|
31
|
-
},
|
|
32
|
-
}),
|
|
33
|
-
|
|
34
|
-
register(container?: Container, ...rest: any[]) {
|
|
35
|
-
if (!container) {
|
|
36
|
-
// Preserve backward compatibility with callers that iterate keys.
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
for (const key in this) {
|
|
41
|
-
if (key === 'register') {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// The values of this object are functions that return a component
|
|
46
|
-
// registration object with a `.register(...)` method.
|
|
47
|
-
(this as any)[key]().register(container, ...rest);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './workspace-manager';
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { css } from '@genesislcap/web-core';
|
|
2
|
-
|
|
3
|
-
export const WorkspaceManagerStyles = css`
|
|
4
|
-
.workspace-manager {
|
|
5
|
-
display: flex;
|
|
6
|
-
gap: 10px;
|
|
7
|
-
align-items: center;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.dialog-content {
|
|
11
|
-
padding: 16px;
|
|
12
|
-
min-width: 400px;
|
|
13
|
-
max-width: 400px;
|
|
14
|
-
display: flex;
|
|
15
|
-
flex-direction: column;
|
|
16
|
-
max-height: 90vh;
|
|
17
|
-
overflow: hidden;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.button-group {
|
|
21
|
-
display: flex;
|
|
22
|
-
gap: 8px;
|
|
23
|
-
justify-content: flex-end;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.workspace-list {
|
|
27
|
-
display: flex;
|
|
28
|
-
flex-direction: column;
|
|
29
|
-
gap: 12px;
|
|
30
|
-
max-height: 400px;
|
|
31
|
-
overflow-y: auto;
|
|
32
|
-
margin: 10px 0;
|
|
33
|
-
align-items: unset;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
rapid-label {
|
|
37
|
-
margin-bottom: 10px;
|
|
38
|
-
display: block;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.empty-state {
|
|
42
|
-
padding: 24px;
|
|
43
|
-
text-align: center;
|
|
44
|
-
color: var(--neutral-foreground-hint);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.save-mode-selector {
|
|
48
|
-
margin-bottom: 16px;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.warning-message {
|
|
52
|
-
margin: 12px 0;
|
|
53
|
-
padding: 12px;
|
|
54
|
-
border: 1px solid var(--warning-color);
|
|
55
|
-
border-radius: 4px;
|
|
56
|
-
font-size: 14px;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.workspace-item {
|
|
60
|
-
padding: 12px;
|
|
61
|
-
border: 1px solid var(--neutral-stroke-rest);
|
|
62
|
-
border-radius: 4px;
|
|
63
|
-
background: var(--neutral-fill-rest);
|
|
64
|
-
cursor: pointer;
|
|
65
|
-
display: flex;
|
|
66
|
-
align-items: center;
|
|
67
|
-
gap: 5px;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.workspace-item:hover {
|
|
71
|
-
background: var(--neutral-fill-hover);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.workspace-item::part(control) {
|
|
75
|
-
margin-top: 2px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.workspace-info {
|
|
79
|
-
flex: 1;
|
|
80
|
-
margin-left: 8px;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.workspace-name {
|
|
84
|
-
font-weight: 600;
|
|
85
|
-
margin-bottom: 4px;
|
|
86
|
-
display: flex;
|
|
87
|
-
align-items: center;
|
|
88
|
-
gap: 8px;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.workspace-date {
|
|
92
|
-
font-size: 12px;
|
|
93
|
-
color: var(--neutral-foreground-hint);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.workspace-description {
|
|
97
|
-
font-size: 12px;
|
|
98
|
-
color: var(--neutral-foreground-hint);
|
|
99
|
-
margin-top: 4px;
|
|
100
|
-
white-space: pre-wrap;
|
|
101
|
-
word-break: break-word;
|
|
102
|
-
line-height: 1.4;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.loading-container {
|
|
106
|
-
display: flex;
|
|
107
|
-
flex-direction: column;
|
|
108
|
-
align-items: center;
|
|
109
|
-
justify-content: center;
|
|
110
|
-
padding: 24px;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.save-field {
|
|
114
|
-
margin-bottom: 20px;
|
|
115
|
-
}
|
|
116
|
-
`;
|