windmill-components 1.305.7 → 1.306.9

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 (31) hide show
  1. package/package/assets/app.css +21 -0
  2. package/package/components/apps/components/display/AppMap.svelte +62 -70
  3. package/package/components/apps/components/display/AppMap.svelte.d.ts +1 -0
  4. package/package/components/apps/components/display/table/AppAggridTable.svelte +110 -9
  5. package/package/components/apps/components/display/table/AppAggridTable.svelte.d.ts +2 -0
  6. package/package/components/apps/components/display/table/AppAggridTableActions.svelte +232 -0
  7. package/package/components/apps/components/display/table/AppAggridTableActions.svelte.d.ts +30 -0
  8. package/package/components/apps/components/display/table/AppAggridTableEe.svelte +10 -1
  9. package/package/components/apps/components/display/table/AppAggridTableEe.svelte.d.ts +2 -0
  10. package/package/components/apps/components/display/table/AppTable.svelte +0 -1
  11. package/package/components/apps/components/inputs/AppCheckbox.svelte +1 -0
  12. package/package/components/apps/editor/AppEditorHeader.svelte +4 -0
  13. package/package/components/apps/editor/AppInputs.svelte +11 -0
  14. package/package/components/apps/editor/SettingsPanel.svelte +17 -0
  15. package/package/components/apps/editor/appUtils.js +30 -0
  16. package/package/components/apps/editor/component/Component.svelte +2 -0
  17. package/package/components/apps/editor/component/ComponentCallbacks.svelte +4 -0
  18. package/package/components/apps/editor/component/components.d.ts +25 -2
  19. package/package/components/apps/editor/component/components.js +12 -0
  20. package/package/components/apps/editor/contextPanel/components/OutputHeader.svelte +13 -0
  21. package/package/components/apps/editor/contextPanel/components/TableActionsOutput.svelte +7 -0
  22. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelWithTable.svelte +14 -0
  23. package/package/components/apps/editor/inlineScriptsPanel/utils.js +8 -0
  24. package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +3 -0
  25. package/package/components/apps/editor/settingsPanel/TableActions.svelte +86 -72
  26. package/package/components/apps/editor/settingsPanel/TableActions.svelte.d.ts +1 -1
  27. package/package/components/apps/utils.js +9 -0
  28. package/package/components/common/fileInput/FileInput.svelte +16 -0
  29. package/package/components/common/fileUpload/FileUpload.svelte +19 -19
  30. package/package/user.js +1 -1
  31. package/package.json +8 -1
@@ -12,6 +12,7 @@ export let configuration;
12
12
  export let initializing = undefined;
13
13
  export let render;
14
14
  export let customCss = undefined;
15
+ export let actions = [];
15
16
  let loaded = false;
