@burdenoff/microfe-bigconsole 2026.707.3 → 2026.708.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/dist/bigconsole/components/widgets/table/TableConfig.js +220 -29
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/hooks/useExportDataSink.js +1 -0
- package/dist/bigconsole/hooks/useExportDataSink.js.map +1 -1
- package/dist/bigconsole/hooks/useImportDataSink.js +101 -85
- package/dist/bigconsole/hooks/useImportDataSink.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +30 -22
- package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +2 -2
- package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,57 +12,69 @@ function o(e) {
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
function s(e) {
|
|
15
|
+
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
16
|
+
}
|
|
17
|
+
function c(e) {
|
|
18
|
+
let t = e;
|
|
19
|
+
return s(t.dataSink) ? t.dataSink : typeof e.key == "string" ? e : null;
|
|
20
|
+
}
|
|
21
|
+
function l(e) {
|
|
22
|
+
if (e) return {
|
|
23
|
+
type: e.type,
|
|
24
|
+
...e.schedule ? { schedule: u(e.schedule) } : {}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function u(e) {
|
|
15
28
|
if (e == null) return e;
|
|
16
|
-
if (Array.isArray(e)) return e.map((e) =>
|
|
29
|
+
if (Array.isArray(e)) return e.map((e) => u(e));
|
|
17
30
|
if (typeof e == "object") {
|
|
18
31
|
let t = {};
|
|
19
|
-
for (let [n, r] of Object.entries(e)) n !== "__typename" && (t[n] =
|
|
32
|
+
for (let [n, r] of Object.entries(e)) n !== "__typename" && (t[n] = u(r));
|
|
20
33
|
return t;
|
|
21
34
|
}
|
|
22
35
|
return e;
|
|
23
36
|
}
|
|
24
|
-
function
|
|
37
|
+
function d(e) {
|
|
25
38
|
try {
|
|
26
|
-
let t = JSON.parse(e);
|
|
27
|
-
return
|
|
39
|
+
let t = JSON.parse(e), n = t;
|
|
40
|
+
return n.exportedFrom?.dataSinkId || n.dataSink?.id || t.id || null;
|
|
28
41
|
} catch {
|
|
29
42
|
return null;
|
|
30
43
|
}
|
|
31
44
|
}
|
|
32
|
-
function
|
|
45
|
+
function f(e) {
|
|
33
46
|
let t = [];
|
|
34
47
|
try {
|
|
35
|
-
let n = JSON.parse(e);
|
|
36
|
-
if (
|
|
48
|
+
let n = JSON.parse(e), r = n, i = c(n);
|
|
49
|
+
if (!r.schemaVersion && !i && t.push({
|
|
37
50
|
code: "MISSING_SCHEMA_VERSION",
|
|
38
51
|
message: "Missing schema version"
|
|
39
|
-
}), !
|
|
52
|
+
}), !i) return t.push({
|
|
40
53
|
code: "MISSING_DATASINK",
|
|
41
|
-
message: "
|
|
54
|
+
message: "This file is not a BigConsole DataSink export. Expected a top-level dataSink object."
|
|
42
55
|
}), {
|
|
43
56
|
isValid: !1,
|
|
44
57
|
dataSinkInfo: null,
|
|
45
58
|
errors: t
|
|
46
59
|
};
|
|
47
|
-
|
|
48
|
-
r.key || t.push({
|
|
60
|
+
i.key || t.push({
|
|
49
61
|
code: "MISSING_KEY",
|
|
50
62
|
message: "DataSink key is required",
|
|
51
63
|
path: "dataSink.key"
|
|
52
64
|
});
|
|
53
|
-
let
|
|
54
|
-
name:
|
|
55
|
-
description:
|
|
56
|
-
key:
|
|
57
|
-
status:
|
|
58
|
-
setupState:
|
|
59
|
-
exportedAt:
|
|
60
|
-
exportedFrom:
|
|
61
|
-
schemaVersion:
|
|
65
|
+
let a = {
|
|
66
|
+
name: i.name || null,
|
|
67
|
+
description: i.description || null,
|
|
68
|
+
key: i.key || "",
|
|
69
|
+
status: i.status || "ready",
|
|
70
|
+
setupState: i.setupState || "not_started",
|
|
71
|
+
exportedAt: r.exportedAt,
|
|
72
|
+
exportedFrom: r.exportedFrom?.dataSinkId,
|
|
73
|
+
schemaVersion: r.schemaVersion || "legacy"
|
|
62
74
|
};
|
|
63
75
|
return {
|
|
64
76
|
isValid: t.length === 0,
|
|
65
|
-
dataSinkInfo:
|
|
77
|
+
dataSinkInfo: a,
|
|
66
78
|
errors: t
|
|
67
79
|
};
|
|
68
80
|
} catch {
|
|
@@ -76,123 +88,127 @@ function l(e) {
|
|
|
76
88
|
};
|
|
77
89
|
}
|
|
78
90
|
}
|
|
79
|
-
function
|
|
80
|
-
let [
|
|
81
|
-
let t =
|
|
82
|
-
return
|
|
83
|
-
}, []),
|
|
91
|
+
function p() {
|
|
92
|
+
let [s, p] = i(!1), [m, h] = i(null), [g, _] = i(null), [v, y] = i(null), b = a(), x = r((e) => {
|
|
93
|
+
let t = f(e);
|
|
94
|
+
return _(t), t;
|
|
95
|
+
}, []), S = r((e) => d(e), []), C = r(async (r, i = {}) => {
|
|
84
96
|
try {
|
|
85
|
-
|
|
86
|
-
let a =
|
|
97
|
+
p(!0), h(null);
|
|
98
|
+
let a = f(r);
|
|
87
99
|
if (!a.isValid || !a.dataSinkInfo) throw Error(a.errors[0]?.message || "Invalid import content");
|
|
88
|
-
let o = JSON.parse(r)
|
|
89
|
-
if (
|
|
90
|
-
|
|
100
|
+
let o = c(JSON.parse(r));
|
|
101
|
+
if (!o) throw Error("Missing DataSink payload in import content");
|
|
102
|
+
let s = Object.prototype.hasOwnProperty.call(o, "data"), m = d(r), g = !1, _;
|
|
103
|
+
if (m) try {
|
|
104
|
+
let e = (await b.query({
|
|
91
105
|
query: t,
|
|
92
|
-
variables: { id:
|
|
106
|
+
variables: { id: m },
|
|
93
107
|
fetchPolicy: "network-only"
|
|
94
108
|
})).data?.getDataSink;
|
|
95
109
|
if (e) {
|
|
96
|
-
if ((e.description || "") !== (o.description || "") || e.ttl !== o.ttl || e.fieldMaskingEnabled !== (o.fieldMaskingEnabled ?? !1) || JSON.stringify(e.fieldMaskingRules) !== JSON.stringify(o.fieldMaskingRules) || JSON.stringify(e.refresh) !== JSON.stringify(o.refresh) || JSON.stringify(e.exports) !== JSON.stringify(o.exports) || JSON.stringify(e.alerts) !== JSON.stringify(o.alerts) || JSON.stringify(e.quota) !== JSON.stringify(o.quota) || JSON.stringify(e.metadata) !== JSON.stringify(o.metadata)) {
|
|
110
|
+
if (s && JSON.stringify(e.data) !== JSON.stringify(o.data) || (e.description || "") !== (o.description || "") || e.ttl !== o.ttl || e.fieldMaskingEnabled !== (o.fieldMaskingEnabled ?? !1) || JSON.stringify(e.fieldMaskingRules) !== JSON.stringify(o.fieldMaskingRules) || JSON.stringify(e.refresh) !== JSON.stringify(o.refresh) || JSON.stringify(e.exports) !== JSON.stringify(o.exports) || JSON.stringify(e.alerts) !== JSON.stringify(o.alerts) || JSON.stringify(e.quota) !== JSON.stringify(o.quota) || JSON.stringify(e.metadata) !== JSON.stringify(o.metadata)) {
|
|
97
111
|
let t = {
|
|
98
|
-
id:
|
|
112
|
+
id: m,
|
|
99
113
|
version: e.version,
|
|
100
114
|
name: e.name,
|
|
101
115
|
description: o.description || void 0,
|
|
102
|
-
|
|
116
|
+
...s && { data: u(o.data) },
|
|
117
|
+
ttl: o.ttl ?? void 0,
|
|
103
118
|
fieldMaskingEnabled: o.fieldMaskingEnabled ?? !1,
|
|
104
|
-
fieldMaskingRules:
|
|
105
|
-
refresh:
|
|
106
|
-
exports:
|
|
107
|
-
alerts:
|
|
108
|
-
quota:
|
|
109
|
-
metadata:
|
|
110
|
-
}, r = (await
|
|
119
|
+
fieldMaskingRules: u(o.fieldMaskingRules) || void 0,
|
|
120
|
+
refresh: l(o.refresh),
|
|
121
|
+
exports: u(o.exports) || void 0,
|
|
122
|
+
alerts: u(o.alerts) || void 0,
|
|
123
|
+
quota: u(o.quota) || void 0,
|
|
124
|
+
metadata: u(o.metadata) || void 0
|
|
125
|
+
}, r = (await b.mutate({
|
|
111
126
|
mutation: n,
|
|
112
127
|
variables: { input: t }
|
|
113
128
|
})).data?.updateDataSink;
|
|
114
|
-
r && (
|
|
129
|
+
r && (g = !0, _ = {
|
|
115
130
|
id: r.id,
|
|
116
131
|
name: r.name,
|
|
117
132
|
key: r.key
|
|
118
133
|
});
|
|
119
134
|
} else {
|
|
120
|
-
|
|
135
|
+
_ = {
|
|
121
136
|
id: e.id,
|
|
122
137
|
name: e.name,
|
|
123
138
|
key: e.key
|
|
124
139
|
};
|
|
125
140
|
let t = {
|
|
126
141
|
success: !0,
|
|
127
|
-
dataSink:
|
|
142
|
+
dataSink: _,
|
|
128
143
|
originalUpdated: !1,
|
|
129
|
-
originalDataSink:
|
|
144
|
+
originalDataSink: _,
|
|
130
145
|
alreadyExists: !0
|
|
131
146
|
};
|
|
132
|
-
return
|
|
147
|
+
return y(t), t;
|
|
133
148
|
}
|
|
134
149
|
let t = {
|
|
135
150
|
success: !0,
|
|
136
|
-
dataSink:
|
|
137
|
-
originalUpdated:
|
|
138
|
-
originalDataSink:
|
|
151
|
+
dataSink: _,
|
|
152
|
+
originalUpdated: g,
|
|
153
|
+
originalDataSink: _,
|
|
139
154
|
alreadyExists: !1
|
|
140
155
|
};
|
|
141
|
-
return
|
|
156
|
+
return y(t), t;
|
|
142
157
|
}
|
|
143
158
|
} catch (e) {
|
|
144
159
|
console.warn("Could not fetch original DataSink:", e);
|
|
145
160
|
}
|
|
146
|
-
let
|
|
161
|
+
let v = {
|
|
147
162
|
name: i.name || o.name || "Imported DataSink",
|
|
148
|
-
key: i.key || o.key,
|
|
163
|
+
key: i.key || o.key || "",
|
|
149
164
|
description: o.description || void 0,
|
|
150
|
-
config:
|
|
151
|
-
|
|
165
|
+
config: u(o.config) || void 0,
|
|
166
|
+
...s && { data: u(o.data) },
|
|
167
|
+
ttl: o.ttl ?? void 0,
|
|
152
168
|
fieldMaskingEnabled: o.fieldMaskingEnabled ?? !1,
|
|
153
|
-
fieldMaskingRules:
|
|
154
|
-
refresh:
|
|
155
|
-
exports:
|
|
156
|
-
alerts:
|
|
157
|
-
quota:
|
|
158
|
-
metadata:
|
|
159
|
-
},
|
|
169
|
+
fieldMaskingRules: u(o.fieldMaskingRules) || void 0,
|
|
170
|
+
refresh: l(o.refresh),
|
|
171
|
+
exports: u(o.exports) || void 0,
|
|
172
|
+
alerts: u(o.alerts) || void 0,
|
|
173
|
+
quota: u(o.quota) || void 0,
|
|
174
|
+
metadata: u(o.metadata) || void 0
|
|
175
|
+
}, x = (await b.mutate({
|
|
160
176
|
mutation: e,
|
|
161
|
-
variables: { input:
|
|
177
|
+
variables: { input: v }
|
|
162
178
|
})).data?.createDataSink;
|
|
163
|
-
if (
|
|
179
|
+
if (x) {
|
|
164
180
|
let e = {
|
|
165
181
|
success: !0,
|
|
166
182
|
dataSink: {
|
|
167
|
-
id:
|
|
168
|
-
name:
|
|
169
|
-
key:
|
|
183
|
+
id: x.id,
|
|
184
|
+
name: x.name,
|
|
185
|
+
key: x.key
|
|
170
186
|
},
|
|
171
187
|
originalUpdated: !1,
|
|
172
188
|
originalDataSink: void 0
|
|
173
189
|
};
|
|
174
|
-
return
|
|
190
|
+
return y(e), e;
|
|
175
191
|
}
|
|
176
192
|
throw Error("Import returned empty result");
|
|
177
193
|
} catch (e) {
|
|
178
194
|
let t = e instanceof Error ? e : /* @__PURE__ */ Error("Failed to import DataSink");
|
|
179
|
-
|
|
195
|
+
h(t);
|
|
180
196
|
let n = {
|
|
181
197
|
success: !1,
|
|
182
198
|
errorMessage: t.message
|
|
183
199
|
};
|
|
184
|
-
return
|
|
200
|
+
return y(n), n;
|
|
185
201
|
} finally {
|
|
186
|
-
|
|
202
|
+
p(!1);
|
|
187
203
|
}
|
|
188
|
-
}, [
|
|
204
|
+
}, [b]);
|
|
189
205
|
return {
|
|
190
|
-
loading:
|
|
191
|
-
error:
|
|
192
|
-
validationResult:
|
|
193
|
-
importResult:
|
|
194
|
-
validateImport:
|
|
195
|
-
importDataSink:
|
|
206
|
+
loading: s,
|
|
207
|
+
error: m,
|
|
208
|
+
validationResult: g,
|
|
209
|
+
importResult: v,
|
|
210
|
+
validateImport: x,
|
|
211
|
+
importDataSink: C,
|
|
196
212
|
importFromFile: r(async (e, t = {}) => {
|
|
197
213
|
try {
|
|
198
214
|
if (!e.name.endsWith(".json")) throw Error("Invalid file type. Please select a JSON file.");
|
|
@@ -202,18 +218,18 @@ function u() {
|
|
|
202
218
|
} catch {
|
|
203
219
|
throw Error("Invalid JSON format. Please select a valid export file.");
|
|
204
220
|
}
|
|
205
|
-
return await
|
|
221
|
+
return await C(n, t);
|
|
206
222
|
} catch (e) {
|
|
207
|
-
return
|
|
223
|
+
return h(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to import from file")), null;
|
|
208
224
|
}
|
|
209
|
-
}, [
|
|
210
|
-
extractDataSinkId:
|
|
225
|
+
}, [C]),
|
|
226
|
+
extractDataSinkId: S,
|
|
211
227
|
clearState: r(() => {
|
|
212
|
-
|
|
228
|
+
h(null), _(null), y(null);
|
|
213
229
|
}, [])
|
|
214
230
|
};
|
|
215
231
|
}
|
|
216
232
|
//#endregion
|
|
217
|
-
export {
|
|
233
|
+
export { p as default };
|
|
218
234
|
|
|
219
235
|
//# sourceMappingURL=useImportDataSink.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useImportDataSink.js","names":[],"sources":["../../../src/bigconsole/hooks/useImportDataSink.ts"],"sourcesContent":["/**\n * useImportDataSink Hook\n *\n * Provides DataSink import functionality with validation and conflict resolution.\n * Supports both creating new DataSinks and updating existing ones on re-import.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { CreateDataSinkDocument, UpdateDataSinkDocument, GetDataSinkDocument } from '../../generated/wspace-operations';\nimport type { DataSink, CreateDataSinkInput } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImportDataSinkInfo {\n name: string | null;\n description: string | null;\n key: string;\n status: string;\n setupState: string;\n exportedAt?: string;\n exportedFrom?: string;\n schemaVersion: string;\n}\n\nexport interface ImportDataSinkValidationError {\n code: string;\n message: string;\n path?: string;\n}\n\nexport interface ImportDataSinkValidationResult {\n isValid: boolean;\n dataSinkInfo: ImportDataSinkInfo | null;\n errors: ImportDataSinkValidationError[];\n}\n\nexport interface ImportDataSinkResult {\n success: boolean;\n dataSink?: {\n id: string;\n name: string | null;\n key: string;\n };\n errorMessage?: string;\n /** Whether the original DataSink was also updated */\n originalUpdated?: boolean;\n /** The original DataSink that was updated (if any) */\n originalDataSink?: {\n id: string;\n name: string | null;\n key: string;\n };\n /** Whether the entity already exists with no changes (show \"already exists\" popup) */\n alreadyExists?: boolean;\n}\n\nexport interface ImportDataSinkOptions {\n /** Override DataSink name (optional) */\n name?: string;\n /** Override DataSink key (optional - required to avoid conflicts) */\n key?: string;\n}\n\nexport interface UseImportDataSinkResult {\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n /** Last validation result */\n validationResult: ImportDataSinkValidationResult | null;\n /** Last import result */\n importResult: ImportDataSinkResult | null;\n /** Validate import content without importing */\n validateImport: (content: string) => ImportDataSinkValidationResult;\n /** Import DataSink from JSON content */\n importDataSink: (content: string, options?: ImportDataSinkOptions) => Promise<ImportDataSinkResult | null>;\n /** Import DataSink from file */\n importFromFile: (file: File, options?: ImportDataSinkOptions) => Promise<ImportDataSinkResult | null>;\n /** Extract DataSink ID from import content */\n extractDataSinkId: (content: string) => string | null;\n /** Clear state */\n clearState: () => void;\n}\n\n// ============================================================================\n// Helper: Read file as text\n// ============================================================================\n\nfunction readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n const result = e.target?.result;\n if (typeof result === 'string') {\n resolve(result);\n } else {\n reject(new Error('Failed to read file as text'));\n }\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n}\n\n/**\n * Recursively remove __typename fields from an object\n * This is necessary because exported data contains __typename fields\n * which are not accepted by GraphQL input types\n */\nfunction stripTypename<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => stripTypename(item)) as T;\n }\n\n if (typeof obj === 'object') {\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (key !== '__typename') {\n cleaned[key] = stripTypename(value);\n }\n }\n return cleaned as T;\n }\n\n return obj;\n}\n\n/**\n * Extract DataSink ID from imported JSON content\n * The ID is stored during export for re-import update support\n */\nfunction extractDataSinkIdFromContent(content: string): string | null {\n try {\n const parsed = JSON.parse(content);\n // Check both locations where ID might be stored\n return parsed.exportedFrom?.dataSinkId || parsed.dataSink?.id || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Validate DataSink export content\n */\nfunction validateDataSinkContent(content: string): ImportDataSinkValidationResult {\n const errors: ImportDataSinkValidationError[] = [];\n\n try {\n const parsed = JSON.parse(content);\n\n // Check schema version\n if (!parsed.schemaVersion) {\n errors.push({\n code: 'MISSING_SCHEMA_VERSION',\n message: 'Missing schema version',\n });\n }\n\n // Check dataSink object exists\n if (!parsed.dataSink) {\n errors.push({\n code: 'MISSING_DATASINK',\n message: 'Missing dataSink object in export file',\n });\n return { isValid: false, dataSinkInfo: null, errors };\n }\n\n const dataSink = parsed.dataSink;\n\n // Validate required fields\n if (!dataSink.key) {\n errors.push({\n code: 'MISSING_KEY',\n message: 'DataSink key is required',\n path: 'dataSink.key',\n });\n }\n\n const dataSinkInfo: ImportDataSinkInfo = {\n name: dataSink.name || null,\n description: dataSink.description || null,\n key: dataSink.key || '',\n status: dataSink.status || 'ready',\n setupState: dataSink.setupState || 'not_started',\n exportedAt: parsed.exportedAt,\n exportedFrom: parsed.exportedFrom?.dataSinkId,\n schemaVersion: parsed.schemaVersion || 'unknown',\n };\n\n return {\n isValid: errors.length === 0,\n dataSinkInfo,\n errors,\n };\n } catch (err) {\n return {\n isValid: false,\n dataSinkInfo: null,\n errors: [\n {\n code: 'INVALID_JSON',\n message: 'Invalid JSON format',\n },\n ],\n };\n }\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useImportDataSink(): UseImportDataSinkResult {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [validationResult, setValidationResult] = useState<ImportDataSinkValidationResult | null>(null);\n const [importResult, setImportResult] = useState<ImportDataSinkResult | null>(null);\n\n const apolloClient = useApolloClient();\n\n // Validate import content\n const validateImport = useCallback((content: string): ImportDataSinkValidationResult => {\n const result = validateDataSinkContent(content);\n setValidationResult(result);\n return result;\n }, []);\n\n // Extract DataSink ID from content\n const extractDataSinkId = useCallback((content: string): string | null => {\n return extractDataSinkIdFromContent(content);\n }, []);\n\n // Import DataSink from JSON content\n // Logic (DECLARATIVE - idempotent re-import):\n // 1. If original DataSink ID exists in JSON, check if original still exists\n // 2. If original exists → UPDATE it with the JSON data (no new copy created)\n // 3. If original doesn't exist → CREATE a new DataSink from the JSON\n // This ensures re-importing the same JSON is idempotent and updates the existing entity\n const importDataSink = useCallback(\n async (content: string, options: ImportDataSinkOptions = {}): Promise<ImportDataSinkResult | null> => {\n try {\n setLoading(true);\n setError(null);\n\n // Validate content first\n const validation = validateDataSinkContent(content);\n if (!validation.isValid || !validation.dataSinkInfo) {\n throw new Error(validation.errors[0]?.message || 'Invalid import content');\n }\n\n // Parse the content to get DataSink data\n const parsed = JSON.parse(content);\n const dataSinkData = parsed.dataSink;\n\n // Extract original DataSink ID from the JSON (if it was exported from an existing DataSink)\n const originalDataSinkId = extractDataSinkIdFromContent(content);\n let originalUpdated = false;\n let originalDataSinkInfo: { id: string; name: string | null; key: string } | undefined;\n\n // Step 1: Check if original DataSink exists and update it\n if (originalDataSinkId) {\n try {\n const getDataSinkResult = await apolloClient.query<{ getDataSink?: DataSink }>({\n query: GetDataSinkDocument,\n variables: { id: originalDataSinkId },\n fetchPolicy: 'network-only',\n });\n\n const existingDataSink = getDataSinkResult.data?.getDataSink;\n\n if (existingDataSink) {\n // Compare to detect changes (excluding name - we don't update the original's name)\n const hasChanges =\n (existingDataSink.description || '') !== (dataSinkData.description || '') ||\n existingDataSink.ttl !== dataSinkData.ttl ||\n existingDataSink.fieldMaskingEnabled !== (dataSinkData.fieldMaskingEnabled ?? false) ||\n JSON.stringify(existingDataSink.fieldMaskingRules) !== JSON.stringify(dataSinkData.fieldMaskingRules) ||\n JSON.stringify(existingDataSink.refresh) !== JSON.stringify(dataSinkData.refresh) ||\n JSON.stringify(existingDataSink.exports) !== JSON.stringify(dataSinkData.exports) ||\n JSON.stringify(existingDataSink.alerts) !== JSON.stringify(dataSinkData.alerts) ||\n JSON.stringify(existingDataSink.quota) !== JSON.stringify(dataSinkData.quota) ||\n JSON.stringify(existingDataSink.metadata) !== JSON.stringify(dataSinkData.metadata);\n\n // Update original if there are changes\n // Note: We intentionally do NOT update the name - the original keeps its name\n if (hasChanges) {\n const updateInput = {\n id: originalDataSinkId,\n version: existingDataSink.version,\n name: existingDataSink.name, // Keep original name\n description: dataSinkData.description || undefined,\n ttl: dataSinkData.ttl || undefined,\n fieldMaskingEnabled: dataSinkData.fieldMaskingEnabled ?? false,\n fieldMaskingRules: stripTypename(dataSinkData.fieldMaskingRules) || undefined,\n refresh: stripTypename(dataSinkData.refresh) || undefined,\n exports: stripTypename(dataSinkData.exports) || undefined,\n alerts: stripTypename(dataSinkData.alerts) || undefined,\n quota: stripTypename(dataSinkData.quota) || undefined,\n metadata: stripTypename(dataSinkData.metadata) || undefined,\n };\n\n const updateResult = await apolloClient.mutate<{ updateDataSink?: DataSink }>({\n mutation: UpdateDataSinkDocument,\n variables: { input: updateInput },\n });\n\n const updatedDataSink = updateResult.data?.updateDataSink;\n if (updatedDataSink) {\n originalUpdated = true;\n originalDataSinkInfo = {\n id: updatedDataSink.id,\n name: updatedDataSink.name,\n key: updatedDataSink.key,\n };\n }\n } else {\n // No changes - entity already exists with same data\n // Return with alreadyExists flag so UI can show \"already exists\" popup\n originalDataSinkInfo = {\n id: existingDataSink.id,\n name: existingDataSink.name,\n key: existingDataSink.key,\n };\n const alreadyExistsResult: ImportDataSinkResult = {\n success: true,\n dataSink: originalDataSinkInfo,\n originalUpdated: false,\n originalDataSink: originalDataSinkInfo,\n alreadyExists: true,\n };\n setImportResult(alreadyExistsResult);\n return alreadyExistsResult;\n }\n\n // If original was updated, return success with the updated DataSink info\n const finalResult: ImportDataSinkResult = {\n success: true,\n dataSink: originalDataSinkInfo,\n originalUpdated,\n originalDataSink: originalDataSinkInfo,\n alreadyExists: false,\n };\n setImportResult(finalResult);\n return finalResult;\n }\n // If original doesn't exist, continue to create a new DataSink\n } catch (fetchErr) {\n // Original DataSink fetch failed (might not exist), continue with creating new\n console.warn('Could not fetch original DataSink:', fetchErr);\n }\n }\n\n // Step 2: Create a NEW DataSink only if original doesn't exist\n // (This happens when importing for the first time, or if original was deleted)\n // Use stripTypename to remove __typename fields from nested objects\n const createInput: CreateDataSinkInput = {\n name: options.name || dataSinkData.name || 'Imported DataSink',\n key: options.key || dataSinkData.key,\n description: dataSinkData.description || undefined,\n config: stripTypename(dataSinkData.config) || undefined,\n ttl: dataSinkData.ttl || undefined,\n fieldMaskingEnabled: dataSinkData.fieldMaskingEnabled ?? false,\n fieldMaskingRules: stripTypename(dataSinkData.fieldMaskingRules) || undefined,\n refresh: stripTypename(dataSinkData.refresh) || undefined,\n exports: stripTypename(dataSinkData.exports) || undefined,\n alerts: stripTypename(dataSinkData.alerts) || undefined,\n quota: stripTypename(dataSinkData.quota) || undefined,\n metadata: stripTypename(dataSinkData.metadata) || undefined,\n };\n\n const result = await apolloClient.mutate<{ createDataSink?: DataSink }>({\n mutation: CreateDataSinkDocument,\n variables: { input: createInput },\n });\n\n const createdDataSink = result.data?.createDataSink;\n\n if (createdDataSink) {\n const finalResult: ImportDataSinkResult = {\n success: true,\n dataSink: {\n id: createdDataSink.id,\n name: createdDataSink.name,\n key: createdDataSink.key,\n },\n originalUpdated: false,\n originalDataSink: undefined,\n };\n setImportResult(finalResult);\n return finalResult;\n }\n\n throw new Error('Import returned empty result');\n } catch (err) {\n const importError = err instanceof Error ? err : new Error('Failed to import DataSink');\n setError(importError);\n const failResult: ImportDataSinkResult = {\n success: false,\n errorMessage: importError.message,\n };\n setImportResult(failResult);\n return failResult;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Import DataSink from file\n const importFromFile = useCallback(\n async (file: File, options: ImportDataSinkOptions = {}): Promise<ImportDataSinkResult | null> => {\n try {\n // Validate file type\n if (!file.name.endsWith('.json')) {\n throw new Error('Invalid file type. Please select a JSON file.');\n }\n\n // Read file content\n const content = await readFileAsText(file);\n\n // Validate JSON format\n try {\n JSON.parse(content);\n } catch {\n throw new Error('Invalid JSON format. Please select a valid export file.');\n }\n\n // Perform import\n return await importDataSink(content, options);\n } catch (err) {\n const fileError = err instanceof Error ? err : new Error('Failed to import from file');\n setError(fileError);\n return null;\n }\n },\n [importDataSink]\n );\n\n // Clear state\n const clearState = useCallback(() => {\n setError(null);\n setValidationResult(null);\n setImportResult(null);\n }, []);\n\n return {\n loading,\n error,\n validationResult,\n importResult,\n validateImport,\n importDataSink,\n importFromFile,\n extractDataSinkId,\n clearState,\n };\n}\n\nexport default useImportDataSink;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useImportDataSink.js","names":[],"sources":["../../../src/bigconsole/hooks/useImportDataSink.ts"],"sourcesContent":["/**\n * useImportDataSink Hook\n *\n * Provides DataSink import functionality with validation and conflict resolution.\n * Supports both creating new DataSinks and updating existing ones on re-import.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { CreateDataSinkDocument, UpdateDataSinkDocument, GetDataSinkDocument } from '../../generated/wspace-operations';\nimport type { DataSink, CreateDataSinkInput } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImportDataSinkInfo {\n name: string | null;\n description: string | null;\n key: string;\n status: string;\n setupState: string;\n exportedAt?: string;\n exportedFrom?: string;\n schemaVersion: string;\n}\n\nexport interface ImportDataSinkValidationError {\n code: string;\n message: string;\n path?: string;\n}\n\nexport interface ImportDataSinkValidationResult {\n isValid: boolean;\n dataSinkInfo: ImportDataSinkInfo | null;\n errors: ImportDataSinkValidationError[];\n}\n\nexport interface ImportDataSinkResult {\n success: boolean;\n dataSink?: {\n id: string;\n name: string | null;\n key: string;\n };\n errorMessage?: string;\n /** Whether the original DataSink was also updated */\n originalUpdated?: boolean;\n /** The original DataSink that was updated (if any) */\n originalDataSink?: {\n id: string;\n name: string | null;\n key: string;\n };\n /** Whether the entity already exists with no changes (show \"already exists\" popup) */\n alreadyExists?: boolean;\n}\n\nexport interface ImportDataSinkOptions {\n /** Override DataSink name (optional) */\n name?: string;\n /** Override DataSink key (optional - required to avoid conflicts) */\n key?: string;\n}\n\nexport interface UseImportDataSinkResult {\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n /** Last validation result */\n validationResult: ImportDataSinkValidationResult | null;\n /** Last import result */\n importResult: ImportDataSinkResult | null;\n /** Validate import content without importing */\n validateImport: (content: string) => ImportDataSinkValidationResult;\n /** Import DataSink from JSON content */\n importDataSink: (content: string, options?: ImportDataSinkOptions) => Promise<ImportDataSinkResult | null>;\n /** Import DataSink from file */\n importFromFile: (file: File, options?: ImportDataSinkOptions) => Promise<ImportDataSinkResult | null>;\n /** Extract DataSink ID from import content */\n extractDataSinkId: (content: string) => string | null;\n /** Clear state */\n clearState: () => void;\n}\n\ninterface ImportedDataSinkPayload {\n id?: string;\n name?: string | null;\n description?: string | null;\n key?: string;\n config?: Record<string, unknown> | null;\n data?: Record<string, unknown>;\n ttl?: number;\n fieldMaskingEnabled?: boolean;\n fieldMaskingRules?: Record<string, unknown> | null;\n status?: string;\n setupState?: string;\n refresh?: DataSink['refresh'];\n exports?: DataSink['exports'];\n alerts?: DataSink['alerts'];\n quota?: DataSink['quota'];\n metadata?: Record<string, unknown> | null;\n}\n\ninterface ParsedDataSinkExport {\n schemaVersion?: string;\n exportedAt?: string;\n exportedFrom?: {\n dataSinkId?: string;\n };\n dataSink?: ImportedDataSinkPayload;\n}\n\n// ============================================================================\n// Helper: Read file as text\n// ============================================================================\n\nfunction readFileAsText(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n const result = e.target?.result;\n if (typeof result === 'string') {\n resolve(result);\n } else {\n reject(new Error('Failed to read file as text'));\n }\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction resolveDataSinkPayload(\n parsed: ParsedDataSinkExport | ImportedDataSinkPayload\n): ImportedDataSinkPayload | null {\n const wrapped = parsed as ParsedDataSinkExport;\n if (isRecord(wrapped.dataSink)) {\n return wrapped.dataSink as ImportedDataSinkPayload;\n }\n\n // Backward-compatible import for raw DataSink JSON objects.\n if (typeof (parsed as ImportedDataSinkPayload).key === 'string') {\n return parsed as ImportedDataSinkPayload;\n }\n\n return null;\n}\n\nfunction normalizeRefreshInput(refresh: DataSink['refresh'] | undefined): CreateDataSinkInput['refresh'] {\n if (!refresh) {\n return undefined;\n }\n\n return {\n type: refresh.type,\n ...(refresh.schedule ? { schedule: stripTypename(refresh.schedule) } : {}),\n };\n}\n\n/**\n * Recursively remove __typename fields from an object\n * This is necessary because exported data contains __typename fields\n * which are not accepted by GraphQL input types\n */\nfunction stripTypename<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => stripTypename(item)) as T;\n }\n\n if (typeof obj === 'object') {\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (key !== '__typename') {\n cleaned[key] = stripTypename(value);\n }\n }\n return cleaned as T;\n }\n\n return obj;\n}\n\n/**\n * Extract DataSink ID from imported JSON content\n * The ID is stored during export for re-import update support\n */\nfunction extractDataSinkIdFromContent(content: string): string | null {\n try {\n const parsed = JSON.parse(content) as ParsedDataSinkExport | ImportedDataSinkPayload;\n const wrapped = parsed as ParsedDataSinkExport;\n // Check both locations where ID might be stored\n return wrapped.exportedFrom?.dataSinkId || wrapped.dataSink?.id || (parsed as ImportedDataSinkPayload).id || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Validate DataSink export content\n */\nfunction validateDataSinkContent(content: string): ImportDataSinkValidationResult {\n const errors: ImportDataSinkValidationError[] = [];\n\n try {\n const parsed = JSON.parse(content) as ParsedDataSinkExport | ImportedDataSinkPayload;\n const wrapped = parsed as ParsedDataSinkExport;\n const dataSink = resolveDataSinkPayload(parsed);\n\n // Check schema version\n if (!wrapped.schemaVersion && !dataSink) {\n errors.push({\n code: 'MISSING_SCHEMA_VERSION',\n message: 'Missing schema version',\n });\n }\n\n // Check dataSink object exists\n if (!dataSink) {\n errors.push({\n code: 'MISSING_DATASINK',\n message: 'This file is not a BigConsole DataSink export. Expected a top-level dataSink object.',\n });\n return { isValid: false, dataSinkInfo: null, errors };\n }\n\n // Validate required fields\n if (!dataSink.key) {\n errors.push({\n code: 'MISSING_KEY',\n message: 'DataSink key is required',\n path: 'dataSink.key',\n });\n }\n\n const dataSinkInfo: ImportDataSinkInfo = {\n name: dataSink.name || null,\n description: dataSink.description || null,\n key: dataSink.key || '',\n status: dataSink.status || 'ready',\n setupState: dataSink.setupState || 'not_started',\n exportedAt: wrapped.exportedAt,\n exportedFrom: wrapped.exportedFrom?.dataSinkId,\n schemaVersion: wrapped.schemaVersion || 'legacy',\n };\n\n return {\n isValid: errors.length === 0,\n dataSinkInfo,\n errors,\n };\n } catch {\n return {\n isValid: false,\n dataSinkInfo: null,\n errors: [\n {\n code: 'INVALID_JSON',\n message: 'Invalid JSON format',\n },\n ],\n };\n }\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useImportDataSink(): UseImportDataSinkResult {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [validationResult, setValidationResult] = useState<ImportDataSinkValidationResult | null>(null);\n const [importResult, setImportResult] = useState<ImportDataSinkResult | null>(null);\n\n const apolloClient = useApolloClient();\n\n // Validate import content\n const validateImport = useCallback((content: string): ImportDataSinkValidationResult => {\n const result = validateDataSinkContent(content);\n setValidationResult(result);\n return result;\n }, []);\n\n // Extract DataSink ID from content\n const extractDataSinkId = useCallback((content: string): string | null => {\n return extractDataSinkIdFromContent(content);\n }, []);\n\n // Import DataSink from JSON content\n // Logic (DECLARATIVE - idempotent re-import):\n // 1. If original DataSink ID exists in JSON, check if original still exists\n // 2. If original exists → UPDATE it with the JSON data (no new copy created)\n // 3. If original doesn't exist → CREATE a new DataSink from the JSON\n // This ensures re-importing the same JSON is idempotent and updates the existing entity\n const importDataSink = useCallback(\n async (content: string, options: ImportDataSinkOptions = {}): Promise<ImportDataSinkResult | null> => {\n try {\n setLoading(true);\n setError(null);\n\n // Validate content first\n const validation = validateDataSinkContent(content);\n if (!validation.isValid || !validation.dataSinkInfo) {\n throw new Error(validation.errors[0]?.message || 'Invalid import content');\n }\n\n // Parse the content to get DataSink data\n const parsed = JSON.parse(content) as ParsedDataSinkExport | ImportedDataSinkPayload;\n const dataSinkData = resolveDataSinkPayload(parsed);\n if (!dataSinkData) {\n throw new Error('Missing DataSink payload in import content');\n }\n const hasImportedData = Object.prototype.hasOwnProperty.call(dataSinkData, 'data');\n\n // Extract original DataSink ID from the JSON (if it was exported from an existing DataSink)\n const originalDataSinkId = extractDataSinkIdFromContent(content);\n let originalUpdated = false;\n let originalDataSinkInfo: { id: string; name: string | null; key: string } | undefined;\n\n // Step 1: Check if original DataSink exists and update it\n if (originalDataSinkId) {\n try {\n const getDataSinkResult = await apolloClient.query<{ getDataSink?: DataSink }>({\n query: GetDataSinkDocument,\n variables: { id: originalDataSinkId },\n fetchPolicy: 'network-only',\n });\n\n const existingDataSink = getDataSinkResult.data?.getDataSink;\n\n if (existingDataSink) {\n // Compare to detect changes (excluding name - we don't update the original's name)\n const hasChanges =\n (hasImportedData && JSON.stringify(existingDataSink.data) !== JSON.stringify(dataSinkData.data)) ||\n (existingDataSink.description || '') !== (dataSinkData.description || '') ||\n existingDataSink.ttl !== dataSinkData.ttl ||\n existingDataSink.fieldMaskingEnabled !== (dataSinkData.fieldMaskingEnabled ?? false) ||\n JSON.stringify(existingDataSink.fieldMaskingRules) !== JSON.stringify(dataSinkData.fieldMaskingRules) ||\n JSON.stringify(existingDataSink.refresh) !== JSON.stringify(dataSinkData.refresh) ||\n JSON.stringify(existingDataSink.exports) !== JSON.stringify(dataSinkData.exports) ||\n JSON.stringify(existingDataSink.alerts) !== JSON.stringify(dataSinkData.alerts) ||\n JSON.stringify(existingDataSink.quota) !== JSON.stringify(dataSinkData.quota) ||\n JSON.stringify(existingDataSink.metadata) !== JSON.stringify(dataSinkData.metadata);\n\n // Update original if there are changes\n // Note: We intentionally do NOT update the name - the original keeps its name\n if (hasChanges) {\n const updateInput = {\n id: originalDataSinkId,\n version: existingDataSink.version,\n name: existingDataSink.name, // Keep original name\n description: dataSinkData.description || undefined,\n ...(hasImportedData && { data: stripTypename(dataSinkData.data) }),\n ttl: dataSinkData.ttl ?? undefined,\n fieldMaskingEnabled: dataSinkData.fieldMaskingEnabled ?? false,\n fieldMaskingRules: stripTypename(dataSinkData.fieldMaskingRules) || undefined,\n refresh: normalizeRefreshInput(dataSinkData.refresh),\n exports: stripTypename(dataSinkData.exports) || undefined,\n alerts: stripTypename(dataSinkData.alerts) || undefined,\n quota: stripTypename(dataSinkData.quota) || undefined,\n metadata: stripTypename(dataSinkData.metadata) || undefined,\n };\n\n const updateResult = await apolloClient.mutate<{ updateDataSink?: DataSink }>({\n mutation: UpdateDataSinkDocument,\n variables: { input: updateInput },\n });\n\n const updatedDataSink = updateResult.data?.updateDataSink;\n if (updatedDataSink) {\n originalUpdated = true;\n originalDataSinkInfo = {\n id: updatedDataSink.id,\n name: updatedDataSink.name,\n key: updatedDataSink.key,\n };\n }\n } else {\n // No changes - entity already exists with same data\n // Return with alreadyExists flag so UI can show \"already exists\" popup\n originalDataSinkInfo = {\n id: existingDataSink.id,\n name: existingDataSink.name,\n key: existingDataSink.key,\n };\n const alreadyExistsResult: ImportDataSinkResult = {\n success: true,\n dataSink: originalDataSinkInfo,\n originalUpdated: false,\n originalDataSink: originalDataSinkInfo,\n alreadyExists: true,\n };\n setImportResult(alreadyExistsResult);\n return alreadyExistsResult;\n }\n\n // If original was updated, return success with the updated DataSink info\n const finalResult: ImportDataSinkResult = {\n success: true,\n dataSink: originalDataSinkInfo,\n originalUpdated,\n originalDataSink: originalDataSinkInfo,\n alreadyExists: false,\n };\n setImportResult(finalResult);\n return finalResult;\n }\n // If original doesn't exist, continue to create a new DataSink\n } catch (fetchErr) {\n // Original DataSink fetch failed (might not exist), continue with creating new\n console.warn('Could not fetch original DataSink:', fetchErr);\n }\n }\n\n // Step 2: Create a NEW DataSink only if original doesn't exist\n // (This happens when importing for the first time, or if original was deleted)\n // Use stripTypename to remove __typename fields from nested objects\n const createInput: CreateDataSinkInput = {\n name: options.name || dataSinkData.name || 'Imported DataSink',\n key: options.key || dataSinkData.key || '',\n description: dataSinkData.description || undefined,\n config: stripTypename(dataSinkData.config) || undefined,\n ...(hasImportedData && { data: stripTypename(dataSinkData.data) }),\n ttl: dataSinkData.ttl ?? undefined,\n fieldMaskingEnabled: dataSinkData.fieldMaskingEnabled ?? false,\n fieldMaskingRules: stripTypename(dataSinkData.fieldMaskingRules) || undefined,\n refresh: normalizeRefreshInput(dataSinkData.refresh),\n exports: stripTypename(dataSinkData.exports) || undefined,\n alerts: stripTypename(dataSinkData.alerts) || undefined,\n quota: stripTypename(dataSinkData.quota) || undefined,\n metadata: stripTypename(dataSinkData.metadata) || undefined,\n };\n\n const result = await apolloClient.mutate<{ createDataSink?: DataSink }>({\n mutation: CreateDataSinkDocument,\n variables: { input: createInput },\n });\n\n const createdDataSink = result.data?.createDataSink;\n\n if (createdDataSink) {\n const finalResult: ImportDataSinkResult = {\n success: true,\n dataSink: {\n id: createdDataSink.id,\n name: createdDataSink.name,\n key: createdDataSink.key,\n },\n originalUpdated: false,\n originalDataSink: undefined,\n };\n setImportResult(finalResult);\n return finalResult;\n }\n\n throw new Error('Import returned empty result');\n } catch (err) {\n const importError = err instanceof Error ? err : new Error('Failed to import DataSink');\n setError(importError);\n const failResult: ImportDataSinkResult = {\n success: false,\n errorMessage: importError.message,\n };\n setImportResult(failResult);\n return failResult;\n } finally {\n setLoading(false);\n }\n },\n [apolloClient]\n );\n\n // Import DataSink from file\n const importFromFile = useCallback(\n async (file: File, options: ImportDataSinkOptions = {}): Promise<ImportDataSinkResult | null> => {\n try {\n // Validate file type\n if (!file.name.endsWith('.json')) {\n throw new Error('Invalid file type. Please select a JSON file.');\n }\n\n // Read file content\n const content = await readFileAsText(file);\n\n // Validate JSON format\n try {\n JSON.parse(content);\n } catch {\n throw new Error('Invalid JSON format. Please select a valid export file.');\n }\n\n // Perform import\n return await importDataSink(content, options);\n } catch (err) {\n const fileError = err instanceof Error ? err : new Error('Failed to import from file');\n setError(fileError);\n return null;\n }\n },\n [importDataSink]\n );\n\n // Clear state\n const clearState = useCallback(() => {\n setError(null);\n setValidationResult(null);\n setImportResult(null);\n }, []);\n\n return {\n loading,\n error,\n validationResult,\n importResult,\n validateImport,\n importDataSink,\n importFromFile,\n extractDataSinkId,\n clearState,\n };\n}\n\nexport default useImportDataSink;\n"],"mappings":"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"}
|
|
@@ -175,13 +175,17 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
175
175
|
style: {
|
|
176
176
|
display: "flex",
|
|
177
177
|
alignItems: "center",
|
|
178
|
-
justifyContent: "space-between"
|
|
178
|
+
justifyContent: "space-between",
|
|
179
|
+
gap: "var(--space-formGap)",
|
|
180
|
+
flexWrap: "wrap"
|
|
179
181
|
},
|
|
180
182
|
children: [/* @__PURE__ */ b("div", {
|
|
181
183
|
style: {
|
|
182
184
|
display: "flex",
|
|
183
185
|
alignItems: "center",
|
|
184
|
-
gap: "var(--space-formGap)"
|
|
186
|
+
gap: "var(--space-formGap)",
|
|
187
|
+
flex: "1 1 280px",
|
|
188
|
+
minWidth: 0
|
|
185
189
|
},
|
|
186
190
|
children: [/* @__PURE__ */ y("div", {
|
|
187
191
|
style: {
|
|
@@ -198,22 +202,25 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
198
202
|
width: "var(--size-icon-lg)",
|
|
199
203
|
color: "var(--color-action-primary-text)"
|
|
200
204
|
} })
|
|
201
|
-
}), /* @__PURE__ */ b("div", {
|
|
202
|
-
style: {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
205
|
+
}), /* @__PURE__ */ b("div", {
|
|
206
|
+
style: { minWidth: 0 },
|
|
207
|
+
children: [/* @__PURE__ */ y("h1", {
|
|
208
|
+
style: {
|
|
209
|
+
fontSize: "var(--font-size-heading-h4)",
|
|
210
|
+
fontWeight: "var(--font-weight-bold)",
|
|
211
|
+
margin: 0,
|
|
212
|
+
color: "var(--color-text-primary)"
|
|
213
|
+
},
|
|
214
|
+
children: /* @__PURE__ */ y(Te, { children: C("bigconsole.dataSinks.title", "Data Sinks") })
|
|
215
|
+
}), /* @__PURE__ */ y("p", {
|
|
216
|
+
style: {
|
|
217
|
+
fontSize: "var(--font-size-body-sm)",
|
|
218
|
+
color: "var(--color-text-secondary)",
|
|
219
|
+
margin: 0
|
|
220
|
+
},
|
|
221
|
+
children: C("bigconsole.dataSinks.subtitle", "Manage pre-processed data from FluidGrids workflows")
|
|
222
|
+
})]
|
|
223
|
+
})]
|
|
217
224
|
}), /* @__PURE__ */ y(Se, {
|
|
218
225
|
primary: {
|
|
219
226
|
label: C("bigconsole.dataSinks.actions.create", "Create Data Sink"),
|
|
@@ -287,7 +294,8 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
287
294
|
style: {
|
|
288
295
|
position: "relative",
|
|
289
296
|
maxWidth: "400px",
|
|
290
|
-
|
|
297
|
+
minWidth: "min(100%, 240px)",
|
|
298
|
+
flex: "1 1 240px"
|
|
291
299
|
},
|
|
292
300
|
children: [/* @__PURE__ */ y(me, { style: {
|
|
293
301
|
position: "absolute",
|
|
@@ -312,7 +320,7 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
312
320
|
value: k || "all",
|
|
313
321
|
onValueChange: (e) => M(e === "all" ? null : e),
|
|
314
322
|
children: [/* @__PURE__ */ y(g, {
|
|
315
|
-
style: { width: "150px" },
|
|
323
|
+
style: { width: "min(100%, 150px)" },
|
|
316
324
|
children: /* @__PURE__ */ y(_, { placeholder: C("bigconsole.dataSinks.filters.status.placeholder", "All Statuses") })
|
|
317
325
|
}), /* @__PURE__ */ b(m, { children: [
|
|
318
326
|
/* @__PURE__ */ y(h, {
|
|
@@ -341,7 +349,7 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
341
349
|
value: A === null ? "all" : A ? "true" : "false",
|
|
342
350
|
onValueChange: (e) => N(e === "all" ? null : e === "true"),
|
|
343
351
|
children: [/* @__PURE__ */ y(g, {
|
|
344
|
-
style: { width: "130px" },
|
|
352
|
+
style: { width: "min(100%, 130px)" },
|
|
345
353
|
children: /* @__PURE__ */ y(_, { placeholder: C("bigconsole.dataSinks.filters.active.placeholder", "All") })
|
|
346
354
|
}), /* @__PURE__ */ b(m, { children: [
|
|
347
355
|
/* @__PURE__ */ y(h, {
|
|
@@ -476,7 +484,7 @@ var x = "bigconsole-datasinks-view-mode", Ae = (e) => e.setupState === "complete
|
|
|
476
484
|
J.length > 0 && D === "grid" && /* @__PURE__ */ y("div", {
|
|
477
485
|
style: {
|
|
478
486
|
display: "grid",
|
|
479
|
-
gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
|
|
487
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(min(100%, 320px), 1fr))",
|
|
480
488
|
gap: "var(--space-formGap)"
|
|
481
489
|
},
|
|
482
490
|
children: J.map((e) => /* @__PURE__ */ y(ne, {
|