@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.
Files changed (64) hide show
  1. package/README.md +46 -46
  2. package/dist/built-in/index.d.ts +723 -0
  3. package/dist/cli.js +22 -0
  4. package/dist/core/client.d.ts +10 -1
  5. package/dist/index.cjs.js +2 -2
  6. package/dist/index.es.js +87 -71
  7. package/dist/types/files.d.ts +6 -0
  8. package/dist/vite-env.d.ts +1 -1
  9. package/docs/builtin/paths.json +22 -6
  10. package/package.json +99 -99
  11. package/resources/AGENTS.md +5 -3
  12. package/src/built-in/AppManager/example.ts +86 -86
  13. package/src/built-in/CDEManager/example.ts +214 -214
  14. package/src/built-in/CDEManager/examples/FileEditing/example.ts +226 -226
  15. package/src/built-in/CDEManager/examples/FileMoves/example.ts +186 -186
  16. package/src/built-in/CDEManager/examples/FileOperations/example.ts +295 -295
  17. package/src/built-in/CDEManager/examples/FileTransfers/example.ts +210 -210
  18. package/src/built-in/CDEManager/examples/FolderManagement/example.ts +230 -230
  19. package/src/built-in/CDEManager/examples/MetadataSchema/example.ts +230 -230
  20. package/src/built-in/CDEManager/examples/MetadataViews/example.ts +166 -166
  21. package/src/built-in/CDEManager/examples/ProjectConfig/example.ts +177 -177
  22. package/src/built-in/FileList/example.ts +107 -107
  23. package/src/built-in/TabbedNavigation/example.ts +115 -115
  24. package/src/built-in/UIManager/src/app/example.ts +99 -0
  25. package/src/built-in/UIManager/src/app/examples/AppState/example.ts +142 -0
  26. package/src/built-in/UIManager/src/app/examples/Contexts/example.ts +125 -0
  27. package/src/built-in/UIManager/src/app/examples/FloatingLayout/example.ts +92 -0
  28. package/src/built-in/UIManager/src/app/examples/Notifications/example.ts +161 -0
  29. package/src/built-in/UIManager/src/app/examples/Sidebar/example.ts +104 -0
  30. package/src/built-in/ViewportsManager/example.ts +106 -106
  31. package/src/built-in/index.ts +755 -755
  32. package/src/cli/templates/app/README.md +241 -241
  33. package/src/cli/templates/app/index.html +27 -27
  34. package/src/cli/templates/app/package.json +27 -25
  35. package/src/cli/templates/app/src/bim-components/CloudRunner/index.ts +87 -91
  36. package/src/cli/templates/app/src/bim-components/CloudRunner/src/index.ts +1 -1
  37. package/src/cli/templates/app/src/bim-components/CloudRunner/src/types.ts +5 -5
  38. package/src/cli/templates/app/src/bim-components/index.ts +1 -1
  39. package/src/cli/templates/app/src/main.ts +56 -89
  40. package/src/cli/templates/app/src/setups/cloud-runner.ts +9 -13
  41. package/src/cli/templates/app/src/setups/fragments.ts +18 -0
  42. package/src/cli/templates/app/src/setups/ifc-loader.ts +12 -0
  43. package/src/cli/templates/app/src/setups/index.ts +3 -3
  44. package/src/cli/templates/app/src/ui-components/AppPanel/index.ts +160 -0
  45. package/src/cli/templates/app/src/ui-components/index.ts +1 -2
  46. package/src/cli/templates/app/tsconfig.json +17 -16
  47. package/src/cli/templates/cloud-component/README.md +205 -205
  48. package/src/cli/templates/cloud-component/_thatopen +5 -5
  49. package/src/cli/templates/cloud-component/declarations.json +4 -4
  50. package/src/cli/templates/cloud-component/package.json +21 -21
  51. package/src/cli/templates/cloud-component/src/main.ts +70 -70
  52. package/src/cli/templates/cloud-component/tsconfig.json +16 -16
  53. package/src/cli/templates/shared/CLAUDE.md +1 -1
  54. package/src/cli/templates/shared/_gitignore +4 -4
  55. package/src/cli/templates/app/src/app.ts +0 -16
  56. package/src/cli/templates/app/src/globals.ts +0 -1
  57. package/src/cli/templates/app/src/setups/ui-manager.ts +0 -27
  58. package/src/cli/templates/app/src/setups/viewports-manager.ts +0 -22
  59. package/src/cli/templates/app/src/ui-components/app-info-section/index.ts +0 -26
  60. package/src/cli/templates/app/src/ui-components/app-info-section/src/index.ts +0 -1
  61. package/src/cli/templates/app/src/ui-components/app-info-section/src/types.ts +0 -15
  62. package/src/cli/templates/app/src/ui-components/cloud-runner-section/index.ts +0 -37
  63. package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/index.ts +0 -1
  64. 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 { AppManager } 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
