windmill-components 1.75.0 → 1.77.0

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 (156) hide show
  1. package/components/DisplayResult.svelte +1 -1
  2. package/components/Dropdown.svelte +14 -4
  3. package/components/FlowGraphViewer.svelte +1 -1
  4. package/components/FolderUsageInfo.svelte +16 -6
  5. package/components/FolderUsageInfo.svelte.d.ts +2 -0
  6. package/components/PageHeader.svelte +1 -1
  7. package/components/Path.svelte +22 -3
  8. package/components/ScriptBuilder.svelte +122 -122
  9. package/components/SettingSection.svelte +44 -0
  10. package/components/SettingSection.svelte.d.ts +21 -0
  11. package/components/Tooltip.svelte +3 -1
  12. package/components/WhitelistIp.svelte +1 -3
  13. package/components/apps/components/buttons/AppButton.svelte +11 -5
  14. package/components/apps/components/buttons/AppButton.svelte.d.ts +1 -0
  15. package/components/apps/components/buttons/AppForm.svelte +3 -7
  16. package/components/apps/components/buttons/AppFormButton.svelte +2 -6
  17. package/components/apps/components/display/table/AppAggridTable.svelte +4 -1
  18. package/components/apps/components/display/table/AppTable.svelte +4 -1
  19. package/components/apps/components/helpers/HiddenComponent.svelte +3 -0
  20. package/components/apps/components/helpers/HiddenComponent.svelte.d.ts +1 -0
  21. package/components/apps/components/helpers/InputValue.svelte +26 -43
  22. package/components/apps/components/helpers/InputValue.svelte.d.ts +4 -3
  23. package/components/apps/components/helpers/RefreshButton.svelte +2 -3
  24. package/components/apps/components/helpers/RunnableComponent.svelte +61 -34
  25. package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +2 -0
  26. package/components/apps/components/helpers/RunnableWrapper.svelte +2 -0
  27. package/components/apps/components/helpers/RunnableWrapper.svelte.d.ts +1 -0
  28. package/components/apps/components/helpers/eval.d.ts +5 -0
  29. package/components/apps/components/helpers/eval.js +57 -0
  30. package/components/apps/components/layout/AppContainer.svelte +1 -6
  31. package/components/apps/components/layout/AppDrawer.svelte +0 -3
  32. package/components/apps/components/layout/AppSplitpanes.svelte +1 -6
  33. package/components/apps/components/layout/AppTabs.svelte +64 -33
  34. package/components/apps/components/layout/AppTabs.svelte.d.ts +1 -0
  35. package/components/apps/editor/AppEditor.svelte +136 -131
  36. package/components/apps/editor/AppEditorHeader.svelte +43 -35
  37. package/components/apps/editor/AppPreview.svelte +3 -2
  38. package/components/apps/editor/ComponentHeader.svelte +3 -1
  39. package/components/apps/editor/ComponentHeader.svelte.d.ts +1 -0
  40. package/components/apps/editor/GridEditor.svelte +53 -51
  41. package/components/apps/editor/RecomputeAllComponents.svelte +7 -1
  42. package/components/apps/editor/SettingsPanel.svelte +23 -10
  43. package/components/apps/editor/SubGridEditor.svelte +56 -52
  44. package/components/apps/editor/SubGridEditor.svelte.d.ts +3 -4
  45. package/components/apps/editor/appUtils.d.ts +12 -3
  46. package/components/apps/editor/appUtils.js +111 -37
  47. package/components/apps/editor/component/Component.svelte +4 -9
  48. package/components/apps/editor/component/ComponentNavigation.svelte +91 -46
  49. package/components/apps/editor/component/components.d.ts +1 -1
  50. package/components/apps/editor/component/components.js +24 -43
  51. package/components/apps/editor/componentsPanel/componentStaticValues.d.ts +1 -0
  52. package/components/apps/editor/componentsPanel/componentStaticValues.js +1 -0
  53. package/components/apps/editor/contextPanel/ComponentOutput.svelte +77 -0
  54. package/components/apps/editor/contextPanel/ComponentOutput.svelte.d.ts +21 -0
  55. package/components/apps/editor/contextPanel/ComponentOutputViewer.svelte +9 -5
  56. package/components/apps/editor/contextPanel/ContextPanel.svelte +80 -136
  57. package/components/apps/editor/contextPanel/SubGridOutput.svelte +71 -0
  58. package/components/apps/editor/contextPanel/SubGridOutput.svelte.d.ts +19 -0
  59. package/components/apps/editor/contextPanel/components/BackgroundScriptOutput.svelte +38 -0
  60. package/components/apps/editor/contextPanel/components/BackgroundScriptOutput.svelte.d.ts +19 -0
  61. package/components/apps/editor/contextPanel/components/BackgroundScriptsOutput.svelte +10 -0
  62. package/components/apps/editor/contextPanel/components/BackgroundScriptsOutput.svelte.d.ts +16 -0
  63. package/components/apps/editor/contextPanel/components/MinMaxButton.svelte +25 -0
  64. package/components/apps/editor/contextPanel/components/MinMaxButton.svelte.d.ts +16 -0
  65. package/components/apps/editor/contextPanel/components/OutputHeader.svelte +78 -0
  66. package/components/apps/editor/contextPanel/components/OutputHeader.svelte.d.ts +26 -0
  67. package/components/apps/editor/contextPanel/components/TableActionOutput.svelte +19 -0
  68. package/components/apps/editor/contextPanel/components/TableActionOutput.svelte.d.ts +18 -0
  69. package/components/apps/editor/contextPanel/components/TableActionsOutput.svelte +14 -0
  70. package/components/apps/editor/contextPanel/components/TableActionsOutput.svelte.d.ts +18 -0
  71. package/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte +53 -21
  72. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +69 -43
  73. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorDrawer.svelte +1 -1
  74. package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte.d.ts +2 -2
  75. package/components/apps/editor/settingsPanel/ComponentPanel.svelte +32 -31
  76. package/components/apps/editor/settingsPanel/GridTab.svelte +4 -12
  77. package/components/apps/editor/settingsPanel/Recompute.svelte +1 -0
  78. package/components/apps/editor/settingsPanel/SelectedRunnable.svelte +6 -0
  79. package/components/apps/editor/settingsPanel/TableActions.svelte +2 -1
  80. package/components/apps/editor/settingsPanel/inputEditor/ConnectedInputEditor.svelte +2 -8
  81. package/components/apps/editor/settingsPanel/inputEditor/EvalInputEditor.svelte +2 -2
  82. package/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte +58 -46
  83. package/components/apps/editor/settingsPanel/inputEditor/JsonEditor.svelte +1 -1
  84. package/components/apps/editor/settingsPanel/inputEditor/JsonEditor.svelte.d.ts +2 -0
  85. package/components/apps/rx.d.ts +6 -4
  86. package/components/apps/rx.js +34 -14
  87. package/components/apps/svelte-grid/Grid.svelte +171 -0
  88. package/components/apps/svelte-grid/Grid.svelte.d.ts +47 -0
  89. package/components/apps/svelte-grid/LICENSE +23 -0
  90. package/components/apps/svelte-grid/MoveResize.svelte +328 -0
  91. package/components/apps/svelte-grid/MoveResize.svelte.d.ts +46 -0
  92. package/components/apps/svelte-grid/types.d.ts +25 -0
  93. package/components/apps/svelte-grid/utils/container.d.ts +1 -0
  94. package/components/apps/svelte-grid/utils/container.js +4 -0
  95. package/components/apps/svelte-grid/utils/helper.d.ts +14 -0
  96. package/components/apps/svelte-grid/utils/helper.js +36 -0
  97. package/components/apps/svelte-grid/utils/item.d.ts +14 -0
  98. package/components/apps/svelte-grid/utils/item.js +192 -0
  99. package/components/apps/svelte-grid/utils/matrix.d.ts +6 -0
  100. package/components/apps/svelte-grid/utils/matrix.js +53 -0
  101. package/components/apps/svelte-grid/utils/other.d.ts +3 -0
  102. package/components/apps/svelte-grid/utils/other.js +30 -0
  103. package/components/apps/types.d.ts +10 -7
  104. package/components/apps/utils.d.ts +1 -1
  105. package/components/apps/utils.js +13 -7
  106. package/components/common/CloseButton.svelte +18 -0
  107. package/components/common/CloseButton.svelte.d.ts +27 -0
  108. package/components/common/badge/Badge.svelte +6 -1
  109. package/components/common/badge/Badge.svelte.d.ts +1 -0
  110. package/components/common/drawer/DrawerContent.svelte +2 -6
  111. package/components/common/languageIcons/JavaScript.svelte +11 -0
  112. package/components/common/languageIcons/JavaScript.svelte.d.ts +25 -0
  113. package/components/common/languageIcons/LanguageIcon.svelte +3 -1
  114. package/components/common/languageIcons/LanguageIcon.svelte.d.ts +1 -1
  115. package/components/common/menu/Menu.svelte +1 -1
  116. package/components/common/popup/Popup.svelte +2 -1
  117. package/components/common/popup/Popup.svelte.d.ts +9 -0
  118. package/components/common/table/AppRow.svelte +1 -4
  119. package/components/common/table/FlowRow.svelte +1 -4
  120. package/components/common/table/ScriptRow.svelte +1 -4
  121. package/components/common/tabs/Tab.svelte +1 -0
  122. package/components/common/tabs/Tab.svelte.d.ts +2 -0
  123. package/components/flows/pickers/FlowScriptPicker.svelte.d.ts +1 -1
  124. package/components/graph/FlowGraph.svelte +1 -1
  125. package/components/sidebar/SidebarContent.svelte +2 -2
  126. package/consts.js +1 -1
  127. package/history.js +8 -1
  128. package/package.json +21 -27
  129. package/utils.js +0 -1
  130. package/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte +0 -92
  131. package/components/apps/editor/settingsPanel/MoveToOtherGrid.svelte.d.ts +0 -18
  132. package/components/graph/svelvet/d3/controllers/README.md +0 -3
  133. package/components/graph/svelvet/d3/controllers/d3Old.d.ts +0 -1
  134. package/components/graph/svelvet/d3/controllers/d3Old.js +0 -43
  135. package/components/graph/svelvet/docs/CHANGELOG.md +0 -145
  136. package/components/graph/svelvet/docs/DESIGN_PATTERNS.md +0 -44
  137. package/components/graph/svelvet/docs/DOCUMENTATION.md +0 -5
  138. package/components/graph/svelvet/docs/README.md +0 -34
  139. package/components/graph/svelvet/docs/TODO.md +0 -14
  140. package/components/graph/svelvet/docs/Tutorials.md +0 -25
  141. package/components/graph/svelvet/docs/images/css-background-after.png +0 -0
  142. package/components/graph/svelvet/docs/images/css-background-before.png +0 -0
  143. package/components/graph/svelvet/docs/images/custom-edges-after.png +0 -0
  144. package/components/graph/svelvet/docs/images/custom-edges-before.png +0 -0
  145. package/components/graph/svelvet/docs/images/custom-nodes-after.png +0 -0
  146. package/components/graph/svelvet/docs/images/custom-nodes-before.png +0 -0
  147. package/components/graph/svelvet/docs/images/custom-svelte-components-after.png +0 -0
  148. package/components/graph/svelvet/docs/images/custom-svelte-components-before.png +0 -0
  149. package/components/graph/svelvet/docs/images/html-docs-after.png +0 -0
  150. package/components/graph/svelvet/docs/images/html-docs-before.png +0 -0
  151. package/components/graph/svelvet/docs/images/minimap-after.png +0 -0
  152. package/components/graph/svelvet/docs/images/minimap-before.png +0 -0
  153. package/components/graph/svelvet/docs/images/node-classes-after.png +0 -0
  154. package/components/graph/svelvet/docs/images/node-classes-before.png +0 -0
  155. package/components/graph/svelvet/docs/images/node-create-after.png +0 -0
  156. package/components/graph/svelvet/docs/images/node-create-before.png +0 -0
