windmill-components 1.502.6 → 1.503.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 (46) hide show
  1. package/package/actions/triggerableByAI.svelte.js +2 -0
  2. package/package/components/Editor.svelte +85 -9
  3. package/package/components/Editor.svelte.d.ts +0 -2
  4. package/package/components/FakeMonacoPlaceHolder.svelte +2 -1
  5. package/package/components/FlowWrapper.svelte +19 -4
  6. package/package/components/FlowWrapper.svelte.d.ts +4 -1
  7. package/package/components/JsonEditor.svelte +9 -2
  8. package/package/components/Path.svelte +2 -2
  9. package/package/components/ResourcePicker.svelte +17 -8
  10. package/package/components/SchemaForm.svelte +3 -3
  11. package/package/components/ScriptEditor.svelte +0 -5
  12. package/package/components/SearchItems.svelte +1 -1
  13. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte +65 -48
  14. package/package/components/common/toggleButton-v2/ToggleButtonGroup.svelte +2 -1
  15. package/package/components/common/toggleButton-v2/ToggleButtonGroup.svelte.d.ts +1 -0
  16. package/package/components/copilot/chat/AIChat.svelte +0 -9
  17. package/package/components/copilot/chat/AIChat.svelte.d.ts +0 -2
  18. package/package/components/copilot/chat/AIChatDisplay.svelte +36 -26
  19. package/package/components/copilot/chat/AIChatInlineWidget.svelte +209 -0
  20. package/package/components/copilot/chat/AIChatInlineWidget.svelte.d.ts +15 -0
  21. package/package/components/copilot/chat/AIChatInput.svelte +50 -38
  22. package/package/components/copilot/chat/AIChatInput.svelte.d.ts +7 -0
  23. package/package/components/copilot/chat/AIChatManager.svelte.js +96 -9
  24. package/package/components/copilot/chat/AIChatMessage.svelte +15 -7
  25. package/package/components/copilot/chat/ChatQuickActions.svelte +1 -1
  26. package/package/components/copilot/chat/ContextElementBadge.svelte +1 -1
  27. package/package/components/copilot/chat/ContextTextarea.svelte +16 -7
  28. package/package/components/copilot/chat/ContextTextarea.svelte.d.ts +2 -1
  29. package/package/components/copilot/chat/GlobalReviewButtons.svelte +10 -8
  30. package/package/components/copilot/chat/GlobalReviewButtons.svelte.d.ts +5 -19
  31. package/package/components/copilot/chat/monaco-adapter.js +2 -2
  32. package/package/components/copilot/chat/script/core.d.ts +1 -0
  33. package/package/components/copilot/chat/script/core.js +84 -0
  34. package/package/components/flows/content/FlowModuleComponent.svelte +0 -8
  35. package/package/components/flows/header/FlowYamlEditor.svelte +8 -4
  36. package/package/components/flows/header/FlowYamlEditor.svelte.d.ts +4 -18
  37. package/package/components/home/ItemsList.svelte +3 -3
  38. package/package/components/home/ListFilters.svelte +5 -9
  39. package/package/components/home/ListFilters.svelte.d.ts +5 -20
  40. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +7 -1
  41. package/package/components/workspaceSettings/AISettings.svelte +1 -0
  42. package/package/gen/schemas.gen.d.ts +0 -3
  43. package/package/gen/schemas.gen.js +0 -3
  44. package/package/gen/types.gen.d.ts +0 -1
  45. package/package.json +1 -1
  46. package/package/components/copilot/chat/AIChatManager.svelte.d.ts +0 -84
@@ -45,10 +45,12 @@ export function triggerableByAI(element, options = {}) {
45
45
  // register the triggerable
46
46
  const currentData = { description, onTrigger: handleTrigger };
47
47
  triggerablesByAi[id] = currentData;
48
+ element.setAttribute('ai-description', description);
48
49
  }
