@thatopen/services 0.8.0 → 0.9.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/README.md +62 -62
- package/dist/built-in/index.d.ts +66 -41
- package/dist/cli.js +31 -12
- package/dist/core/client.d.ts +6 -0
- package/dist/core/platform-client.d.ts +139 -0
- package/dist/core/platform-client.live.test.d.ts +1 -0
- package/dist/core/platform-client.notifications.test.d.ts +1 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +635 -445
- package/dist/types/notifications.d.ts +77 -0
- package/dist/vite-env.d.ts +1 -1
- package/docs/cli/create.md +29 -29
- package/docs/cli/local-server.md +38 -38
- package/docs/cli/login.md +32 -32
- package/docs/cli/publish.md +31 -31
- package/docs/cli/run.md +26 -26
- package/docs/cli/serve.md +43 -43
- package/docs/cli/swap.md +30 -30
- package/package.json +1 -1
- package/src/built-in/CDEManager/example.ts +214 -214
- package/src/built-in/CDEManager/examples/FileEditing/example.ts +226 -226
- package/src/built-in/CDEManager/examples/FileMoves/example.ts +186 -186
- package/src/built-in/CDEManager/examples/FileOperations/example.ts +295 -295
- package/src/built-in/CDEManager/examples/FileTransfers/example.ts +210 -210
- package/src/built-in/CDEManager/examples/FolderManagement/example.ts +230 -230
- package/src/built-in/CDEManager/examples/MetadataSchema/example.ts +230 -230
- package/src/built-in/CDEManager/examples/MetadataViews/example.ts +166 -166
- package/src/built-in/CDEManager/examples/ProjectConfig/example.ts +177 -177
- package/src/built-in/UIManager/src/app/example.ts +97 -97
- package/src/built-in/UIManager/src/app/examples/AppState/example.ts +140 -140
- package/src/built-in/UIManager/src/app/examples/Banner/example.ts +159 -159
- package/src/built-in/UIManager/src/app/examples/Contexts/example.ts +123 -123
- package/src/built-in/UIManager/src/app/examples/FileDrop/example.ts +124 -124
- package/src/built-in/UIManager/src/app/examples/FloatingLayout/example.ts +90 -90
- package/src/built-in/UIManager/src/app/examples/Modal/example.ts +163 -163
- package/src/built-in/UIManager/src/app/examples/Notifications/example.ts +133 -133
- package/src/built-in/UIManager/src/app/examples/ProjectFileStorage/example.ts +150 -150
- package/src/built-in/UIManager/src/app/examples/Sidebar/example.ts +102 -102
- package/src/built-in/UIManager/src/clashes-panel/example.ts +183 -183
- package/src/built-in/UIManager/src/git-history-panel/example.ts +70 -70
- package/src/built-in/UIManager/src/models-list/example.ts +122 -122
- package/src/built-in/UIManager/src/topics-panel/example.ts +170 -170
- package/src/built-in/index.ts +66 -41
- package/src/cli/templates/app/index.html +35 -35
- package/src/cli/templates/app/package.json +32 -32
- package/src/cli/templates/app/src/bim-components/CloudRunner/index.ts +95 -95
- package/src/cli/templates/app/src/bim-components/CloudRunner/src/index.ts +1 -1
- package/src/cli/templates/app/src/bim-components/CloudRunner/src/types.ts +5 -5
- package/src/cli/templates/app/src/bim-components/index.ts +1 -1
- package/src/cli/templates/app/src/globals.ts +1 -1
- package/src/cli/templates/app/src/ui-components/app-info-section/index.ts +26 -26
- package/src/cli/templates/app/src/ui-components/app-info-section/src/index.ts +1 -1
- package/src/cli/templates/app/src/ui-components/app-info-section/src/types.ts +15 -15
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/index.ts +37 -37
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/index.ts +1 -1
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/types.ts +14 -14
- package/src/cli/templates/app/src/ui-components/index.ts +2 -2
- package/src/cli/templates/app/tsconfig.json +16 -16
- package/src/cli/templates/app/vite.config.js +57 -57
- package/src/cli/templates/cloud-component/README.md +205 -205
- package/src/cli/templates/cloud-component/_thatopen +5 -5
- package/src/cli/templates/cloud-component/declarations.json +4 -4
- package/src/cli/templates/cloud-component/package.json +21 -21
- package/src/cli/templates/cloud-component/src/main.ts +70 -70
- package/src/cli/templates/cloud-component/tsconfig.json +16 -16
- package/src/cli/templates/cloud-component/vite.config.js +46 -46
- package/src/cli/templates/shared/AGENTS.md +8 -8
- package/src/cli/templates/shared/CLAUDE.md +1 -1
- package/src/cli/templates/shared/_gitignore +5 -5
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
/* MD
|
|
2
|
-
## Metadata views — organize fields into named table layouts
|
|
3
|
-
---
|
|
4
|
-
A structural engineer and an MEP coordinator look at the same file list but care
|
|
5
|
-
about completely different metadata. Showing every field to everyone produces a
|
|
6
|
-
wide table that is hard to navigate. Metadata views let each role define which
|
|
7
|
-
fields appear in which order — saving the layout so the table opens correctly next
|
|
8
|
-
time without requiring a manual setup every session.
|
|
9
|
-
|
|
10
|
-
CDEManager stores a list of named views, each carrying an ordered set of field keys.
|
|
11
|
-
An active view filters both which columns are visible and which metadata groupings
|
|
12
|
-
appear in the sidebar. Changes to the view list are staged in memory first, just like
|
|
13
|
-
schema changes, and saved in one batch — so the user can add, rename, and remove
|
|
14
|
-
views without any partial state reaching the backend.
|
|
15
|
-
|
|
16
|
-
This tutorial covers initializing views from a saved configuration; switching the
|
|
17
|
-
active view and reading the result; adding, updating, and removing views in the
|
|
18
|
-
pending list; and committing the full batch, which saves to the user's personal
|
|
19
|
-
config and fires an event with the final view list.
|
|
20
|
-
|
|
21
|
-
By the end, you'll know how to load, display, edit, and persist named metadata
|
|
22
|
-
layouts through the state machine.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import * as OBC from "@thatopen/components";
|
|
26
|
-
// In production platform apps, CDEManager is loaded through the platform client:
|
|
27
|
-
// const cde = await client.initBuiltInComponent(CDEManager.uuid, components);
|
|
28
|
-
// Here we import directly from source for local testing.
|
|
29
|
-
import { CDEManager } from "../../index";
|
|
30
|
-
import type { CDEMetadataView } from "../../src/types";
|
|
31
|
-
|
|
32
|
-
/* MD
|
|
33
|
-
### 🛠️ Setting up
|
|
34
|
-
Loading views from a saved config and switching the active view don't require
|
|
35
|
-
permissions. We still simulate the startup step to load permissions so the save
|
|
36
|
-
path works later, then clear the context — staging is in-memory only.
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
const components = new OBC.Components();
|
|
40
|
-
const cde = components.get(CDEManager);
|
|
41
|
-
|
|
42
|
-
const output = document.getElementById("output") as HTMLPreElement;
|
|
43
|
-
const log = (msg: string) => { console.log(msg); output.textContent += msg + "\n"; };
|
|
44
|
-
|
|
45
|
-
cde.ctx = {
|
|
46
|
-
client: {
|
|
47
|
-
checkPermissionBatch: async () => Array(5).fill({ hasPermission: true }),
|
|
48
|
-
getProjectData: async () => ({ project: { title: "" }, users: [] }),
|
|
49
|
-
listFolders: async () => [],
|
|
50
|
-
} as any,
|
|
51
|
-
projectId: "mock",
|
|
52
|
-
};
|
|
53
|
-
await cde.loadFolders();
|
|
54
|
-
cde.ctx = undefined;
|
|
55
|
-
|
|
56
|
-
cde.onMachineStateChanged.add((s) => log(` → ${s.kind}`));
|
|
57
|
-
cde.onMetadataViewsChanged.add((views) => log(` [onMetadataViewsChanged] ${views.length} view(s)`));
|
|
58
|
-
|
|
59
|
-
/* MD
|
|
60
|
-
### 📋 Initializing views from config
|
|
61
|
-
After loading from the backend, views and the last active view ID are pushed into
|
|
62
|
-
CDEManager through `initMetadataViews`. This populates the internal view list and
|
|
63
|
-
fires the views-changed event so any subscribed component can render immediately.
|
|
64
|
-
The active view controls which fields `getSelectedFiles` uses for grouping when
|
|
65
|
-
metadata mode is on.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
log("\n--- init views ---");
|
|
69
|
-
const savedViews: CDEMetadataView[] = [
|
|
70
|
-
{ id: "view-str", name: "Structural", fields: ["discipline", "phase"] },
|
|
71
|
-
{ id: "view-mep", name: "MEP", fields: ["discipline", "zone"] },
|
|
72
|
-
];
|
|
73
|
-
cde.initMetadataViews(savedViews, "view-str");
|
|
74
|
-
|
|
75
|
-
log(` metadataViews: ${cde.metadataViews.length}`);
|
|
76
|
-
log(` activeMetadataViewId: ${cde.activeMetadataViewId}`);
|
|
77
|
-
log(` activeMetadataView name: ${cde.activeMetadataView?.name}`);
|
|
78
|
-
|
|
79
|
-
/* MD
|
|
80
|
-
### 🔀 Switching the active view
|
|
81
|
-
The active view can be changed from idle, a selection, or while the viewer is open.
|
|
82
|
-
Switching resets the selected metadata group so the table doesn't show a stale
|
|
83
|
-
filter from the previous view's grouping. The transition doesn't change the machine
|
|
84
|
-
state kind — it's a targeted property update, not a full state change.
|
|
85
|
-
*/
|
|
86
|
-
|
|
87
|
-
log("\n--- switch active view ---");
|
|
88
|
-
cde.sendMachineEvent({ type: "SET_ACTIVE_METADATA_VIEW", id: "view-mep" });
|
|
89
|
-
log(` active: ${cde.activeMetadataView?.name}`);
|
|
90
|
-
|
|
91
|
-
cde.sendMachineEvent({ type: "SET_ACTIVE_METADATA_VIEW", id: "view-str" });
|
|
92
|
-
log(` active: ${cde.activeMetadataView?.name}`);
|
|
93
|
-
|
|
94
|
-
/* MD
|
|
95
|
-
### ✏️ Staging view changes
|
|
96
|
-
Adding, updating, and removing views all operate on the `pendingViews` list inside
|
|
97
|
-
the machine state. The committed view list is unchanged until the save fires. Adding
|
|
98
|
-
a view generates a stable random ID immediately, so the UI can reference it for
|
|
99
|
-
subsequent updates within the same session without waiting for a server response.
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
log("\n--- stage: add, update, delete ---");
|
|
103
|
-
cde.sendMachineEvent({ type: "START_CONFIGURE_METADATA_VIEWS" });
|
|
104
|
-
|
|
105
|
-
// Add a new view — gets a UUID immediately.
|
|
106
|
-
cde.sendMachineEvent({ type: "ADD_METADATA_VIEW" });
|
|
107
|
-
|
|
108
|
-
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
109
|
-
const newView = cde.machineState.pendingViews.find(v => v.name === "New View")!;
|
|
110
|
-
log(` new view id: ${newView.id.slice(0, 8)}…`);
|
|
111
|
-
|
|
112
|
-
// Name it and set its fields.
|
|
113
|
-
cde.sendMachineEvent({
|
|
114
|
-
type: "UPDATE_METADATA_VIEW",
|
|
115
|
-
id: newView.id,
|
|
116
|
-
view: { ...newView, name: "Civil", fields: ["discipline", "zone", "level"] },
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
log(` views in pending: ${cde.machineState.pendingViews.length}`);
|
|
120
|
-
log(` updated view name: ${cde.machineState.pendingViews.find(v => v.id === newView.id)?.name}`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Remove an existing view from the pending list.
|
|
124
|
-
cde.sendMachineEvent({ type: "DELETE_METADATA_VIEW", id: "view-mep" });
|
|
125
|
-
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
126
|
-
log(` views after delete: ${cde.machineState.pendingViews.length}`);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
cde.sendMachineEvent({ type: "CANCEL_CONFIGURE_METADATA_VIEWS" });
|
|
130
|
-
// Cancelled — committed view list is unchanged.
|
|
131
|
-
log(` committed views after cancel: ${cde.metadataViews.length}`);
|
|
132
|
-
|
|
133
|
-
/* MD
|
|
134
|
-
### 💾 Committing views
|
|
135
|
-
Saving replaces the committed view list with the pending one and fires the views-
|
|
136
|
-
changed event. The user's personal config is updated at the same time if the account
|
|
137
|
-
has create permission — the same config that `loadUserConfig` reads back on the
|
|
138
|
-
next session load. Without a real user identity in the mock, the persistence step is
|
|
139
|
-
silently skipped but the local update still applies.
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
log("\n--- commit ---");
|
|
143
|
-
cde.sendMachineEvent({ type: "START_CONFIGURE_METADATA_VIEWS" });
|
|
144
|
-
|
|
145
|
-
cde.sendMachineEvent({ type: "ADD_METADATA_VIEW" });
|
|
146
|
-
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
147
|
-
const civil = cde.machineState.pendingViews.find(v => v.name === "New View")!;
|
|
148
|
-
cde.sendMachineEvent({
|
|
149
|
-
type: "UPDATE_METADATA_VIEW",
|
|
150
|
-
id: civil.id,
|
|
151
|
-
view: { ...civil, name: "Civil", fields: ["discipline", "zone"] },
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
cde.sendMachineEvent({ type: "DELETE_METADATA_VIEW", id: "view-mep" });
|
|
155
|
-
|
|
156
|
-
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
157
|
-
log(` pending: ${cde.machineState.pendingViews.length} view(s)`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
await new Promise<void>(resolve => {
|
|
161
|
-
cde.onMachineStateChanged.add((s) => { if (s.kind === "idle") resolve(); });
|
|
162
|
-
cde.sendMachineEvent({ type: "SAVE_METADATA_VIEWS" });
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
log(` state after save: ${cde.machineState.kind}`);
|
|
166
|
-
log(` committed views: ${cde.metadataViews.map(v => v.name).join(", ")}`);
|
|
1
|
+
/* MD
|
|
2
|
+
## Metadata views — organize fields into named table layouts
|
|
3
|
+
---
|
|
4
|
+
A structural engineer and an MEP coordinator look at the same file list but care
|
|
5
|
+
about completely different metadata. Showing every field to everyone produces a
|
|
6
|
+
wide table that is hard to navigate. Metadata views let each role define which
|
|
7
|
+
fields appear in which order — saving the layout so the table opens correctly next
|
|
8
|
+
time without requiring a manual setup every session.
|
|
9
|
+
|
|
10
|
+
CDEManager stores a list of named views, each carrying an ordered set of field keys.
|
|
11
|
+
An active view filters both which columns are visible and which metadata groupings
|
|
12
|
+
appear in the sidebar. Changes to the view list are staged in memory first, just like
|
|
13
|
+
schema changes, and saved in one batch — so the user can add, rename, and remove
|
|
14
|
+
views without any partial state reaching the backend.
|
|
15
|
+
|
|
16
|
+
This tutorial covers initializing views from a saved configuration; switching the
|
|
17
|
+
active view and reading the result; adding, updating, and removing views in the
|
|
18
|
+
pending list; and committing the full batch, which saves to the user's personal
|
|
19
|
+
config and fires an event with the final view list.
|
|
20
|
+
|
|
21
|
+
By the end, you'll know how to load, display, edit, and persist named metadata
|
|
22
|
+
layouts through the state machine.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import * as OBC from "@thatopen/components";
|
|
26
|
+
// In production platform apps, CDEManager is loaded through the platform client:
|
|
27
|
+
// const cde = await client.initBuiltInComponent(CDEManager.uuid, components);
|
|
28
|
+
// Here we import directly from source for local testing.
|
|
29
|
+
import { CDEManager } from "../../index";
|
|
30
|
+
import type { CDEMetadataView } from "../../src/types";
|
|
31
|
+
|
|
32
|
+
/* MD
|
|
33
|
+
### 🛠️ Setting up
|
|
34
|
+
Loading views from a saved config and switching the active view don't require
|
|
35
|
+
permissions. We still simulate the startup step to load permissions so the save
|
|
36
|
+
path works later, then clear the context — staging is in-memory only.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const components = new OBC.Components();
|
|
40
|
+
const cde = components.get(CDEManager);
|
|
41
|
+
|
|
42
|
+
const output = document.getElementById("output") as HTMLPreElement;
|
|
43
|
+
const log = (msg: string) => { console.log(msg); output.textContent += msg + "\n"; };
|
|
44
|
+
|
|
45
|
+
cde.ctx = {
|
|
46
|
+
client: {
|
|
47
|
+
checkPermissionBatch: async () => Array(5).fill({ hasPermission: true }),
|
|
48
|
+
getProjectData: async () => ({ project: { title: "" }, users: [] }),
|
|
49
|
+
listFolders: async () => [],
|
|
50
|
+
} as any,
|
|
51
|
+
projectId: "mock",
|
|
52
|
+
};
|
|
53
|
+
await cde.loadFolders();
|
|
54
|
+
cde.ctx = undefined;
|
|
55
|
+
|
|
56
|
+
cde.onMachineStateChanged.add((s) => log(` → ${s.kind}`));
|
|
57
|
+
cde.onMetadataViewsChanged.add((views) => log(` [onMetadataViewsChanged] ${views.length} view(s)`));
|
|
58
|
+
|
|
59
|
+
/* MD
|
|
60
|
+
### 📋 Initializing views from config
|
|
61
|
+
After loading from the backend, views and the last active view ID are pushed into
|
|
62
|
+
CDEManager through `initMetadataViews`. This populates the internal view list and
|
|
63
|
+
fires the views-changed event so any subscribed component can render immediately.
|
|
64
|
+
The active view controls which fields `getSelectedFiles` uses for grouping when
|
|
65
|
+
metadata mode is on.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
log("\n--- init views ---");
|
|
69
|
+
const savedViews: CDEMetadataView[] = [
|
|
70
|
+
{ id: "view-str", name: "Structural", fields: ["discipline", "phase"] },
|
|
71
|
+
{ id: "view-mep", name: "MEP", fields: ["discipline", "zone"] },
|
|
72
|
+
];
|
|
73
|
+
cde.initMetadataViews(savedViews, "view-str");
|
|
74
|
+
|
|
75
|
+
log(` metadataViews: ${cde.metadataViews.length}`);
|
|
76
|
+
log(` activeMetadataViewId: ${cde.activeMetadataViewId}`);
|
|
77
|
+
log(` activeMetadataView name: ${cde.activeMetadataView?.name}`);
|
|
78
|
+
|
|
79
|
+
/* MD
|
|
80
|
+
### 🔀 Switching the active view
|
|
81
|
+
The active view can be changed from idle, a selection, or while the viewer is open.
|
|
82
|
+
Switching resets the selected metadata group so the table doesn't show a stale
|
|
83
|
+
filter from the previous view's grouping. The transition doesn't change the machine
|
|
84
|
+
state kind — it's a targeted property update, not a full state change.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
log("\n--- switch active view ---");
|
|
88
|
+
cde.sendMachineEvent({ type: "SET_ACTIVE_METADATA_VIEW", id: "view-mep" });
|
|
89
|
+
log(` active: ${cde.activeMetadataView?.name}`);
|
|
90
|
+
|
|
91
|
+
cde.sendMachineEvent({ type: "SET_ACTIVE_METADATA_VIEW", id: "view-str" });
|
|
92
|
+
log(` active: ${cde.activeMetadataView?.name}`);
|
|
93
|
+
|
|
94
|
+
/* MD
|
|
95
|
+
### ✏️ Staging view changes
|
|
96
|
+
Adding, updating, and removing views all operate on the `pendingViews` list inside
|
|
97
|
+
the machine state. The committed view list is unchanged until the save fires. Adding
|
|
98
|
+
a view generates a stable random ID immediately, so the UI can reference it for
|
|
99
|
+
subsequent updates within the same session without waiting for a server response.
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
log("\n--- stage: add, update, delete ---");
|
|
103
|
+
cde.sendMachineEvent({ type: "START_CONFIGURE_METADATA_VIEWS" });
|
|
104
|
+
|
|
105
|
+
// Add a new view — gets a UUID immediately.
|
|
106
|
+
cde.sendMachineEvent({ type: "ADD_METADATA_VIEW" });
|
|
107
|
+
|
|
108
|
+
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
109
|
+
const newView = cde.machineState.pendingViews.find(v => v.name === "New View")!;
|
|
110
|
+
log(` new view id: ${newView.id.slice(0, 8)}…`);
|
|
111
|
+
|
|
112
|
+
// Name it and set its fields.
|
|
113
|
+
cde.sendMachineEvent({
|
|
114
|
+
type: "UPDATE_METADATA_VIEW",
|
|
115
|
+
id: newView.id,
|
|
116
|
+
view: { ...newView, name: "Civil", fields: ["discipline", "zone", "level"] },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
log(` views in pending: ${cde.machineState.pendingViews.length}`);
|
|
120
|
+
log(` updated view name: ${cde.machineState.pendingViews.find(v => v.id === newView.id)?.name}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Remove an existing view from the pending list.
|
|
124
|
+
cde.sendMachineEvent({ type: "DELETE_METADATA_VIEW", id: "view-mep" });
|
|
125
|
+
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
126
|
+
log(` views after delete: ${cde.machineState.pendingViews.length}`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
cde.sendMachineEvent({ type: "CANCEL_CONFIGURE_METADATA_VIEWS" });
|
|
130
|
+
// Cancelled — committed view list is unchanged.
|
|
131
|
+
log(` committed views after cancel: ${cde.metadataViews.length}`);
|
|
132
|
+
|
|
133
|
+
/* MD
|
|
134
|
+
### 💾 Committing views
|
|
135
|
+
Saving replaces the committed view list with the pending one and fires the views-
|
|
136
|
+
changed event. The user's personal config is updated at the same time if the account
|
|
137
|
+
has create permission — the same config that `loadUserConfig` reads back on the
|
|
138
|
+
next session load. Without a real user identity in the mock, the persistence step is
|
|
139
|
+
silently skipped but the local update still applies.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
log("\n--- commit ---");
|
|
143
|
+
cde.sendMachineEvent({ type: "START_CONFIGURE_METADATA_VIEWS" });
|
|
144
|
+
|
|
145
|
+
cde.sendMachineEvent({ type: "ADD_METADATA_VIEW" });
|
|
146
|
+
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
147
|
+
const civil = cde.machineState.pendingViews.find(v => v.name === "New View")!;
|
|
148
|
+
cde.sendMachineEvent({
|
|
149
|
+
type: "UPDATE_METADATA_VIEW",
|
|
150
|
+
id: civil.id,
|
|
151
|
+
view: { ...civil, name: "Civil", fields: ["discipline", "zone"] },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
cde.sendMachineEvent({ type: "DELETE_METADATA_VIEW", id: "view-mep" });
|
|
155
|
+
|
|
156
|
+
if (cde.machineState.kind === "configuringMetadataViews") {
|
|
157
|
+
log(` pending: ${cde.machineState.pendingViews.length} view(s)`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
await new Promise<void>(resolve => {
|
|
161
|
+
cde.onMachineStateChanged.add((s) => { if (s.kind === "idle") resolve(); });
|
|
162
|
+
cde.sendMachineEvent({ type: "SAVE_METADATA_VIEWS" });
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
log(` state after save: ${cde.machineState.kind}`);
|
|
166
|
+
log(` committed views: ${cde.metadataViews.map(v => v.name).join(", ")}`);
|