16
17
  async function load() {
17
18
  await import('ag-grid-enterprise');
@@ -23,7 +24,15 @@ load();
23
24
  </script>
24
25
 
25
26
  {#if loaded}
26
- <AppAggridTable {id} {componentInput} {configuration} {initializing} {render} {customCss} />
27
+ <AppAggridTable
28
+ {id}
29
+ {componentInput}
30
+ {configuration}
31
+ {initializing}
32
+ {render}
33
+ {customCss}
34
+ {actions}
35
+ />
27
36
  {:else}
28
37
  <Loader2 class="animate-spin" />
29
38
  {/if}
@@ -3,6 +3,7 @@ import type { AppInput } from '../../../inputType';
3
3
  import type { ComponentCustomCSS, RichConfigurations } from '../../../types';
4
4
  import 'ag-grid-community/styles/ag-grid.css';
5
5
  import 'ag-grid-community/styles/ag-theme-alpine.css';
6
+ import type { TableAction } from '../../../editor/component';
6
7
  declare const __propDef: {
7
8
  props: {
8
9
  id: string;
@@ -12,6 +13,7 @@ declare const __propDef: {
12
13
  initializing?: boolean | undefined;
13
14
  render: boolean;
14
15
  customCss?: ComponentCustomCSS<'aggridcomponent'> | undefined;
16
+ actions?: TableAction[] | undefined;
15
17
  };
16
18
  events: {
17
19
  [evt: string]: CustomEvent<any>;
@@ -569,7 +569,6 @@ function updateCellValue(rowIndex, columnIndex, newCellValue) {
569
569
  <AppSelect
570
570
  noDefault
571
571
  noInitialize
572
- --font-size="10px"
573
572
  extraKey={'idx' + rowIndex}
574
573
  {render}
575
574
  id={actionButton.id}
@@ -107,6 +107,7 @@ let css = initCss($app.css?.checkboxcomponent, customCss);
107
107
  textStyle={css?.text?.style ?? ''}
108
108
  on:change={(e) => {
109
109
  preclickAction?.()
110
+
110
111
  value = e.detail
111
112
  if (recomputeIds) {
112
113
  recomputeIds.forEach((id) => $runnableComponents?.[id]?.cb?.forEach((cb) => cb()))
@@ -112,6 +112,10 @@ async function computeTriggerables() {
112
112
  if (c.type === 'tablecomponent') {
113
113
  r.push(...c.actionButtons.map((x) => ({ input: x.componentInput, id: x.id })));
114
114
  }
115
+ if ((c.type === 'aggridcomponent' || c.type === 'aggridcomponentee') &&
116
+ Array.isArray(c.actions)) {
117
+ r.push(...c.actions.map((x) => ({ input: x.componentInput, id: x.id })));
118
+ }
115
119
  if (c.type === 'menucomponent') {
116
120
  r.push(...c.menuItems.map((x) => ({ input: x.componentInput, id: x.id })));
117
121
  }
@@ -25,6 +25,17 @@ let resourceOnly = true;
25
25
  {/each}
26
26
  </div>
27
27
  </div>
28
+ {:else if gridItem?.data?.type === 'aggridcomponent' || gridItem?.data?.type === 'aggridcomponentee'}
29
+ <div>
30
+ <AppComponentInput bind:component={gridItem.data} {resourceOnly} />
31
+ <div class="ml-4 mt-4">
32
+ {#if Array.isArray(gridItem.data.actions)}
33
+ {#each gridItem.data.actions as actionButton (actionButton.id)}
34
+ <AppComponentInput bind:component={actionButton.data} {resourceOnly} />
35
+ {/each}
36
+ {/if}
37
+ </div>
38
+ </div>
28
39
  {:else}
29
40
  <AppComponentInput bind:component={gridItem.data} {resourceOnly} />
30
41
  {/if}
@@ -26,6 +26,14 @@ function findTableActionSettings(app, id) {
26
26
  }
27
27
  }
28
28
  }
29
+ else if (x?.data?.type === 'aggridcomponent' || x?.data?.type === 'aggridcomponentee') {
30
+ if (x?.data?.actions) {
31
+ const tableAction = x.data.actions.find((x) => x.id === id);
32
+ if (tableAction) {
33
+ return { item: { data: tableAction, id: tableAction.id }, parent: x.data.id };
34
+ }
35
+ }
36
+ }
29
37
  })
30
38
  .find((x) => x);
31
39
  }
@@ -71,6 +79,15 @@ const dispatch = createEventDispatcher();
71
79
  (x) => x.id !== tableActionSettings?.item.id
72
80
  )
73
81
  }
82
+
83
+ if (
84
+ (parent.data.type === 'aggridcomponent' || parent.data.type === 'aggridcomponentee') &&
85
+ Array.isArray(parent.data.actions)
86
+ ) {
87
+ parent.data.actions = parent.data.actions.filter(
88
+ (x) => x.id !== tableActionSettings?.item.id
89
+ )
90
+ }
74
91
  }
75
92
  }}
76
93
  />
@@ -41,6 +41,10 @@ export function dfs(grid, id, subgrids) {
41
41
  else if (item.data.type == 'menucomponent' && item.data.menuItems.find((x) => id == x.id)) {
42
42
  return [item.id, id];
43
43
  }
44
+ else if ((item.data.type == 'aggridcomponent' || item.data.type == 'aggridcomponentee') &&
45
+ item.data.actions?.find((x) => id == x.id)) {
46
+ return [item.id, id];
47
+ }
44
48
  else {
45
49
  for (let i = 0; i < (item.data.numberOfSubgrids ?? 0); i++) {
46
50
  const res = dfs(subgrids[`${item.id}-${i}`], id, subgrids);
@@ -120,6 +124,10 @@ export function allsubIds(app, parentId) {
120
124
  if (item.data.type === 'tablecomponent') {
121
125
  subIds.push(...item.data.actionButtons?.map((x) => x.id));
122
126
  }
127
+ if (item.data.type === 'aggridcomponent' ||
128
+ (item.data.type === 'aggridcomponentee' && Array.isArray(item.data.actions))) {
129
+ subIds.push(...item.data.actions?.map((x) => x.id));
130
+ }
123
131
  if (item.data.type === 'menucomponent') {
124
132
  subIds.push(...item.data.menuItems?.map((x) => x.id));
125
133
  }
@@ -136,6 +144,10 @@ export function getNextGridItemId(app) {
136
144
  if (x.data.type === 'tablecomponent') {
137
145
  return [x.id, ...x.data.actionButtons.map((x) => x.id)];
138
146
  }
147
+ else if ((x.data.type === 'aggridcomponent' || x.data.type === 'aggridcomponentee') &&
148
+ Array.isArray(x.data.actions)) {
149
+ return [x.id, ...x.data.actions.map((x) => x.id)];
150
+ }
139
151
  else if (x.data.type === 'menucomponent') {
140
152
  return [x.id, ...x.data.menuItems.map((x) => x.id)];
141
153
  }
@@ -248,6 +260,7 @@ export function appComponentFromType(type, overrideConfiguration, extra) {
248
260
  customCss: ccomponents[type].customCss,
249
261
  recomputeIds: init.recomputeIds ? [] : undefined,
250
262
  actionButtons: init.actionButtons ? [] : undefined,
263
+ actions: [],
251
264
  menuItems: init.menuItems ? [] : undefined,
252
265
  numberOfSubgrids: init.numberOfSubgrids,
253
266
  horizontalAlignment: init.horizontalAlignment,
@@ -312,6 +325,16 @@ export function copyComponent(app, item, parentGrid, subgrids, alreadyVisited) {
312
325
  })) ?? []
313
326
  };
314
327
  }
328
+ else if (item.data.type === 'aggridcomponent' || item.data.type === 'aggridcomponentee') {
329
+ return {
330
+ ...item.data,
331
+ id,
332
+ actionButtons: (item.data.actions ?? []).map((x) => ({
333
+ ...x,
334
+ id: x.id.replace(`${item.id}_`, `${id}_`)
335
+ })) ?? []
336
+ };
337
+ }
315
338
  else if (item.data.type === 'menucomponent') {
316
339
  return {
317
340
  ...item.data,
@@ -339,6 +362,9 @@ export function getAllSubgridsAndComponentIds(app, component) {
339
362
  if (component.type === 'tablecomponent') {
340
363
  components.push(...component.actionButtons?.map((x) => x.id));
341
364
  }
365
+ if (component.type === 'aggridcomponent' || component.type === 'aggridcomponentee') {
366
+ components.push(...(component.actions?.map((x) => x.id) ?? []));
367
+ }
342
368
  if (component.type === 'menucomponent') {
343
369
  components.push(...component.menuItems?.map((x) => x.id));
344
370
  }
@@ -365,6 +391,10 @@ export function getAllGridItems(app) {
365
391
  if (x?.data?.type === 'tablecomponent') {
366
392
  return [x, ...x?.data?.actionButtons?.map((x) => ({ data: x, id: x.id }))];
367
393
  }
394
+ else if ((x?.data?.type === 'aggridcomponent' || x?.data?.type === 'aggridcomponentee') &&
395
+ Array.isArray(x?.data?.actions)) {
396
+ return [x, ...x?.data?.actions?.map((x) => ({ data: x, id: x.id }))];
397
+ }
368
398
  else if (x?.data?.type === 'menucomponent') {
369
399
  return [x, ...x?.data?.menuItems?.map((x) => ({ data: x, id: x.id }))];
370
400
  }
@@ -306,6 +306,7 @@ function mouseOut() {
306
306
  bind:initializing
307
307
  componentInput={component.componentInput}
308
308
  customCss={component.customCss}
309
+ actions={component.actions ?? []}
309
310
  {render}
310
311
  />
311
312
  {:else if component.type === 'aggridcomponentee'}
@@ -316,6 +317,7 @@ function mouseOut() {
316
317
  bind:initializing
317
318
  componentInput={component.componentInput}
318
319
  customCss={component.customCss}
320
+ actions={component.actions ?? []}
319
321
  {render}
320
322
  />
321
323
  {:else if component.type === 'textcomponent'}
@@ -35,6 +35,10 @@ export function left(event) {
35
35
  if (left.data.type === 'tablecomponent' && left.data.actionButtons.length >= 1) {
36
36
  $selectedComponent = [left.data.actionButtons[left.data.actionButtons.length - 1].id];
37
37
  }
38
+ else if ((left.data.type === 'aggridcomponent' || left.data.type === 'aggridcomponentee') && Array.isArray(left.data.actions) &&
39
+ left.data.actions.length >= 1) {
40
+ $selectedComponent = [left.data.actions[left.data.actions.length - 1].id];
41
+ }
38
42
  else {
39
43
  $selectedComponent = [left.id];
40
44
  }
@@ -64,12 +64,16 @@ export type AgChartsComponentEe = BaseComponent<'agchartscomponentee'> & {
64
64
  datasets: RichConfiguration | undefined;
65
65
  };
66
66
  export type ScatterChartComponent = BaseComponent<'scatterchartcomponent'>;
67
+ export type TableAction = BaseAppComponent & (ButtonComponent | CheckboxComponent | SelectComponent) & GridItem;
67
68
  export type TableComponent = BaseComponent<'tablecomponent'> & {
68
- actionButtons: (BaseAppComponent & ButtonComponent & GridItem)[];
69
+ actionButtons: TableAction[];
70
+ };
71
+ export type AggridComponent = BaseComponent<'aggridcomponent'> & {
72
+ actions: TableAction[];
69
73
  };
70
- export type AggridComponent = BaseComponent<'aggridcomponent'>;
71
74
  export type AggridComponentEe = BaseComponent<'aggridcomponentee'> & {
72
75
  license: string;
76
+ actions: TableAction[];
73
77
  };
74
78
  export type DisplayComponent = BaseComponent<'displaycomponent'>;
75
79
  export type LogComponent = BaseComponent<'logcomponent'>;
@@ -181,6 +185,7 @@ export interface InitialAppComponent extends Partial<Aligned> {
181
185
  numberOfSubgrids?: number;
182
186
  recomputeIds?: boolean;
183
187
  actionButtons?: boolean;
188
+ actions?: boolean;
184
189
  menuItems?: boolean;
185
190
  tabs?: string[];
186
191
  panes?: number[];
@@ -1863,6 +1868,12 @@ export declare const components: {
1863
1868
  readonly selectOptions: readonly ["normal", "compact", "comfortable"];
1864
1869
  readonly tooltip: "Change the row height";
1865
1870
  };
1871
+ readonly wrapActions: {
1872
+ readonly type: "static";
1873
+ readonly fieldType: "boolean";
1874
+ readonly value: false;
1875
+ readonly tooltip: "When true, actions will wrap to the next line. Otherwise, the column will grow to fit the actions.";
1876
+ };
1866
1877
  };
1867
1878
  readonly componentInput: StaticAppInput;
1868
1879
  };
@@ -1930,6 +1941,12 @@ export declare const components: {
1930
1941
  readonly selectOptions: readonly ["normal", "compact", "comfortable"];
1931
1942
  readonly tooltip: "Change the row height";
1932
1943
  };
1944
+ readonly wrapActions: {
1945
+ readonly type: "static";
1946
+ readonly fieldType: "boolean";
1947
+ readonly value: false;
1948
+ readonly tooltip: "When true, actions will wrap to the next line. Otherwise, the column will grow to fit the actions.";
1949
+ };
1933
1950
  };
1934
1951
  readonly componentInput: StaticAppInput;
1935
1952
  };
@@ -3072,6 +3089,12 @@ export declare const components: {
3072
3089
  readonly value: 3;
3073
3090
  };
3074
3091
  readonly markers: StaticAppInput;
3092
+ readonly lock: {
3093
+ readonly fieldType: "boolean";
3094
+ readonly type: "static";
3095
+ readonly value: false;
3096
+ readonly tooltip: "Lock the map to prevent user interaction";
3097
+ };
3075
3098
  };
3076
3099
  };
3077
3100
  };
@@ -313,6 +313,12 @@ const aggridcomponentconst = {
313
313
  value: 'normal',
314
314
  selectOptions: ['normal', 'compact', 'comfortable'],
315
315
  tooltip: 'Change the row height'
316
+ },
317
+ wrapActions: {
318
+ type: 'static',
319
+ fieldType: 'boolean',
320
+ value: false,
321
+ tooltip: 'When true, actions will wrap to the next line. Otherwise, the column will grow to fit the actions.'
316
322
  }
317
323
  },
318
324
  componentInput: {
@@ -2409,6 +2415,12 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
2409
2415
  title: 'London'
2410
2416
  }
2411
2417
  ]
2418
+ },
2419
+ lock: {
2420
+ fieldType: 'boolean',
2421
+ type: 'static',
2422
+ value: false,
2423
+ tooltip: 'Lock the map to prevent user interaction'
2412
2424
  }
2413
2425
  }
2414
2426
  }