49
50
  function unregister() {
50
51
  if (isDisabled || !id)
51
52
  return;
53
+ element.removeAttribute('ai-description');
52
54
  // unregister the triggerable
53
55
  if (triggerablesByAi[id]) {
54
56
  delete triggerablesByAi[id];
@@ -105,11 +105,13 @@ import { conf, language } from '../vueMonarch';
105
105
  import { Autocompletor } from './copilot/autocomplete/Autocompletor';
106
106
  import { AIChatEditorHandler } from './copilot/chat/monaco-adapter';
107
107
  import GlobalReviewButtons from './copilot/chat/GlobalReviewButtons.svelte';
108
+ import AIChatInlineWidget from './copilot/chat/AIChatInlineWidget.svelte';
108
109
  import { writable } from 'svelte/store';
109
110
  import { formatResourceTypes } from './copilot/chat/script/core';
110
111
  import FakeMonacoPlaceHolder from './FakeMonacoPlaceHolder.svelte';
111
112
  import { editorPositionMap } from '../utils';
112
113
  import { extToLang, langToExt } from '../editorLangUtils';
114
+ import { aiChatManager } from './copilot/chat/AIChatManager.svelte';
113
115
  // import EditorTheme from './EditorTheme.svelte'
114
116
  let divEl = null;
115
117
  let editor = null;
@@ -185,7 +187,7 @@ function computePath(path) {
185
187
  return randomHash();
186
188
  }
187
189
  else {
188
- console.log('path', path);
190
+ // console.log('path', path)
189
191
  return path;
190
192
  }
191
193
  }
@@ -544,6 +546,10 @@ function addDBSchemaCompletions() {
544
546
  }
545
547
  let reviewingChanges = writable(false);
546
548
  let aiChatEditorHandler = undefined;
549
+ // Inline ai chat widget
550
+ let showInlineAIChat = false;
551
+ let inlineAIChatSelection = null;
552
+ let selectedCode = '';
547
553
  export function reviewAndApplyCode(code) {
548
554
  aiChatEditorHandler?.reviewAndApply(code);
549
555
  }
@@ -1068,6 +1074,20 @@ async function loadMonaco() {
1068
1074
  });
