windmill-components 1.83.1 → 1.83.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/components/ArgInput.svelte +35 -27
  2. package/components/DisplayResult.svelte +10 -1
  3. package/components/DisplayResult.svelte.d.ts +1 -0
  4. package/components/FlowGraphViewer.svelte +4 -20
  5. package/components/FlowJobResult.svelte +2 -1
  6. package/components/FlowJobResult.svelte.d.ts +1 -0
  7. package/components/FlowStatusViewer.svelte +1 -0
  8. package/components/RunForm.svelte +6 -2
  9. package/components/ScriptBuilder.svelte +6 -4
  10. package/components/ScriptBuilder.svelte.d.ts +1 -0
  11. package/components/apps/components/display/PlotlyHtml.svelte +26 -13
  12. package/components/apps/components/display/table/AppAggridTable.svelte +29 -17
  13. package/components/apps/components/display/table/AppTable.svelte +17 -4
  14. package/components/apps/components/display/table/AppTableFooter.svelte +2 -2
  15. package/components/apps/components/display/table/AppTableFooter.svelte.d.ts +1 -1
  16. package/components/apps/components/layout/AppDrawer.svelte +32 -14
  17. package/components/apps/editor/AppEditor.svelte +8 -4
  18. package/components/apps/editor/component/components.d.ts +27 -14
  19. package/components/apps/editor/component/components.js +28 -14
  20. package/components/apps/editor/componentsPanel/CssProperty.svelte +11 -6
  21. package/components/apps/editor/componentsPanel/CssProperty.svelte.d.ts +4 -2
  22. package/components/apps/editor/componentsPanel/ListItem.svelte +14 -4
  23. package/components/apps/editor/componentsPanel/ListItem.svelte.d.ts +5 -0
  24. package/components/apps/editor/componentsPanel/QuickStyleMenu.svelte +62 -21
  25. package/components/apps/editor/componentsPanel/QuickStyleMenu.svelte.d.ts +5 -2
  26. package/components/apps/editor/componentsPanel/QuickStyleProperty.svelte +1 -0
  27. package/components/apps/editor/componentsPanel/quickStyleProperties.d.ts +29 -503
  28. package/components/apps/editor/componentsPanel/quickStyleProperties.js +97 -98
  29. package/components/apps/editor/componentsPanel/store.d.ts +1 -0
  30. package/components/apps/editor/componentsPanel/store.js +1 -0
  31. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte +2 -3
  32. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +1 -1
  33. package/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte +17 -3
  34. package/components/apps/editor/settingsPanel/StylePanel.svelte +2 -0
  35. package/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte +1 -1
  36. package/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte +2 -2
  37. package/components/flows/content/FlowLoop.svelte +26 -14
  38. package/components/flows/flowStore.js +4 -40
  39. package/components/flows/utils.js +16 -22
  40. package/components/propertyPicker/ObjectViewer.svelte +7 -1
  41. package/gen/core/OpenAPI.js +1 -1
  42. package/gen/models/FlowModule.d.ts +0 -1
  43. package/gen/services/JobService.d.ts +15 -0
  44. package/gen/services/JobService.js +18 -1
  45. package/infer.js +2 -0
  46. package/init_scripts/python_failure_module.d.ts +2 -0
  47. package/init_scripts/{python_failure_module.py → python_failure_module.js} +2 -2
  48. package/init_scripts/python_init_code.d.ts +2 -0
  49. package/init_scripts/{python_init_code.py → python_init_code.js} +3 -3
  50. package/init_scripts/python_init_code_clear.d.ts +2 -0
  51. package/init_scripts/python_init_code_clear.js +5 -0
  52. package/init_scripts/python_init_code_trigger.d.ts +2 -0
  53. package/init_scripts/{python_init_code_trigger.py → python_init_code_trigger.js} +2 -2
  54. package/package.json +673 -673
  55. package/script_helpers.d.ts +5 -5
  56. package/script_helpers.js +15 -5
  57. package/stores.d.ts +4 -3
  58. package/stores.js +23 -19
  59. package/utils.d.ts +1 -0
  60. package/utils.js +8 -0
  61. package/init_scripts/python_init_code_clear.py +0 -5
