@industream/flowmaker-flowbox-ui-components 0.0.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 ADDED
@@ -0,0 +1,179 @@
1
+ # @industream/flowmaker-flowbox-ui-components
2
+
3
+ Reusable Svelte 5 components for FlowMaker FlowBox configuration UIs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @industream/flowmaker-flowbox-ui-components
9
+ ```
10
+
11
+ **Peer dependencies:**
12
+ - `svelte@^5.0.0`
13
+ - `@industream/datacatalog-client@^1.0.0-preview.1`
14
+
15
+ ---
16
+
17
+ ## Components
18
+
19
+ ### DataCatalog Integration
20
+
21
+ #### DCSourceConnection
22
+
23
+ A dropdown component that fetches and displays source connections from the DataCatalog API, allowing users to select a data source for their FlowBox configuration.
24
+
25
+ ##### Import
26
+
27
+ ```typescript
28
+ import { DCSourceConnection, type SourceConnection } from '@industream/flowmaker-flowbox-ui-components';
29
+ ```
30
+
31
+ ##### Props
32
+
33
+ | Prop | Type | Default | Description |
34
+ |------|------|---------|-------------|
35
+ | `dcapiurl` | `string` | `''` | Base URL of the DataCatalog API |
36
+ | `sourcetypefilter` | `string \| string[] \| null` | `null` | Filter connections by source type(s) |
37
+ | `onsourceselect` | `(connection: SourceConnection) => void` | `null` | Callback when a connection is selected |
38
+ | `onitemsloaded` | `(connections: SourceConnection[]) => void` | `null` | Callback when connections are loaded |
39
+
40
+ ##### Exported Methods
41
+
42
+ | Method | Signature | Description |
43
+ |--------|-----------|-------------|
44
+ | `select` | `(idOrConnection: string \| SourceConnection) => void` | Programmatically select a connection |
45
+ | `getSelection` | `() => SourceConnection \| null` | Get the currently selected connection |
46
+ | `getConnections` | `() => SourceConnection[]` | Get all loaded connections |
47
+
48
+ ##### Types
49
+
50
+ ```typescript
51
+ interface SourceConnection {
52
+ id: string;
53
+ name: string;
54
+ sourceType?: { name: string };
55
+ [key: string]: any;
56
+ }
57
+ ```
58
+
59
+ ##### Example: FlowBox Config Form
60
+
61
+ This example shows how to integrate `DCSourceConnection` into a FlowBox configuration form using `@industream/flowmaker-flowbox-ui`.
62
+
63
+ ```svelte
64
+ <script lang="ts">
65
+ import { flowMakerBridge } from '@industream/flowmaker-flowbox-ui';
66
+ import { DCSourceConnection, type SourceConnection } from '@industream/flowmaker-flowbox-ui-components';
67
+
68
+ const props = $props();
69
+ const { context, values, validity, emit } = flowMakerBridge(props);
70
+
71
+ // Get DC API URL from context (passed by FlowMaker)
72
+ const dcApiUrl = $derived($context?.dcApiUrl || 'http://localhost:8002');
73
+
74
+ // Optional: filter by source type
75
+ const sourceTypeFilter = $derived($context?.sourceTypeFilter || null);
76
+
77
+ // Reference to component for programmatic access
78
+ let dcSourceConnection: ReturnType<typeof DCSourceConnection>;
79
+
80
+ function handleSourceSelect(connection: SourceConnection) {
81
+ // Store selected connection ID in values
82
+ $values.sourceConnectionId = connection.id;
83
+
84
+ // Optionally store more details
85
+ $values.sourceConnectionName = connection.name;
86
+ $values.sourceType = connection.sourceType?.name;
87
+ }
88
+
89
+ function handleItemsLoaded(connections: SourceConnection[]) {
90
+ // Restore previous selection if exists
91
+ if ($values.sourceConnectionId) {
92
+ dcSourceConnection.select($values.sourceConnectionId);
93
+ }
94
+ }
95
+ </script>
96
+
97
+ <div class="config-form">
98
+ <h4>Select Source Connection</h4>
99
+
100
+ <DCSourceConnection
101
+ dcapiurl={dcApiUrl}
102
+ sourcetypefilter={sourceTypeFilter}
103
+ onsourceselect={handleSourceSelect}
104
+ onitemsloaded={handleItemsLoaded}
105
+ bind:this={dcSourceConnection}
106
+ />
107
+
108
+ {#if $values.sourceConnectionId}
109
+ <div class="selection-info">
110
+ <p><strong>Selected:</strong> {$values.sourceConnectionName}</p>
111
+ <p><strong>Type:</strong> {$values.sourceType}</p>
112
+ </div>
113
+ {/if}
114
+ </div>
115
+
116
+ <style>
117
+ .config-form {
118
+ display: flex;
119
+ flex-direction: column;
120
+ gap: 1rem;
121
+ }
122
+
123
+ .selection-info {
124
+ padding: 1rem;
125
+ background: var(--cds-layer-01, #393939);
126
+ border-radius: 4px;
127
+ }
128
+ </style>
129
+ ```
130
+
131
+ ##### Context Configuration
132
+
133
+ When registering your FlowBox, pass the DataCatalog API URL via context:
134
+
135
+ ```json
136
+ {
137
+ "context": {
138
+ "dcApiUrl": "https://datacatalog.example.com/api",
139
+ "sourceTypeFilter": ["Mqtt", "DataBridge"]
140
+ }
141
+ }
142
+ ```
143
+
144
+ ##### Filtering by Source Type
145
+
146
+ Filter to show only specific source types:
147
+
148
+ ```svelte
149
+ <!-- Single type -->
150
+ <DCSourceConnection
151
+ dcapiurl={dcApiUrl}
152
+ sourcetypefilter="DataBridge"
153
+ onsourceselect={handleSelect}
154
+ />
155
+
156
+ <!-- Multiple types -->
157
+ <DCSourceConnection
158
+ dcapiurl={dcApiUrl}
159
+ sourcetypefilter={["Relational", "DataBridge", "Mqtt"]}
160
+ onsourceselect={handleSelect}
161
+ />
162
+ ```
163
+
164
+ ##### Programmatic Selection
165
+
166
+ ```typescript
167
+ // Select by ID
168
+ dcSourceConnection.select('xxxx-guid-1234-4567');
169
+
170
+ // Select by connection object
171
+ dcSourceConnection.select(connectionObject);
172
+
173
+ // Get current selection
174
+ const selected = dcSourceConnection.getSelection();
175
+
176
+ // Get all loaded connections
177
+ const all = dcSourceConnection.getConnections();
178
+ ```
179
+
@@ -0,0 +1,141 @@
1
+ <script lang="ts">
2
+ import { DataCatalogClient } from '@industream/datacatalog-client';
3
+
4
+ export interface SourceConnection {
5
+ id: string;
6
+ name: string;
7
+ sourceType?: { name: string };
8
+ [key: string]: any;
9
+ }
10
+
11
+ interface Props {
12
+ dcapiurl?: string;
13
+ sourcetypefilter?: string | string[] | null;
14
+ onsourceselect?: (connection: SourceConnection) => void;
15
+ onitemsloaded?: (connections: SourceConnection[]) => void;
16
+ }
17
+
18
+ let {
19
+ dcapiurl = '',
20
+ sourcetypefilter = null,
21
+ onsourceselect = null,
22
+ onitemsloaded = null
23
+ }: Props = $props();
24
+
25
+ let sourceConnections = $state<SourceConnection[]>([]);
26
+ let selectedValue = $state('');
27
+ let loading = $state(true);
28
+ let error = $state<string | null>(null);
29
+ let dropdownRef = $state<HTMLElement | null>(null);
30
+
31
+ // Load source connections when component mounts or dcapiurl changes
32
+ $effect(() => {
33
+ if (dcapiurl && sourcetypefilter !== null) {
34
+ loadSourceConnections();
35
+ }
36
+ });
37
+
38
+ // Add event listener for Carbon's custom event
39
+ $effect(() => {
40
+ if (dropdownRef) {
41
+ dropdownRef.addEventListener('cds-dropdown-selected', handleSelect);
42
+ return () => {
43
+ dropdownRef.removeEventListener('cds-dropdown-selected', handleSelect);
44
+ };
45
+ }
46
+ });
47
+
48
+ async function loadSourceConnections() {
49
+ loading = true;
50
+ error = null;
51
+
52
+ try {
53
+ const client = new DataCatalogClient({ baseUrl: dcapiurl });
54
+ const filters = {};
55
+
56
+ if (sourcetypefilter && sourcetypefilter.length > 0) {
57
+ filters.sourceTypes = Array.isArray(sourcetypefilter)
58
+ ? sourcetypefilter
59
+ : [sourcetypefilter];
60
+ }
61
+
62
+ const result = await client.sourceConnections.get(filters);
63
+ sourceConnections = result.items || [];
64
+ console.log('Loaded source connections:', sourceConnections);
65
+ onitemsloaded?.(sourceConnections);
66
+ } catch (e) {
67
+ console.error('Failed to load source connections:', e);
68
+ error = e.message || 'Failed to load source connections';
69
+ sourceConnections = [];
70
+ } finally {
71
+ loading = false;
72
+ }
73
+ }
74
+
75
+ function handleSelect(e: CustomEvent) {
76
+ const selectedId = e.detail?.item?.value || e.target?.value;
77
+ console.log('Dropdown selected event:', e, 'selectedId:', selectedId);
78
+ selectedValue = selectedId;
79
+
80
+ if (selectedId && onsourceselect) {
81
+ const selected = sourceConnections.find(sc => sc.id === selectedId);
82
+ console.log('Found selected:', selected);
83
+ if (selected) {
84
+ onsourceselect(selected);
85
+ }
86
+ }
87
+ }
88
+
89
+ // Exposed method to programmatically select a source connection
90
+ export function select(idOrConnection: string | SourceConnection) {
91
+ const id = typeof idOrConnection === 'string' ? idOrConnection : idOrConnection?.id;
92
+ if (!id) return;
93
+
94
+ const connection = sourceConnections.find(sc => sc.id === id);
95
+ if (connection) {
96
+ selectedValue = id;
97
+ if (dropdownRef) {
98
+ dropdownRef.value = id;
99
+ }
100
+ if (onsourceselect) {
101
+ onsourceselect(connection);
102
+ }
103
+ }
104
+ }
105
+
106
+ // Exposed method to get current selection
107
+ export function getSelection(): SourceConnection | null {
108
+ return sourceConnections.find(sc => sc.id === selectedValue) || null;
109
+ }
110
+
111
+ // Exposed method to get all loaded connections
112
+ export function getConnections(): SourceConnection[] {
113
+ return sourceConnections;
114
+ }
115
+ </script>
116
+
117
+ {#if loading}
118
+ <cds-dropdown label="Source Connection" disabled>
119
+ <cds-dropdown-item value="">Loading...</cds-dropdown-item>
120
+ </cds-dropdown>
121
+ {:else if error}
122
+ <cds-dropdown label="Source Connection" invalid invalid-text={error}>
123
+ <cds-dropdown-item value="">Error loading connections</cds-dropdown-item>
124
+ </cds-dropdown>
125
+ {:else}
126
+ <cds-dropdown
127
+ bind:this={dropdownRef}
128
+ label="Select a source connection"
129
+ value={selectedValue}
130
+ >
131
+ {#each sourceConnections as conn}
132
+ <cds-dropdown-item value={conn.id}>
133
+ {conn.name} [{conn.sourceType?.name || 'Unknown'}]
134
+ </cds-dropdown-item>
135
+ {/each}
136
+ </cds-dropdown>
137
+ {/if}
138
+
139
+ <style>
140
+ /* Component styles */
141
+ </style>
@@ -0,0 +1,21 @@
1
+ export interface SourceConnection {
2
+ id: string;
3
+ name: string;
4
+ sourceType?: {
5
+ name: string;
6
+ };
7
+ [key: string]: any;
8
+ }
9
+ interface Props {
10
+ dcapiurl?: string;
11
+ sourcetypefilter?: string | string[] | null;
12
+ onsourceselect?: (connection: SourceConnection) => void;
13
+ onitemsloaded?: (connections: SourceConnection[]) => void;
14
+ }
15
+ declare const DCSourceConnection: import("svelte").Component<Props, {
16
+ select: (idOrConnection: string | SourceConnection) => void;
17
+ getSelection: () => SourceConnection | null;
18
+ getConnections: () => SourceConnection[];
19
+ }, "">;
20
+ type DCSourceConnection = ReturnType<typeof DCSourceConnection>;
21
+ export default DCSourceConnection;
@@ -0,0 +1,2 @@
1
+ export { default as DCSourceConnection } from './DCSourceConnection.svelte';
2
+ export type { SourceConnection } from './DCSourceConnection.svelte';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default as DCSourceConnection } from './DCSourceConnection.svelte';
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@industream/flowmaker-flowbox-ui-components",
3
+ "version": "0.0.1",
4
+ "description": "Reusable Svelte components for FlowMaker FlowBox UI",
5
+ "type": "module",
6
+ "svelte": "./dist/index.js",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "svelte": "./dist/index.js",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./DCSourceConnection.svelte": {
17
+ "types": "./dist/DCSourceConnection.svelte.d.ts",
18
+ "svelte": "./dist/DCSourceConnection.svelte",
19
+ "import": "./dist/DCSourceConnection.svelte"
20
+ }
21
+ },
22
+ "files": [
23
+ "src",
24
+ "dist",
25
+ "README.md"
26
+ ],
27
+ "scripts": {
28
+ "build": "svelte-package --input src"
29
+ },
30
+ "peerDependencies": {
31
+ "svelte": "^5.0.0",
32
+ "@industream/datacatalog-client": "^1.0.0-preview.1"
33
+ },
34
+ "devDependencies": {
35
+ "svelte": "^5.0.0",
36
+ "vite": "^6.0.0",
37
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
38
+ "@sveltejs/package": "^2.0.0",
39
+ "typescript": "^5.0.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ }
44
+ }
@@ -0,0 +1,141 @@
1
+ <script lang="ts">
2
+ import { DataCatalogClient } from '@industream/datacatalog-client';
3
+
4
+ export interface SourceConnection {
5
+ id: string;
6
+ name: string;
7
+ sourceType?: { name: string };
8
+ [key: string]: any;
9
+ }
10
+
11
+ interface Props {
12
+ dcapiurl?: string;
13
+ sourcetypefilter?: string | string[] | null;
14
+ onsourceselect?: (connection: SourceConnection) => void;
15
+ onitemsloaded?: (connections: SourceConnection[]) => void;
16
+ }
17
+
18
+ let {
19
+ dcapiurl = '',
20
+ sourcetypefilter = null,
21
+ onsourceselect = null,
22
+ onitemsloaded = null
23
+ }: Props = $props();
24
+
25
+ let sourceConnections = $state<SourceConnection[]>([]);
26
+ let selectedValue = $state('');
27
+ let loading = $state(true);
28
+ let error = $state<string | null>(null);
29
+ let dropdownRef = $state<HTMLElement | null>(null);
30
+
31
+ // Load source connections when component mounts or dcapiurl changes
32
+ $effect(() => {
33
+ if (dcapiurl && sourcetypefilter !== null) {
34
+ loadSourceConnections();
35
+ }
36
+ });
37
+
38
+ // Add event listener for Carbon's custom event
39
+ $effect(() => {
40
+ if (dropdownRef) {
41
+ dropdownRef.addEventListener('cds-dropdown-selected', handleSelect);
42
+ return () => {
43
+ dropdownRef.removeEventListener('cds-dropdown-selected', handleSelect);
44
+ };
45
+ }
46
+ });
47
+
48
+ async function loadSourceConnections() {
49
+ loading = true;
50
+ error = null;
51
+
52
+ try {
53
+ const client = new DataCatalogClient({ baseUrl: dcapiurl });
54
+ const filters = {};
55
+
56
+ if (sourcetypefilter && sourcetypefilter.length > 0) {
57
+ filters.sourceTypes = Array.isArray(sourcetypefilter)
58
+ ? sourcetypefilter
59
+ : [sourcetypefilter];
60
+ }
61
+
62
+ const result = await client.sourceConnections.get(filters);
63
+ sourceConnections = result.items || [];
64
+ console.log('Loaded source connections:', sourceConnections);
65
+ onitemsloaded?.(sourceConnections);
66
+ } catch (e) {
67
+ console.error('Failed to load source connections:', e);
68
+ error = e.message || 'Failed to load source connections';
69
+ sourceConnections = [];
70
+ } finally {
71
+ loading = false;
72
+ }
73
+ }
74
+
75
+ function handleSelect(e: CustomEvent) {
76
+ const selectedId = e.detail?.item?.value || e.target?.value;
77
+ console.log('Dropdown selected event:', e, 'selectedId:', selectedId);
78
+ selectedValue = selectedId;
79
+
80
+ if (selectedId && onsourceselect) {
81
+ const selected = sourceConnections.find(sc => sc.id === selectedId);
82
+ console.log('Found selected:', selected);
83
+ if (selected) {
84
+ onsourceselect(selected);
85
+ }
86
+ }
87
+ }
88
+
89
+ // Exposed method to programmatically select a source connection
90
+ export function select(idOrConnection: string | SourceConnection) {
91
+ const id = typeof idOrConnection === 'string' ? idOrConnection : idOrConnection?.id;
92
+ if (!id) return;
93
+
94
+ const connection = sourceConnections.find(sc => sc.id === id);
95
+ if (connection) {
96
+ selectedValue = id;
97
+ if (dropdownRef) {
98
+ dropdownRef.value = id;
99
+ }
100
+ if (onsourceselect) {
101
+ onsourceselect(connection);
102
+ }
103
+ }
104
+ }
105
+
106
+ // Exposed method to get current selection
107
+ export function getSelection(): SourceConnection | null {
108
+ return sourceConnections.find(sc => sc.id === selectedValue) || null;
109
+ }
110
+
111
+ // Exposed method to get all loaded connections
112
+ export function getConnections(): SourceConnection[] {
113
+ return sourceConnections;
114
+ }
115
+ </script>
116
+
117
+ {#if loading}
118
+ <cds-dropdown label="Source Connection" disabled>
119
+ <cds-dropdown-item value="">Loading...</cds-dropdown-item>
120
+ </cds-dropdown>
121
+ {:else if error}
122
+ <cds-dropdown label="Source Connection" invalid invalid-text={error}>
123
+ <cds-dropdown-item value="">Error loading connections</cds-dropdown-item>
124
+ </cds-dropdown>
125
+ {:else}
126
+ <cds-dropdown
127
+ bind:this={dropdownRef}
128
+ label="Select a source connection"
129
+ value={selectedValue}
130
+ >
131
+ {#each sourceConnections as conn}
132
+ <cds-dropdown-item value={conn.id}>
133
+ {conn.name} [{conn.sourceType?.name || 'Unknown'}]
134
+ </cds-dropdown-item>
135
+ {/each}
136
+ </cds-dropdown>
137
+ {/if}
138
+
139
+ <style>
140
+ /* Component styles */
141
+ </style>
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default as DCSourceConnection } from './DCSourceConnection.svelte';
2
+ export type { SourceConnection } from './DCSourceConnection.svelte';