- constructor(components: OBC.Components) {
22
- super(components);
23
- components.add(CloudRunner.uuid, this);
24
- }
25
-
26
- async run(useLocal: boolean) {
27
- // Resolve client at call time via AppManager — never store it as a field.
28
- const app = this.components.get(AppManager);
29
- const client = app.client;
30
-
31
- client.localServerUrl = useLocal ? this.localServerUrl : null;
32
-
33
- this.status = useLocal ? "Starting (local)..." : "Starting (deployed)...";
34
- this.progress = 0;
35
- this.messages = [];
36
- this._trigger();
37
-
38
- try {
39
- const { executionId } = await client.executeComponent(this.componentId, {
40
- greeting: "Hello from the BIM app!",
41
- });
42
-
43
- this.status = `Running (${executionId.slice(0, 8)}...)`;
44
- this._trigger();
45
-
46
- // Subscribe to real-time progress updates via WebSocket.
47
- client.onExecutionProgress(executionId, (data) => {
48
- if (data.progressUpdate) {
49
- this.progress = data.progressUpdate.progress;
50
- if (data.progressUpdate.result) {
51
- this.status = `${data.progressUpdate.result}: ${data.progressUpdate.resultMessage ?? "Done"}`;
52
- }
53
- }
54
- if (data.messageUpdate) {
55
- this.messages.push(data.messageUpdate.content);
56
- }
57
- this._trigger();
58
- });
59
-
60
- // Poll once after a short delay to catch fast executions that complete
61
- // before the WebSocket subscription is established.
62
- setTimeout(async () => {
63
- try {
64
- const exec = await client.getExecution(executionId);
65
- if (exec.result) {
66
- this.progress = exec.progress;
67
- this.status = `${exec.result}: ${exec.resultMessage ?? "Done"}`;
68
- this._trigger();
69
- }
70
- } catch {
71
- /* WebSocket handles it */
72
- }
73
- }, 2000);
74
- } catch (err) {
75
- this.status = `Error: ${err}`;
76
- this._trigger();
77
- } finally {
78
- client.localServerUrl = null;
79
- }
80
- }
81
-
82
- private _trigger() {
83
- this.onExecutionUpdated.trigger({
84
- status: this.status,
85
- progress: this.progress,
86
- messages: [...this.messages],
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 * as THREE from "three";
2
- import * as OBC from "@thatopen/components";
3
- import * as OBF from "@thatopen/components-front";
4
- import * as FRAGS from "@thatopen/fragments";
5
- import * as BUI from "@thatopen/ui";
6
- import * as MARKERJS from "@markerjs/markerjs3"
7
- import {
8
- PlatformClient,
9
- AppManager,
10
- ViewportsManager,
11
- UIManager,
12
- } from "@thatopen/services";
13
-
14
- import { getAppManager } from "./app";
15
- import { uiManager, cloudRunner, viewportsManager, getUIManager } from "./setups";
16
-
17
- // Wrap in async function since IIFE format does not support top-level await.
18
- async function main() {
19
- // ─── Platform Client ──────────────────────────────────────────
20
- // Reads auth context from window.__THATOPEN_CONTEXT__ (injected by the
21
- // platform) and creates a client with Bearer auth.
22
- const client = PlatformClient.fromPlatformContext();
23
-
24
- // ─── Built-in Components ──────────────────────────────────────
25
- // First argument: library globals used by the engine.
26
- // Subsequent arguments: platform built-in components to initialise.
27
- const { components } = await client.setup<OBC.Components>(
28
- { OBC, OBF, BUI, THREE, FRAGS, MARKERJS },
29
- { uuid: ViewportsManager.uuid },
30
- { uuid: AppManager.uuid },
31
- { uuid: UIManager.uuid },
32
- );
33
-
34
- // ─── Viewport ─────────────────────────────────────────────────
35
- // Must run before app.init() so the element is ready for the grid.
36
- const viewerElement = await viewportsManager(components);
37
-
38
- // ─── App Init ─────────────────────────────────────────────────
39
- const app = getAppManager(components);
40
-
41
- await app.init({
42
- client,
43
- icons: [],
44
- componentSetups: {
45
- // core: runs in parallel before the grid mounts.
46
- core: [uiManager, cloudRunner],
47
- },
48
- grid: (grid) => {
49
- const uis = getUIManager(components);
50
-
51
- grid.elements = {
52
- viewer: viewerElement,
53
- appInfoSection: {
54
- template: uis.custom.get("appInfoSection").template,
55
- initialState: { components },
56
- label: "App Info",
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 { CloudRunner } from "../bim-components";
3
- import { getUIManager } from "./ui-manager";
4
-
5
- export const cloudRunner = (components: OBC.Components) => {
6
- const runner = components.get(CloudRunner);
7
- const uis = getUIManager(components);
8
-
9
- // Re-render all appInfoSection instances whenever execution state changes.
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 "./ui-manager";
2
- export * from "./viewports-manager";
3
- export * from "./cloud-runner";
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 "./app-info-section";
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
- "include": ["src"]
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
+ }