@@ -140,6 +140,7 @@ $: {
140
140
  }
141
141
  $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding);
142
142
  let redraw = 0;
143
+ let itemsLimit = 50;
143
144
  </script>
144
145
 
145
146
  <div class="flex flex-col w-full min-w-[250px]">
@@ -249,34 +250,41 @@ let redraw = 0;
249
250
  {#key redraw}
250
251
  {#if Array.isArray(value)}
251
252
  {#each value ?? [] as v, i}
252
- <div class="flex max-w-md mt-1 w-full items-center">
253
- {#if itemsType?.type == 'number'}
254
- <input type="number" bind:value={v} />
255
- {:else if itemsType?.type == 'string' && itemsType?.contentEncoding == 'base64'}
256
- <input
257
- type="file"
258
- class="my-6"
259
- on:change={(x) => fileChanged(x, (val) => (value[i] = val))}
260
- multiple={false}
261
- />
262
- {:else if itemsType?.type == 'object'}
263
- <JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
264
- {:else}
265
- <input type="text" bind:value={v} />
266
- {/if}
267
- <button
268
- transition:fade|local={{ duration: 100 }}
269
- class="rounded-full p-1 bg-white/60 duration-200 hover:bg-gray-200"
270
- aria-label="Clear"
271
- on:click={() => {
272
- value.splice(i, 1)
273
- redraw += 1
274
- }}
275
- >
276
- <X size={14} />
277
- </button>
278
- </div>
253
+ {#if i < itemsLimit}
254
+ <div class="flex max-w-md mt-1 w-full items-center">
255
+ {#if itemsType?.type == 'number'}
256
+ <input type="number" bind:value={v} />
257
+ {:else if itemsType?.type == 'string' && itemsType?.contentEncoding == 'base64'}
258
+ <input
259
+ type="file"
260
+ class="my-6"
261
+ on:change={(x) => fileChanged(x, (val) => (value[i] = val))}
262
+ multiple={false}
263
+ />
264
+ {:else if itemsType?.type == 'object'}
265
+ <JsonEditor code={JSON.stringify(v, null, 2)} bind:value={v} />
266
+ {:else}
267
+ <input type="text" bind:value={v} />
268
+ {/if}
269
+ <button
270
+ transition:fade|local={{ duration: 100 }}
271
+ class="rounded-full p-1 bg-white/60 duration-200 hover:bg-gray-200"
272
+ aria-label="Clear"
273
+ on:click={() => {
274
+ value.splice(i, 1)
275
+ redraw += 1
276
+ }}
277
+ >
278
+ <X size={14} />
279
+ </button>
280
+ </div>
281
+ {/if}
279
282
  {/each}
283
+ {#if value.length > itemsLimit}
284
+ <button on:click={() => (itemsLimit += 50)} class="text-xs py-2 text-blue-600"
285
+ >{itemsLimit}/{value.length}: Load 50 more...</button
286
+ >
287
+ {/if}
280
288
  {/if}
281
289
  {/key}
282
290
  </div>
@@ -8,6 +8,7 @@ import { ClipboardCopy } from 'lucide-svelte';
8
8
  import Portal from 'svelte-portal';
9
9
  export let result;
10
10
  export let requireHtmlApproval = false;
11
+ export let filename = undefined;
11
12
  let resultKind;
12
13
  $: resultKind = inferResultKind(result);
13
14
  let forceJson = false;
@@ -214,7 +215,15 @@ let jsonViewer;
214
215
  >
215
216
  </div>
216
217
  {:else}
217
- <Highlight language={json} code={JSON.stringify(result, null, 4).replace(/\\n/g, '\n')} />
218
+ {@const jsonStr = JSON.stringify(result, null, 4).replace(/\\n/g, '\n')}
219
+ {#if jsonStr.length > 10000}
220
+ JSON too large. <a
221
+ download="{filename ?? 'result'}.json"
222
+ href="data:text/json;charset=utf-8,{encodeURIComponent(jsonStr)}">Download</a
223
+ >
224
+ {:else}
225
+ <Highlight language={json} code={jsonStr} />
226
+ {/if}
218
227
  {/if}
219
228
  {:else}
220
229
  <div class="text-gray-500 text-sm">No result: {JSON.stringify(result)}</div>
@@ -3,6 +3,7 @@ declare const __propDef: {
3
3
  props: {
4
4
  result: any;
5
5
  requireHtmlApproval?: boolean | undefined;
6
+ filename?: string | undefined;
6
7
  };
7
8
  events: {
8
9
  [evt: string]: CustomEvent<any>;
@@ -34,11 +34,7 @@ let topHeight = 0;
34
34
  </div>
35
35
  <div class="text-2xs mb-4">
36
36
  <h3 class="mb-2">Step Inputs</h3>
37
- <InputTransformsViewer
38
- inputTransforms={stepDetail?.value?.input_transforms ??
39
- stepDetail?.input_transforms ??
40
- {}}
41
- />
37
+ <InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
42
38
  </div>
43
39
  {#if stepDetail.value.path.startsWith('hub/')}
44
40
  <div class="mt-6">
@@ -54,11 +50,7 @@ let topHeight = 0;
54
50
  {:else if stepDetail.value.type == 'rawscript'}
55
51
  <div class="text-2xs mb-4">
56
52
  <h3 class="mb-2">Step Inputs</h3>
57
- <InputTransformsViewer
58
- inputTransforms={stepDetail?.value?.input_transforms ??
59
- stepDetail?.input_transforms ??
60
- {}}
61
- />
53
+ <InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
62
54
  </div>
63
55
 
64
56
  <h3 class="mb-2">Code</h3>
@@ -107,11 +99,7 @@ let topHeight = 0;
107
99
  {:else if stepDetail.value.type == 'rawscript'}
108
100
  <div class="text-2xs mb-4">
109
101
  <h3 class="mb-2">Step Inputs</h3>
110
- <InputTransformsViewer
111
- inputTransforms={stepDetail?.value?.input_transforms ??
112
- stepDetail?.input_transforms ??
113
- {}}
114
- />
102
+ <InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
115
103
  </div>
116
104
 
117
105
  <h3 class="mb-2"
@@ -135,11 +123,7 @@ let topHeight = 0;
135
123
  </div>
136
124
  <div class="text-2xs mb-4">
137
125
  <h3 class="mb-2">Step Inputs</h3>
138
- <InputTransformsViewer
139
- inputTransforms={stepDetail?.value?.input_transforms ??
140
- stepDetail?.input_transforms ??
141
- {}}
142
- />
126
+ <InputTransformsViewer inputTransforms={stepDetail?.value?.input_transforms ?? {}} />
143
127
  </div>
144
128
  {#if stepDetail.value.path.startsWith('hub/')}
145
129
  <div class="mt-6">
@@ -6,6 +6,7 @@ export let logs;
6
6
  export let col = false;
7
7
  export let noBorder = false;
8
8
  export let loading;
9
+ export let filename = undefined;
9
10
  </script>
10
11
 
11
12
  <div
@@ -15,7 +16,7 @@ export let loading;
15
16
  <div class="bg-white {col ? '' : 'max-h-80'} h-full p-1 overflow-auto relative">
16
17
  <span class="text-gray-500">Result</span>
17
18
  {#if result}
18
- <DisplayResult {result} />
19
+ <DisplayResult {filename} {result} />
19
20
  {:else if loading}
20
21
  <Loader2 class="animate-spin" />
21
22
  {:else}
@@ -6,6 +6,7 @@ declare const __propDef: {
6
6
  col?: boolean | undefined;
7
7
  noBorder?: boolean | undefined;
8
8
  loading: any;
9
+ filename?: string | undefined;
9
10
  };
10
11
  events: {
11
12
  [evt: string]: CustomEvent<any>;
@@ -440,6 +440,7 @@ function isSuccess(arg) {
440
440
  {@const node = localFlowModuleStates[selectedNode]}
441
441
  {#if selectedNode == 'end'}
442
442
  <FlowJobResult
443
+ filename={job.id}
443
444
  loading={job['running']}
444
445
  noBorder
445
446
  col
@@ -6,7 +6,7 @@ import SchemaForm from './SchemaForm.svelte';
6
6
  import { Badge, Button } from './common';
7
7
  import SharedBadge from './SharedBadge.svelte';
8
8
  import Toggle from './Toggle.svelte';
9
- import { userStore } from '../stores';
9
+ import { runFormStore, userStore } from '../stores';
10
10
  import Tooltip from './Tooltip.svelte';
11
11
  import CliHelpBox from './CliHelpBox.svelte';
12
12
  import InlineCodeCopy from './InlineCodeCopy.svelte';
@@ -21,7 +21,11 @@ export let loading = false;
21
21
  export let noVariablePicker = false;
22
22
  export let viewCliRun = false;
23
23
  export let isFlow;
24
- export let args = decodeArgs($page.url.searchParams.get('args') ?? undefined);
24
+ export let args = {};
25
+ if ($runFormStore) {
26
+ args = $runFormStore;
27
+ $runFormStore = undefined;
28
+ }
25
29
  export function run() {
26
30
  runAction(scheduledForStr, args, invisible_to_owner);
27
31
  }
@@ -21,6 +21,7 @@ export let initialPath = '';
21
21
  export let template = 'script';
22
22
  export let initialArgs = {};
23
23
  export let lockedLanguage = false;
24
+ export let topHash = undefined;
24
25
  const langs = [
25
26
  ['Typescript', Script.language.DENO],
26
27
  ['Python', Script.language.PYTHON3],
@@ -70,7 +71,7 @@ async function editScript(leave) {
70
71
  await inferArgs(script.language, script.content, script.schema);
71
72
  }
72
73
  catch (error) {
73
- sendUserToast(`Impossible to infer the schema. Assuming this is a script without main function`, true);
74
+ sendUserToast(`The main signature was not parsable. This script is considered to be without main function`);
74
75
  }
75
76
  const newHash = await ScriptService.createScript({
76
77
  workspace: $workspaceStore,
@@ -79,7 +80,7 @@ async function editScript(leave) {
79
80
  summary: script.summary,
80
81
  description: script.description ?? '',
81
82
  content: script.content,
82
- parent_hash: script.hash != '' ? script.hash : undefined,
83
+ parent_hash: script.hash != '' ? topHash ?? script.hash : undefined,
83
84
  schema: script.schema,
84
85
  is_template: script.is_template,
85
86
  language: script.language,
@@ -93,10 +94,11 @@ async function editScript(leave) {
93
94
  else {
94
95
  await goto(`/scripts/edit/${newHash}?step=2`);
95
96
  script.hash = newHash;
97
+ topHash = undefined;
96
98
  }
97
99
  }
98
100
  catch (error) {
99
- sendUserToast(`Impossible to save the script: ${error.body || error.message}`, true);
101
+ sendUserToast(`Error while saving the script: ${error.body || error.message}`, true);
100
102
  }
101
103
  loadingSave = false;
102
104
  }
@@ -107,7 +109,7 @@ async function changeStep(step) {
107
109
  await inferArgs(script.language, script.content, script.schema);
108
110
  }
109
111
  catch (error) {
110
- console.info('Impossible to infer the schema. Assuming this is a script without main function');
112
+ console.info('The main signature was not parsable. This script is considered to be without main function');
111
113
  }
112
114
  }
113
115
  goto(`?step=${step}`);
@@ -7,6 +7,7 @@ declare const __propDef: {
7
7
  template?: "script" | "pgsql" | "mysql" | undefined;
8
8
  initialArgs?: Record<string, any> | undefined;
9
9
  lockedLanguage?: boolean | undefined;
10
+ topHash?: string | undefined;
10
11
  };
11
12
  events: {
12
13
  [evt: string]: CustomEvent<any>;
@@ -1,4 +1,5 @@
1
- <script>import { getContext, onMount } from 'svelte';
1
+ <script>import { Alert } from '../../../common';
2
+ import { getContext, onMount } from 'svelte';
2
3
  import { initConfig, initOutput } from '../../editor/appUtils';
3
4
  import { components } from '../../editor/component';
4
5
  import ResolveConfig from '../helpers/ResolveConfig.svelte';
@@ -24,18 +25,23 @@ onMount(async () => {
24
25
  });
25
26
  let h = undefined;
26
27
  let w = undefined;
27
- $: Plotly &&
28
- render &&
29
- result &&
30
- divEl &&
31
- h &&
32
- w &&
33
- Plotly.newPlot(divEl, Array.isArray(result) ? result : [result], {
34
- width: w,
35
- height: h,
36
- margin: { l: 50, r: 40, b: 40, t: 40, pad: 4 },
37
- ...resolvedConfig.layout
38
- }, { responsive: true, displayModeBar: false });
28
+ $: Plotly && render && result && divEl && h && w && plot();
29
+ let error = '';
30
+ function plot() {
31
+ try {
32
+ Plotly.newPlot(divEl, Array.isArray(result) ? result : [result], {
33
+ width: w,
34
+ height: h,
35
+ margin: { l: 50, r: 40, b: 40, t: 40, pad: 4 },
36
+ ...resolvedConfig.layout
37
+ }, { responsive: true, displayModeBar: false });
38
+ error = '';
39
+ }
40
+ catch (e) {
41
+ error = e.message;
42
+ console.error(e);
43
+ }
44
+ }
39
45
  </script>
40
46
 
41
47
  {#each Object.keys(components['plotlycomponent'].initialData.configuration) as key (key)}
@@ -49,6 +55,13 @@ $: Plotly &&
49
55
 
50
56
  <div class="w-full h-full" bind:clientHeight={h} bind:clientWidth={w}>
51
57
  <RunnableWrapper {outputs} {render} {componentInput} {id} bind:initializing bind:result>
58
+ {#if error != ''}
59
+ <div class="flex flex-col h-full w-full overflow-auto">
60
+ <Alert title="Plotly error" type="error" size="xs" class="h-full w-full ">
61
+ <pre class="w-full bg-white p-2 rounded-md whitespace-pre-wrap">{error}</pre>
62
+ </Alert>
63
+ </div>
64
+ {/if}
52
65
  <div on:pointerdown bind:this={divEl} />
53
66
  </RunnableWrapper>
54
67
  </div>
@@ -2,11 +2,12 @@
2
2
  import 'ag-grid-community/styles/ag-grid.css';
3
3
  import 'ag-grid-community/styles/ag-theme-alpine.css';
4
4
  import { getContext, onMount } from 'svelte';
5
- import InputValue from '../../helpers/InputValue.svelte';
6
5
  import RunnableWrapper from '../../helpers/RunnableWrapper.svelte';
7
6
  import { isObject } from '../../../../../utils';
8
7
  import Alert from '../../../../common/alert/Alert.svelte';
9
- import { initOutput } from '../../../editor/appUtils';
8
+ import { initConfig, initOutput } from '../../../editor/appUtils';
9
+ import ResolveConfig from '../../helpers/ResolveConfig.svelte';
10
+ import { components } from '../../../editor/component';
10
11
  export let id;
11
12
  export let componentInput;
12
13
  export let configuration;
@@ -14,11 +15,14 @@ export let initializing = undefined;
14
15
  export let render;
15
16
  let result = undefined;
16
17
  const { worldStore, selectedComponent } = getContext('AppViewerContext');
18
+ let resolvedConfig = initConfig(components['aggridcomponent'].initialData.configuration, configuration);
17
19
  let outputs = initOutput($worldStore, id, {
18
20
  selectedRowIndex: 0,
19
21
  selectedRow: {},
20
22
  result: [],
21
- loading: false
23
+ loading: false,
24
+ page: 0,
25
+ newChange: { row: 0, column: '', value: undefined }
22
26
  });
23
27
  let selectedRowIndex = -1;
24
28
  function toggleRow(row, rowIndex) {
@@ -42,10 +46,6 @@ $: selectedRowIndex === -1 &&
42
46
  $: outputs?.result?.set(result ?? []);
43
47
  let clientHeight;
44
48
  let clientWidth;
45
- let columnDefs = undefined;
46
- let allEditable = undefined;
47
- let pagination = undefined;
48
- let pageSize = 10;
49
49
  function onCellValueChanged(event) {
50
50
  if (result) {
51
51
  let dataCell = event.newValue;
@@ -53,15 +53,24 @@ function onCellValueChanged(event) {
53
53
  dataCell = JSON.parse(dataCell);
54
54
  }
55
55
  catch (e) { }
56
- result[event.node.rowIndex][event.column.colId] = dataCell;
56
+ outputs?.newChange?.set({
57
+ row: event.node.rowIndex,
58
+ column: event.colDef.field,
59
+ value: dataCell
60
+ });
61
+ result[event.node.rowIndex][event.colDef.field] = dataCell;
57
62
  }
58
63
  }
59
64
  </script>
60
65
 
61
- <InputValue {id} input={configuration.columnDefs} bind:value={columnDefs} />
62
- <InputValue {id} input={configuration.allEditable} bind:value={allEditable} />
63
- <InputValue {id} input={configuration.pagination} bind:value={pagination} />
64
- <InputValue {id} input={configuration.pageSize} bind:value={pageSize} />
66
+ {#each Object.keys(components['aggridcomponent'].initialData.configuration) as key (key)}
67
+ <ResolveConfig
68
+ {id}
69
+ {key}
70
+ bind:resolvedConfig={resolvedConfig[key]}
71
+ configuration={configuration[key]}
72
+ />
73
+ {/each}
65
74
 
66
75
  <RunnableWrapper {outputs} {render} {componentInput} {id} bind:initializing bind:result>
67
76
  {#if Array.isArray(result) && result.every(isObject)}
@@ -78,13 +87,16 @@ function onCellValueChanged(event) {
78
87
  style:width="{clientWidth}px"
79
88
  class="ag-theme-alpine"
80
89
  >
81
- {#key pagination}
90
+ {#key resolvedConfig?.pagination}
82
91
  <AgGridSvelte
83
92
  bind:rowData={result}
84
- {columnDefs}
85
- {pagination}
86
- paginationPageSize={pageSize}
87
- defaultColDef={{ flex: 1, editable: allEditable, onCellValueChanged }}
93
+ columnDefs={resolvedConfig?.columnDefs}
94
+ pagination={resolvedConfig?.pagination}
95
+ paginationAutoPageSize={resolvedConfig?.pagination}
96
+ defaultColDef={{ flex: 1, editable: resolvedConfig?.allEditable, onCellValueChanged }}
97
+ onPaginationChanged={(event) => {
98
+ outputs?.page.set(event.api.paginationGetCurrentPage())
99
+ }}
88
100
  />
89
101
  {/key}
90
102
  </div>
@@ -88,7 +88,8 @@ function setFilteredResult() {
88
88
  filteredResult = searchInResult(result ?? [], searchValue);
89
89
  }
90
90
  }
91
- $: (result || resolvedConfig.search || searchValue) && setFilteredResult();
91
+ $: (result || resolvedConfig.search || searchValue || resolvedConfig.pagination) &&
92
+ setFilteredResult();
92
93
  $: outputs.page.set($table.getState().pagination.pageIndex);
93
94
  function rerender() {
94
95
  if (!Array.isArray(result)) {
@@ -97,7 +98,19 @@ function rerender() {
97
98
  const headers = Array.from(new Set(result.flatMap((row) => (typeof row == 'object' ? Object.keys(row) : []))));
98
99
  $options = {
99
100
  ...tableOptions,
100
- manualPagination: resolvedConfig.manualPagination,
101
+ ...(resolvedConfig?.pagination?.selected != 'manual'
102
+ ? {
103
+ initialState: {
104
+ pagination: {
105
+ pageSize: resolvedConfig?.pagination?.configuration?.auto?.pageSize ?? 20
106
+ }
107
+ }
108
+ }
109
+ : {}),
110
+ manualPagination: resolvedConfig?.pagination?.selected == 'manual',
111
+ pageCount: resolvedConfig?.pagination?.selected == 'manual'
112
+ ? resolvedConfig?.pagination?.configuration.manual.pageCount ?? -1
113
+ : undefined,
101
114
  data: filteredResult,
102
115
  columns: headers.map((header) => {
103
116
  return {
@@ -333,8 +346,8 @@ $componentControl[id] = {
333
346
  </div>
334
347
 
335
348
  <AppTableFooter
336
- paginationEnabled
337
- manualPagination={resolvedConfig.manualPagination}
349
+ pageSize={resolvedConfig?.pagination?.configuration?.auto?.pageSize ?? 20}
350
+ manualPagination={resolvedConfig?.pagination?.selected == 'manual'}
338
351
  result={filteredResult}
339
352
  {table}
340
353
  class={css?.tableFooter?.class}
@@ -4,8 +4,8 @@ import { ChevronLeft, ChevronRight } from 'lucide-svelte';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { tableOptions } from './tableOptions';
6
6
  export let result;
7
- export let paginationEnabled = false;
8
7
  export let manualPagination;
8
+ export let pageSize;
9
9
  export let table;
10
10
  let c = '';
11
11
  export { c as class };
@@ -25,7 +25,7 @@ function downloadResultAsJSON() {
25
25
  class={twMerge('px-2 py-1 text-xs gap-2 items-center justify-between', c, 'flex flex-row')}
26
26
  {style}
27
27
  >
28
- {#if (paginationEnabled && result.length > (tableOptions.initialState?.pagination?.pageSize ?? 25)) || manualPagination}
28
+ {#if result.length > pageSize || manualPagination}
29
29
  <div class="flex items-center gap-2 flex-row">
30
30
  <Button
31
31
  size="xs"
@@ -4,8 +4,8 @@ import type { Readable } from 'svelte/store';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  result: Record<string, any>[];
7
- paginationEnabled?: boolean | undefined;
8
7
  manualPagination: boolean;
8
+ pageSize: number;
9
9
  table: Readable<Table<Record<string, any>>>;
10
10
  class?: string | undefined;
11
11
  style?: string | undefined;
@@ -70,21 +70,39 @@ $: css = concatCustomCss($app.css?.containercomponent, customCss);
70
70
  $focusedGrid = undefined
71
71
  }}
72
72
  >
73
- {#if $app.subgrids?.[`${id}-0`]}
74
- <SubGridEditor
75
- visible={open && render}
76
- {id}
77
- class={css?.container?.class}
78
- style={css?.container?.style}
79
- subGridId={`${id}-0`}
80
- containerHeight={1200}
81
- on:focus={() => {
82
- if (!$connectingInput.opened) {
83
- $selectedComponent = [id]
73
+ <div
74
+ class="h-full"
75
+ on:pointerdown={(e) => {
76
+ e?.stopPropagation()
77
+ if (!$connectingInput.opened) {
78
+ $selectedComponent = [id]
79
+ $focusedGrid = {
80
+ parentComponentId: id,
81
+ subGridIndex: 0
84
82
  }
85
- }}
86
- />
87
- {/if}
83
+ }
84
+ }}
85
+ >
86
+ {#if $app.subgrids?.[`${id}-0`]}
87
+ <SubGridEditor
88
+ visible={open && render}
89
+ {id}
90
+ class={css?.container?.class}
91
+ style={css?.container?.style}
92
+ subGridId={`${id}-0`}
93
+ containerHeight={1200}
94
+ on:focus={() => {
95
+ if (!$connectingInput.opened) {
96
+ $selectedComponent = [id]
97
+ $focusedGrid = {
98
+ parentComponentId: id,
99
+ subGridIndex: 0
100
+ }
101
+ }
102
+ }}
103
+ />
104
+ {/if}
105
+ </div>
88
106
  </DrawerContent>
89
107
  </Drawer>
90
108
  </Portal>
@@ -54,8 +54,9 @@ let context = {
54
54
  query: Object.fromEntries($page.url.searchParams.entries()),
55
55
  hash: $page.url.hash
56
56
  };
57
+ const worldStore = buildWorld(context);
57
58
  setContext('AppViewerContext', {
58
- worldStore: buildWorld(context),
59
+ worldStore,
59
60
  app: appStore,
60
61
  summary: summaryStore,
61
62
  selectedComponent,
@@ -115,7 +116,6 @@ let befSelected = undefined;
115
116
  $: if ($selectedComponent?.[0] != befSelected) {
116
117
  befSelected = $selectedComponent?.[0];
117
118
  selectedTab = 'settings';
118
- console.log('focusedGrid1', befSelected);
119
119
  if (befSelected) {
120
120
  if (!['ctx', 'state'].includes(befSelected) && !befSelected?.startsWith('bg_')) {
121
121
  let item = findGridItem($appStore, befSelected);
@@ -125,11 +125,15 @@ $: if ($selectedComponent?.[0] != befSelected) {
125
125
  subGridIndex: 0
126
126
  };
127
127
  }
128
+ else if (item?.data.type === 'tabscomponent') {
129
+ $focusedGrid = {
130
+ parentComponentId: befSelected,
131
+ subGridIndex: $worldStore.outputsById?.[befSelected]?.selectedTabIndex?.peak() ?? 0
132
+ };
133
+ }
128
134
  else {
129
- console.log('focusedGrid2', befSelected);
130
135
  let subgrid = findGridItemParentGrid($appStore, befSelected);
131
136
  if (subgrid) {
132
- console.log('focusedGrid3', befSelected);
133
137
  try {
134
138
  $focusedGrid = {
135
139
  parentComponentId: subgrid.split('-')[0],
@@ -768,14 +768,34 @@ export declare const components: {
768
768
  readonly type: "static";
769
769
  readonly onlyStatic: true;
770
770
  readonly selectOptions: string[];
771
- readonly value: "Disabled";
771
+ readonly value: string;
772
772
  };
773
- readonly manualPagination: {
774
- readonly fieldType: "boolean";
775
- readonly type: "static";
776
- readonly onlyStatic: true;
777
- readonly value: false;
778
- readonly tooltip: "Pagination would not be handled by the component but by the script itself. Connect to the pagination output";
773
+ readonly pagination: {
774
+ readonly type: "oneOf";
775
+ readonly selected: "auto";
776
+ readonly labels: {
777
+ readonly auto: "Auto";
778
+ readonly manual: "Manual";
779
+ };
780
+ readonly configuration: {
781
+ readonly auto: {
782
+ readonly pageSize: {
783
+ readonly type: "static";
784
+ readonly fieldType: "number";
785
+ readonly value: 20;
786
+ readonly onlyStatic: true;
787
+ readonly tooltip: "Number of rows per page";
788
+ };
789
+ };
790
+ readonly manual: {
791
+ readonly pageCount: {
792
+ readonly type: "static";
793
+ readonly fieldType: "number";
794
+ readonly value: -1;
795
+ readonly tooltip: "Number of pages (-1 if you do not know)";
796
+ };
797
+ };
798
+ };
779
799
  };
780
800
  };
781
801
  readonly componentInput: StaticAppInput;
@@ -803,13 +823,6 @@ export declare const components: {
803
823
  readonly value: false;
804
824
  readonly onlyStatic: true;
805
825
  };
806
- readonly pageSize: {
807
- readonly type: "static";
808
- readonly fieldType: "number";
809
- readonly value: 10;
810
- readonly onlyStatic: true;
811
- readonly tooltip: "Number of rows per page";
812
- };
813
826
  };
814
827
  readonly componentInput: StaticAppInput;
815
828
  };