@@ -86,7 +86,10 @@ function onCellValueChanged(event) {
86
86
  </div>
87
87
  {:else if result != undefined}
88
88
  <Alert title="Parsing issues" type="error" size="xs">
89
- The result should be an array of objects
89
+ The result should be an array of objects, received:
90
+ <pre class="overflow-auto">
91
+ {JSON.stringify(result)}
92
+ </pre>
90
93
  </Alert>
91
94
  {/if}
92
95
  </RunnableWrapper>
@@ -248,7 +248,10 @@ $: css = concatCustomCss($app.css?.tablecomponent, customCss);
248
248
  </div>
249
249
  {:else if result != undefined}
250
250
  <Alert title="Parsing issues" type="error" size="xs">
251
- The result should be an array of objects
251
+ The result should be an array of objects. Received:
252
+ <pre class="overflow-auto">
253
+ {JSON.stringify(result)}
254
+ </pre>
252
255
  </Alert>
253
256
  {/if}
254
257
  </RunnableWrapper>
@@ -3,6 +3,7 @@ export let id;
3
3
  export let name;
4
4
  export let inlineScript;
5
5
  export let fields;
6
+ export let autoRefresh = false;
6
7
  let result = undefined;
7
8
  export const staticOutputs = ['result', 'loading'];
8
9
  </script>
@@ -11,6 +12,7 @@ export const staticOutputs = ['result', 'loading'];
11
12
  render={false}
12
13
  {id}
13
14
  {fields}
15
+ {autoRefresh}
14
16
  bind:result
15
17
  runnable={{
16
18
  name,
@@ -18,6 +20,7 @@ export const staticOutputs = ['result', 'loading'];
18
20
  type: 'runnableByName'
19
21
  }}
20
22
  wrapperClass="hidden"
23
+ recomputable
21
24
  >
22
25
  <slot />
23
26
  </RunnableComponent>
@@ -7,6 +7,7 @@ declare const __propDef: {
7
7
  name: string;
8
8
  inlineScript: InlineScript | undefined;
9
9
  fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput>;
10
+ autoRefresh?: boolean | undefined;
10
11
  staticOutputs?: string[] | undefined;
11
12
  };
12
13
  events: {
@@ -1,11 +1,18 @@
1
1
  <script>import { isCodeInjection } from '../../../flows/utils';
2
2
  import { deepEqual } from 'fast-equals';
3
- import { getContext } from 'svelte';
3
+ import { createEventDispatcher, getContext } from 'svelte';
4
4
  import { accessPropertyByPath } from '../../utils';
5
+ import { computeGlobalContext, eval_like } from './eval';
5
6
  export let input;
6
7
  export let value;
7
8
  export let id = undefined;
8
9
  export let error = '';
10
+ export let extraContext = {};
11
+ const { componentControl } = getContext('AppViewerContext');
12
+ const dispatch = createEventDispatcher();
13
+ if (input == undefined) {
14
+ dispatch('done');
15
+ }
9
16
  let lastInput = input ? JSON.parse(JSON.stringify(input)) : undefined;
10
17
  $: if (input && !deepEqual(input, lastInput)) {
11
18
  lastInput = JSON.parse(JSON.stringify(input));
@@ -14,8 +21,8 @@ $: if (input && !deepEqual(input, lastInput)) {
14
21
  lastInput.value = input?.['value'];
15
22
  }
16
23
  }
17
- const { worldStore } = getContext('AppViewerContext');
18
- $: state = $worldStore?.state;
24
+ const { worldStore, state, mode } = getContext('AppViewerContext');
25
+ $: stateId = $worldStore?.stateId;
19
26
  let timeout = undefined;
20
27
  const debounce_ms = 50;
21
28
  function debounce(cb) {
@@ -27,21 +34,26 @@ function debounce(cb) {
27
34
  $: lastInput && $worldStore && debounce(handleConnection);
28
35
  $: lastInput &&
29
36
  lastInput.type == 'template' &&
37
+ $stateId &&
30
38
  $state &&
31
- debounce(() => (value = getValue(lastInput)));
39
+ debounce(async () => {
40
+ value = await getValue(lastInput);
41
+ dispatch('done');
42
+ });
32
43
  $: lastInput &&
33
44
  lastInput.type == 'eval' &&
45
+ $stateId &&
34
46
  $state &&
35
- debounce(() => (value = evalExpr(lastInput)));
36
- function handleConnection() {
47
+ debounce(async () => (value = await evalExpr(lastInput)));
48
+ async function handleConnection() {
37
49
  if (lastInput.type === 'connected') {
38
- $worldStore?.connect(lastInput, onValueChange);
50
+ $worldStore?.connect(lastInput, onValueChange, id);
39
51
  }
40
52
  else if (lastInput.type === 'static' || lastInput.type == 'template') {
41
- value = getValue(lastInput);
53
+ value = await getValue(lastInput);
42
54
  }
43
55
  else if (lastInput.type == 'eval') {
44
- value = evalExpr(lastInput);
56
+ value = await evalExpr(lastInput);
45
57
  }
46
58
  else if (lastInput.type == 'upload') {
47
59
  value = lastInput.value;
@@ -49,10 +61,11 @@ function handleConnection() {
49
61
  else {
50
62
  value = undefined;
51
63
  }
64
+ dispatch('done');
52
65
  }
53
- function evalExpr(input) {
66
+ async function evalExpr(input) {
54
67
  try {
55
- const r = eval_like(input.expr, computeGlobalContext());
68
+ const r = await eval_like(input.expr, computeGlobalContext($worldStore, id, extraContext), true, $state, $mode == 'dnd', $componentControl, $worldStore);
56
69
  error = '';
57
70
  return r;
58
71
  }
@@ -61,20 +74,10 @@ function evalExpr(input) {
61
74
  return value;
62
75
  }
63
76
  }
64
- function computeGlobalContext() {
65
- return Object.fromEntries(Object.entries($worldStore?.outputsById ?? {})
66
- .filter(([k, _]) => k != id)
67
- .map(([key, value]) => {
68
- return [
69
- key,
70
- Object.fromEntries(Object.entries(value ?? {}).map((x) => [x[0], x[1].peak()]))
71
- ];
72
- }));
73
- }
74
- export function getValue(input) {
77
+ async function getValue(input) {
75
78
  if (input.type === 'template' && isCodeInjection(input.eval)) {
76
79
  try {
77
- const r = eval_like('`' + input.eval + '`', computeGlobalContext());
80
+ const r = await eval_like('`' + input.eval + '`', computeGlobalContext($worldStore, id, extraContext), true, $state, $mode == 'dnd', $componentControl, $worldStore);
78
81
  error = '';
79
82
  return r;
80
83
  }
@@ -89,26 +92,6 @@ export function getValue(input) {
89
92
  return input.eval;
90
93
  }
91
94
  }
92
- function create_context_function_template(eval_string, context) {
93
- return `
94
- return function (context) {
95
- "use strict";
96
- ${Object.keys(context).length > 0
97
- ? `let ${Object.keys(context).map((key) => ` ${key} = context['${key}']`)};`
98
- : ``}
99
- return ${eval_string};
100
- }
101
- `;
102
- }
103
- function make_context_evaluator(eval_string, context) {
104
- let template = create_context_function_template(eval_string, context);
105
- let functor = Function(template);
106
- return functor();
107
- }
108
- function eval_like(text, context = {}) {
109
- let evaluator = make_context_evaluator(text, context);
110
- return evaluator(context);
111
- }
112
95
  function onValueChange(newValue) {
113
96
  if (lastInput.type === 'connected' && newValue !== undefined && newValue !== null) {
114
97
  const { connection } = lastInput;
@@ -2,13 +2,15 @@ import { SvelteComponentTyped } from "svelte";
2
2
  import type { AppInput } from '../../inputType';
3
3
  declare const __propDef: {
4
4
  props: {
5
- input: AppInput;
5
+ input: AppInput | undefined;
6
6
  value: string | number | boolean | Record<string | number, any> | undefined;
7
7
  id?: string | undefined;
8
8
  error?: string | undefined;
9
- getValue?: ((input: AppInput) => any) | undefined;
9
+ extraContext?: Record<string, any> | undefined;
10
10
  };
11
11
  events: {
12
+ done: CustomEvent<any>;
13
+ } & {
12
14
  [evt: string]: CustomEvent<any>;
13
15
  };
14
16
  slots: {};
@@ -17,6 +19,5 @@ export type InputValueProps = typeof __propDef.props;
17
19
  export type InputValueEvents = typeof __propDef.events;
18
20
  export type InputValueSlots = typeof __propDef.slots;
19
21
  export default class InputValue extends SvelteComponentTyped<InputValueProps, InputValueEvents, InputValueSlots> {
20
- get getValue(): (input: AppInput) => any;
21
22
  }
22
23
  export {};
@@ -1,6 +1,4 @@
1
- <script>import Button from '../../../common/button/Button.svelte';
2
- import { faRefresh } from '@fortawesome/free-solid-svg-icons';
3
- import { RefreshCcw, RefreshCw } from 'lucide-svelte';
1
+ <script>import { RefreshCw } from 'lucide-svelte';
4
2
  import { getContext } from 'svelte';
5
3
  export let componentId;
6
4
  const { runnableComponents, worldStore } = getContext('AppViewerContext');
@@ -10,6 +8,7 @@ async function refresh() {
10
8
  }
11
9
  let loading = false;
12
10
  $: $worldStore?.outputsById[componentId]?.['loading']?.subscribe({
11
+ id: 'refresh-' + componentId,
13
12
  next: (value) => {
14
13
  loading = value;
15
14
  }
@@ -5,9 +5,10 @@ import SchemaForm from '../../../SchemaForm.svelte';
5
5
  import TestJobLoader from '../../../TestJobLoader.svelte';
6
6
  import { AppService } from '../../../../gen';
7
7
  import { classNames, defaultIfEmptyString, emptySchema, sendUserToast } from '../../../../utils';
8
- import { Bug, Loader2 } from 'lucide-svelte';
9
- import { getContext, onMount } from 'svelte';
10
- import { fade } from 'svelte/transition';
8
+ import { Bug } from 'lucide-svelte';
9
+ import { getContext } from 'svelte';
10
+ import { initOutput } from '../../editor/appUtils';
11
+ import { computeGlobalContext, eval_like } from './eval';
11
12
  import InputValue from './InputValue.svelte';
12
13
  import RefreshButton from './RefreshButton.svelte';
13
14
  // Component props
@@ -25,15 +26,24 @@ export let initializing = undefined;
25
26
  export let gotoUrl = undefined;
26
27
  export let gotoNewTab = undefined;
27
28
  export let render;
28
- const { worldStore, runnableComponents, workspace, appPath, isEditor, jobs, noBackend, errorByComponent, mode, stateId } = getContext('AppViewerContext');
29
- onMount(() => {
30
- if (autoRefresh) {
29
+ export let recomputable = false;
30
+ export let recomputeIds = [];
31
+ const { worldStore, runnableComponents, workspace, appPath, isEditor, jobs, noBackend, errorByComponent, mode, stateId, state, componentControl } = getContext('AppViewerContext');
32
+ $: autoRefresh && handleAutorefresh();
33
+ if (recomputable) {
34
+ $runnableComponents[id] = async () => {
35
+ await executeComponent(true);
36
+ };
37
+ $runnableComponents = $runnableComponents;
38
+ }
39
+ function handleAutorefresh() {
40
+ if (autoRefresh && $worldStore) {
31
41
  $runnableComponents[id] = async () => {
32
42
  await executeComponent(true);
33
43
  };
34
44
  executeComponent(true);
35
45
  }
36
- });
46
+ }
37
47
  let args = undefined;
38
48
  let testIsLoading = false;
39
49
  let runnableInputValues = {};
@@ -56,22 +66,23 @@ let currentStaticValues = lazyStaticValues;
56
66
  $: fields && (currentStaticValues = computeStaticValues());
57
67
  $: if (JSON.stringify(currentStaticValues) != JSON.stringify(lazyStaticValues)) {
58
68
  lazyStaticValues = currentStaticValues;
69
+ refreshIfAutoRefresh();
70
+ }
71
+ $: fields && (lazyStaticValues = computeStaticValues());
72
+ $: (runnableInputValues || extraQueryParams || args) && testJobLoader && refreshIfAutoRefresh();
73
+ $: runnable?.type == 'runnableByName' &&
74
+ runnable.inlineScript?.language == 'frontend' &&
75
+ ($stateId || $state) &&
76
+ refreshIfAutoRefresh();
77
+ function refreshIfAutoRefresh() {
59
78
  if (autoRefresh) {
60
79
  setDebouncedExecute();
61
80
  }
62
81
  }
63
- $: fields && (lazyStaticValues = computeStaticValues());
64
- $: (runnableInputValues || extraQueryParams || args) &&
65
- autoRefresh &&
66
- testJobLoader &&
67
- setDebouncedExecute();
68
82
  // Test job internal state
69
83
  let testJob = undefined;
70
84
  let testJobLoader = undefined;
71
- $: outputs = $worldStore?.outputsById[id];
72
- $: if (outputs?.loading != undefined) {
73
- outputs.loading.set(false, true);
74
- }
85
+ $: outputs = initOutput($worldStore, id, { result: undefined, loading: false });
75
86
  $: outputs?.loading?.set(testIsLoading);
76
87
  $: schemaStripped = stripSchema(fields, $stateId);
77
88
  function stripSchema(inputs, s) {
@@ -102,6 +113,19 @@ $: disabledArgs = Object.keys(fields ?? {}).reduce((disabledArgsAccumulator, inp
102
113
  return disabledArgsAccumulator;
103
114
  }, []);
104
115
  async function executeComponent(noToast = false) {
116
+ if (runnable?.type === 'runnableByName' && runnable.inlineScript?.language === 'frontend') {
117
+ outputs?.loading?.set(true);
118
+ try {
119
+ const r = await eval_like(runnable.inlineScript?.content, computeGlobalContext($worldStore, id, {}), false, $state, $mode == 'dnd', $componentControl, $worldStore);
120
+ setResult(r);
121
+ $state = $state;
122
+ }
123
+ catch (e) {
124
+ sendUserToast('Error running frontend script: ' + e.message, true);
125
+ }
126
+ outputs?.loading?.set(false);
127
+ return;
128
+ }
105
129
  if (noBackend) {
106
130
  if (!noToast) {
107
131
  sendUserToast('This app is not connected to a windmill backend, it is a static preview');
@@ -167,6 +191,26 @@ function recordError(error) {
167
191
  };
168
192
  }
169
193
  }
194
+ function setResult(res) {
195
+ outputs.result?.set(res);
196
+ result = res;
197
+ const previousJobId = Object.keys($errorByComponent).find((key) => $errorByComponent[key].componentId === id);
198
+ if (previousJobId && !result?.error) {
199
+ delete $errorByComponent[previousJobId];
200
+ $errorByComponent = $errorByComponent;
201
+ }
202
+ if (gotoUrl && gotoUrl != '' && result?.error == undefined) {
203
+ if (gotoNewTab) {
204
+ window.open(gotoUrl, '_blank');
205
+ }
206
+ else {
207
+ goto(gotoUrl);
208
+ }
209
+ }
210
+ if (recomputeIds) {
211
+ recomputeIds.map((id) => $runnableComponents?.[id]?.());
212
+ }
213
+ }
170
214
  $: result?.error && recordError(result.error);
171
215
  </script>
172
216
 
@@ -183,24 +227,7 @@ $: result?.error && recordError(result.error);
183
227
  const startedAt = new Date(testJob.started_at).getTime()
184
228
  if (startedAt > lastStartedAt) {
185
229
  lastStartedAt = startedAt
186
- outputs.result?.set(testJob?.result)
187
- result = testJob.result
188
-
189
- const previousJobId = Object.keys($errorByComponent).find(
190
- (key) => $errorByComponent[key].componentId === id
191
- )
192
-
193
- if (previousJobId && !result?.error) {
194
- delete $errorByComponent[previousJobId]
195
- $errorByComponent = $errorByComponent
196
- }
197
- if (gotoUrl && gotoUrl != '' && result?.error == undefined) {
198
- if (gotoNewTab) {
199
- window.open(gotoUrl, '_blank')
200
- } else {
201
- goto(gotoUrl)
202
- }
203
- }
230
+ setResult(e.detail.result)
204
231
  }
205
232
  }
206
233
  }}
@@ -16,6 +16,8 @@ declare const __propDef: {
16
16
  gotoUrl?: string | undefined;
17
17
  gotoNewTab?: boolean | undefined;
18
18
  render: boolean;
19
+ recomputable?: boolean | undefined;
20
+ recomputeIds?: string[] | undefined;
19
21
  runComponent?: (() => Promise<void>) | undefined;
20
22
  };
21
23
  events: {
@@ -16,6 +16,7 @@ export let runnableStyle = '';
16
16
  export let goto = undefined;
17
17
  export let gotoNewTab = undefined;
18
18
  export let render;
19
+ export let recomputeIds = [];
19
20
  const { staticExporter, noBackend } = getContext('AppViewerContext');
20
21
  $: if (initializing && result) {
21
22
  initializing = false;
@@ -35,6 +36,7 @@ function isRunnableDefined() {
35
36
  <slot />
36
37
  {:else if componentInput.type === 'runnable' && isRunnableDefined()}
37
38
  <RunnableComponent
39
+ {recomputeIds}
38
40
  gotoUrl={goto}
39
41
  {gotoNewTab}
40
42
  {flexWrap}
@@ -17,6 +17,7 @@ declare const __propDef: {
17
17
  goto?: string | undefined;
18
18
  gotoNewTab?: boolean | undefined;
19
19
  render: boolean;
20
+ recomputeIds?: string[] | undefined;
20
21
  };
21
22
  events: {
22
23
  [evt: string]: CustomEvent<any>;
@@ -0,0 +1,5 @@
1
+ import type { World } from '../../rx';
2
+ export declare function computeGlobalContext(world: World | undefined, id: string | undefined, extraContext?: any): any;
3
+ export declare function eval_like(text: string, context: {} | undefined, noReturn: boolean, state: Record<string, any>, editor: boolean, controlComponents: Record<string, {
4
+ setTab?: (index: number) => void;
5
+ }>, worldStore: World | undefined): Promise<any>;
@@ -0,0 +1,57 @@
1
+ import { sendUserToast } from '../../../../utils';
2
+ export function computeGlobalContext(world, id, extraContext = {}) {
3
+ return {
4
+ ...Object.fromEntries(Object.entries(world?.outputsById ?? {})
5
+ .filter(([k, _]) => k != id && k != 'state')
6
+ .map(([key, value]) => {
7
+ return [
8
+ key,
9
+ Object.fromEntries(Object.entries(value ?? {}).map((x) => [x[0], x[1].peak()]))
10
+ ];
11
+ })),
12
+ ...extraContext
13
+ };
14
+ }
15
+ function create_context_function_template(eval_string, context, noReturn) {
16
+ return `
17
+ return async function (context, state, goto, setTab) {
18
+ "use strict";
19
+ ${Object.keys(context).length > 0
20
+ ? `let ${Object.keys(context).map((key) => ` ${key} = context['${key}']`)};`
21
+ : ``}
22
+ ${noReturn ? `return ${eval_string}` : eval_string}
23
+ }
24
+ `;
25
+ }
26
+ function make_context_evaluator(eval_string, context, noReturn) {
27
+ let template = create_context_function_template(eval_string, context, noReturn);
28
+ let functor = Function(template);
29
+ return functor();
30
+ }
31
+ export async function eval_like(text, context = {}, noReturn, state, editor, controlComponents, worldStore) {
32
+ const proxiedState = new Proxy(state, {
33
+ set(target, key, value) {
34
+ if (typeof key !== 'string') {
35
+ throw new Error('Invalid key');
36
+ }
37
+ let o = worldStore?.newOutput('state', key, value);
38
+ o?.set(value);
39
+ target[key] = value;
40
+ return true;
41
+ }
42
+ });
43
+ let evaluator = make_context_evaluator(text, context, noReturn);
44
+ return await evaluator(context, proxiedState, async (x, newTab) => {
45
+ if (newTab || editor) {
46
+ if (!newTab) {
47
+ sendUserToast('In editor mode, `goto` opens a new tab to prevent losing your work. To test the redirection , use the preview mode.');
48
+ }
49
+ window.open(x, '_blank');
50
+ }
51
+ else {
52
+ await newTab(x);
53
+ }
54
+ }, (id, index) => {
55
+ controlComponents[id]?.setTab?.(index);
56
+ });
57
+ }
@@ -1,13 +1,11 @@
1
1
  <script>import { getContext } from 'svelte';
2
2
  import SubGridEditor from '../../editor/SubGridEditor.svelte';
3
3
  import { concatCustomCss } from '../../utils';
4
- import InputValue from '../helpers/InputValue.svelte';
5
4
  export let id;
6
5
  export let configuration;
7
6
  export let componentContainerHeight;
8
7
  export let customCss = undefined;
9
8
  export let render;
10
- let noPadding = undefined;
11
9
  export const staticOutputs = [];
12
10
  const { app, focusedGrid, selectedComponent } = getContext('AppViewerContext');
13
11
  function onFocus() {
@@ -20,13 +18,10 @@ $: $selectedComponent === id && onFocus();
20
18
  $: css = concatCustomCss($app.css?.containercomponent, customCss);
21
19
  </script>
22
20
 
23
- <InputValue {id} input={configuration.noPadding} bind:value={noPadding} />
24
-
25
- <div>
21
+ <div class="w-full h-full">
26
22
  {#if $app.subgrids?.[`${id}-0`]}
27
23
  <SubGridEditor
28
24
  visible={render}
29
- {noPadding}
30
25
  {id}
31
26
  class={css?.container.class}
32
27
  style={css?.container.style}
@@ -15,7 +15,6 @@ export let noWFull = false;
15
15
  export let render;
16
16
  const { app, focusedGrid, selectedComponent } = getContext('AppViewerContext');
17
17
  let gridContent = undefined;
18
- let noPadding = undefined;
19
18
  let drawerTitle = undefined;
20
19
  let appDrawer;
21
20
  let labelValue;
@@ -54,7 +53,6 @@ $: css = concatCustomCss($app.css?.containercomponent, customCss);
54
53
  </div>
55
54
 
56
55
  <InputValue {id} input={configuration.gridContent} bind:value={gridContent} />
57
- <InputValue {id} input={configuration.noPadding} bind:value={noPadding} />
58
56
  <InputValue {id} input={configuration.drawerTitle} bind:value={drawerTitle} />
59
57
  <InputValue {id} input={configuration.label} bind:value={labelValue} />
60
58
  <InputValue {id} input={configuration.color} bind:value={color} />
@@ -73,7 +71,6 @@ $: css = concatCustomCss($app.css?.containercomponent, customCss);
73
71
  {#if $app.subgrids?.[`${id}-0`]}
74
72
  <SubGridEditor
75
73
  visible={open && render}
76
- {noPadding}
77
74
  {id}
78
75
  class={css?.container.class}
79
76
  style={css?.container.style}
@@ -11,9 +11,7 @@ export let customCss = undefined;
11
11
  export let horizontal = false;
12
12
  export let panes;
13
13
  export let render;
14
- const { app, focusedGrid, selectedComponent } = getContext('AppViewerContext');
15
- const { componentControl } = getContext('AppEditorContext');
16
- let noPadding = undefined;
14
+ const { app, focusedGrid, selectedComponent, componentControl } = getContext('AppViewerContext');
17
15
  function onFocus() {
18
16
  $focusedGrid = {
19
17
  parentComponentId: id,
@@ -54,8 +52,6 @@ $: {
54
52
  }
55
53
  </script>
56
54
 
57
- <InputValue {id} input={configuration.noPadding} bind:value={noPadding} />
58
-
59
55
  <div class="h-full w-full border" on:pointerdown|stopPropagation>
60
56
  <Splitpanes {horizontal}>
61
57
  {#each sumedup as paneSize, index (index)}
@@ -64,7 +60,6 @@ $: {
64
60
  <SubGridEditor
65
61
  visible={render}
66
62
  noYPadding
67
- {noPadding}
68
63
  {id}
69
64
  shouldHighlight={$focusedGrid?.subGridIndex === index}
70
65
  class={css?.container.class}