@elixir-cloud/trs-filer 2.0.0-alpha.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.
Files changed (36) hide show
  1. package/LICENSE +133 -0
  2. package/README.md +48 -0
  3. package/dist/chunks/chunk.3WU6NPWM.js +1 -0
  4. package/dist/chunks/chunk.5A4EA5NE.js +1803 -0
  5. package/dist/chunks/chunk.C5TPOPDW.js +10 -0
  6. package/dist/chunks/chunk.Q5GOJN3Z.js +849 -0
  7. package/dist/chunks/chunk.ULOGEPYW.js +23 -0
  8. package/dist/components/index.d.ts +1 -0
  9. package/dist/components/index.js +4 -0
  10. package/dist/components/tool-create/index.d.ts +8 -0
  11. package/dist/components/tool-create/index.js +3 -0
  12. package/dist/components/tool-create/tool-create.d.ts +75 -0
  13. package/dist/components/tool-create/tool-create.js +2 -0
  14. package/dist/components/tool-create/tw-styles.d.ts +1 -0
  15. package/dist/components/tool-create/tw-styles.js +1 -0
  16. package/dist/custom-elements.json +832 -0
  17. package/dist/events/ecc-tool-create-error.d.ts +6 -0
  18. package/dist/events/ecc-tool-create-success.d.ts +6 -0
  19. package/dist/events/ecc-tool-create-validation-error.d.ts +6 -0
  20. package/dist/events/ecc-tool-created.d.ts +6 -0
  21. package/dist/events/ecc-tools-change.d.ts +6 -0
  22. package/dist/events/ecc-tools-click.d.ts +6 -0
  23. package/dist/events/index.d.ts +6 -0
  24. package/dist/global.d.ts +1 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +4 -0
  27. package/dist/providers/index.d.ts +4 -0
  28. package/dist/providers/rest-trs-filer-provider.d.ts +25 -0
  29. package/dist/providers/trs-filer-provider.d.ts +136 -0
  30. package/dist/react/ecc-client-elixir-trs-tool-create/index.d.ts +29 -0
  31. package/dist/react/ecc-client-elixir-trs-tool-create/index.js +3 -0
  32. package/dist/react/index.d.ts +1 -0
  33. package/dist/react/index.js +3 -0
  34. package/dist/vscode.html-custom-data.json +17 -0
  35. package/dist/web-types.json +129 -0
  36. package/package.json +79 -0