1069
1075
  editor?.onDidFocusEditorText(() => {
1070
1076
  dispatch('focus');
1077
+ editor?.addCommand(KeyCode.Escape, function () {
1078
+ if (showInlineAIChat) {
1079
+ closeAIInlineWidget();
1080
+ }
1081
+ aiChatEditorHandler?.rejectAll();
1082
+ });
1083
+ editor?.addCommand(KeyMod.CtrlCmd | KeyCode.DownArrow, function () {
1084
+ if (aiChatManager.pendingNewCode) {
1085
+ aiChatManager.scriptEditorApplyCode?.(aiChatManager.pendingNewCode);
1086
+ if (showInlineAIChat) {
1087
+ closeAIInlineWidget();
1088
+ }
1089
+ }
1090
+ });
1071
1091
  editor?.addCommand(KeyMod.CtrlCmd | KeyCode.KeyS, function () {
1072
1092
  updateCode();
1073
1093
  shouldBindKey && format && format();
@@ -1087,14 +1107,22 @@ async function loadMonaco() {
1087
1107
  (selection.startLineNumber !== selection.endLineNumber ||
1088
1108
  selection.startColumn !== selection.endColumn);
1089
1109
  if (hasSelection && selectedLines) {
1090
- dispatch('addSelectedLinesToAiChat', {
1091
- lines: selectedLines,
1092
- startLine: selection.startLineNumber,
1093
- endLine: selection.endLineNumber
1094
- });
1110
+ aiChatManager.addSelectedLinesToContext(selectedLines, selection.startLineNumber, selection.endLineNumber);
1095
1111
  }
1096
1112
  else {
1097
- dispatch('toggleAiPanel');
1113
+ aiChatManager.toggleOpen();
1114
+ aiChatManager.focusInput();
1115
+ }
1116
+ });
1117
+ editor?.addCommand(KeyMod.CtrlCmd | KeyCode.KeyK, function () {
1118
+ if ($copilotInfo.enabled) {
1119
+ aiChatEditorHandler?.rejectAll();
1120
+ if (showInlineAIChat) {
1121
+ closeAIInlineWidget();
1122
+ }
1123
+ else {
1124
+ showAIInlineWidget();
1125
+ }
1098
1126
  }
1099
1127
  });
1100
1128
  editor?.addCommand(KeyMod.CtrlCmd | KeyCode.KeyU, function () {
@@ -1118,6 +1146,7 @@ async function loadMonaco() {
1118
1146
  try {
1119
1147
  closeWebsockets();
1120
1148
  vimDisposable?.dispose();
1149
+ closeAIInlineWidget();
1121
1150
  console.log('disposing editor');
1122
1151
  model?.dispose();
1123
1152
  editor && editor.dispose();
@@ -1231,6 +1260,27 @@ export function addAction(id, label, callback, keybindings = []) {
1231
1260
  }
1232
1261
  });
1233
1262
  }
1263
+ function showAIInlineWidget() {
1264
+ if (!editor)
1265
+ return;
1266
+ inlineAIChatSelection = editor.getSelection();
1267
+ if (!inlineAIChatSelection) {
1268
+ return;
1269
+ }
1270
+ const model = editor.getModel();
1271
+ selectedCode = '';
1272
+ if (model) {
1273
+ selectedCode = model.getValueInRange(inlineAIChatSelection);
1274
+ }
1275
+ showInlineAIChat = true;
1276
+ aiChatInlineWidget?.focusInput();
1277
+ }
1278
+ function closeAIInlineWidget() {
1279
+ showInlineAIChat = false;
1280
+ inlineAIChatSelection = null;
1281
+ selectedCode = '';
1282
+ }
1283
+ let aiChatInlineWidget = null;
1234
1284
  let loadTimeout = undefined;
1235
1285
  onMount(async () => {
1236
1286
  if (BROWSER) {
@@ -1270,8 +1320,23 @@ async function genRoot(hostname) {
1270
1320
  let root = hostname + '/api/scripts_u/tokened_raw/' + $workspaceStore + '/' + token;
1271
1321
  return root;
1272
1322
  }
1323
+ function onKeyDown(e) {
1324
+ if (e.key === 'Escape') {
1325
+ if (showInlineAIChat) {
1326
+ closeAIInlineWidget();
1327
+ }
1328
+ aiChatEditorHandler?.rejectAll();
1329
+ }
1330
+ else if ((e.ctrlKey || e.metaKey) && e.key === 'ArrowDown' && aiChatManager.pendingNewCode) {
1331
+ aiChatManager.scriptEditorApplyCode?.(aiChatManager.pendingNewCode);
1332
+ if (showInlineAIChat) {
1333
+ closeAIInlineWidget();
1334
+ }
1335
+ }
1336
+ }
1273
1337
  </script>
1274
1338
 
1339
+ <svelte:window onkeydown={onKeyDown} />
1275
1340
  <EditorTheme />
1276
1341
  {#if !editor}
1277
1342
  <div class="inset-0 absolute overflow-clip">
@@ -1285,15 +1350,26 @@ async function genRoot(hostname) {
1285
1350
 
1286
1351
  {#if $reviewingChanges}
1287
1352
  <GlobalReviewButtons
1288
- on:acceptAll={() => {
1353
+ onAcceptAll={() => {
1289
1354
  aiChatEditorHandler?.acceptAll()
1290
1355
  }}
1291
- on:rejectAll={() => {
1356
+ onRejectAll={() => {
1292
1357
  aiChatEditorHandler?.rejectAll()
1293
1358
  }}
1294
1359
  />
1295
1360
  {/if}
1296
1361
 
1362
+ {#if editor && $copilotInfo.enabled && aiChatEditorHandler}
1363
+ <AIChatInlineWidget
1364
+ bind:this={aiChatInlineWidget}
1365
+ bind:show={showInlineAIChat}
1366
+ {editor}
1367
+ editorHandler={aiChatEditorHandler}
1368
+ selection={inlineAIChatSelection}
1369
+ {selectedCode}
1370
+ />
1371
+ {/if}
1372
+
1297
1373
  <style global>
1298
1374
  :global(.editor) {
1299
1375
  padding: 0px;
@@ -75,8 +75,6 @@ declare const Editor: $$__sveltets_2_IsomorphicComponent<{
75
75
  saveDraft: CustomEvent<any>;
76
76
  blur: CustomEvent<any>;
77
77
  focus: CustomEvent<any>;
78
- addSelectedLinesToAiChat: CustomEvent<any>;
79
- toggleAiPanel: CustomEvent<any>;
80
78
  toggleTestPanel: CustomEvent<any>;
81
79
  ataReady: CustomEvent<any>;
82
80
  } & {
@@ -11,9 +11,10 @@ const fontFamily = getOS() === 'Windows'
11
11
  : getOS() === 'macOS'
12
12
  ? DEFAULT_MAC_FONT_FAMILY
13
13
  : DEFAULT_LINUX_FONT_FAMILY;
14
+ const CHAR_LIMIT = 5000;
14
15
  // https://github.com/microsoft/vscode/blob/baa2dad3cdacd97ac02eff0604984faf1167ff1e/src/vs/editor/common/config/fontInfo.ts#L14
15
16
  const GOLDEN_LINE_HEIGHT_RATIO = getOS() == 'macOS' ? 1.5 : 1.35;
16
- let lines = $derived(code?.split('\n') ?? []);
17
+ let lines = $derived(code?.substring(0, CHAR_LIMIT)?.split('\n') ?? []);
17
18
  const charWidth = 9; // try to match as closely as possible to monaco editor
18
19
  const lineHeight = fontSize * GOLDEN_LINE_HEIGHT_RATIO;
19
20
  let [clientWidth, clientHeight] = $state([0, 0]);
@@ -1,9 +1,24 @@
1
1
  <script lang="ts">import AiChatLayout from './copilot/chat/AiChatLayout.svelte';
2
2
  import FlowBuilder from './FlowBuilder.svelte';
3
- let { flowStore: oldFlowStore, disableAi, ...props } = $props();
3
+ let { flowStore: oldFlowStore, disableAi, light, ...props } = $props();
4
4
  let flowStore = $state(oldFlowStore);
5
+ let trialRender = $state(true);
6
+ if (light) {
7
+ setTimeout(() => {
8
+ trialRender = false;
9
+ }, 1000 * 300);
10
+ }
5
11
  </script>
6
12
 
7
- <AiChatLayout noPadding={true} {disableAi}>
8
- <FlowBuilder {flowStore} {disableAi} {...props} />
9
- </AiChatLayout>
13
+ {#if trialRender}
14
+ <AiChatLayout noPadding={true} {disableAi}>
15
+ {#if light}<div class="bg-red-500 absolute z-10">Trial version</div>{/if}
16
+ <FlowBuilder {flowStore} {disableAi} {...props} />
17
+ </AiChatLayout>
18
+ {:else}
19
+ <div class="flex flex-col items-center justify-center h-screen">
20
+ <div class="text-2xl font-bold"
21
+ >Windmill Whitelabel SDK is in trial mode and disabled itself after 5 minutes</div
22
+ >
23
+ </div>
24
+ {/if}
@@ -1,4 +1,7 @@
1
1
  import type { FlowBuilderProps } from './flow_builder';
2
- declare const FlowWrapper: import("svelte").Component<FlowBuilderProps, {}, "">;
2
+ type $$ComponentProps = FlowBuilderProps & {
3
+ light?: boolean;
4
+ };
5
+ declare const FlowWrapper: import("svelte").Component<$$ComponentProps, {}, "">;
3
6
  type FlowWrapper = ReturnType<typeof FlowWrapper>;
4
7
  export default FlowWrapper;
@@ -2,6 +2,7 @@
2
2
  import SimpleEditor from './SimpleEditor.svelte';
3
3
  import { createEventDispatcher } from 'svelte';
4
4
  import { createDispatcherIfMounted } from '../createDispatcherIfMounted';
5
+ import Button from './common/button/Button.svelte';
5
6
  export let code;
6
7
  export let value = undefined;
7
8
  export let error = '';
@@ -9,6 +10,7 @@ export let editor = undefined;
9
10
  export let small = false;
10
11
  export let loadAsync = false;
11
12
  $: tooBig = code && code?.length > 1000000;
13
+ let loadTooBigAnyway = false;
12
14
  const dispatch = createEventDispatcher();
13
15
  const dispatchIfMounted = createDispatcherIfMounted(dispatch);
14
16
  function parseJson() {
@@ -29,8 +31,13 @@ function parseJson() {
29
31
  $: code != undefined && parseJson();
30
32
  </script>
31
33
 
32
- {#if tooBig}
33
- <span class="text-tertiary">JSON to edit is too big</span>
34
+ {#if tooBig && !loadTooBigAnyway}
35
+ <div class="flex-1 text-sm">
36
+ JSON is too big
37
+ <Button size="xs2" variant="border" on:click={() => (loadTooBigAnyway = true)}>
38
+ Load anyway
39
+ </Button>
40
+ </div>
34
41
  {:else}
35
42
  <div class="flex flex-col w-full">
36
43
  <div class="border w-full">
@@ -269,12 +269,12 @@ function setDirty() {
269
269
  !dirty && (dirty = true);
270
270
  }
271
271
  const openSearchWithPrefilledText = getContext('openSearchWithPrefilledText');
272
- $effect(() => {
272
+ $effect.pre(() => {
273
273
  ;
274
274
  [meta?.name, meta?.owner, meta?.ownerKind];
275
275
  meta && untrack(() => onMetaChange());
276
276
  });
277
- $effect(() => {
277
+ $effect.pre(() => {
278
278
  if ($workspaceStore && $userStore) {
279
279
  untrack(() => {
280
280
  loadFolders();
@@ -34,7 +34,9 @@ $effect(() => {
34
34
  if (value === undefined) {
35
35
  if (initialValue) {
36
36
  console.log('initialValue', initialValue);
37
- value = initialValue;
37
+ if (initialValue != value) {
38
+ value = initialValue;
39
+ }
38
40
  }
39
41
  else {
40
42
  console.log('no value');
@@ -49,7 +51,7 @@ export async function askNewResource() {
49
51
  appConnect?.open?.(resourceType);
50
52
  }
51
53
  let loading = $state(true);
52
- async function loadResources(resourceType, initialValue, value) {
54
+ async function loadResources(resourceType) {
53
55
  loading = true;
54
56
  try {
55
57
  const resourceTypesToQuery = resourceType === 'snowflake' ? ['snowflake', 'snowflake_oauth'] : [resourceType];
@@ -70,7 +72,7 @@ async function loadResources(resourceType, initialValue, value) {
70
72
  nc.push({ value: value ?? initialValue, label: value ?? initialValue, type: '' });
71
73
  }
72
74
  collection = nc;
73
- if (collection.length == 1 && selectFirst && value == undefined) {
75
+ if (collection.length == 1 && selectFirst && (value == undefined || value == '')) {
74
76
  console.log('selectFirst', collection[0].value);
75
77
  value = collection[0].value;
76
78
  valueType = collection[0].type;
@@ -82,9 +84,16 @@ async function loadResources(resourceType, initialValue, value) {
82
84
  }
83
85
  loading = false;
84
86
  }
87
+ let previousResourceType = resourceType;
85
88
  $effect(() => {
86
- $workspaceStore &&
87
- loadResources(resourceType, untrack(() => initialValue), untrack(() => value));
89
+ $workspaceStore && resourceType;
90
+ untrack(() => {
91
+ if (previousResourceType != resourceType) {
92
+ previousResourceType = resourceType;
93
+ value = undefined;
94
+ }
95
+ });
96
+ untrack(() => loadResources(resourceType));
88
97
  });
89
98
  let appConnect = $state();
90
99
  let resourceEditor = $state();
@@ -92,7 +101,7 @@ let resourceEditor = $state();
92
101
 
93
102
  <AppConnect
94
103
  on:refresh={async (e) => {
95
- await loadResources(resourceType, initialValue, value)
104
+ await loadResources(resourceType)
96
105
  value = e.detail
97
106
  valueType = collection.find((x) => x?.value == value)?.type
98
107
  }}
@@ -102,7 +111,7 @@ let resourceEditor = $state();
102
111
  <ResourceEditorDrawer
103
112
  bind:this={resourceEditor}
104
113
  on:refresh={async (e) => {
105
- await loadResources(resourceType, initialValue, value)
114
+ await loadResources(resourceType)
106
115
  if (e.detail) {
107
116
  value = e.detail
108
117
  valueType = collection.find((x) => x?.value == value)?.type
@@ -188,7 +197,7 @@ let resourceEditor = $state();
188
197
  btnClasses="w-8 px-0.5 py-1.5"
189
198
  size="sm"
190
199
  on:click={() => {
191
- loadResources(resourceType, initialValue, value)
200
+ loadResources(resourceType)
192
201
  }}
193
202
  startIcon={{ icon: RotateCw }}
194
203
  iconOnly
@@ -109,8 +109,8 @@ $effect.pre(() => {
109
109
  }
110
110
  });
111
111
  $effect.pre(() => {
112
- schema.order;
113
- Object.keys(schema.properties ?? {});
112
+ schema?.order;
113
+ Object.keys(schema?.properties ?? {});
114
114
  schema && (untrack(() => reorder()), (hidden = {}));
115
115
  });
116
116
  $effect.pre(() => {
@@ -119,7 +119,7 @@ $effect.pre(() => {
119
119
  if (args && typeof args == 'object') {
120
120
  let oneShowExpr = false;
121
121
  for (const key of fields) {
122
- if (schema.properties?.[key.value]?.showExpr) {
122
+ if (schema?.properties?.[key.value]?.showExpr) {
123
123
  oneShowExpr = true;
124
124
  }
125
125
  }
@@ -440,11 +440,6 @@ $effect(() => {
440
440
  inferSchema(e.detail)
441
441
  }}
442
442
  on:saveDraft
443
- on:toggleAiPanel={() => aiChatManager.toggleOpen()}
444
- on:addSelectedLinesToAiChat={(e) => {
445
- const { lines, startLine, endLine } = e.detail
446
- aiChatManager.addSelectedLinesToContext(lines, startLine, endLine)
447
- }}
448
443
  on:toggleTestPanel={toggleTestPanel}
449
444
  cmdEnterAction={async () => {
450
445
  await inferSchema(code)
@@ -23,7 +23,7 @@ function filterItems() {
23
23
  filteredItems = result;
24
24
  }
25
25
  let plaintextItems = $derived(items?.map((item) => f(item)) ?? []);
26
- $effect(() => {
26
+ $effect.pre(() => {
27
27
  plaintextItems && filter != undefined && setTimeout(() => untrack(() => filterItems()), 0);
28
28
  });
29
29
  </script>
@@ -3,7 +3,6 @@ import { Pane, Splitpanes } from 'svelte-splitpanes';
3
3
  import InlineScriptsPanelList from './InlineScriptsPanelList.svelte';
4
4
  import InlineScriptEditor from './InlineScriptEditor.svelte';
5
5
  import InlineScriptsPanelWithTable from './InlineScriptsPanelWithTable.svelte';
6
- import { findGridItem } from '../appUtils';
7
6
  import InlineScriptHiddenRunnable from './InlineScriptHiddenRunnable.svelte';
8
7
  import { BG_PREFIX } from '../../utils';
9
8
  import { sendUserToast } from '../../../../toast';
@@ -35,16 +34,12 @@ function deleteBackgroundScript(index) {
35
34
  $runnableComponents = $runnableComponents;
36
35
  }
37
36
  }
38
- let gridItem = $derived($selectedComponentInEditor && !$selectedComponentInEditor.startsWith(BG_PREFIX)
39
- ? findGridItem($app, $selectedComponentInEditor?.split('_')?.[0])
40
- : undefined);
41
- let hiddenInlineScript = $derived($app?.hiddenInlineScripts?.findIndex((k_, index) => {
42
- const [prefix, id] = $selectedComponentInEditor?.split('_') || [];
43
- if (prefix !== 'bg')
44
- return false;
45
- return Number(id) === index;
46
- }));
47
- let unusedInlineScript = $derived($app?.unusedInlineScripts?.findIndex((k_, index) => `unused-${index}` === $selectedComponentInEditor));
37
+ // let gridItem = $derived(
38
+ // $selectedComponentInEditor && !$selectedComponentInEditor.startsWith(BG_PREFIX)
39
+ // // ? findGridItem($app, $selectedComponentInEditor?.split('_')?.[0])
40
+ // : undefined
41
+ // )
42
+ let [prefixOrId, id] = $derived($selectedComponentInEditor?.split('_') ?? []);
48
43
  let { width = undefined } = $props();
49
44
  </script>
50
45
 
@@ -60,42 +55,62 @@ let { width = undefined } = $props();
60
55
  <div class="text-sm text-secondary text-center py-8 px-2">
61
56
  Select a runnable on the left panel
62
57
  </div>
63
- {:else if gridItem}
64
- {#key gridItem?.id}
65
- <InlineScriptsPanelWithTable
66
- on:createScriptFromInlineScript={(e) => {
67
- createScriptFromInlineScript(
68
- gridItem?.id ?? 'unknown',
69
- e.detail,
70
- $workspaceStore ?? '',
71
- $appPath
72
- )
73
- }}
74
- bind:gridItem
75
- />
76
- {/key}
77
- {:else if unusedInlineScript > -1 && $app.unusedInlineScripts?.[unusedInlineScript]}
78
- {#key unusedInlineScript}
79
- <InlineScriptEditor
80
- on:createScriptFromInlineScript={() =>
81
- sendUserToast('Cannot save to workspace unused scripts', true)}
82
- id={`unused-${unusedInlineScript}`}
83
- bind:name={$app.unusedInlineScripts[unusedInlineScript].name}
84
- bind:inlineScript={$app.unusedInlineScripts[unusedInlineScript].inlineScript}
85
- on:delete={() => {
86
- // remove the script from the array at the index
87
- $app.unusedInlineScripts.splice(unusedInlineScript, 1)
88
- $app.unusedInlineScripts = [...$app.unusedInlineScripts]
89
- }}
90
- />
91
- {/key}
92
- {:else if hiddenInlineScript > -1}
93
- {#key hiddenInlineScript}
94
- {#if $app.hiddenInlineScripts?.[hiddenInlineScript]}
58
+ {:else if prefixOrId != 'bg' && !prefixOrId.startsWith('unused-')}
59
+ {#each $app.grid as gridItem, index (gridItem?.id)}
60
+ {#if gridItem?.id == prefixOrId}
61
+ <InlineScriptsPanelWithTable
62
+ on:createScriptFromInlineScript={(e) => {
63
+ createScriptFromInlineScript(
64
+ gridItem?.id ?? 'unknown',
65
+ e.detail,
66
+ $workspaceStore ?? '',
67
+ $appPath
68
+ )
69
+ }}
70
+ bind:gridItem={$app.grid[index]}
71
+ />
72
+ {/if}
73
+ {/each}
74
+ {#each Object.keys($app.subgrids ?? {}) as subgrid (subgrid)}
75
+ {#each $app.subgrids?.[subgrid] ?? [] as subgridItem, index (subgridItem?.id)}
76
+ {#if subgridItem?.id == prefixOrId && $app.subgrids?.[subgrid]}
77
+ <InlineScriptsPanelWithTable
78
+ on:createScriptFromInlineScript={(e) => {
79
+ createScriptFromInlineScript(
80
+ subgridItem?.id ?? 'unknown',
81
+ e.detail,
82
+ $workspaceStore ?? '',
83
+ $appPath
84
+ )
85
+ }}
86
+ bind:gridItem={$app.subgrids[subgrid][index]}
87
+ />
88
+ {/if}
89
+ {/each}
90
+ {/each}
91
+ {:else if prefixOrId != 'bg' && prefixOrId.startsWith('unused-')}
92
+ {#each $app.unusedInlineScripts as unusedInlineScript, index}
93
+ {#if `unused-${index}` == prefixOrId}
94
+ <InlineScriptEditor
95
+ on:createScriptFromInlineScript={() =>
96
+ sendUserToast('Cannot save to workspace unused scripts', true)}
97
+ id={`unused-${index}`}
98
+ bind:name={unusedInlineScript.name}
99
+ bind:inlineScript={unusedInlineScript.inlineScript}
100
+ on:delete={() => {
101
+ $app.unusedInlineScripts.splice(index, 1)
102
+ $app.unusedInlineScripts = [...$app.unusedInlineScripts]
103
+ }}
104
+ />
105
+ {/if}
106
+ {/each}
107
+ {:else if prefixOrId == 'bg'}
108
+ {#each $app.hiddenInlineScripts as _inlineScript, index}
109
+ {#if index.toString() == id}
95
110
  <InlineScriptHiddenRunnable
96
111
  on:createScriptFromInlineScript={(e) => {
97
112
  createScriptFromInlineScript(
98
- BG_PREFIX + hiddenInlineScript,
113
+ BG_PREFIX + index,
99
114
  e.detail,
100
115
  $workspaceStore ?? '',
101
116
  $appPath
@@ -103,10 +118,12 @@ let { width = undefined } = $props();
103
118
  $app = $app
104
119
  }}
105
120
  transformer={$selectedComponentInEditor?.endsWith('_transformer')}
106
- on:delete={() => deleteBackgroundScript(hiddenInlineScript)}
107
- id={BG_PREFIX + hiddenInlineScript}
108
- bind:runnable={$app.hiddenInlineScripts[hiddenInlineScript]}
109
- />{/if}{/key}
121
+ on:delete={() => deleteBackgroundScript(index)}
122
+ id={BG_PREFIX + index}
123
+ bind:runnable={$app.hiddenInlineScripts[index]}
124
+ />
125
+ {/if}
126
+ {/each}
110
127
  {:else}
111
128
  <div class="text-sm text-tertiary text-center py-8 px-2">
112
129
  No runnable found at id {$selectedComponentInEditor}
@@ -3,7 +3,7 @@ import { twMerge } from 'tailwind-merge';
3
3
  import { createSync } from '@melt-ui/svelte';
4
4
  const dispatch = createEventDispatcher();
5
5
  import { createToggleGroup, melt } from '@melt-ui/svelte';
6
- let { id = undefined, selected = $bindable(undefined), noWFull = false, disabled = false, tabListClass = '', allowEmpty = false, class: className = '', children } = $props();
6
+ let { id = undefined, selected = $bindable(undefined), noWFull = false, disabled = false, tabListClass = '', allowEmpty = false, class: className = '', onSelected, children } = $props();
7
7
  const { elements: { root, item }, options: { disabled: disabledOption }, states } = createToggleGroup({
8
8
  type: 'single',
9
9
  onValueChange: ({ curr, next }) => {
@@ -12,6 +12,7 @@ const { elements: { root, item }, options: { disabled: disabledOption }, states
12
12
  }
13
13
  if (curr !== next && curr !== undefined) {
14
14
  dispatch('selected', next);
15
+ onSelected?.(next);
15
16
  }
16
17
  return next;
17
18
  }
@@ -7,6 +7,7 @@ interface Props {
7
7
  allowEmpty?: boolean;
8
8
  class?: string;
9
9
  children?: import('svelte').Snippet<[any]>;
10
+ onSelected?: (value: any) => void;
10
11
  }
11
12
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
12
13
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -36,12 +36,6 @@ export async function sendRequest(options = {}) {
36
36
  function cancel() {
37
37
  aiChatManager.cancel();
38
38
  }
39
- export function addSelectedLinesToContext(lines, startLine, endLine) {
40
- aiChatManager.contextManager.addSelectedLinesToContext(lines, startLine, endLine);
41
- }
42
- export function focusTextArea() {
43
- aiChatDisplay?.focusInput();
44
- }
45
39
  const historyManager = aiChatManager.historyManager;
46
40
  historyManager.init();
47
41
  onDestroy(() => {
@@ -58,9 +52,6 @@ $effect(() => {
58
52
  $effect(() => {
59
53
  aiChatManager.updateMode(untrack(() => aiChatManager.mode));
60
54
  });
61
- $effect(() => {
62
- aiChatManager.loadApiTools();
63
- });
64
55
  </script>
65
56
 
66
57
  <svelte:window
@@ -10,8 +10,6 @@ declare const AiChat: import("svelte").Component<Record<string, never>, {
10
10
  lang?: ScriptLang | "bunnative";
11
11
  isPreprocessor?: boolean;
12
12
  }) => Promise<void>;
13
- addSelectedLinesToContext: (lines: string, startLine: number, endLine: number) => void;
14
- focusTextArea: () => void;
15
13
  }, "">;
16
14
  type AiChat = ReturnType<typeof AiChat>;
17
15
  export default AiChat;