@thatopen/services 0.0.6 → 0.1.3
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 +46 -46
- package/dist/built-in/index.d.ts +723 -0
- package/dist/cli.js +22 -0
- package/dist/core/client.d.ts +10 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.es.js +87 -71
- package/dist/types/files.d.ts +6 -0
- package/dist/vite-env.d.ts +1 -1
- package/docs/builtin/paths.json +22 -6
- package/package.json +99 -99
- package/resources/AGENTS.md +5 -3
- package/src/built-in/AppManager/example.ts +86 -86
- 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/FileList/example.ts +107 -107
- package/src/built-in/TabbedNavigation/example.ts +115 -115
- package/src/built-in/UIManager/src/app/example.ts +99 -0
- package/src/built-in/UIManager/src/app/examples/AppState/example.ts +142 -0
- package/src/built-in/UIManager/src/app/examples/Contexts/example.ts +125 -0
- package/src/built-in/UIManager/src/app/examples/FloatingLayout/example.ts +92 -0
- package/src/built-in/UIManager/src/app/examples/Notifications/example.ts +161 -0
- package/src/built-in/UIManager/src/app/examples/Sidebar/example.ts +104 -0
- package/src/built-in/ViewportsManager/example.ts +106 -106
- package/src/built-in/index.ts +755 -755
- package/src/cli/templates/app/README.md +241 -241
- package/src/cli/templates/app/index.html +27 -27
- package/src/cli/templates/app/package.json +27 -25
- package/src/cli/templates/app/src/bim-components/CloudRunner/index.ts +87 -91
- 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/main.ts +56 -89
- package/src/cli/templates/app/src/setups/cloud-runner.ts +9 -13
- package/src/cli/templates/app/src/setups/fragments.ts +18 -0
- package/src/cli/templates/app/src/setups/ifc-loader.ts +12 -0
- package/src/cli/templates/app/src/setups/index.ts +3 -3
- package/src/cli/templates/app/src/ui-components/AppPanel/index.ts +160 -0
- package/src/cli/templates/app/src/ui-components/index.ts +1 -2
- package/src/cli/templates/app/tsconfig.json +17 -16
- 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/shared/CLAUDE.md +1 -1
- package/src/cli/templates/shared/_gitignore +4 -4
- package/src/cli/templates/app/src/app.ts +0 -16
- package/src/cli/templates/app/src/globals.ts +0 -1
- package/src/cli/templates/app/src/setups/ui-manager.ts +0 -27
- package/src/cli/templates/app/src/setups/viewports-manager.ts +0 -22
- package/src/cli/templates/app/src/ui-components/app-info-section/index.ts +0 -26
- package/src/cli/templates/app/src/ui-components/app-info-section/src/index.ts +0 -1
- package/src/cli/templates/app/src/ui-components/app-info-section/src/types.ts +0 -15
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/index.ts +0 -37
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/index.ts +0 -1
- package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/types.ts +0 -14
|
@@ -1,91 +1,87 @@
|
|
|
1
|
-
import * as OBC from "@thatopen/components";
|
|
2
|
-
import {
|
|
3
|
-
import { CloudRunnerStatus } from "./src";
|
|
4
|
-
|
|
5
|
-
export class CloudRunner extends OBC.Component {
|
|
6
|
-
static readonly uuid = "7c4e5d3b-2a1f-4e8d-9b6c-0a3f7e2c5d1b" as const;
|
|
7
|
-
|
|
8
|
-
enabled = true;
|
|
9
|
-
|
|
10
|
-
readonly onExecutionUpdated = new OBC.Event<CloudRunnerStatus>();
|
|
11
|
-
|
|
12
|
-
// TODO: Replace with your actual component ID after publishing.
|
|
13
|
-
componentId = "your-component-id";
|
|
14
|
-
localServerUrl = "http://localhost:4001";
|
|
15
|
-
|
|
16
|
-
// Reactive state — read by the UI template on each render.
|
|
17
|
-
status = "Idle";
|
|
18
|
-
progress = 0;
|
|
19
|
-
messages: string[] = [];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export * from "./src";
|
|
1
|
+
import * as OBC from "@thatopen/components";
|
|
2
|
+
import { EngineServicesClient } from "@thatopen/services";
|
|
3
|
+
import { CloudRunnerStatus } from "./src";
|
|
4
|
+
|
|
5
|
+
export class CloudRunner extends OBC.Component {
|
|
6
|
+
static readonly uuid = "7c4e5d3b-2a1f-4e8d-9b6c-0a3f7e2c5d1b" as const;
|
|
7
|
+
|
|
8
|
+
enabled = true;
|
|
9
|
+
|
|
10
|
+
readonly onExecutionUpdated = new OBC.Event<CloudRunnerStatus>();
|
|
11
|
+
|
|
12
|
+
// TODO: Replace with your actual component ID after publishing.
|
|
13
|
+
componentId = "your-component-id";
|
|
14
|
+
localServerUrl = "http://localhost:4001";
|
|
15
|
+
|
|
16
|
+
// Reactive state — read by the UI template on each render.
|
|
17
|
+
status = "Idle";
|
|
18
|
+
progress = 0;
|
|
19
|
+
messages: string[] = [];
|
|
20
|
+
|
|
21
|
+
// Set this before calling run() — injected from the app setup.
|
|
22
|
+
client!: EngineServicesClient;
|
|
23
|
+
|
|
24
|
+
constructor(components: OBC.Components) {
|
|
25
|
+
super(components);
|
|
26
|
+
components.add(CloudRunner.uuid, this);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async run(useLocal: boolean) {
|
|
30
|
+
this.client.localServerUrl = useLocal ? this.localServerUrl : null;
|
|
31
|
+
|
|
32
|
+
this.status = useLocal ? "Starting (local)..." : "Starting (deployed)...";
|
|
33
|
+
this.progress = 0;
|
|
34
|
+
this.messages = [];
|
|
35
|
+
this._trigger();
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const { executionId } = await this.client.executeComponent(this.componentId, {
|
|
39
|
+
greeting: "Hello from the BIM app!",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.status = `Running (${executionId.slice(0, 8)}...)`;
|
|
43
|
+
this._trigger();
|
|
44
|
+
|
|
45
|
+
this.client.onExecutionProgress(executionId, (data) => {
|
|
46
|
+
if (data.progressUpdate) {
|
|
47
|
+
this.progress = data.progressUpdate.progress;
|
|
48
|
+
if (data.progressUpdate.result) {
|
|
49
|
+
this.status = `${data.progressUpdate.result}: ${data.progressUpdate.resultMessage ?? "Done"}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (data.messageUpdate) {
|
|
53
|
+
this.messages.push(data.messageUpdate.content);
|
|
54
|
+
}
|
|
55
|
+
this._trigger();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
setTimeout(async () => {
|
|
59
|
+
try {
|
|
60
|
+
const exec = await this.client.getExecution(executionId);
|
|
61
|
+
if (exec.result) {
|
|
62
|
+
this.progress = exec.progress;
|
|
63
|
+
this.status = `${exec.result}: ${exec.resultMessage ?? "Done"}`;
|
|
64
|
+
this._trigger();
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
/* WebSocket handles it */
|
|
68
|
+
}
|
|
69
|
+
}, 2000);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
this.status = `Error: ${err}`;
|
|
72
|
+
this._trigger();
|
|
73
|
+
} finally {
|
|
74
|
+
this.client.localServerUrl = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private _trigger() {
|
|
79
|
+
this.onExecutionUpdated.trigger({
|
|
80
|
+
status: this.status,
|
|
81
|
+
progress: this.progress,
|
|
82
|
+
messages: [...this.messages],
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export * from "./src";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./types";
|
|
1
|
+
export * from "./types";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export interface CloudRunnerStatus {
|
|
2
|
-
status: string;
|
|
3
|
-
progress: number;
|
|
4
|
-
messages: string[];
|
|
5
|
-
}
|
|
1
|
+
export interface CloudRunnerStatus {
|
|
2
|
+
status: string;
|
|
3
|
+
progress: number;
|
|
4
|
+
messages: string[];
|
|
5
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./CloudRunner";
|
|
1
|
+
export * from "./CloudRunner";
|
|
@@ -1,89 +1,56 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
icon: "solar:info-circle-bold",
|
|
58
|
-
},
|
|
59
|
-
cloudRunnerSection: {
|
|
60
|
-
template: uis.custom.get("cloudRunnerSection").template,
|
|
61
|
-
initialState: { components },
|
|
62
|
-
label: "Cloud Component",
|
|
63
|
-
icon: "solar:code-bold",
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
grid.layouts = {
|
|
68
|
-
Viewer: {
|
|
69
|
-
template: `"viewer" 1fr / 1fr`,
|
|
70
|
-
},
|
|
71
|
-
Split: {
|
|
72
|
-
template: `
|
|
73
|
-
"tabs:left(appInfoSection, cloudRunnerSection) viewer" 1fr
|
|
74
|
-
/ 24rem 1fr
|
|
75
|
-
`,
|
|
76
|
-
icon: "solar:info-circle-bold",
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
grid.areaGroups = {
|
|
81
|
-
left: { switchersFull: true },
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
grid.layout = "Split";
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
main().catch(console.error);
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
import * as OBC from "@thatopen/components";
|
|
4
|
+
import * as OBF from "@thatopen/components-front";
|
|
5
|
+
import * as FRAGS from "@thatopen/fragments";
|
|
6
|
+
import * as BUI from "@thatopen/ui";
|
|
7
|
+
import { PlatformClient, UIManager } from "@thatopen/services";
|
|
8
|
+
import { initFragments } from "./setups/fragments";
|
|
9
|
+
import { initIfcLoader } from "./setups/ifc-loader";
|
|
10
|
+
import "./ui-components";
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
const client = PlatformClient.fromPlatformContext();
|
|
14
|
+
|
|
15
|
+
const { components } = await client.setup(
|
|
16
|
+
{ OBC, OBF, BUI, THREE, FRAGS },
|
|
17
|
+
{ uuid: UIManager.uuid },
|
|
18
|
+
) as { components: OBC.Components };
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
(components.get(UIManager as any) as any).init();
|
|
22
|
+
|
|
23
|
+
const app = document.createElement("top-app") as any;
|
|
24
|
+
|
|
25
|
+
app.setup = (waitUntil: (promise: Promise<unknown>, label: string) => void) => {
|
|
26
|
+
waitUntil(initFragments(components), "Fragments Core");
|
|
27
|
+
waitUntil(initIfcLoader(components), "IFC Loader");
|
|
28
|
+
return { components, client };
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
app.elements = {
|
|
32
|
+
viewer: () => html`<top-viewer><top-viewer-tools></top-viewer-tools></top-viewer>`,
|
|
33
|
+
panel: () => html`<app-panel></app-panel>`,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
app.layouts = {
|
|
37
|
+
main: {
|
|
38
|
+
label: "Main",
|
|
39
|
+
icon: "solar:home-bold",
|
|
40
|
+
template: `"panel" 1fr / 22rem`,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
app.base = "viewer";
|
|
45
|
+
app.layout = "main";
|
|
46
|
+
|
|
47
|
+
app.addEventListener("thatopen:app-ready", () => {
|
|
48
|
+
app.showToast("App ready", "success");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const container = document.getElementById("that-open-app") ?? document.body;
|
|
52
|
+
container.appendChild(app);
|
|
53
|
+
document.body.style.margin = "0";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
main().catch(console.error);
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import * as OBC from "@thatopen/components";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export const
|
|
6
|
-
const runner = components.get(CloudRunner);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
runner.onExecutionUpdated.add(() => {
|
|
11
|
-
uis.custom.get("cloudRunnerSection").updateInstances();
|
|
12
|
-
});
|
|
13
|
-
};
|
|
1
|
+
import * as OBC from "@thatopen/components";
|
|
2
|
+
import { EngineServicesClient } from "@thatopen/services";
|
|
3
|
+
import { CloudRunner } from "../bim-components";
|
|
4
|
+
|
|
5
|
+
export const setupCloudRunner = (components: OBC.Components, client: EngineServicesClient) => {
|
|
6
|
+
const runner = components.get(CloudRunner);
|
|
7
|
+
runner.client = client;
|
|
8
|
+
return runner;
|
|
9
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as OBC from "@thatopen/components";
|
|
2
|
+
import * as FRAGS from "@thatopen/fragments";
|
|
3
|
+
|
|
4
|
+
export const initFragments = async (components: OBC.Components): Promise<void> => {
|
|
5
|
+
const fragments = components.get(OBC.FragmentsManager);
|
|
6
|
+
|
|
7
|
+
const moduleWorkerUrl = await FRAGS.FragmentsModels.getWorker();
|
|
8
|
+
const workerUrl = await FRAGS.toClassicWorker(moduleWorkerUrl);
|
|
9
|
+
fragments.init(workerUrl, { classicWorker: true });
|
|
10
|
+
|
|
11
|
+
fragments.core.models.materials.list.onItemSet.add(({ value: material }) => {
|
|
12
|
+
if (!("isLodMaterial" in material && material.isLodMaterial)) {
|
|
13
|
+
material.polygonOffset = true;
|
|
14
|
+
material.polygonOffsetUnits = 1;
|
|
15
|
+
material.polygonOffsetFactor = Math.random();
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as OBC from "@thatopen/components";
|
|
2
|
+
|
|
3
|
+
export const initIfcLoader = async (components: OBC.Components): Promise<void> => {
|
|
4
|
+
const ifcLoader = components.get(OBC.IfcLoader);
|
|
5
|
+
await ifcLoader.setup({
|
|
6
|
+
autoSetWasm: false,
|
|
7
|
+
wasm: {
|
|
8
|
+
path: "https://unpkg.com/web-ifc@0.0.77/",
|
|
9
|
+
absolute: true,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
1
|
+
export * from "./cloud-runner";
|
|
2
|
+
export * from "./fragments";
|
|
3
|
+
export * from "./ifc-loader";
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { LitElement, html } from "lit";
|
|
2
|
+
import { state } from "lit/decorators.js";
|
|
3
|
+
import { consume, createContext } from "@lit/context";
|
|
4
|
+
import * as OBC from "@thatopen/components";
|
|
5
|
+
import * as BUI from "@thatopen/ui";
|
|
6
|
+
import { PlatformClient } from "@thatopen/services";
|
|
7
|
+
import type { Item } from "@thatopen/services";
|
|
8
|
+
import { CloudRunner } from "../../bim-components";
|
|
9
|
+
|
|
10
|
+
const componentsContext = createContext<OBC.Components | undefined>("obc-components");
|
|
11
|
+
const clientContext = createContext<PlatformClient | undefined>("platform-client");
|
|
12
|
+
|
|
13
|
+
type FileRow = { Name: string; Extension: string; Load: string };
|
|
14
|
+
|
|
15
|
+
export class AppPanel extends LitElement {
|
|
16
|
+
@consume({ context: componentsContext, subscribe: true })
|
|
17
|
+
@state() private _components?: OBC.Components;
|
|
18
|
+
|
|
19
|
+
@consume({ context: clientContext, subscribe: true })
|
|
20
|
+
@state() private _client?: PlatformClient;
|
|
21
|
+
|
|
22
|
+
@state() private _files: Item[] = [];
|
|
23
|
+
@state() private _loaded = new Set<string>();
|
|
24
|
+
@state() private _loading = new Set<string>();
|
|
25
|
+
|
|
26
|
+
@state() private _runnerStatus = "Idle";
|
|
27
|
+
@state() private _runnerProgress = 0;
|
|
28
|
+
@state() private _runnerMessages: string[] = [];
|
|
29
|
+
@state() private _runnerComponentId = "your-component-id";
|
|
30
|
+
@state() private _running = false;
|
|
31
|
+
|
|
32
|
+
private _runner?: CloudRunner;
|
|
33
|
+
|
|
34
|
+
async updated(changed: Map<string, unknown>) {
|
|
35
|
+
if ((changed.has("_components") || changed.has("_client")) && this._components && this._client) {
|
|
36
|
+
if (!this._runner) {
|
|
37
|
+
this._runner = this._components.get(CloudRunner);
|
|
38
|
+
this._runner.client = this._client;
|
|
39
|
+
this._runner.onExecutionUpdated.add(({ status, progress, messages }) => {
|
|
40
|
+
this._runnerStatus = status;
|
|
41
|
+
this._runnerProgress = progress;
|
|
42
|
+
this._runnerMessages = messages;
|
|
43
|
+
if (status.startsWith("SUCCESS") || status.startsWith("ERROR") || status.startsWith("WARNING")) {
|
|
44
|
+
this._running = false;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
this._runner.client = this._client;
|
|
49
|
+
}
|
|
50
|
+
await this._fetchFiles();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private async _fetchFiles() {
|
|
55
|
+
const projectId = (window as any).__THATOPEN_CONTEXT__?.projectId;
|
|
56
|
+
if (!this._client || !projectId) return;
|
|
57
|
+
const all = await this._client.listFiles({ projectId });
|
|
58
|
+
this._files = all.filter(f => f.fileExtension === "ifc" || f.fileExtension === "frag");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async _toggleModel(file: Item) {
|
|
62
|
+
const id = file._id;
|
|
63
|
+
if (this._loaded.has(id)) {
|
|
64
|
+
await this._components!.get(OBC.FragmentsManager).core.disposeModel(id).catch(() => {});
|
|
65
|
+
this._loaded = new Set([...this._loaded].filter(x => x !== id));
|
|
66
|
+
} else {
|
|
67
|
+
this._loading = new Set([...this._loading, id]);
|
|
68
|
+
try {
|
|
69
|
+
const response = await this._client!.downloadFile(id);
|
|
70
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
71
|
+
if (file.fileExtension === "frag") {
|
|
72
|
+
await this._components!.get(OBC.FragmentsManager).core.load(bytes, { modelId: id });
|
|
73
|
+
} else {
|
|
74
|
+
await this._components!.get(OBC.IfcLoader).load(bytes, true, id);
|
|
75
|
+
}
|
|
76
|
+
this._loaded = new Set([...this._loaded, id]);
|
|
77
|
+
} finally {
|
|
78
|
+
this._loading = new Set([...this._loading].filter(x => x !== id));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private async _run(useLocal: boolean) {
|
|
84
|
+
if (!this._runner) return;
|
|
85
|
+
this._runner.componentId = this._runnerComponentId;
|
|
86
|
+
this._running = true;
|
|
87
|
+
await this._runner.run(useLocal);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private get _tableData(): BUI.TableGroupData<FileRow>[] {
|
|
91
|
+
return this._files.map(f => ({
|
|
92
|
+
data: { Name: f.name, Extension: f.fileExtension ?? "", Load: f._id },
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private get _dataTransform(): BUI.TableDataTransform<FileRow> {
|
|
97
|
+
return {
|
|
98
|
+
Load: (fileId) => {
|
|
99
|
+
const file = this._files.find(f => f._id === fileId)!;
|
|
100
|
+
const loaded = this._loaded.has(fileId);
|
|
101
|
+
const loading = this._loading.has(fileId);
|
|
102
|
+
return BUI.html`
|
|
103
|
+
<bim-button
|
|
104
|
+
.label=${loaded ? "Unload" : "Load"}
|
|
105
|
+
.icon=${loaded ? "solar:eye-closed-bold" : "solar:eye-bold"}
|
|
106
|
+
.loading=${loading}
|
|
107
|
+
@click=${() => this._toggleModel(file)}
|
|
108
|
+
></bim-button>
|
|
109
|
+
`;
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
render() {
|
|
115
|
+
return html`
|
|
116
|
+
<bim-tabs>
|
|
117
|
+
<bim-tab name="models" label="Models" icon="solar:folder-bold">
|
|
118
|
+
<bim-panel-section label="Project Files">
|
|
119
|
+
<bim-table
|
|
120
|
+
.columns=${["Name", "Extension", "Load"]}
|
|
121
|
+
.data=${this._tableData}
|
|
122
|
+
.dataTransform=${this._dataTransform}
|
|
123
|
+
></bim-table>
|
|
124
|
+
</bim-panel-section>
|
|
125
|
+
</bim-tab>
|
|
126
|
+
<bim-tab name="runner" label="Cloud Runner" icon="solar:code-bold">
|
|
127
|
+
<bim-panel>
|
|
128
|
+
<bim-panel-section label="Component">
|
|
129
|
+
<bim-text-input
|
|
130
|
+
label="Component ID"
|
|
131
|
+
value=${this._runnerComponentId}
|
|
132
|
+
@change=${(e: Event) => { this._runnerComponentId = (e.target as HTMLInputElement).value; }}
|
|
133
|
+
></bim-text-input>
|
|
134
|
+
<div style="display:flex;gap:0.5rem;">
|
|
135
|
+
<bim-button
|
|
136
|
+
label="Run"
|
|
137
|
+
.icon=${"solar:play-bold"}
|
|
138
|
+
.loading=${this._running}
|
|
139
|
+
@click=${() => this._run(false)}
|
|
140
|
+
></bim-button>
|
|
141
|
+
<bim-button
|
|
142
|
+
label="Run Local"
|
|
143
|
+
.icon=${"solar:server-bold"}
|
|
144
|
+
.loading=${this._running}
|
|
145
|
+
@click=${() => this._run(true)}
|
|
146
|
+
></bim-button>
|
|
147
|
+
</div>
|
|
148
|
+
</bim-panel-section>
|
|
149
|
+
<bim-panel-section label="Status">
|
|
150
|
+
<bim-label>${this._runnerStatus}</bim-label>
|
|
151
|
+
${this._runnerMessages.map(m => html`<bim-label>${m}</bim-label>`)}
|
|
152
|
+
</bim-panel-section>
|
|
153
|
+
</bim-panel>
|
|
154
|
+
</bim-tab>
|
|
155
|
+
</bim-tabs>
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
customElements.define("app-panel", AppPanel);
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./cloud-runner-section";
|
|
1
|
+
export * from "./AppPanel";
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"moduleResolution": "bundler",
|
|
9
|
-
"allowImportingTsExtensions": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"strict": true
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"experimentalDecorators": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src"]
|
|
17
|
+
}
|