@@ -67,6 +67,13 @@ function renameId(newId) {
67
67
  propagateRename(old, c.id);
68
68
  }
69
69
  }
70
+ if (item?.data.type == 'aggridcomponent' || item?.data.type == 'aggridcomponentee') {
71
+ for (let c of item.data.actions ?? []) {
72
+ let old = c.id;
73
+ c.id = c.id.replace(id + '_', newId + '_');
74
+ propagateRename(old, c.id);
75
+ }
76
+ }
70
77
  if (item?.data.type === 'menucomponent') {
71
78
  for (let c of item.data.menuItems) {
72
79
  let old = c.id;
@@ -84,6 +91,12 @@ function renameComponent(from, to, data) {
84
91
  renameComponent(from, to, c);
85
92
  }
86
93
  }
94
+ if ((data.type == 'aggridcomponent' || data.type == 'aggridcomponentee') &&
95
+ Array.isArray(data.actions)) {
96
+ for (let c of data.actions) {
97
+ renameComponent(from, to, c);
98
+ }
99
+ }
87
100
  if (data.type === 'menucomponent') {
88
101
  for (let c of data.menuItems) {
89
102
  renameComponent(from, to, c);
@@ -10,4 +10,11 @@ export let gridItem;
10
10
  {/each}
11
11
  </div>
12
12
  {/if}
13
+ {#if (gridItem.data.type === 'aggridcomponent' || gridItem.data.type === 'aggridcomponentee') && gridItem.data.actions?.length > 0}
14
+ <div class="ml-2 border-l">
15
+ {#each gridItem.data.actions as action, index}
16
+ <Output id={action.id} first={index === 0} label="Table action" />
17
+ {/each}
18
+ </div>
19
+ {/if}
13
20
  </div>
@@ -30,6 +30,20 @@ export let gridItem;
30
30
  {/each}
31
31
  {/if}
32
32
 
33
+ {#if (gridItem?.data?.type === 'aggridcomponent' || gridItem?.data?.type === 'aggridcomponentee') && Array.isArray(gridItem.data.actions)}
34
+ {#each gridItem.data.actions as actionButton, index (index)}
35
+ {#if actionButton?.id === $selectedComponentInEditor || actionButton?.id + '_transformer' === $selectedComponentInEditor}
36
+ <InlineScriptEditorPanel
37
+ on:createScriptFromInlineScript
38
+ componentType={actionButton.type}
39
+ id={actionButton.id}
40
+ transformer={$selectedComponentInEditor?.endsWith('_transformer')}
41
+ bind:componentInput={actionButton.componentInput}
42
+ />
43
+ {/if}
44
+ {/each}
45
+ {/if}
46
+
33
47
  {#if gridItem?.data?.type === 'menucomponent'}
34
48
  {#each gridItem.data.menuItems as actionButton, index (index)}
35
49
  {#if actionButton?.id === $selectedComponentInEditor || actionButton?.id + '_transformer' === $selectedComponentInEditor}
@@ -46,6 +46,14 @@ function processGridItemRunnable(gridItem, list) {
46
46
  processRunnable(actionButton.componentInput.runnable, actionButton.componentInput.transformer, actionButton.id, list);
47
47
  });
48
48
  }
49
+ if (component.type === 'aggridcomponent' || component.type === 'aggridcomponentee') {
50
+ component.actions?.forEach((actionButton) => {
51
+ if (actionButton.componentInput?.type !== 'runnable') {
52
+ return;
53
+ }
54
+ processRunnable(actionButton.componentInput.runnable, actionButton.componentInput.transformer, actionButton.id, list);
55
+ });
56
+ }
49
57
  if (component.type === 'menucomponent') {
50
58
  component.menuItems?.forEach((menuItem) => {
51
59
  if (menuItem.componentInput?.type !== 'runnable') {
@@ -294,6 +294,7 @@ function isMac() {
294
294
  />
295
295
  {:else if componentSettings.item.data.type === 'aggridcomponentee'}
296
296
  <GridAgGridLicenseKey bind:license={componentSettings.item.data.license} />
297
+ <TableActions id={component.id} bind:components={componentSettings.item.data.actions} />
297
298
  {:else if componentSettings.item.data.type === 'agchartscomponentee'}
298
299
  <GridAgChartsLicenseKe bind:license={componentSettings.item.data.license} />
299
300
  {:else if componentSettings.item.data.type === 'steppercomponent'}
@@ -323,6 +324,8 @@ function isMac() {
323
324
  bind:panes={componentSettings.item.data.panes}
324
325
  bind:component={componentSettings.item.data}
325
326
  />
327
+ {:else if componentSettings.item.data.type === 'aggridcomponent'}
328
+ <TableActions id={component.id} bind:components={componentSettings.item.data.actions} />
326
329
  {:else if componentSettings.item.data.type === 'tablecomponent' && Array.isArray(componentSettings.item.data.actionButtons)}
327
330
  <TableActions id={component.id} bind:components={componentSettings.item.data.actionButtons} />
328
331
  {:else if componentSettings.item.data.type === 'menucomponent' && Array.isArray(componentSettings.item.data.menuItems)}
@@ -2,14 +2,23 @@
2
2
  import Button from '../../../common/button/Button.svelte';
3
3
  import { getNextId } from '../../../flows/idUtils';
4
4
  import { classNames } from '../../../../utils';
5
- import { getContext } from 'svelte';
5
+ import { getContext, onMount } from 'svelte';
6
6
  import { appComponentFromType } from '../appUtils';
7
7
  import PanelSection from './common/PanelSection.svelte';
8
8
  import { Inspect, List, ToggleRightIcon, Trash } from 'lucide-svelte';
9
9
  export let components;
10
+ // Migration code:
11
+ onMount(() => {
12
+ if (components === undefined) {
13
+ components = [];
14
+ }
15
+ });
10
16
  export let id;
11
17
  const { selectedComponent, app, errorByComponent } = getContext('AppViewerContext');
12
18
  function addComponent(typ) {
19
+ if (!components) {
20
+ return;
21
+ }
13
22
  const actionId = getNextId(components.map((x) => x.id.split('_')[1]));
14
23
  const newComponent = {
15
24
  ...appComponentFromType(typ)(`${id}_${actionId}`),
@@ -19,6 +28,9 @@ function addComponent(typ) {
19
28
  $app = $app;
20
29
  }
21
30
  function deleteComponent(cid) {
31
+ if (!components) {
32
+ return;
33
+ }
22
34
  components = components.filter((x) => x.id !== cid);
23
35
  delete $errorByComponent[cid];
24
36
  $selectedComponent = [id];
@@ -26,77 +38,79 @@ function deleteComponent(cid) {
26
38
  }
27
39
  </script>
28
40
 
29
- <PanelSection title={`Table Actions`}>
30
- {#if components.length == 0}
31
- <span class="text-xs text-tertiary">No action buttons</span>
32
- {/if}
33
- {#each components as component}
34
- <!-- svelte-ignore a11y-no-static-element-interactions -->
35
- <div
36
- class={classNames(
37
- 'w-full text-xs font-bold gap-1 truncate py-1.5 px-2 cursor-pointer transition-all justify-between flex items-center border border-gray-3 rounded-md',
38
- 'bg-surface hover:bg-surface-hover focus:border-primary text-secondary',
39
- $selectedComponent?.includes(component.id) ? 'outline outline-blue-500 bg-red-400' : ''
40
- )}
41
- on:click={() => {
42
- $selectedComponent = [component.id]
43
- }}
44
- on:keypress
45
- >
46
- <Badge color="dark-indigo">
47
- {component.id}
48
- </Badge>
41
+ {#if components}
42
+ <PanelSection title={`Table Actions`}>
43
+ {#if components.length == 0}
44
+ <span class="text-xs text-tertiary">No action buttons</span>
45
+ {/if}
46
+ {#each components as component}
47
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
48
+ <div
49
+ class={classNames(
50
+ 'w-full text-xs font-bold gap-1 truncate py-1.5 px-2 cursor-pointer transition-all justify-between flex items-center border border-gray-3 rounded-md',
51
+ 'bg-surface hover:bg-surface-hover focus:border-primary text-secondary',
52
+ $selectedComponent?.includes(component.id) ? 'outline outline-blue-500 bg-red-400' : ''
53
+ )}
54
+ on:click={() => {
55
+ $selectedComponent = [component.id]
56
+ }}
57
+ on:keypress
58
+ >
59
+ <Badge color="dark-indigo">
60
+ {component.id}
61
+ </Badge>
49
62
 
50
- <div>
51
- {#if component.type == 'buttoncomponent'}
52
- Button
53
- {:else if component.type == 'selectcomponent'}
54
- Select
55
- {:else if component.type == 'checkboxcomponent'}
56
- Toggle
57
- {/if}
58
- </div>
59
- <div>
60
- <Button
61
- variant="border"
62
- color="red"
63
- on:click={() => deleteComponent(component.id)}
64
- startIcon={{ icon: Trash }}
65
- iconOnly
66
- />
63
+ <div>
64
+ {#if component.type == 'buttoncomponent'}
65
+ Button
66
+ {:else if component.type == 'selectcomponent'}
67
+ Select
68
+ {:else if component.type == 'checkboxcomponent'}
69
+ Toggle
70
+ {/if}
71
+ </div>
72
+ <div>
73
+ <Button
74
+ variant="border"
75
+ color="red"
76
+ on:click={() => deleteComponent(component.id)}
77
+ startIcon={{ icon: Trash }}
78
+ iconOnly
79
+ />
80
+ </div>
67
81
  </div>
82
+ {/each}
83
+ <div class="w-full flex gap-2">
84
+ <Button
85
+ btnClasses="gap-1 flex items-center text-sm text-tertiary"
86
+ wrapperClasses="w-full"
87
+ color="light"
88
+ variant="border"
89
+ on:click={() => addComponent('buttoncomponent')}
90
+ title="Add Button"
91
+ >
92
+ + <Inspect size={14} />
93
+ </Button>
94
+ <Button
95
+ btnClasses="gap-1 flex items-center text-sm text-tertiary"
96
+ wrapperClasses="w-full"
97
+ color="light"
98
+ variant="border"
99
+ on:click={() => addComponent('checkboxcomponent')}
100
+ title="Add Toggle"
101
+ >
102
+ + <ToggleRightIcon size={14} />
103
+ </Button>
104
+ <Button
105
+ btnClasses="gap-1 flex items-center text-sm text-tertiary"
106
+ wrapperClasses="w-full"
107
+ color="light"
108
+ variant="border"
109
+ on:click={() => addComponent('selectcomponent')}
110
+ title="Add Select"
111
+ >
112
+ + <List size={14} />
113
+ </Button>
68
114
  </div>
69
- {/each}
70
- <div class="w-full flex gap-2">
71
- <Button
72
- btnClasses="gap-1 flex items-center text-sm text-tertiary"
73
- wrapperClasses="w-full"
74
- color="light"
75
- variant="border"
76
- on:click={() => addComponent('buttoncomponent')}
77
- title="Add Button"
78
- >
79
- + <Inspect size={14} />
80
- </Button>
81
- <Button
82
- btnClasses="gap-1 flex items-center text-sm text-tertiary"
83
- wrapperClasses="w-full"
84
- color="light"
85
- variant="border"
86
- on:click={() => addComponent('checkboxcomponent')}
87
- title="Add Toggle"
88
- >
89
- + <ToggleRightIcon size={14} />
90
- </Button>
91
- <Button
92
- btnClasses="gap-1 flex items-center text-sm text-tertiary"
93
- wrapperClasses="w-full"
94
- color="light"
95
- variant="border"
96
- on:click={() => addComponent('selectcomponent')}
97
- title="Add Select"
98
- >
99
- + <List size={14} />
100
- </Button>
101
- </div>
102
- </PanelSection>
115
+ </PanelSection>
116
+ {/if}
@@ -3,7 +3,7 @@ import type { BaseAppComponent } from '../../types';
3
3
  import type { ButtonComponent, CheckboxComponent, SelectComponent } from '../component';
4
4
  declare const __propDef: {
5
5
  props: {
6
- components: (BaseAppComponent & (ButtonComponent | CheckboxComponent | SelectComponent))[];
6
+ components: (BaseAppComponent & (ButtonComponent | CheckboxComponent | SelectComponent))[] | undefined;
7
7
  id: string;
8
8
  };
9
9
  events: {
@@ -235,6 +235,15 @@ export function getAllScriptNames(app) {
235
235
  }
236
236
  });
237
237
  }
238
+ if (gridItem.data.type === 'aggridcomponent' || gridItem.data.type === 'aggridcomponentee') {
239
+ gridItem.data.actions?.forEach((actionButton) => {
240
+ if (actionButton.componentInput?.type === 'runnable') {
241
+ if (actionButton.componentInput.runnable?.type === 'runnableByName') {
242
+ acc.push(actionButton.componentInput.runnable.name);
243
+ }
244
+ }
245
+ });
246
+ }
238
247
  if (gridItem.data.type === 'menucomponent') {
239
248
  gridItem.data.menuItems.forEach((menuItem) => {
240
249
  if (menuItem.componentInput?.type === 'runnable') {
@@ -64,6 +64,20 @@ async function convertFile(file) {
64
64
  }
65
65
  });
66
66
  }
67
+ function handleDragOver(event) {
68
+ event.preventDefault();
69
+ if (event.dataTransfer) {
70
+ event.dataTransfer.dropEffect = 'copy';
71
+ }
72
+ }
73
+ function handleDrop(event) {
74
+ event.preventDefault();
75
+ if (event.dataTransfer) {
76
+ if (event.dataTransfer.files && event.dataTransfer.files.length) {
77
+ onChange(event.dataTransfer.files);
78
+ }
79
+ }
80
+ }
67
81
  function removeFile(index) {
68
82
  if (!files)
69
83
  return;
@@ -99,6 +113,8 @@ export function clearFiles() {
99
113
  duration-200 rounded-lg p-1`,
100
114
  c
101
115
  )}
116
+ on:dragover={handleDragOver}
117
+ on:drop={handleDrop}
102
118
  {style}
103
119
  >
104
120
  {#if !hideIcon && !files}