@@ -0,0 +1,1803 @@
1
+ import { ComponentStyles, __decorateClass, __spreadProps, __spreadValues } from './chunk.Q5GOJN3Z.js';
2
+ import { css, LitElement, html } from 'lit';
3
+ import { property, state } from 'lit/decorators.js';
4
+ import '@elixir-cloud/design/components/button/index.js';
5
+ import '@elixir-cloud/design/components/input/index.js';
6
+ import '@elixir-cloud/design/components/select/index.js';
7
+ import '@elixir-cloud/design/components/multi-select/index.js';
8
+ import '@elixir-cloud/design/components/label/index.js';
9
+ import '@elixir-cloud/design/components/textarea/index.js';
10
+ import '@elixir-cloud/design/components/badge/index.js';
11
+ import '@elixir-cloud/design/components/code/index.js';
12
+ import '@elixir-cloud/design/components/tabs/index.js';
13
+ import '@elixir-cloud/design/components/separator/index.js';
14
+ import '@elixir-cloud/design/components/checkbox/index.js';
15
+ import '@elixir-cloud/design/components/collapsible/index.js';
16
+ import JSZip from '@progress/jszip-esm';
17
+
18
+ var GlobalStyles = css`
19
+ :host {
20
+ --background: var(--ecc-background, oklch(1 0 0));
21
+ --foreground: var(--ecc-foreground, oklch(0.145 0 0));
22
+ --card: var(--ecc-card, oklch(1 0 0));
23
+ --card-foreground: var(--ecc-card-foreground, oklch(0.145 0 0));
24
+ --popover: var(--ecc-popover, oklch(1 0 0));
25
+ --popover-foreground: var(--ecc-popover-foreground, oklch(0.145 0 0));
26
+ --primary: var(--ecc-primary, oklch(0.205 0 0));
27
+ --primary-foreground: var(--ecc-primary-foreground, oklch(0.985 0 0));
28
+ --secondary: var(--ecc-secondary, oklch(0.97 0 0));
29
+ --secondary-foreground: var(--ecc-secondary-foreground, oklch(0.205 0 0));
30
+ --muted: var(--ecc-muted, oklch(0.97 0 0));
31
+ --muted-foreground: var(--ecc-muted-foreground, oklch(0.556 0 0));
32
+ --accent: var(--ecc-accent, oklch(0.97 0 0));
33
+ --accent-foreground: var(--ecc-accent-foreground, oklch(0.205 0 0));
34
+ --destructive: var(--ecc-destructive, oklch(0.577 0.245 27.325));
35
+ --destructive-foreground: var(
36
+ --ecc-destructive-foreground,
37
+ oklch(0.985 0 0)
38
+ );
39
+ --border: var(--ecc-border, oklch(0.922 0 0));
40
+ --input: var(--ecc-input, oklch(0.922 0 0));
41
+ --ring: var(--ecc-ring, oklch(0.708 0 0));
42
+ --chart-1: var(--ecc-chart-1, oklch(0.646 0.222 41.116));
43
+ --chart-2: var(--ecc-chart-2, oklch(0.6 0.118 184.704));
44
+ --chart-3: var(--ecc-chart-3, oklch(0.398 0.07 227.392));
45
+ --chart-4: var(--ecc-chart-4, oklch(0.828 0.189 84.429));
46
+ --chart-5: var(--ecc-chart-5, oklch(0.769 0.188 70.08));
47
+ --radius: var(--ecc-radius, 0.625rem);
48
+ --sidebar: var(--ecc-sidebar, oklch(0.985 0 0));
49
+ --sidebar-foreground: var(--ecc-sidebar-foreground, oklch(0.145 0 0));
50
+ --sidebar-primary: var(--ecc-sidebar-primary, oklch(0.205 0 0));
51
+ --sidebar-primary-foreground: var(
52
+ --ecc-sidebar-primary-foreground,
53
+ oklch(0.985 0 0)
54
+ );
55
+ --sidebar-accent: var(--ecc-sidebar-accent, oklch(0.97 0 0));
56
+ --sidebar-accent-foreground: var(
57
+ --ecc-sidebar-accent-foreground,
58
+ oklch(0.205 0 0)
59
+ );
60
+ --sidebar-border: var(--ecc-sidebar-border, oklch(0.922 0 0));
61
+ --sidebar-ring: var(--ecc-sidebar-ring, oklch(0.708 0 0));
62
+ }
63
+
64
+ :host([dark]),
65
+ :host-context([dark]),
66
+ :host-context(.dark) {
67
+ --background: var(--ecc-background, oklch(0.145 0 0));
68
+ --foreground: var(--ecc-foreground, oklch(0.985 0 0));
69
+ --card: var(--ecc-card, oklch(0.145 0 0));
70
+ --card-foreground: var(--ecc-card-foreground, oklch(0.985 0 0));
71
+ --popover: var(--ecc-popover, oklch(0.145 0 0));
72
+ --popover-foreground: var(--ecc-popover-foreground, oklch(0.985 0 0));
73
+ --primary: var(--ecc-primary, oklch(0.985 0 0));
74
+ --primary-foreground: var(--ecc-primary-foreground, oklch(0.205 0 0));
75
+ --secondary: var(--ecc-secondary, oklch(0.269 0 0));
76
+ --secondary-foreground: var(--ecc-secondary-foreground, oklch(0.985 0 0));
77
+ --muted: var(--ecc-muted, oklch(0.269 0 0));
78
+ --muted-foreground: var(--ecc-muted-foreground, oklch(0.708 0 0));
79
+ --accent: var(--ecc-accent, oklch(0.269 0 0));
80
+ --accent-foreground: var(--ecc-accent-foreground, oklch(0.985 0 0));
81
+ --destructive: var(--ecc-destructive, oklch(0.396 0.141 25.723));
82
+ --destructive-foreground: var(
83
+ --ecc-destructive-foreground,
84
+ oklch(0.637 0.237 25.331)
85
+ );
86
+ --border: var(--ecc-border, oklch(0.269 0 0));
87
+ --input: var(--ecc-input, oklch(0.269 0 0));
88
+ --ring: var(--ecc-ring, oklch(0.439 0 0));
89
+ --chart-1: var(--ecc-chart-1, oklch(0.488 0.243 264.376));
90
+ --chart-2: var(--ecc-chart-2, oklch(0.696 0.17 162.48));
91
+ --chart-3: var(--ecc-chart-3, oklch(0.769 0.188 70.08));
92
+ --chart-4: var(--ecc-chart-4, oklch(0.627 0.265 303.9));
93
+ --chart-5: var(--ecc-chart-5, oklch(0.645 0.246 16.439));
94
+ --sidebar: var(--ecc-sidebar, oklch(0.205 0 0));
95
+ --sidebar-foreground: var(--ecc-sidebar-foreground, oklch(0.985 0 0));
96
+ --sidebar-primary: var(--ecc-sidebar-primary, oklch(0.488 0.243 264.376));
97
+ --sidebar-primary-foreground: var(
98
+ --ecc-sidebar-primary-foreground,
99
+ oklch(0.985 0 0)
100
+ );
101
+ --sidebar-accent: var(--ecc-sidebar-accent, oklch(0.269 0 0));
102
+ --sidebar-accent-foreground: var(
103
+ --ecc-sidebar-accent-foreground,
104
+ oklch(0.985 0 0)
105
+ );
106
+ --sidebar-border: var(--ecc-sidebar-border, oklch(0.269 0 0));
107
+ --sidebar-ring: var(--ecc-sidebar-ring, oklch(0.439 0 0));
108
+ }
109
+ `;
110
+
111
+ // src/providers/rest-trs-filer-provider.ts
112
+ var RestTrsFilerProvider = class {
113
+ constructor(baseUrl) {
114
+ this.baseUrl = baseUrl;
115
+ }
116
+ async getToolClasses() {
117
+ const url = `${this.baseUrl}/toolClasses`;
118
+ const response = await fetch(url);
119
+ if (!response.ok) {
120
+ throw new Error(`Failed to fetch tool classes: ${response.statusText}`);
121
+ }
122
+ return response.json();
123
+ }
124
+ async getToolsList(limit, offset, filters, query) {
125
+ let url = `${this.baseUrl}/tools?${limit ? `limit=${limit}&` : ""}${offset ? `offset=${offset}&` : ""}`;
126
+ if (query && query.length > 0) {
127
+ url += `&name=${encodeURIComponent(query)}`;
128
+ }
129
+ Object.entries(filters).forEach(([key, value]) => {
130
+ if (value !== "" && value !== void 0 && key !== "offset") {
131
+ url += `&${key}=${encodeURIComponent(String(value))}`;
132
+ }
133
+ });
134
+ const response = await fetch(url);
135
+ if (!response.ok) {
136
+ throw new Error(`Failed to fetch tools: ${response.statusText}`);
137
+ }
138
+ return response.json();
139
+ }
140
+ async getTool(url, id) {
141
+ const encodedToolId = encodeURIComponent(id);
142
+ const response = await fetch(`${this.baseUrl}/tools/${encodedToolId}`);
143
+ if (!response.ok) {
144
+ throw new Error(`Failed to fetch tool: ${response.statusText}`);
145
+ }
146
+ return response.json();
147
+ }
148
+ async getToolVersions(url, id) {
149
+ const encodedToolId = encodeURIComponent(id);
150
+ const response = await fetch(
151
+ `${this.baseUrl}/tools/${encodedToolId}/versions`
152
+ );
153
+ if (!response.ok) {
154
+ throw new Error(`Failed to fetch tool versions: ${response.statusText}`);
155
+ }
156
+ return response.json();
157
+ }
158
+ async getToolVersion(url, id, versionId) {
159
+ const encodedToolId = encodeURIComponent(id);
160
+ const version = versionId.split(":")[1] ? versionId.split(":")[1] : versionId;
161
+ const encodedVersionId = encodeURIComponent(version);
162
+ const response = await fetch(
163
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}`
164
+ );
165
+ if (!response.ok) {
166
+ throw new Error(`Failed to fetch tool version: ${response.statusText}`);
167
+ }
168
+ return response.json();
169
+ }
170
+ async getToolFiles(url, id, version, descriptorType, format) {
171
+ const encodedToolId = encodeURIComponent(id);
172
+ const versionPart = version.split(":")[1] ? version.split(":")[1] : version;
173
+ const encodedVersionId = encodeURIComponent(versionPart);
174
+ const encodedType = encodeURIComponent(descriptorType);
175
+ let requestUrl = `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/files`;
176
+ if (format) {
177
+ requestUrl += `?format=${format}`;
178
+ }
179
+ const response = await fetch(requestUrl);
180
+ if (!response.ok) {
181
+ throw new Error(`Failed to fetch tool files: ${response.statusText}`);
182
+ }
183
+ return response.json();
184
+ }
185
+ async getToolDescriptor(url, id, version, descriptorType) {
186
+ const encodedToolId = encodeURIComponent(id);
187
+ const versionPart = version.split(":")[1] ? version.split(":")[1] : version;
188
+ const encodedVersionId = encodeURIComponent(versionPart);
189
+ const encodedType = encodeURIComponent(descriptorType);
190
+ const response = await fetch(
191
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/descriptor`
192
+ );
193
+ if (!response.ok) {
194
+ throw new Error(
195
+ `Failed to fetch tool descriptor: ${response.statusText}`
196
+ );
197
+ }
198
+ return response.json();
199
+ }
200
+ async getToolDescriptorByPath(url, id, version, descriptorType, path) {
201
+ const encodedToolId = encodeURIComponent(id);
202
+ const versionPart = version.split(":")[1] ? version.split(":")[1] : version;
203
+ const encodedVersionId = encodeURIComponent(versionPart);
204
+ const encodedType = encodeURIComponent(descriptorType);
205
+ try {
206
+ const response = await fetch(
207
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/descriptor/${path}`
208
+ );
209
+ if (response.ok) {
210
+ return response.json();
211
+ }
212
+ const encodedPath = encodeURIComponent(path);
213
+ const encodedResponse = await fetch(
214
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/descriptor/${encodedPath}`
215
+ );
216
+ if (encodedResponse.ok) {
217
+ return encodedResponse.json();
218
+ }
219
+ throw new Error(
220
+ `Failed to fetch tool descriptor by path: ${encodedResponse.statusText}`
221
+ );
222
+ } catch (error) {
223
+ const encodedPath = encodeURIComponent(path);
224
+ try {
225
+ const encodedResponse = await fetch(
226
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/descriptor/${encodedPath}`
227
+ );
228
+ if (encodedResponse.ok) {
229
+ return encodedResponse.json();
230
+ }
231
+ throw new Error(
232
+ `Failed to fetch tool descriptor by path: ${encodedResponse.statusText}`
233
+ );
234
+ } catch (encodedError) {
235
+ throw error;
236
+ }
237
+ }
238
+ }
239
+ async getContainerfile(url, id, version) {
240
+ const encodedToolId = encodeURIComponent(id);
241
+ const versionPart = version.split(":")[1] ? version.split(":")[1] : version;
242
+ const encodedVersionId = encodeURIComponent(versionPart);
243
+ const response = await fetch(
244
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/containerfile`
245
+ );
246
+ if (!response.ok) {
247
+ throw new Error(`Failed to fetch containerfile: ${response.statusText}`);
248
+ }
249
+ return response.json();
250
+ }
251
+ async getToolTests(url, id, version, descriptorType) {
252
+ const encodedToolId = encodeURIComponent(id);
253
+ const versionPart = version.split(":")[1] ? version.split(":")[1] : version;
254
+ const encodedVersionId = encodeURIComponent(versionPart);
255
+ const encodedType = encodeURIComponent(descriptorType);
256
+ const response = await fetch(
257
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}/${encodedType}/tests`
258
+ );
259
+ if (!response.ok) {
260
+ throw new Error(`Failed to fetch tool tests: ${response.statusText}`);
261
+ }
262
+ return response.json();
263
+ }
264
+ // Creation methods (TRS-Filer specific functionality)
265
+ async createTool(tool) {
266
+ console.log("Creating tool:", tool);
267
+ const response = await fetch(`${this.baseUrl}/tools`, {
268
+ method: "POST",
269
+ headers: {
270
+ "Content-Type": "application/json"
271
+ },
272
+ body: JSON.stringify(tool)
273
+ });
274
+ if (!response.ok) {
275
+ throw new Error(`Failed to create tool: ${response.statusText}`);
276
+ }
277
+ return response.text();
278
+ }
279
+ async createToolWithId(id, tool) {
280
+ const encodedToolId = encodeURIComponent(id);
281
+ const response = await fetch(`${this.baseUrl}/tools/${encodedToolId}`, {
282
+ method: "PUT",
283
+ headers: {
284
+ "Content-Type": "application/json"
285
+ },
286
+ body: JSON.stringify(tool)
287
+ });
288
+ if (!response.ok) {
289
+ throw new Error(`Failed to create/update tool: ${response.statusText}`);
290
+ }
291
+ return response.text();
292
+ }
293
+ async createToolVersion(toolId, version) {
294
+ const encodedToolId = encodeURIComponent(toolId);
295
+ const response = await fetch(`${this.baseUrl}/tools/${encodedToolId}/versions`, {
296
+ method: "POST",
297
+ headers: {
298
+ "Content-Type": "application/json"
299
+ },
300
+ body: JSON.stringify(version)
301
+ });
302
+ if (!response.ok) {
303
+ throw new Error(`Failed to create tool version: ${response.statusText}`);
304
+ }
305
+ return response.text();
306
+ }
307
+ async createToolVersionWithId(toolId, versionId, version) {
308
+ const encodedToolId = encodeURIComponent(toolId);
309
+ const encodedVersionId = encodeURIComponent(versionId);
310
+ const response = await fetch(
311
+ `${this.baseUrl}/tools/${encodedToolId}/versions/${encodedVersionId}`,
312
+ {
313
+ method: "PUT",
314
+ headers: {
315
+ "Content-Type": "application/json"
316
+ },
317
+ body: JSON.stringify(version)
318
+ }
319
+ );
320
+ if (!response.ok) {
321
+ throw new Error(`Failed to create/update tool version: ${response.statusText}`);
322
+ }
323
+ return response.text();
324
+ }
325
+ async createToolClass(toolClass) {
326
+ const response = await fetch(`${this.baseUrl}/toolClasses`, {
327
+ method: "POST",
328
+ headers: {
329
+ "Content-Type": "application/json"
330
+ },
331
+ body: JSON.stringify(toolClass)
332
+ });
333
+ if (!response.ok) {
334
+ throw new Error(`Failed to create tool class: ${response.statusText}`);
335
+ }
336
+ return response.text();
337
+ }
338
+ async createToolClassWithId(id, toolClass) {
339
+ const encodedId = encodeURIComponent(id);
340
+ const response = await fetch(`${this.baseUrl}/toolClasses/${encodedId}`, {
341
+ method: "PUT",
342
+ headers: {
343
+ "Content-Type": "application/json"
344
+ },
345
+ body: JSON.stringify(toolClass)
346
+ });
347
+ if (!response.ok) {
348
+ throw new Error(`Failed to create/update tool class: ${response.statusText}`);
349
+ }
350
+ return response.text();
351
+ }
352
+ };
353
+ var ECCClientElixirTrsToolCreate = class extends LitElement {
354
+ constructor() {
355
+ super(...arguments);
356
+ this.baseUrl = "";
357
+ this.toolClasses = [];
358
+ this.loading = false;
359
+ this.error = null;
360
+ this.success = null;
361
+ this.formData = {
362
+ name: "",
363
+ organization: "",
364
+ description: "",
365
+ toolClassId: "",
366
+ aliases: [],
367
+ checkerUrl: "",
368
+ hasChecker: false,
369
+ customToolId: "",
370
+ useCustomId: false
371
+ };
372
+ this.versions = [
373
+ {
374
+ name: "",
375
+ author: [],
376
+ descriptorTypes: [],
377
+ isProduction: false,
378
+ signed: false,
379
+ verified: false,
380
+ verifiedSource: [],
381
+ includedApps: [],
382
+ files: [],
383
+ images: [],
384
+ customVersionId: "",
385
+ useCustomVersionId: false
386
+ }
387
+ ];
388
+ this._provider = null;
389
+ this.activeFileIndex = {};
390
+ this.activeDescriptorType = {};
391
+ }
392
+ async firstUpdated() {
393
+ if (!this.baseUrl && !this.provider) {
394
+ this.dispatchEvent(
395
+ new CustomEvent("ecc-tool-create-validation-error", {
396
+ detail: {
397
+ error: "Please provide either a base URL for the TRS API or a custom provider."
398
+ },
399
+ bubbles: true,
400
+ composed: true
401
+ })
402
+ );
403
+ return;
404
+ }
405
+ if (this.provider) {
406
+ this._provider = this.provider;
407
+ } else if (this.baseUrl) {
408
+ this._provider = new RestTrsFilerProvider(this.baseUrl);
409
+ } else {
410
+ this._provider = null;
411
+ }
412
+ if (this._provider) {
413
+ await this.loadToolClasses();
414
+ }
415
+ }
416
+ updated(changedProperties) {
417
+ if (changedProperties.has("baseUrl") && this.baseUrl) {
418
+ this._provider = new RestTrsFilerProvider(this.baseUrl);
419
+ this.loadToolClasses();
420
+ }
421
+ }
422
+ async loadToolClasses() {
423
+ if (!this._provider)
424
+ return;
425
+ try {
426
+ this.toolClasses = await this._provider.getToolClasses();
427
+ } catch (error) {
428
+ console.error("Failed to load tool classes:", error);
429
+ this.dispatchEvent(
430
+ new CustomEvent("ecc-tool-create-error", {
431
+ detail: { error: "Failed to load tool classes" },
432
+ bubbles: true,
433
+ composed: true
434
+ })
435
+ );
436
+ }
437
+ }
438
+ handleInputChange(field, value) {
439
+ this.formData = __spreadProps(__spreadValues({}, this.formData), { [field]: value });
440
+ }
441
+ handleArrayInputChange(field, value) {
442
+ const array = value.split(",").map((item) => item.trim()).filter((item) => item);
443
+ this.formData = __spreadProps(__spreadValues({}, this.formData), { [field]: array });
444
+ }
445
+ handleVersionChange(index, field, value) {
446
+ const updatedVersions = [...this.versions];
447
+ updatedVersions[index] = __spreadProps(__spreadValues({}, updatedVersions[index]), { [field]: value });
448
+ if (field === "customVersionId") {
449
+ updatedVersions[index].useCustomVersionId = Boolean(value);
450
+ }
451
+ this.versions = updatedVersions;
452
+ }
453
+ addVersion() {
454
+ this.versions = [
455
+ ...this.versions,
456
+ {
457
+ name: "",
458
+ author: [],
459
+ descriptorTypes: [],
460
+ isProduction: false,
461
+ signed: false,
462
+ verified: false,
463
+ verifiedSource: [],
464
+ includedApps: [],
465
+ files: [],
466
+ images: [],
467
+ customVersionId: "",
468
+ useCustomVersionId: false
469
+ }
470
+ ];
471
+ }
472
+ removeVersion(index) {
473
+ if (this.versions.length > 1) {
474
+ this.versions = this.versions.filter((_, i) => i !== index);
475
+ }
476
+ }
477
+ addFileToVersion(versionIndex) {
478
+ const version = this.versions[versionIndex];
479
+ const activeDescriptorType = this.activeDescriptorType[versionIndex] || (version.descriptorTypes.length > 0 ? version.descriptorTypes[0] : null);
480
+ if (!activeDescriptorType) {
481
+ this.dispatchEvent(
482
+ new CustomEvent("ecc-tool-create-validation-error", {
483
+ detail: { error: "Please select a descriptor type before adding files." },
484
+ bubbles: true,
485
+ composed: true
486
+ })
487
+ );
488
+ return;
489
+ }
490
+ const updatedVersions = [...this.versions];
491
+ const descriptorType = activeDescriptorType;
492
+ updatedVersions[versionIndex].files.push({
493
+ path: "",
494
+ fileType: "PRIMARY_DESCRIPTOR",
495
+ content: "",
496
+ checksumType: "sha256",
497
+ checksumValue: "",
498
+ descriptorType
499
+ });
500
+ this.versions = updatedVersions;
501
+ }
502
+ removeFileFromVersion(versionIndex, fileIndex) {
503
+ const updatedVersions = [...this.versions];
504
+ updatedVersions[versionIndex].files = updatedVersions[versionIndex].files.filter((_, i) => i !== fileIndex);
505
+ this.versions = updatedVersions;
506
+ }
507
+ handleFileUpload(versionIndex, fileIndex, event) {
508
+ var _a;
509
+ const input = event.target;
510
+ const file = (_a = input.files) == null ? void 0 : _a[0];
511
+ if (file) {
512
+ const updatedVersions = [...this.versions];
513
+ updatedVersions[versionIndex].files[fileIndex].file = file;
514
+ updatedVersions[versionIndex].files[fileIndex].path = file.name;
515
+ const reader = new FileReader();
516
+ reader.onload = (e) => {
517
+ var _a2;
518
+ updatedVersions[versionIndex].files[fileIndex].content = (_a2 = e.target) == null ? void 0 : _a2.result;
519
+ this.versions = [...updatedVersions];
520
+ };
521
+ reader.readAsText(file);
522
+ this.versions = updatedVersions;
523
+ }
524
+ }
525
+ handleBulkFileUpload(versionIndex, event) {
526
+ const input = event.target;
527
+ const files = input.files;
528
+ if (files && files.length > 0) {
529
+ const version = this.versions[versionIndex];
530
+ const activeDescriptorType = this.activeDescriptorType[versionIndex] || (version.descriptorTypes.length > 0 ? version.descriptorTypes[0] : null);
531
+ if (!activeDescriptorType) {
532
+ this.dispatchEvent(
533
+ new CustomEvent("ecc-tool-create-validation-error", {
534
+ detail: { error: "Please select a descriptor type before uploading files." },
535
+ bubbles: true,
536
+ composed: true
537
+ })
538
+ );
539
+ input.value = "";
540
+ return;
541
+ }
542
+ const updatedVersions = [...this.versions];
543
+ const descriptorType = activeDescriptorType;
544
+ Array.from(files).forEach((file, index) => {
545
+ const fileData = {
546
+ path: file.name,
547
+ fileType: this.getDefaultFileType(file.name),
548
+ content: "",
549
+ file,
550
+ checksumType: "sha256",
551
+ checksumValue: "",
552
+ descriptorType
553
+ };
554
+ updatedVersions[versionIndex].files.push(fileData);
555
+ const reader = new FileReader();
556
+ reader.onload = (e) => {
557
+ var _a;
558
+ const currentVersions = [...this.versions];
559
+ const targetFileIndex = currentVersions[versionIndex].files.findIndex(
560
+ (f) => f.file === file
561
+ );
562
+ if (targetFileIndex !== -1 && currentVersions[versionIndex].files[targetFileIndex]) {
563
+ currentVersions[versionIndex].files[targetFileIndex].content = (_a = e.target) == null ? void 0 : _a.result;
564
+ this.versions = currentVersions;
565
+ }
566
+ };
567
+ reader.readAsText(file);
568
+ });
569
+ this.versions = updatedVersions;
570
+ input.value = "";
571
+ }
572
+ }
573
+ async handleZipFileUpload(versionIndex, event) {
574
+ var _a;
575
+ const input = event.target;
576
+ const file = (_a = input.files) == null ? void 0 : _a[0];
577
+ if (!file || !file.name.toLowerCase().endsWith(".zip")) {
578
+ this.dispatchEvent(
579
+ new CustomEvent("ecc-tool-create-validation-error", {
580
+ detail: { error: "Please select a valid ZIP file" },
581
+ bubbles: true,
582
+ composed: true
583
+ })
584
+ );
585
+ return;
586
+ }
587
+ const version = this.versions[versionIndex];
588
+ const activeDescriptorType = this.activeDescriptorType[versionIndex] || (version.descriptorTypes.length > 0 ? version.descriptorTypes[0] : null);
589
+ if (!activeDescriptorType) {
590
+ this.dispatchEvent(
591
+ new CustomEvent("ecc-tool-create-validation-error", {
592
+ detail: { error: "Please select a descriptor type before uploading ZIP files." },
593
+ bubbles: true,
594
+ composed: true
595
+ })
596
+ );
597
+ input.value = "";
598
+ return;
599
+ }
600
+ try {
601
+ this.loading = true;
602
+ const zip = new JSZip();
603
+ const zipContent = await zip.loadAsync(file);
604
+ const updatedVersions = [...this.versions];
605
+ const filePromises = [];
606
+ let extractedCount = 0;
607
+ const descriptorType = activeDescriptorType;
608
+ zipContent.forEach((relativePath, zipEntry) => {
609
+ if (zipEntry.dir)
610
+ return;
611
+ const promise = this.extractFileFromZip(zipEntry, relativePath).then((fileData) => {
612
+ if (fileData) {
613
+ fileData.descriptorType = descriptorType;
614
+ updatedVersions[versionIndex].files.push(fileData);
615
+ extractedCount++;
616
+ } else {
617
+ }
618
+ }).catch((error) => {
619
+ console.error(`Failed to extract file ${relativePath}:`, error);
620
+ });
621
+ filePromises.push(promise);
622
+ });
623
+ await Promise.all(filePromises);
624
+ this.versions = updatedVersions;
625
+ this.dispatchEvent(
626
+ new CustomEvent("ecc-tool-create-success", {
627
+ detail: { message: `Successfully extracted ${extractedCount} files from ZIP archive` },
628
+ bubbles: true,
629
+ composed: true
630
+ })
631
+ );
632
+ input.value = "";
633
+ } catch (error) {
634
+ console.error("ZIP extraction error details:", error);
635
+ console.error("Error type:", typeof error);
636
+ console.error(
637
+ "Error message:",
638
+ error instanceof Error ? error.message : String(error)
639
+ );
640
+ console.error(
641
+ "Error stack:",
642
+ error instanceof Error ? error.stack : "No stack trace"
643
+ );
644
+ this.dispatchEvent(
645
+ new CustomEvent("ecc-tool-create-error", {
646
+ detail: {
647
+ error: `Failed to extract ZIP file: ${error instanceof Error ? error.message : "Unknown error"}. Please ensure it's a valid ZIP archive.`
648
+ },
649
+ bubbles: true,
650
+ composed: true
651
+ })
652
+ );
653
+ } finally {
654
+ this.loading = false;
655
+ }
656
+ }
657
+ async extractFileFromZip(zipEntry, relativePath) {
658
+ try {
659
+ const isTextFile = this.isTextFile(relativePath);
660
+ let content;
661
+ if (isTextFile) {
662
+ content = await zipEntry.async("text");
663
+ } else {
664
+ const arrayBuffer = await zipEntry.async("arraybuffer");
665
+ const uint8Array = new Uint8Array(arrayBuffer);
666
+ content = btoa(String.fromCharCode(...uint8Array));
667
+ }
668
+ const fileData = {
669
+ path: relativePath,
670
+ fileType: this.getDefaultFileType(relativePath),
671
+ content,
672
+ file: void 0,
673
+ // No actual File object for extracted files
674
+ checksumType: "sha256",
675
+ checksumValue: "",
676
+ descriptorType: void 0
677
+ // Will be set by the calling method
678
+ };
679
+ return fileData;
680
+ } catch (error) {
681
+ console.error(`Error extracting file ${relativePath}:`, error);
682
+ console.error(`Error details for ${relativePath}:`, {
683
+ message: error instanceof Error ? error.message : String(error),
684
+ stack: error instanceof Error ? error.stack : "No stack trace"
685
+ });
686
+ return null;
687
+ }
688
+ }
689
+ isTextFile(filename) {
690
+ var _a;
691
+ const textExtensions = [
692
+ "txt",
693
+ "md",
694
+ "json",
695
+ "yml",
696
+ "yaml",
697
+ "xml",
698
+ "html",
699
+ "htm",
700
+ "css",
701
+ "js",
702
+ "ts",
703
+ "cwl",
704
+ "wdl",
705
+ "nf",
706
+ "py",
707
+ "r",
708
+ "sh",
709
+ "bash",
710
+ "dockerfile",
711
+ "def",
712
+ "config",
713
+ "conf",
714
+ "ini",
715
+ "log",
716
+ "csv",
717
+ "tsv",
718
+ "sql",
719
+ "graphql",
720
+ "gql"
721
+ ];
722
+ const extension = (_a = filename.split(".").pop()) == null ? void 0 : _a.toLowerCase();
723
+ return textExtensions.includes(extension || "") || filename.toLowerCase().includes("readme") || filename.toLowerCase().includes("license") || filename.toLowerCase().includes("changelog");
724
+ }
725
+ getDefaultFileType(filename) {
726
+ var _a;
727
+ const extension = (_a = filename.split(".").pop()) == null ? void 0 : _a.toLowerCase();
728
+ const basename = filename.toLowerCase();
729
+ if (basename.includes("workflow") || basename.includes("main") || extension === "cwl" || extension === "wdl" || extension === "nf") {
730
+ return "PRIMARY_DESCRIPTOR";
731
+ }
732
+ if (basename.includes("test") || basename.includes("example")) {
733
+ return "TEST_FILE";
734
+ }
735
+ if (basename === "dockerfile" || basename.includes("container") || extension === "def") {
736
+ return "CONTAINERFILE";
737
+ }
738
+ if (extension === "yml" || extension === "yaml" || extension === "json") {
739
+ return "SECONDARY_DESCRIPTOR";
740
+ }
741
+ return "OTHER";
742
+ }
743
+ getDefaultDescriptorType(filename) {
744
+ return void 0;
745
+ }
746
+ getContainerImageType(filename) {
747
+ var _a;
748
+ const basename = filename.toLowerCase();
749
+ const extension = (_a = filename.split(".").pop()) == null ? void 0 : _a.toLowerCase();
750
+ if (basename === "singularity" || basename.includes("singularity") || extension === "def" || extension === "sif" || basename.includes(".def")) {
751
+ return "Singularity";
752
+ }
753
+ if (basename === "environment.yml" || basename === "environment.yaml" || basename === "conda.yml" || basename === "conda.yaml" || basename.includes("conda") || basename.includes("environment")) {
754
+ return "Conda";
755
+ }
756
+ return "Docker";
757
+ }
758
+ getFileExtension(filename) {
759
+ var _a;
760
+ return ((_a = filename.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "txt";
761
+ }
762
+ handleFileFieldChange(versionIndex, fileIndex, field, value) {
763
+ const updatedVersions = [...this.versions];
764
+ updatedVersions[versionIndex].files[fileIndex] = __spreadProps(__spreadValues({}, updatedVersions[versionIndex].files[fileIndex]), {
765
+ [field]: value
766
+ });
767
+ this.versions = updatedVersions;
768
+ }
769
+ addImageToVersion(versionIndex) {
770
+ const updatedVersions = [...this.versions];
771
+ updatedVersions[versionIndex].images.push({
772
+ registry_host: "",
773
+ image_name: "",
774
+ image_type: "Docker",
775
+ checksum: []
776
+ });
777
+ this.versions = updatedVersions;
778
+ }
779
+ removeImageFromVersion(versionIndex, imageIndex) {
780
+ const updatedVersions = [...this.versions];
781
+ updatedVersions[versionIndex].images = updatedVersions[versionIndex].images.filter((_, i) => i !== imageIndex);
782
+ this.versions = updatedVersions;
783
+ }
784
+ async handleSubmit() {
785
+ console.log("handleSubmit");
786
+ if (!this._provider || !this._provider.createTool) {
787
+ this.dispatchEvent(
788
+ new CustomEvent("ecc-tool-create-error", {
789
+ detail: { error: "Tool creation is not supported by the current provider" },
790
+ bubbles: true,
791
+ composed: true
792
+ })
793
+ );
794
+ return;
795
+ }
796
+ this.loading = true;
797
+ try {
798
+ const selectedToolClass = this.toolClasses.find(
799
+ (tc) => tc.id === this.formData.toolClassId
800
+ );
801
+ if (!selectedToolClass) {
802
+ throw new Error("Please select a valid tool class");
803
+ }
804
+ const toolData = {
805
+ name: this.formData.name || void 0,
806
+ organization: this.formData.organization,
807
+ description: this.formData.description || void 0,
808
+ toolclass: {
809
+ id: selectedToolClass.id,
810
+ name: selectedToolClass.name,
811
+ description: selectedToolClass.description
812
+ },
813
+ aliases: this.formData.aliases.length > 0 ? this.formData.aliases : void 0,
814
+ checker_url: this.formData.checkerUrl || void 0,
815
+ has_checker: this.formData.hasChecker,
816
+ versions: this.versions.map((version) => __spreadProps(__spreadValues({}, version.useCustomVersionId && version.customVersionId ? { id: version.customVersionId } : {}), {
817
+ name: version.name || void 0,
818
+ author: version.author.length > 0 ? version.author : void 0,
819
+ descriptor_type: version.descriptorTypes.length > 0 ? version.descriptorTypes : void 0,
820
+ is_production: version.isProduction,
821
+ signed: version.signed,
822
+ verified: version.verified,
823
+ verified_source: version.verifiedSource.length > 0 ? version.verifiedSource : void 0,
824
+ included_apps: version.includedApps.length > 0 ? version.includedApps : void 0,
825
+ files: version.files.length > 0 ? version.files.map((file) => ({
826
+ tool_file: {
827
+ path: file.path,
828
+ file_type: file.fileType
829
+ },
830
+ file_wrapper: {
831
+ content: file.content || void 0,
832
+ checksum: file.checksumValue ? [
833
+ {
834
+ type: file.checksumType,
835
+ checksum: file.checksumValue
836
+ }
837
+ ] : void 0
838
+ },
839
+ type: file.fileType === "CONTAINERFILE" ? this.getContainerImageType(file.path) : file.descriptorType || version.descriptorTypes[0] || "CWL"
840
+ // Use file's descriptor type or first version descriptor type as default
841
+ })) : void 0,
842
+ images: version.images.length > 0 ? version.images : void 0
843
+ }))
844
+ };
845
+ let toolId;
846
+ if (this.formData.useCustomId && this.formData.customToolId) {
847
+ toolId = await this._provider.createToolWithId(
848
+ this.formData.customToolId,
849
+ toolData
850
+ );
851
+ } else {
852
+ toolId = await this._provider.createTool(toolData);
853
+ }
854
+ const successMessage = `Tool created successfully with ID: ${toolId}`;
855
+ this.dispatchEvent(
856
+ new CustomEvent("ecc-tool-create-success", {
857
+ detail: { message: successMessage },
858
+ bubbles: true,
859
+ composed: true
860
+ })
861
+ );
862
+ this.dispatchEvent(
863
+ new CustomEvent("ecc-tool-created", {
864
+ detail: { toolId, toolData },
865
+ bubbles: true,
866
+ composed: true
867
+ })
868
+ );
869
+ this.resetForm();
870
+ } catch (err) {
871
+ const errorMessage = err instanceof Error ? err.message : "Failed to create tool";
872
+ this.dispatchEvent(
873
+ new CustomEvent("ecc-tool-create-error", {
874
+ detail: { error: errorMessage },
875
+ bubbles: true,
876
+ composed: true
877
+ })
878
+ );
879
+ } finally {
880
+ this.loading = false;
881
+ }
882
+ }
883
+ resetForm() {
884
+ this.formData = {
885
+ name: "",
886
+ organization: "",
887
+ description: "",
888
+ toolClassId: "",
889
+ aliases: [],
890
+ checkerUrl: "",
891
+ hasChecker: false,
892
+ customToolId: "",
893
+ useCustomId: false
894
+ };
895
+ this.versions = [
896
+ {
897
+ name: "",
898
+ author: [],
899
+ descriptorTypes: [],
900
+ isProduction: false,
901
+ signed: false,
902
+ verified: false,
903
+ verifiedSource: [],
904
+ includedApps: [],
905
+ files: [],
906
+ images: [],
907
+ customVersionId: "",
908
+ useCustomVersionId: false
909
+ }
910
+ ];
911
+ }
912
+ renderBasicFields() {
913
+ return html`
914
+ <div class="grid gap-4">
915
+ <!-- Tool Name, Organization, Tool Class in same row on desktop -->
916
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
917
+ <div class="grid gap-2">
918
+ <ecc-utils-design-label
919
+ for="tool-name"
920
+ class="text-sm font-medium"
921
+ >
922
+ Tool Name
923
+ </ecc-utils-design-label>
924
+ <ecc-utils-design-input
925
+ id="tool-name"
926
+ .value=${this.formData.name}
927
+ @ecc-utils-change=${(e) => this.handleInputChange("name", e.detail.value)}
928
+ placeholder="Enter a descriptive name for your tool"
929
+ class="h-10"
930
+ ></ecc-utils-design-input>
931
+ </div>
932
+
933
+ <div class="grid gap-2">
934
+ <ecc-utils-design-label
935
+ for="organization"
936
+ class="text-sm font-medium"
937
+ >
938
+ Organization <span class="text-destructive">*</span>
939
+ </ecc-utils-design-label>
940
+ <ecc-utils-design-input
941
+ id="organization"
942
+ .value=${this.formData.organization}
943
+ @ecc-utils-change=${(e) => this.handleInputChange("organization", e.detail.value)}
944
+ placeholder="Enter your organization name"
945
+ required
946
+ class="h-10"
947
+ ></ecc-utils-design-input>
948
+ </div>
949
+
950
+ <div class="grid gap-1">
951
+ <ecc-utils-design-label
952
+ for="tool-class"
953
+ class="text-sm font-medium"
954
+ >
955
+ Tool Class <span class="text-destructive">*</span>
956
+ </ecc-utils-design-label>
957
+ <ecc-utils-design-select
958
+ id="tool-class-select"
959
+ .value=${this.formData.toolClassId}
960
+ @ecc-utils-change=${(e) => {
961
+ this.handleInputChange("toolClassId", e.detail.value);
962
+ }}
963
+ required
964
+ >
965
+ <ecc-utils-design-select-trigger class="h-10">
966
+ <ecc-utils-design-select-value
967
+ placeholder="Select a tool class"
968
+ ></ecc-utils-design-select-value>
969
+ </ecc-utils-design-select-trigger>
970
+
971
+ <ecc-utils-design-select-content>
972
+ <ecc-utils-design-select-item value="">
973
+ Select a tool class
974
+ </ecc-utils-design-select-item>
975
+ ${this.toolClasses.map(
976
+ (tc) => html`
977
+ <ecc-utils-design-select-item value=${tc.id}>
978
+ <div class="flex flex-col">
979
+ <span class="font-medium">${tc.name}</span>
980
+ </div>
981
+ </ecc-utils-design-select-item>
982
+ `
983
+ )}
984
+ </ecc-utils-design-select-content>
985
+ </ecc-utils-design-select>
986
+ </div>
987
+ </div>
988
+
989
+ <!-- Description spans full width -->
990
+ <div class="grid gap-2">
991
+ <ecc-utils-design-label
992
+ for="description"
993
+ class="text-sm font-medium"
994
+ >
995
+ Description
996
+ </ecc-utils-design-label>
997
+ <ecc-utils-design-textarea
998
+ id="description"
999
+ .value=${this.formData.description}
1000
+ @ecc-utils-change=${(e) => this.handleInputChange("description", e.detail.value)}
1001
+ placeholder="Provide a detailed description of what your tool does"
1002
+ rows="4"
1003
+ class="resize-none"
1004
+ ></ecc-utils-design-textarea>
1005
+ </div>
1006
+ ${this.renderAdvancedFields()}
1007
+ </div>
1008
+ `;
1009
+ }
1010
+ renderAdvancedFields() {
1011
+ return html`
1012
+ <div class="space-y-6">
1013
+ <ecc-utils-design-collapsible>
1014
+ <ecc-utils-design-collapsible-trigger>
1015
+ <div
1016
+ class="flex items-center justify-between w-full py-2 text-left hover:bg-muted/50 focus:outline-none focus:ring-1 focus:ring-ring rounded-t cursor-pointer transition-colors px-2"
1017
+ >
1018
+ <div class="space-y-0.5">
1019
+ <h4 class="text-sm font-medium text-muted-foreground">
1020
+ Advance Configuration
1021
+ </h4>
1022
+ </div>
1023
+ <svg
1024
+ class="w-4 h-4 text-muted-foreground/60 transition-transform duration-200 shrink-0"
1025
+ fill="none"
1026
+ stroke="currentColor"
1027
+ viewBox="0 0 24 24"
1028
+ >
1029
+ <path
1030
+ stroke-linecap="round"
1031
+ stroke-linejoin="round"
1032
+ stroke-width="2"
1033
+ d="M19 9l-7 7-7-7"
1034
+ ></path>
1035
+ </svg>
1036
+ </div>
1037
+ </ecc-utils-design-collapsible-trigger>
1038
+
1039
+ <ecc-utils-design-collapsible-content>
1040
+ <div class="pt-4 space-y-4 border-t border-border/50">
1041
+ <!-- Tool Configuration in grid layout -->
1042
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
1043
+ <!-- Custom Tool ID Section -->
1044
+ <div class="grid gap-2">
1045
+ <ecc-utils-design-label
1046
+ for="custom-tool-id"
1047
+ class="text-sm font-medium h-6"
1048
+ >
1049
+ Custom Tool ID
1050
+ </ecc-utils-design-label>
1051
+ <ecc-utils-design-input
1052
+ id="custom-tool-id"
1053
+ .value=${this.formData.customToolId}
1054
+ @ecc-utils-change=${(e) => {
1055
+ this.handleInputChange("customToolId", e.detail.value);
1056
+ this.handleInputChange(
1057
+ "useCustomId",
1058
+ Boolean(e.detail.value)
1059
+ );
1060
+ }}
1061
+ placeholder="my-org/my-tool (optional)"
1062
+ class="h-10"
1063
+ ></ecc-utils-design-input>
1064
+ </div>
1065
+
1066
+ <!-- Aliases Section -->
1067
+ <div class="grid gap-2">
1068
+ <ecc-utils-design-label
1069
+ for="aliases"
1070
+ class="text-sm font-medium h-6"
1071
+ >
1072
+ Aliases
1073
+ </ecc-utils-design-label>
1074
+ <ecc-utils-design-input
1075
+ id="aliases"
1076
+ .value=${this.formData.aliases.join(", ")}
1077
+ @ecc-utils-change=${(e) => this.handleArrayInputChange("aliases", e.detail.value)}
1078
+ placeholder="alias1, alias2, alias3"
1079
+ class="h-10"
1080
+ ></ecc-utils-design-input>
1081
+ </div>
1082
+
1083
+ <!-- Checker Tool Section -->
1084
+ <div class="grid gap-2">
1085
+ <ecc-utils-design-label
1086
+ for="checker-url"
1087
+ class="text-sm font-medium h-6"
1088
+ >
1089
+ Checker Tool URL
1090
+ </ecc-utils-design-label>
1091
+ <ecc-utils-design-input
1092
+ id="checker-url"
1093
+ .value=${this.formData.checkerUrl}
1094
+ @ecc-utils-change=${(e) => {
1095
+ this.handleInputChange("checkerUrl", e.detail.value);
1096
+ this.handleInputChange(
1097
+ "hasChecker",
1098
+ Boolean(e.detail.value)
1099
+ );
1100
+ }}
1101
+ placeholder="https://example.com/checker-tool (optional)"
1102
+ class="h-10"
1103
+ ></ecc-utils-design-input>
1104
+ </div>
1105
+ </div>
1106
+ </div>
1107
+ </ecc-utils-design-collapsible-content>
1108
+ </ecc-utils-design-collapsible>
1109
+ </div>
1110
+ `;
1111
+ }
1112
+ renderVersions() {
1113
+ return html`
1114
+ <div class="space-y-6">
1115
+ <ecc-utils-design-tabs default-value="version-0" class="part:w-full">
1116
+ <div class="flex items-center w-full">
1117
+ <div class="flex-1 overflow-x-auto tabs-scroll-container">
1118
+ <ecc-utils-design-tabs-list
1119
+ class="part:flex part:min-w-max part:justify-start"
1120
+ >
1121
+ ${this.versions.map(
1122
+ (version, index) => html`
1123
+ <ecc-utils-design-tabs-trigger
1124
+ value="version-${index}"
1125
+ class="part:relative part:flex-shrink-0"
1126
+ >
1127
+ <span>Version ${index + 1}</span>
1128
+ ${version.name ? html`<span class="text-xs text-muted-foreground ml-1"
1129
+ >(${version.name})</span
1130
+ >` : ""}
1131
+ ${this.versions.length > 1 ? html`
1132
+ <ecc-utils-design-button
1133
+ variant="ghost"
1134
+ size="sm"
1135
+ class="part:ml-2 part:h-4 part:w-4 part:p-0 part:hover:bg-destructive part:hover:text-destructive-foreground"
1136
+ @click=${(e) => {
1137
+ e.stopPropagation();
1138
+ this.removeVersion(index);
1139
+ }}
1140
+ >
1141
+ <svg
1142
+ class="w-3 h-3"
1143
+ fill="none"
1144
+ stroke="currentColor"
1145
+ viewBox="0 0 24 24"
1146
+ >
1147
+ <path
1148
+ stroke-linecap="round"
1149
+ stroke-linejoin="round"
1150
+ stroke-width="2"
1151
+ d="M6 18L18 6M6 6l12 12"
1152
+ ></path>
1153
+ </svg>
1154
+ </ecc-utils-design-button>
1155
+ ` : ""}
1156
+ </ecc-utils-design-tabs-trigger>
1157
+ `
1158
+ )}
1159
+ </ecc-utils-design-tabs-list>
1160
+ </div>
1161
+
1162
+ <ecc-utils-design-button
1163
+ @click=${this.addVersion}
1164
+ variant="outline"
1165
+ size="sm"
1166
+ class="ml-4 flex-shrink-0 part:h-10"
1167
+ >
1168
+ <svg
1169
+ class="w-4 h-4"
1170
+ fill="none"
1171
+ stroke="currentColor"
1172
+ viewBox="0 0 24 24"
1173
+ >
1174
+ <path
1175
+ stroke-linecap="round"
1176
+ stroke-linejoin="round"
1177
+ stroke-width="2"
1178
+ d="M12 4v16m8-8H4"
1179
+ ></path>
1180
+ </svg>
1181
+ Add Version
1182
+ </ecc-utils-design-button>
1183
+ </div>
1184
+
1185
+ ${this.versions.map(
1186
+ (version, index) => html`
1187
+ <ecc-utils-design-tabs-content value="version-${index}">
1188
+ ${this.renderVersionContent(version, index)}
1189
+ </ecc-utils-design-tabs-content>
1190
+ `
1191
+ )}
1192
+ </ecc-utils-design-tabs>
1193
+ </div>
1194
+ `;
1195
+ }
1196
+ renderVersionContent(version, index) {
1197
+ return html`
1198
+ <div class="flex flex-col gap-4 pt-4">
1199
+ <!-- Basic Version Information -->
1200
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
1201
+ <div class="grid gap-2">
1202
+ <ecc-utils-design-label class="text-sm font-medium h-6"
1203
+ >Version Name</ecc-utils-design-label
1204
+ >
1205
+ <ecc-utils-design-input
1206
+ .value=${version.name}
1207
+ @ecc-utils-change=${(e) => this.handleVersionChange(index, "name", e.detail.value)}
1208
+ placeholder="e.g., v1.0.0"
1209
+ class="h-10"
1210
+ ></ecc-utils-design-input>
1211
+ </div>
1212
+
1213
+ <div class="grid gap-2">
1214
+ <ecc-utils-design-label class="text-sm font-medium h-6">
1215
+ Authors (comma-separated)
1216
+ </ecc-utils-design-label>
1217
+ <ecc-utils-design-input
1218
+ .value=${version.author.join(", ")}
1219
+ @ecc-utils-change=${(e) => {
1220
+ const authors = e.detail.value.split(",").map((a) => a.trim()).filter((a) => a);
1221
+ this.handleVersionChange(index, "author", authors);
1222
+ }}
1223
+ placeholder="author1, author2"
1224
+ class="h-10"
1225
+ ></ecc-utils-design-input>
1226
+ </div>
1227
+
1228
+ <!-- Descriptor Types Selection -->
1229
+ <div class="grid">
1230
+ <ecc-utils-design-label class="text-sm font-medium"
1231
+ >Supported Languages</ecc-utils-design-label
1232
+ >
1233
+ <ecc-utils-design-multi-select
1234
+ .value=${version.descriptorTypes}
1235
+ placeholder="Select supported languages..."
1236
+ @ecc-utils-change=${(e) => {
1237
+ const updatedVersions = [...this.versions];
1238
+ updatedVersions[index].descriptorTypes = e.detail.value;
1239
+ this.versions = updatedVersions;
1240
+ }}
1241
+ class="mt-2"
1242
+ >
1243
+ <ecc-utils-design-multi-select-trigger>
1244
+ </ecc-utils-design-multi-select-trigger>
1245
+
1246
+ <ecc-utils-design-multi-select-content>
1247
+ <ecc-utils-design-multi-select-item value="CWL">
1248
+ CWL (Common Workflow Language)
1249
+ </ecc-utils-design-multi-select-item>
1250
+ <ecc-utils-design-multi-select-item value="WDL">
1251
+ WDL (Workflow Description Language)
1252
+ </ecc-utils-design-multi-select-item>
1253
+ <ecc-utils-design-multi-select-item value="NFL">
1254
+ Nextflow
1255
+ </ecc-utils-design-multi-select-item>
1256
+ <ecc-utils-design-multi-select-item value="GALAXY">
1257
+ Galaxy
1258
+ </ecc-utils-design-multi-select-item>
1259
+ <ecc-utils-design-multi-select-item value="SMK">
1260
+ Snakemake
1261
+ </ecc-utils-design-multi-select-item>
1262
+ </ecc-utils-design-multi-select-content>
1263
+ </ecc-utils-design-multi-select>
1264
+ </div>
1265
+ </div>
1266
+
1267
+ <!-- Advanced Version Options -->
1268
+ <div class="">
1269
+ <ecc-utils-design-collapsible>
1270
+ <ecc-utils-design-collapsible-trigger>
1271
+ <div
1272
+ class="flex items-center justify-between w-full py-2 text-left hover:bg-muted/50 focus:outline-none focus:ring-1 focus:ring-ring rounded cursor-pointer transition-colors px-2"
1273
+ >
1274
+ <h4 class="text-sm font-medium text-muted-foreground">
1275
+ Advance Version Configuration
1276
+ </h4>
1277
+ <svg
1278
+ class="w-4 h-4 text-muted-foreground/60 transition-transform duration-200 shrink-0"
1279
+ fill="none"
1280
+ stroke="currentColor"
1281
+ viewBox="0 0 24 24"
1282
+ >
1283
+ <path
1284
+ stroke-linecap="round"
1285
+ stroke-linejoin="round"
1286
+ stroke-width="2"
1287
+ d="M19 9l-7 7-7-7"
1288
+ ></path>
1289
+ </svg>
1290
+ </div>
1291
+ </ecc-utils-design-collapsible-trigger>
1292
+
1293
+ <ecc-utils-design-collapsible-content>
1294
+ <div class="pt-4 space-y-4 border-t border-border/50">
1295
+ <!-- Tags and Custom Version ID in same row -->
1296
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
1297
+ <div class="grid gap-1">
1298
+ <ecc-utils-design-label class="text-sm font-medium h-6">
1299
+ Tags
1300
+ </ecc-utils-design-label>
1301
+ <ecc-utils-design-multi-select
1302
+ .value=${this.getVersionTags(version)}
1303
+ placeholder="Select tags..."
1304
+ @ecc-utils-change=${(e) => {
1305
+ this.handleVersionTagsChange(index, e.detail.value);
1306
+ }}
1307
+ >
1308
+ <ecc-utils-design-multi-select-trigger>
1309
+ </ecc-utils-design-multi-select-trigger>
1310
+
1311
+ <ecc-utils-design-multi-select-content>
1312
+ <ecc-utils-design-multi-select-item value="prod">
1313
+ Production
1314
+ </ecc-utils-design-multi-select-item>
1315
+ <ecc-utils-design-multi-select-item value="verified">
1316
+ Verified
1317
+ </ecc-utils-design-multi-select-item>
1318
+ <ecc-utils-design-multi-select-item value="signed">
1319
+ Signed
1320
+ </ecc-utils-design-multi-select-item>
1321
+ </ecc-utils-design-multi-select-content>
1322
+ </ecc-utils-design-multi-select>
1323
+ </div>
1324
+
1325
+ <div class="grid gap-2">
1326
+ <ecc-utils-design-label class="text-sm font-medium h-6">
1327
+ Custom Version ID
1328
+ </ecc-utils-design-label>
1329
+ <ecc-utils-design-input
1330
+ .value=${version.customVersionId}
1331
+ @ecc-utils-change=${(e) => this.handleVersionChange(
1332
+ index,
1333
+ "customVersionId",
1334
+ e.detail.value
1335
+ )}
1336
+ placeholder="Enter custom version ID (optional)"
1337
+ class="h-10"
1338
+ ></ecc-utils-design-input>
1339
+ </div>
1340
+ </div>
1341
+ </div>
1342
+ </ecc-utils-design-collapsible-content>
1343
+ </ecc-utils-design-collapsible>
1344
+ </div>
1345
+
1346
+ <!-- Files Section -->
1347
+ <div class="space-y-2">
1348
+ <div class="flex justify-between items-center">
1349
+ <h4 class="text-base font-semibold">Files</h4>
1350
+ <div class="flex gap-2">
1351
+ <div class="relative">
1352
+ <input
1353
+ type="file"
1354
+ multiple
1355
+ @change=${(e) => this.handleBulkFileUpload(index, e)}
1356
+ class="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
1357
+ id="bulk-upload-${index}"
1358
+ ?disabled=${version.descriptorTypes.length === 0}
1359
+ />
1360
+ <ecc-utils-design-button
1361
+ variant="outline"
1362
+ size="sm"
1363
+ as="label"
1364
+ for="bulk-upload-${index}"
1365
+ .disabled=${version.descriptorTypes.length === 0}
1366
+ >
1367
+ Upload Files
1368
+ </ecc-utils-design-button>
1369
+ </div>
1370
+ <div class="relative">
1371
+ <input
1372
+ type="file"
1373
+ accept=".zip"
1374
+ @change=${(e) => this.handleZipFileUpload(index, e)}
1375
+ class="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
1376
+ id="zip-upload-${index}"
1377
+ ?disabled=${version.descriptorTypes.length === 0}
1378
+ />
1379
+ <ecc-utils-design-button
1380
+ variant="outline"
1381
+ size="sm"
1382
+ as="label"
1383
+ for="zip-upload-${index}"
1384
+ .disabled=${version.descriptorTypes.length === 0}
1385
+ >
1386
+ Upload ZIP
1387
+ </ecc-utils-design-button>
1388
+ </div>
1389
+ <ecc-utils-design-button
1390
+ @click=${() => this.addFileToVersion(index)}
1391
+ variant="outline"
1392
+ size="sm"
1393
+ .disabled=${version.descriptorTypes.length === 0}
1394
+ >
1395
+ Add File Manually
1396
+ </ecc-utils-design-button>
1397
+ ${version.descriptorTypes.length > 0 ? html`
1398
+ <div
1399
+ class="flex items-center gap-2 text-sm text-muted-foreground"
1400
+ >
1401
+ <span
1402
+ class="text-sm text-muted-foreground"
1403
+ style="font-style: italic;"
1404
+ >for:</span
1405
+ >
1406
+ <ecc-utils-design-select
1407
+ .value=${this.activeDescriptorType[index] || version.descriptorTypes[0]}
1408
+ @ecc-utils-change=${(e) => {
1409
+ this.activeDescriptorType = __spreadProps(__spreadValues({}, this.activeDescriptorType), {
1410
+ [index]: e.detail.value
1411
+ });
1412
+ if (e.detail.value) {
1413
+ const filteredFiles = version.files.filter(
1414
+ (file) => file.descriptorType === e.detail.value
1415
+ );
1416
+ if (filteredFiles.length > 0) {
1417
+ const firstFileIndex = version.files.indexOf(
1418
+ filteredFiles[0]
1419
+ );
1420
+ this.activeFileIndex = __spreadProps(__spreadValues({}, this.activeFileIndex), {
1421
+ [index]: firstFileIndex
1422
+ });
1423
+ } else {
1424
+ this.activeFileIndex = __spreadProps(__spreadValues({}, this.activeFileIndex), {
1425
+ [index]: -1
1426
+ });
1427
+ }
1428
+ } else {
1429
+ this.activeFileIndex = __spreadProps(__spreadValues({}, this.activeFileIndex), {
1430
+ [index]: -1
1431
+ });
1432
+ }
1433
+ this.requestUpdate();
1434
+ }}
1435
+ class="w-24"
1436
+ >
1437
+ <ecc-utils-design-select-trigger
1438
+ class="part:text-sm part:h-8 part:w-24"
1439
+ >
1440
+ <ecc-utils-design-select-value></ecc-utils-design-select-value>
1441
+ </ecc-utils-design-select-trigger>
1442
+ <ecc-utils-design-select-content
1443
+ class="part:text-sm part:w-24 part:min-w-24"
1444
+ >
1445
+ ${version.descriptorTypes.map(
1446
+ (descriptorType) => html`
1447
+ <ecc-utils-design-select-item
1448
+ value=${descriptorType}
1449
+ class="part:text-sm"
1450
+ >
1451
+ ${descriptorType}
1452
+ </ecc-utils-design-select-item>
1453
+ `
1454
+ )}
1455
+ </ecc-utils-design-select-content>
1456
+ </ecc-utils-design-select>
1457
+ </div>
1458
+ ` : ``}
1459
+ </div>
1460
+ </div>
1461
+
1462
+ <!-- Language Filter Section -->
1463
+
1464
+ ${version.files.length === 0 ? html`<p class="text-gray-500 text-sm">
1465
+ ${version.descriptorTypes.length > 0 ? "No files added yet. Upload files or add them manually." : "Select a language this version supports to upload and manage files."}
1466
+ </p>` : this.renderFilesLayout(index, version.files)}
1467
+ </div>
1468
+ </div>
1469
+ `;
1470
+ }
1471
+ renderFilesLayout(versionIndex, files) {
1472
+ const version = this.versions[versionIndex];
1473
+ const activeDescriptor = this.activeDescriptorType[versionIndex] || (version.descriptorTypes.length > 0 ? version.descriptorTypes[0] : null);
1474
+ if (!activeDescriptor) {
1475
+ return html`
1476
+ <div class="text-center py-8 text-gray-500">
1477
+ <p>Please select a descriptor type to view and manage files</p>
1478
+ <p class="text-sm">
1479
+ Files will be filtered by the selected descriptor type
1480
+ </p>
1481
+ </div>
1482
+ `;
1483
+ }
1484
+ const filteredFiles = files.filter(
1485
+ (file) => file.descriptorType === activeDescriptor
1486
+ );
1487
+ return html`
1488
+ <div class="grid grid-cols-5 gap-4">
1489
+ <!-- Files List Section - 1/5 of screen -->
1490
+ <div class="col-span-5 md:col-span-1">
1491
+ <div class="space-y-1 max-h-[400px] overflow-y-auto">
1492
+ ${filteredFiles.map((file, fileIndex) => {
1493
+ const originalIndex = files.indexOf(file);
1494
+ return html`
1495
+ <ecc-utils-design-button
1496
+ variant="ghost"
1497
+ type="button"
1498
+ class="part:h-8 part:w-full part:text-left part:px-3 part:py-1 part:rounded-md part:text-sm part:flex part:items-center part:justify-between ${this.activeFileIndex[versionIndex] === originalIndex ? "part:bg-primary/10" : "part:hover:bg-muted"}"
1499
+ @click=${() => {
1500
+ this.activeFileIndex = __spreadProps(__spreadValues({}, this.activeFileIndex), {
1501
+ [versionIndex]: originalIndex
1502
+ });
1503
+ this.requestUpdate();
1504
+ }}
1505
+ >
1506
+ <span class="truncate">
1507
+ ${file.path || `File ${originalIndex + 1}`}
1508
+ ${file.descriptorType ? html`<span class="text-xs text-muted-foreground ml-1"
1509
+ >(${file.descriptorType})</span
1510
+ >` : ""}
1511
+ </span>
1512
+ <ecc-utils-design-button
1513
+ type="button"
1514
+ variant="ghost"
1515
+ class="part:h-8 part:w-8 part:text-left part:px-3 part:py-1 part:rounded-md part:text-sm part:flex part:items-center part:justify-between"
1516
+ @click=${(e) => {
1517
+ e.stopPropagation();
1518
+ this.removeFileFromVersion(versionIndex, originalIndex);
1519
+ }}
1520
+ >
1521
+ ×
1522
+ </ecc-utils-design-button>
1523
+ </ecc-utils-design-button>
1524
+ `;
1525
+ })}
1526
+ </div>
1527
+ </div>
1528
+
1529
+ <!-- Mobile Separator -->
1530
+ <div class="block md:hidden col-span-5">
1531
+ <ecc-utils-design-separator
1532
+ orientation="horizontal"
1533
+ class="part:my-4"
1534
+ ></ecc-utils-design-separator>
1535
+ </div>
1536
+
1537
+ <!-- File Content Section - 4/5 of screen -->
1538
+ <div
1539
+ class="col-span-5 md:col-span-4 md:border-l md:pl-4 md:border-muted w-full"
1540
+ >
1541
+ ${this.renderFileContentArea(versionIndex, files)}
1542
+ </div>
1543
+ </div>
1544
+ `;
1545
+ }
1546
+ renderFileContentArea(versionIndex, files) {
1547
+ var _a;
1548
+ const activeIndex = (_a = this.activeFileIndex[versionIndex]) != null ? _a : 0;
1549
+ const activeFile = files[activeIndex];
1550
+ if (!activeFile) {
1551
+ return html`
1552
+ <div class="text-center py-8 text-gray-500">
1553
+ <p>No files available</p>
1554
+ <p class="text-sm">Add files to see content preview</p>
1555
+ </div>
1556
+ `;
1557
+ }
1558
+ const fileTypes = [
1559
+ { value: "PRIMARY_DESCRIPTOR", label: "Primary Descriptor" },
1560
+ { value: "SECONDARY_DESCRIPTOR", label: "Secondary Descriptor" },
1561
+ { value: "TEST_FILE", label: "Test File" },
1562
+ { value: "CONTAINERFILE", label: "Container File" },
1563
+ { value: "OTHER", label: "Other" }
1564
+ ];
1565
+ const checksumTypes = ["sha256", "sha1", "md5"];
1566
+ return html`
1567
+ <div class="space-y-4">
1568
+
1569
+ <!-- File Configuration -->
1570
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
1571
+ <div>
1572
+ <ecc-utils-design-label>File Path</ecc-utils-design-label>
1573
+ <ecc-utils-design-input
1574
+ .value=${activeFile.path}
1575
+ @ecc-utils-change=${(e) => {
1576
+ this.handleFileFieldChange(
1577
+ versionIndex,
1578
+ activeIndex,
1579
+ "path",
1580
+ e.detail.value
1581
+ );
1582
+ }}
1583
+ placeholder="e.g., Readme.md"
1584
+ ></ecc-utils-design-input>
1585
+ </div>
1586
+
1587
+ <div>
1588
+ <ecc-utils-design-label>File Type</ecc-utils-design-label>
1589
+ <ecc-utils-design-select
1590
+ .value=${activeFile.fileType}
1591
+ @ecc-utils-change=${(e) => {
1592
+ this.handleFileFieldChange(
1593
+ versionIndex,
1594
+ activeIndex,
1595
+ "fileType",
1596
+ e.detail.value
1597
+ );
1598
+ }}
1599
+ >
1600
+ <ecc-utils-design-select-trigger>
1601
+ <ecc-utils-design-select-value></ecc-utils-design-select-value>
1602
+ </ecc-utils-design-select-trigger>
1603
+ <ecc-utils-design-select-content>
1604
+ ${fileTypes.map(
1605
+ (type) => html`
1606
+ <ecc-utils-design-select-item value=${type.value}>
1607
+ ${type.label}
1608
+ </ecc-utils-design-select-item>
1609
+ `
1610
+ )}
1611
+ </ecc-utils-design-select-content>
1612
+ </ecc-utils-design-select>
1613
+ </div>
1614
+
1615
+ <div>
1616
+ <ecc-utils-design-label>Checksum Type</ecc-utils-design-label>
1617
+ <ecc-utils-design-select
1618
+ .value=${activeFile.checksumType}
1619
+ @ecc-utils-change=${(e) => {
1620
+ this.handleFileFieldChange(
1621
+ versionIndex,
1622
+ activeIndex,
1623
+ "checksumType",
1624
+ e.detail.value
1625
+ );
1626
+ }}
1627
+ >
1628
+ <ecc-utils-design-select-trigger>
1629
+ <ecc-utils-design-select-value></ecc-utils-design-select-value>
1630
+ </ecc-utils-design-select-trigger>
1631
+ <ecc-utils-design-select-content>
1632
+ ${checksumTypes.map(
1633
+ (type) => html`
1634
+ <ecc-utils-design-select-item value=${type}>
1635
+ ${type.toUpperCase()}
1636
+ </ecc-utils-design-select-item>
1637
+ `
1638
+ )}
1639
+ </ecc-utils-design-select-content>
1640
+ </ecc-utils-design-select>
1641
+ </div>
1642
+
1643
+ <div>
1644
+ <ecc-utils-design-label
1645
+ >Checksum Value (optional)</ecc-utils-design-label
1646
+ >
1647
+ <ecc-utils-design-input
1648
+ .value=${activeFile.checksumValue}
1649
+ @ecc-utils-change=${(e) => {
1650
+ this.handleFileFieldChange(
1651
+ versionIndex,
1652
+ activeIndex,
1653
+ "checksumValue",
1654
+ e.detail.value
1655
+ );
1656
+ }}
1657
+ placeholder="Enter checksum value"
1658
+ ></ecc-utils-design-input>
1659
+ </div>
1660
+ </div>
1661
+
1662
+ <!-- File Content -->
1663
+ <div class="space-y-2">
1664
+ <ecc-utils-design-label>File Content</ecc-utils-design-label>
1665
+
1666
+ ${activeFile.content !== void 0 ? html`
1667
+ <ecc-utils-design-code
1668
+ value=${activeFile.content}
1669
+ extension=${this.getFileExtension(activeFile.path)}
1670
+ @ecc-utils-change=${(e) => {
1671
+ this.handleFileFieldChange(
1672
+ versionIndex,
1673
+ activeIndex,
1674
+ "content",
1675
+ e.detail.value
1676
+ );
1677
+ }}
1678
+ class="part:h-[500px]"
1679
+ ></ecc-utils-design-code>
1680
+ ` : html`
1681
+ <div
1682
+ class="text-center py-8 text-gray-500 border-2 border-dashed border-gray-300 rounded-lg"
1683
+ >
1684
+ <p>No content available</p>
1685
+ <p class="text-sm">This file was not uploaded with content</p>
1686
+ </div>
1687
+ `}
1688
+ </div>
1689
+ </div>
1690
+ `;
1691
+ }
1692
+ renderFileInput(versionIndex, fileIndex, file) {
1693
+ return html``;
1694
+ }
1695
+ getVersionTags(version) {
1696
+ const tags = [];
1697
+ if (version.isProduction)
1698
+ tags.push("prod");
1699
+ if (version.verified)
1700
+ tags.push("verified");
1701
+ if (version.signed)
1702
+ tags.push("signed");
1703
+ return tags;
1704
+ }
1705
+ handleVersionTagsChange(index, tags) {
1706
+ const updatedVersions = [...this.versions];
1707
+ updatedVersions[index] = __spreadProps(__spreadValues({}, updatedVersions[index]), {
1708
+ isProduction: tags.includes("prod"),
1709
+ verified: tags.includes("verified"),
1710
+ signed: tags.includes("signed")
1711
+ });
1712
+ this.versions = updatedVersions;
1713
+ }
1714
+ render() {
1715
+ return html`
1716
+ <div class="">
1717
+ <form
1718
+ @submit=${(e) => {
1719
+ e.preventDefault();
1720
+ this.handleSubmit();
1721
+ }}
1722
+ >
1723
+ <div class="space-y-4">
1724
+ ${this.renderBasicFields()}
1725
+ ${this.renderVersions()}
1726
+ </div>
1727
+
1728
+ <div class="flex justify-between items-center mt-4">
1729
+ <div></div>
1730
+ <div class="space-x-2">
1731
+ <ecc-utils-design-button
1732
+ type="button"
1733
+ variant="outline"
1734
+ @click=${this.resetForm}
1735
+ >
1736
+ Reset
1737
+ </ecc-utils-design-button>
1738
+ <ecc-utils-design-button
1739
+ type="submit"
1740
+ @click=${this.handleSubmit}
1741
+ .disabled=${this.loading || !this.formData.organization || !this.formData.toolClassId}
1742
+ >
1743
+ ${this.loading ? "Creating..." : "Create"}
1744
+ </ecc-utils-design-button>
1745
+ </div>
1746
+ </div>
1747
+ </form>
1748
+ </div>
1749
+ `;
1750
+ }
1751
+ };
1752
+ ECCClientElixirTrsToolCreate.styles = [
1753
+ ComponentStyles,
1754
+ GlobalStyles,
1755
+ css`
1756
+ :host {
1757
+ display: block;
1758
+ width: 100%;
1759
+ }
1760
+
1761
+ .tabs-scroll-container {
1762
+ scrollbar-width: none; /* Firefox */
1763
+ -ms-overflow-style: none; /* Internet Explorer 10+ */
1764
+ }
1765
+
1766
+ .tabs-scroll-container::-webkit-scrollbar {
1767
+ display: none; /* WebKit */
1768
+ }
1769
+ `
1770
+ ];
1771
+ __decorateClass([
1772
+ property({ type: String, reflect: true })
1773
+ ], ECCClientElixirTrsToolCreate.prototype, "baseUrl", 2);
1774
+ __decorateClass([
1775
+ property({ attribute: false, reflect: true })
1776
+ ], ECCClientElixirTrsToolCreate.prototype, "provider", 2);
1777
+ __decorateClass([
1778
+ state()
1779
+ ], ECCClientElixirTrsToolCreate.prototype, "toolClasses", 2);
1780
+ __decorateClass([
1781
+ state()
1782
+ ], ECCClientElixirTrsToolCreate.prototype, "loading", 2);
1783
+ __decorateClass([
1784
+ state()
1785
+ ], ECCClientElixirTrsToolCreate.prototype, "error", 2);
1786
+ __decorateClass([
1787
+ state()
1788
+ ], ECCClientElixirTrsToolCreate.prototype, "success", 2);
1789
+ __decorateClass([
1790
+ state()
1791
+ ], ECCClientElixirTrsToolCreate.prototype, "formData", 2);
1792
+ __decorateClass([
1793
+ state()
1794
+ ], ECCClientElixirTrsToolCreate.prototype, "versions", 2);
1795
+ __decorateClass([
1796
+ state()
1797
+ ], ECCClientElixirTrsToolCreate.prototype, "activeFileIndex", 2);
1798
+ __decorateClass([
1799
+ state()
1800
+ ], ECCClientElixirTrsToolCreate.prototype, "activeDescriptorType", 2);
1801
+ var tool_create_default = ECCClientElixirTrsToolCreate;
1802
+
1803
+ export { ECCClientElixirTrsToolCreate, tool_create_default };