windmill-components 1.504.0 → 1.504.2

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 (87) hide show
  1. package/package/components/AppWrapper.svelte +0 -3
  2. package/package/components/{DBManagerDrawerButton.svelte → DBManagerDrawer.svelte} +38 -38
  3. package/package/components/DBManagerDrawer.svelte.d.ts +7 -0
  4. package/package/components/DarkModeObserver.svelte +30 -16
  5. package/package/components/DarkModeObserver.svelte.d.ts +9 -4
  6. package/package/components/Dev.svelte +1 -1
  7. package/package/components/EditorBar.svelte +108 -67
  8. package/package/components/FlowBuilder.svelte +2 -3
  9. package/package/components/FlowStatusViewerInner.svelte +19 -0
  10. package/package/components/FlowWrapper.svelte +0 -3
  11. package/package/components/ItemPicker.svelte +1 -1
  12. package/package/components/ItemPicker.svelte.d.ts +1 -1
  13. package/package/components/MoveDrawer.svelte.d.ts +2 -2
  14. package/package/components/ResourcePicker.svelte +11 -4
  15. package/package/components/S3FilePicker.svelte +10 -3
  16. package/package/components/S3FilePicker.svelte.d.ts +6 -4
  17. package/package/components/ScriptBuilder.svelte +3 -1
  18. package/package/components/ScriptEditor.svelte +31 -3
  19. package/package/components/ScriptEditor.svelte.d.ts +3 -1
  20. package/package/components/ScriptWrapper.svelte +0 -3
  21. package/package/components/ShareModal.svelte.d.ts +1 -1
  22. package/package/components/apps/editor/AppEditor.svelte +1 -1
  23. package/package/components/apps/editor/AppEditorHeader.svelte +1 -1
  24. package/package/components/apps/editor/GridEditor.svelte +1 -1
  25. package/package/components/apps/editor/SubGridEditor.svelte +1 -1
  26. package/package/components/apps/editor/component/componentCallbacks.svelte.js +1 -1
  27. package/package/components/apps/editor/componentsPanel/ComponentList.svelte +1 -1
  28. package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +1 -1
  29. package/package/components/apps/editor/settingsPanel/DeleteComponent.svelte +1 -1
  30. package/package/components/apps/types.d.ts +2 -2
  31. package/package/components/assets/AssetsDropdownButton.svelte +178 -0
  32. package/package/components/assets/AssetsDropdownButton.svelte.d.ts +16 -0
  33. package/package/components/assets/AssetsUsageDrawer.svelte +43 -0
  34. package/package/components/assets/AssetsUsageDrawer.svelte.d.ts +12 -0
  35. package/package/components/assets/lib.d.ts +16 -0
  36. package/package/components/assets/lib.js +60 -0
  37. package/package/components/auditLogs/AuditLogsFilters.svelte.d.ts +1 -1
  38. package/package/components/common/OnChange.svelte +18 -0
  39. package/package/components/common/OnChange.svelte.d.ts +21 -0
  40. package/package/components/common/button/UndoRedo.svelte +2 -2
  41. package/package/components/common/button/UndoRedo.svelte.d.ts +5 -6
  42. package/package/components/copilot/chat/script/core.js +4 -4
  43. package/package/components/custom_ui.d.ts +1 -0
  44. package/package/components/flows/content/FlowModuleComponent.svelte +20 -1
  45. package/package/components/flows/types.d.ts +15 -1
  46. package/package/components/graph/FlowGraphV2.svelte +111 -8
  47. package/package/components/graph/FlowGraphV2.svelte.d.ts +2 -0
  48. package/package/components/graph/graphBuilder.svelte.d.ts +14 -1
  49. package/package/components/graph/renderers/edges/BaseEdge.svelte +10 -1
  50. package/package/components/graph/renderers/edges/EmptyEdge.svelte +7 -1
  51. package/package/components/graph/renderers/edges/EmptyEdge.svelte.d.ts +3 -0
  52. package/package/components/graph/renderers/nodes/AssetNode.svelte +257 -0
  53. package/package/components/graph/renderers/nodes/AssetNode.svelte.d.ts +21 -0
  54. package/package/components/graph/renderers/nodes/AssetsOverflowedNode.svelte +55 -0
  55. package/package/components/graph/renderers/nodes/AssetsOverflowedNode.svelte.d.ts +7 -0
  56. package/package/components/icons/AssetGenericIcon.svelte +16 -0
  57. package/package/components/icons/AssetGenericIcon.svelte.d.ts +10 -0
  58. package/package/components/icons/AssetResIcon.svelte +32 -0
  59. package/package/components/icons/AssetResIcon.svelte.d.ts +9 -0
  60. package/package/components/icons/AssetS3Icon.svelte +30 -0
  61. package/package/components/icons/AssetS3Icon.svelte.d.ts +9 -0
  62. package/package/components/icons/AssetVarIcon.svelte +31 -0
  63. package/package/components/icons/AssetVarIcon.svelte.d.ts +9 -0
  64. package/package/components/meltComponents/Popover.svelte +2 -0
  65. package/package/components/meltComponents/Popover.svelte.d.ts +2 -0
  66. package/package/components/schema/EditableSchemaSdkWrapper.svelte +1 -4
  67. package/package/components/script_builder.d.ts +2 -0
  68. package/package/components/settings/WorkspaceOperatorSettings.svelte +20 -17
  69. package/package/components/sidebar/OperatorMenu.svelte +5 -0
  70. package/package/components/sidebar/SidebarContent.svelte +9 -1
  71. package/package/components/tutorials/app/AppTutorial.svelte +1 -1
  72. package/package/components/tutorials/app/ConnectionTutorial.svelte +1 -1
  73. package/package/gen/schemas.gen.d.ts +69 -1
  74. package/package/gen/schemas.gen.js +69 -1
  75. package/package/gen/services.gen.d.ts +20 -1
  76. package/package/gen/services.gen.js +37 -0
  77. package/package/gen/types.gen.d.ts +103 -0
  78. package/package/history.svelte.d.ts +2 -2
  79. package/package/history.svelte.js +6 -6
  80. package/package/infer.d.ts +2 -0
  81. package/package/infer.js +31 -5
  82. package/package/svelte5Utils.svelte.d.ts +2 -1
  83. package/package/svelte5Utils.svelte.js +3 -2
  84. package/package/utils.d.ts +12 -0
  85. package/package/utils.js +22 -0
  86. package/package.json +5 -5
  87. package/package/components/DBManagerDrawerButton.svelte.d.ts +0 -9
@@ -4,7 +4,7 @@ import { File as FileIcon, FolderClosed, FolderOpen, RotateCw, Loader2, Download
4
4
  import { workspaceStore } from '../stores';
5
5
  import { HelpersService, SettingService } from '../gen';
6
6
  import { base } from '../base';
7
- import { displayDate, displaySize, emptyString, sendUserToast } from '../utils';
7
+ import { displayDate, displaySize, emptyString, parseS3Object, sendUserToast } from '../utils';
8
8
  import { Alert, Button, Drawer } from './common';
9
9
  import DrawerContent from './common/drawer/DrawerContent.svelte';
10
10
  import Section from './Section.svelte';
@@ -46,7 +46,10 @@ let displayedCount = $state(0);
46
46
  let filter = $state('');
47
47
  let timeout = undefined;
48
48
  let firstLoad = true;
49
- let secondaryStorageNames = usePromise(() => SettingService.getSecondaryStorageNames({ workspace: $workspaceStore }));
49
+ let secondaryStorageNames = usePromise(() => SettingService.getSecondaryStorageNames({ workspace: $workspaceStore }), { loadInit: false });
50
+ $effect(() => {
51
+ $workspaceStore && untrack(() => secondaryStorageNames.refresh());
52
+ });
50
53
  function onFilterChange() {
51
54
  if (!firstLoad) {
52
55
  timeout && clearTimeout(timeout);
@@ -290,7 +293,8 @@ async function moveS3File(srcFileKey, destFileKey) {
290
293
  await loadFileMetadataPlusPreviewAsync(selectedFileKey.s3);
291
294
  }
292
295
  let storage = $state(undefined);
293
- export async function open(preSelectedFileKey = undefined) {
296
+ export async function open(_preSelectedFileKey = undefined) {
297
+ const preSelectedFileKey = _preSelectedFileKey && parseS3Object(_preSelectedFileKey);
294
298
  storage = preSelectedFileKey?.storage;
295
299
  if (preSelectedFileKey !== undefined) {
296
300
  initialFileKey = { ...preSelectedFileKey };
@@ -328,6 +332,9 @@ async function reloadContent() {
328
332
  }
329
333
  }
330
334
  async function selectAndClose() {
335
+ if (selectedFileKey?.s3) {
336
+ dispatch('selectAndClose', { s3: selectedFileKey.s3, storage });
337
+ }
331
338
  drawer?.closeDrawer?.();
332
339
  }
333
340
  async function exit() {
@@ -1,3 +1,4 @@
1
+ import { type S3Object } from '../utils';
1
2
  interface Props {
2
3
  fromWorkspaceSettings?: boolean;
3
4
  readOnlyMode: boolean;
@@ -30,13 +31,14 @@ declare const S3FilePicker: $$__sveltets_2_IsomorphicComponent<Props, {
30
31
  s3: string;
31
32
  storage: string | undefined;
32
33
  } | undefined>;
34
+ selectAndClose: CustomEvent<{
35
+ s3: string;
36
+ storage: string | undefined;
37
+ }>;
33
38
  } & {
34
39
  [evt: string]: CustomEvent<any>;
35
40
  }, {}, {
36
- open: (preSelectedFileKey?: {
37
- s3: string;
38
- storage?: string;
39
- } | undefined) => Promise<void>;
41
+ open: (_preSelectedFileKey?: S3Object | undefined) => Promise<void>;
40
42
  }, "initialFileKey" | "selectedFileKey">;
41
43
  type S3FilePicker = InstanceType<typeof S3FilePicker>;
42
44
  export default S3FilePicker;
@@ -360,7 +360,8 @@ async function editScript(stay, parentHash, deploymentMsg, triggersToDeploy) {
360
360
  no_main_func: script.no_main_func,
361
361
  has_preprocessor: script.has_preprocessor,
362
362
  deployment_message: deploymentMsg || undefined,
363
- on_behalf_of_email: script.on_behalf_of_email
363
+ on_behalf_of_email: script.on_behalf_of_email,
364
+ fallback_access_types: script.fallback_access_types
364
365
  }
365
366
  });
366
367
  if (!initialPath) {
@@ -1556,6 +1557,7 @@ async function loadWorkerTags() {
1556
1557
  kind={script.kind}
1557
1558
  {template}
1558
1559
  tag={script.tag}
1560
+ bind:fallbackAccessTypes={script.fallback_access_types}
1559
1561
  lastSavedCode={savedScript?.draft?.content}
1560
1562
  lastDeployedCode={savedScript?.draft_only ? undefined : savedScript?.content}
1561
1563
  bind:args
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">import { BROWSER } from 'esm-env';
2
- import { JobService } from '../gen';
2
+ import { AssetService, JobService } from '../gen';
3
3
  import { copilotInfo, enterpriseLicense, userStore, workspaceStore } from '../stores';
4
4
  import { copyToClipboard, emptySchema, sendUserToast } from '../utils';
5
5
  import Editor from './Editor.svelte';
6
- import { inferArgs } from '../infer';
6
+ import { inferArgs, inferAssets } from '../infer';
7
7
  import { Pane, Splitpanes } from 'svelte-splitpanes';
8
8
  import SchemaForm from './SchemaForm.svelte';
9
9
  import LogPanel from './scriptEditor/LogPanel.svelte';
@@ -33,7 +33,10 @@ import { SUPPORTED_CHAT_SCRIPT_LANGUAGES } from './copilot/chat/script/core';
33
33
  import { getStringError } from './copilot/chat/utils';
34
34
  import { aiChatManager, AIMode } from './copilot/chat/AIChatManager.svelte';
35
35
  import { triggerableByAI } from '../actions/triggerableByAI.svelte';
36
- let { schema = $bindable(), code = $bindable(), path, lang, kind = undefined, template = 'script', tag, fixedOverflowWidgets = true, noSyncFromGithub = false, editor = $bindable(undefined), diffEditor = $bindable(undefined), collabMode = false, edit = true, noHistory = false, saveToWorkspace = false, watchChanges = false, customUi = undefined, args = $bindable(), selectedTab = $bindable('main'), hasPreprocessor = $bindable(false), captureTable = $bindable(undefined), showCaptures = true, stablePathForCaptures = '', lastSavedCode = undefined, lastDeployedCode = undefined, disableAi = false, editor_bar_right } = $props();
36
+ import AssetsDropdownButton from './assets/AssetsDropdownButton.svelte';
37
+ import { usePromise } from '../svelte5Utils.svelte';
38
+ import { assetEq } from './assets/lib';
39
+ let { schema = $bindable(), code = $bindable(), path, lang, kind = undefined, template = 'script', tag, fixedOverflowWidgets = true, noSyncFromGithub = false, editor = $bindable(undefined), diffEditor = $bindable(undefined), collabMode = false, edit = true, noHistory = false, saveToWorkspace = false, watchChanges = false, customUi = undefined, args = $bindable(), selectedTab = $bindable('main'), hasPreprocessor = $bindable(false), captureTable = $bindable(undefined), showCaptures = true, stablePathForCaptures = '', lastSavedCode = undefined, lastDeployedCode = undefined, disableAi = false, editor_bar_right, fallbackAccessTypes = $bindable() } = $props();
37
40
  $effect.pre(() => {
38
41
  if (schema == undefined) {
39
42
  schema = emptySchema();
@@ -55,6 +58,27 @@ $effect(() => {
55
58
  (code != undefined || schema != undefined) &&
56
59
  dispatch('change', { code, schema });
57
60
  });
61
+ let parsedAssets = usePromise(() => inferAssets(lang, code), { clearValueOnRefresh: false });
62
+ $effect(() => {
63
+ untrack(() => parsedAssets.refresh()), [lang, code];
64
+ });
65
+ // Load initial fallbackAccessTypes
66
+ if (edit && path) {
67
+ AssetService.listAssetsByUsage({
68
+ workspace: $workspaceStore,
69
+ requestBody: { usages: [{ path, kind: 'script' }] }
70
+ }).then((arr) => {
71
+ const v = arr[0];
72
+ setTimeout(() => {
73
+ for (const a of parsedAssets.value ?? []) {
74
+ const fallback = v.find((a2) => assetEq(a2, a))?.access_type;
75
+ if (!a.access_type && fallback) {
76
+ fallbackAccessTypes = [...(fallbackAccessTypes ?? []), { ...a, access_type: fallback }];
77
+ }
78
+ }
79
+ }, 200);
80
+ });
81
+ }
58
82
  let width = $state(1200);
59
83
  let testJobLoader = $state(undefined);
60
84
  let isValid = $state(true);
@@ -377,6 +401,9 @@ $effect(() => {
377
401
  <Pane bind:size={codePanelSize} minSize={10} class="!overflow-visible">
378
402
  <div class="h-full !overflow-visible bg-gray-50 dark:bg-[#272D38] relative">
379
403
  <div class="absolute top-2 right-4 z-10 flex flex-row gap-2">
404
+ {#if parsedAssets.value?.length}
405
+ <AssetsDropdownButton assets={parsedAssets.value} bind:fallbackAccessTypes />
406
+ {/if}
380
407
  {#if testPanelSize === 0}
381
408
  <HideButton
382
409
  hidden={true}
@@ -426,6 +453,7 @@ $effect(() => {
426
453
  {/if}
427
454
  {/if}
428
455
  </div>
456
+
429
457
  {#key lang}
430
458
  <Editor
431
459
  lineNumbersMinChars={4}
@@ -4,6 +4,7 @@ import Editor from './Editor.svelte';
4
4
  import DiffEditor from './DiffEditor.svelte';
5
5
  import type { ScriptEditorWhitelabelCustomUi } from './custom_ui';
6
6
  import CaptureTable from './triggers/CaptureTable.svelte';
7
+ import { type AssetWithAccessType } from './assets/lib';
7
8
  interface Props {
8
9
  schema?: Schema | any;
9
10
  code: string;
@@ -33,6 +34,7 @@ interface Props {
33
34
  lastDeployedCode?: string | undefined;
34
35
  disableAi?: boolean;
35
36
  editor_bar_right?: import('svelte').Snippet;
37
+ fallbackAccessTypes?: AssetWithAccessType[];
36
38
  }
37
39
  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> {
38
40
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -72,6 +74,6 @@ declare const ScriptEditor: $$__sveltets_2_IsomorphicComponent<Props, {
72
74
  setCollaborationMode: () => Promise<void>;
73
75
  disableCollaboration: () => void;
74
76
  updateArgs: (newArgs: Record<string, any>) => Promise<void>;
75
- }, "args" | "code" | "schema" | "editor" | "selectedTab" | "diffEditor" | "hasPreprocessor" | "captureTable">;
77
+ }, "args" | "code" | "schema" | "editor" | "selectedTab" | "diffEditor" | "hasPreprocessor" | "fallbackAccessTypes" | "captureTable">;
76
78
  type ScriptEditor = InstanceType<typeof ScriptEditor>;
77
79
  export default ScriptEditor;
@@ -2,9 +2,6 @@
2
2
  import AiChatLayout from './copilot/chat/AiChatLayout.svelte';
3
3
  let { script: oldScript, disableAi, ...props } = $props();
4
4
  let script = $state(oldScript);
5
- $effect(() => {
6
- script = oldScript;
7
- });
8
5
  </script>
9
6
 
10
7
  <AiChatLayout noPadding {disableAi}>
@@ -16,7 +16,7 @@ declare const ShareModal: $$__sveltets_2_IsomorphicComponent<Record<string, neve
16
16
  } & {
17
17
  [evt: string]: CustomEvent<any>;
18
18
  }, {}, {
19
- openDrawer: (newPath: string, kind_l: "script" | "flow" | "resource" | "schedule" | "app" | "variable" | "group_" | "raw_app" | "http_trigger" | "websocket_trigger" | "kafka_trigger" | "nats_trigger" | "postgres_trigger" | "mqtt_trigger" | "gcp_trigger" | "sqs_trigger") => Promise<void>;
19
+ openDrawer: (newPath: string, kind_l: "resource" | "script" | "flow" | "schedule" | "app" | "variable" | "group_" | "raw_app" | "http_trigger" | "websocket_trigger" | "kafka_trigger" | "nats_trigger" | "postgres_trigger" | "mqtt_trigger" | "gcp_trigger" | "sqs_trigger") => Promise<void>;
20
20
  }, "">;
21
21
  type ShareModal = InstanceType<typeof ShareModal>;
22
22
  export default ShareModal;
@@ -19,7 +19,7 @@ import ContextPanel from './contextPanel/ContextPanel.svelte';
19
19
  import ItemPicker from '../../ItemPicker.svelte';
20
20
  import VariableEditor from '../../VariableEditor.svelte';
21
21
  import { VariableService } from '../../../gen';
22
- import { initHistory } from '../../../history';
22
+ import { initHistory } from '../../../history.svelte';
23
23
  import { Component, Minus, Paintbrush, Plus, Smartphone, Scan, Hand, Grab } from 'lucide-svelte';
24
24
  import { animateTo, findGridItem, findGridItemParentGrid } from './appUtils';
25
25
  import ComponentNavigation from './component/ComponentNavigation.svelte';
@@ -5,7 +5,7 @@ import Button from '../../common/button/Button.svelte';
5
5
  import Path from '../../Path.svelte';
6
6
  import Toggle from '../../Toggle.svelte';
7
7
  import { AppService, DraftService } from '../../../gen';
8
- import { redo, undo } from '../../../history';
8
+ import { redo, undo } from '../../../history.svelte';
9
9
  import { enterpriseLicense, userStore, workspaceStore } from '../../../stores';
10
10
  import { AlignHorizontalSpaceAround, BellOff, Bug, DiffIcon, Expand, FileJson, FileUp, FormInput, History, Laptop2, Loader2, Save, Smartphone, FileClock, Sun, Moon, SunMoon, Zap, Globe, AlertTriangle } from 'lucide-svelte';
11
11
  import { getContext, untrack } from 'svelte';
@@ -3,7 +3,7 @@ import { gridColumns, isFixed, toggleFixed } from '../gridUtils';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import HiddenComponent from '../components/helpers/HiddenComponent.svelte';
5
5
  import Component from './component/Component.svelte';
6
- import { push } from '../../../history';
6
+ import { push } from '../../../history.svelte';
7
7
  import { dfs, expandGriditem, findGridItem, findGridItemParentGrid, insertNewGridItem, isContainer, subGridIndexKey } from './appUtils';
8
8
  import Grid from '../svelte-grid/Grid.svelte';
9
9
  import { deepEqual } from 'fast-equals';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">import { stopPropagation } from 'svelte/legacy';
2
- import { push } from '../../../history';
2
+ import { push } from '../../../history.svelte';
3
3
  import { classNames } from '../../../utils';
4
4
  import { createEventDispatcher, getContext, onDestroy } from 'svelte';
5
5
  import { twMerge } from 'tailwind-merge';
@@ -1,6 +1,6 @@
1
1
  // import { getContext } from 'svelte'
2
2
  import { copyComponent, findGridItem, findGridItemParentGrid, getAllSubgridsAndComponentIds, insertNewGridItem } from '../appUtils';
3
- import { push } from '../../../../history';
3
+ import { push } from '../../../../history.svelte';
4
4
  import { sendUserToast } from '../../../../toast';
5
5
  import { gridColumns } from '../../gridUtils';
6
6
  import { copyToClipboard } from '../../../../utils';
@@ -2,7 +2,7 @@
2
2
  import { components as componentsRecord, presets as presetsRecord, COMPONENT_SETS, DEPRECATED_COMPONENTS, processDimension } from '../component';
3
3
  import ListItem from './ListItem.svelte';
4
4
  import { appComponentFromType, copyComponent, insertNewGridItem, setUpTopBarComponentContent } from '../appUtils';
5
- import { push } from '../../../../history';
5
+ import { push } from '../../../../history.svelte';
6
6
  import { ClearableInput, Drawer, DrawerContent } from '../../../common';
7
7
  import { enterpriseLicense, workspaceStore } from '../../../../stores';
8
8
  import { getGroup, listGroups } from './groupUtils';
@@ -18,7 +18,7 @@ import GridTab from './GridTab.svelte';
18
18
  import { deleteGridItem, isTableAction } from '../appUtils';
19
19
  import GridPane from './GridPane.svelte';
20
20
  import { slide } from 'svelte/transition';
21
- import { push } from '../../../../history';
21
+ import { push } from '../../../../history.svelte';
22
22
  import StylePanel from './StylePanel.svelte';
23
23
  import { ChevronLeft, ArrowBigUp, ArrowLeft } from 'lucide-svelte';
24
24
  import GridCondition from './GridCondition.svelte';
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">import { getContext } from 'svelte';
2
2
  import { deleteGridItem, findComponentSettings } from '../appUtils';
3
- import { push } from '../../../../history';
3
+ import { push } from '../../../../history.svelte';
4
4
  let { onDelete = undefined, noGrid = false } = $props();
5
5
  const { app, runnableComponents, selectedComponent, worldStore, focusedGrid, errorByComponent, componentControl } = getContext('AppViewerContext');
6
6
  const { history, movingcomponents } = getContext('AppEditorContext');
@@ -1,6 +1,6 @@
1
1
  import type { Schema } from '../../common';
2
2
  import type { Policy, Preview } from '../../gen';
3
- import type { History } from '../../history';
3
+ import type { History } from '../../history.svelte';
4
4
  import type { Writable } from 'svelte/store';
5
5
  import type { AppComponent, PresetComponentConfig, RecomputeOthersSource, components } from './editor/component/components';
6
6
  import type { AppInput, ConnectedAppInput, ConnectedInput, EvalAppInput, EvalV2AppInput, InputConnection, ResultAppInput, RowAppInput, Runnable, StaticAppInput, TemplateV2AppInput, UploadAppInput, UploadS3AppInput, UserAppInput } from './inputType';
@@ -94,7 +94,7 @@ export type AppTheme = {
94
94
  type: 'inlined';
95
95
  css: string;
96
96
  };
97
- import type { DiffDrawerI } from "../diff_drawer";
97
+ import type { DiffDrawerI } from '../diff_drawer';
98
98
  export interface AppEditorProps {
99
99
  app: App;
100
100
  path: string;
@@ -0,0 +1,178 @@
1
+ <script lang="ts">import { clone, pluralize } from '../../utils';
2
+ import { deepEqual } from 'fast-equals';
3
+ import { AlertTriangle, Edit2, Pyramid } from 'lucide-svelte';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { Popover } from '../meltComponents';
6
+ import S3FilePicker from '../S3FilePicker.svelte';
7
+ import ExploreAssetButton, { assetCanBeExplored } from '../../../routes/(root)/(logged)/assets/ExploreAssetButton.svelte';
8
+ import { assetEq, formatAssetKind } from './lib';
9
+ import DbManagerDrawer from '../DBManagerDrawer.svelte';
10
+ import { tick, untrack } from 'svelte';
11
+ import { ResourceService } from '../../gen';
12
+ import { workspaceStore } from '../../stores';
13
+ import Button from '../common/button/Button.svelte';
14
+ import Tooltip from '../meltComponents/Tooltip.svelte';
15
+ import ResourceEditorDrawer from '../ResourceEditorDrawer.svelte';
16
+ import ToggleButtonGroup from '../common/toggleButton-v2/ToggleButtonGroup.svelte';
17
+ import ToggleButton from '../common/toggleButton-v2/ToggleButton.svelte';
18
+ let { assets, enableChangeAnimation = true, size = 'xs', noBtnText = false, popoverPlacement = 'bottom-end', disableLiTooltip = false, fallbackAccessTypes = $bindable(), onHoverLi, liSubtitle } = $props();
19
+ let prevAssets = $state([]);
20
+ let blueBgDiv = $state();
21
+ let s3FilePicker = $state();
22
+ let dbManagerDrawer = $state();
23
+ let resourceEditorDrawer = $state();
24
+ let isOpen = $state(false);
25
+ let resourceDataCache = $state({});
26
+ $effect(() => {
27
+ if (!enableChangeAnimation) {
28
+ if (blueBgDiv) {
29
+ blueBgDiv.classList.remove('animate-fade-out');
30
+ }
31
+ }
32
+ });
33
+ $effect(() => {
34
+ assets;
35
+ untrack(() => {
36
+ if (deepEqual(assets, prevAssets))
37
+ return;
38
+ prevAssets = clone(assets);
39
+ // Replay animation
40
+ if (blueBgDiv && enableChangeAnimation) {
41
+ blueBgDiv.classList.add('animate-fade-out');
42
+ blueBgDiv.style.animation = 'none';
43
+ blueBgDiv.offsetHeight; /* trigger reflow */
44
+ blueBgDiv.style.animation = '';
45
+ }
46
+ for (const asset of assets) {
47
+ if (asset.kind !== 'resource' || asset.path in resourceDataCache)
48
+ continue;
49
+ ResourceService.getResource({ path: asset.path, workspace: $workspaceStore })
50
+ .then((resource) => (resourceDataCache[asset.path] = resource.resource_type))
51
+ .catch((err) => (resourceDataCache[asset.path] = undefined));
52
+ }
53
+ });
54
+ });
55
+ </script>
56
+
57
+ <Popover
58
+ floatingConfig={{ strategy: 'absolute', placement: popoverPlacement }}
59
+ usePointerDownOutside
60
+ closeOnOtherPopoverOpen
61
+ bind:isOpen
62
+ escapeBehavior="ignore"
63
+ >
64
+ <svelte:fragment slot="trigger">
65
+ <div
66
+ class={twMerge(
67
+ size === '3xs' ? 'h-[1.6rem]' : 'py-1.5',
68
+ 'text-xs flex items-center gap-1.5 px-2 rounded-md relative',
69
+ 'border border-tertiary/30',
70
+ 'bg-surface hover:bg-surface-hover active:bg-surface',
71
+ 'transition-all hover:text-primary cursor-pointer'
72
+ )}
73
+ >
74
+ <div
75
+ bind:this={blueBgDiv}
76
+ class="absolute pointer-events-none bg-slate-300 dark:bg-[#576278] inset-0 rounded-md opacity-0"
77
+ ></div>
78
+ <Pyramid size={size === '3xs' ? 13 : 16} class="z-10" />
79
+ <span
80
+ class={twMerge('z-10 font-normal', size === '3xs' ? 'text-3xs mt-[0.08rem]' : 'text-xs')}
81
+ >
82
+ {noBtnText ? assets.length : pluralize(assets.length, 'asset')}
83
+ </span>
84
+ </div>
85
+ </svelte:fragment>
86
+ <svelte:fragment slot="content">
87
+ <ul class="divide-y rounded-md">
88
+ {#each assets as asset}
89
+ {@const fallbackAccessType = fallbackAccessTypes?.find((a) =>
90
+ assetEq(a, asset)
91
+ )?.access_type}
92
+ {@const hasWarning = !asset.access_type && !fallbackAccessType}
93
+ <li
94
+ class="text-sm px-4 h-12 flex gap-4 items-center justify-between hover:bg-surface-hover"
95
+ onmouseenter={() => onHoverLi?.(asset, 'enter')}
96
+ onmouseleave={() => onHoverLi?.(asset, 'leave')}
97
+ >
98
+ <div class="flex flex-col">
99
+ <Tooltip class="select-none max-w-48 truncate" disablePopup={disableLiTooltip}>
100
+ {asset.path}
101
+ <svelte:fragment slot="text">
102
+ {asset.path}
103
+ </svelte:fragment>
104
+ </Tooltip>
105
+ <span class="text-xs text-tertiary select-none">
106
+ {liSubtitle?.(asset) ??
107
+ formatAssetKind({
108
+ ...asset,
109
+ metadata: { resource_type: resourceDataCache[asset.path] }
110
+ })}
111
+ </span>
112
+ </div>
113
+
114
+ <div class="flex gap-2 items-center">
115
+ {#if asset.kind === 'resource' && resourceDataCache[asset.path] !== undefined}
116
+ <Button
117
+ startIcon={{ icon: Edit2 }}
118
+ size="xs"
119
+ variant="border"
120
+ spacingSize="xs2"
121
+ iconOnly
122
+ on:click={() => (resourceEditorDrawer?.initEdit(asset.path), (isOpen = false))}
123
+ />
124
+ {/if}
125
+ {#if asset.kind === 'resource' && resourceDataCache[asset.path] === undefined}
126
+ <Tooltip class="mr-2.5">
127
+ <AlertTriangle size={16} class="text-orange-600 dark:text-orange-500" />
128
+ <svelte:fragment slot="text">Could not find resource</svelte:fragment>
129
+ </Tooltip>
130
+ {/if}
131
+ {#if assetCanBeExplored(asset, { resource_type: resourceDataCache[asset.path] })}
132
+ <ExploreAssetButton
133
+ {asset}
134
+ {s3FilePicker}
135
+ {dbManagerDrawer}
136
+ onClick={() => (isOpen = false)}
137
+ noText
138
+ _resourceMetadata={{ resource_type: resourceDataCache[asset.path] }}
139
+ />
140
+ {/if}
141
+
142
+ <ToggleButtonGroup
143
+ disabled={!!asset.access_type}
144
+ tabListClass={hasWarning ? 'bg-red-200 dark:bg-red-300' : ''}
145
+ bind:selected={
146
+ () => asset.access_type ?? fallbackAccessType,
147
+ async (access_type) => {
148
+ fallbackAccessTypes ??= []
149
+ await tick()
150
+ let val = fallbackAccessTypes?.filter((a) => !assetEq(a, asset))
151
+ val.push({ ...asset, access_type })
152
+ fallbackAccessTypes = val
153
+ }
154
+ }
155
+ >
156
+ {#snippet children({ item })}
157
+ {#each ['r', 'w', 'rw'] as v}
158
+ <ToggleButton
159
+ class={hasWarning
160
+ ? 'bg-transparent hover:bg-red-100 dark:text-primary-inverse'
161
+ : ''}
162
+ value={v}
163
+ label={v}
164
+ {item}
165
+ tooltip={'Could not infer access type from code, please select manually'}
166
+ />
167
+ {/each}
168
+ {/snippet}
169
+ </ToggleButtonGroup>
170
+ </div>
171
+ </li>
172
+ {/each}
173
+ </ul>
174
+ </svelte:fragment>
175
+ </Popover>
176
+ <S3FilePicker bind:this={s3FilePicker} readOnlyMode />
177
+ <DbManagerDrawer bind:this={dbManagerDrawer} />
178
+ <ResourceEditorDrawer bind:this={resourceEditorDrawer} />
@@ -0,0 +1,16 @@
1
+ import { type Asset, type AssetWithAccessType } from './lib';
2
+ import type { Placement } from '@floating-ui/core';
3
+ type $$ComponentProps = {
4
+ assets: AssetWithAccessType[];
5
+ enableChangeAnimation?: boolean;
6
+ size?: 'xs' | '3xs';
7
+ noBtnText?: boolean;
8
+ popoverPlacement?: Placement;
9
+ disableLiTooltip?: boolean;
10
+ fallbackAccessTypes?: AssetWithAccessType[];
11
+ onHoverLi?: (asset: Asset, eventType: 'enter' | 'leave') => void;
12
+ liSubtitle?: (asset: Asset) => string;
13
+ };
14
+ declare const AssetsDropdownButton: import("svelte").Component<$$ComponentProps, {}, "fallbackAccessTypes">;
15
+ type AssetsDropdownButton = ReturnType<typeof AssetsDropdownButton>;
16
+ export default AssetsDropdownButton;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">import { Drawer, DrawerContent } from '../common';
2
+ import RowIcon from '../common/table/RowIcon.svelte';
3
+ import { assetDisplaysAsInputInFlowGraph, assetDisplaysAsOutputInFlowGraph } from '../graph/renderers/nodes/AssetNode.svelte';
4
+ import { getAssetUsagePageUri } from './lib';
5
+ let usagesDrawerData = $state();
6
+ export function open(data) {
7
+ usagesDrawerData = data;
8
+ }
9
+ </script>
10
+
11
+ <Drawer
12
+ open={usagesDrawerData !== undefined}
13
+ size="900px"
14
+ on:close={() => (usagesDrawerData = undefined)}
15
+ >
16
+ <DrawerContent title="Asset usage" on:close={() => (usagesDrawerData = undefined)}>
17
+ <ul class="flex flex-col border rounded-md divide-y">
18
+ {#each usagesDrawerData?.usages ?? [] as u}
19
+ <li>
20
+ <a
21
+ href={getAssetUsagePageUri(u)}
22
+ aria-label={`${u.kind}/${u.path}`}
23
+ class="text-sm text-primary flex items-center py-3 px-4 gap-3 hover:bg-surface-hover cursor-pointer"
24
+ >
25
+ <RowIcon kind={u.kind} />
26
+ <div class="flex flex-col justify-center flex-1">
27
+ <span class="font-semibold">{u.path}</span>
28
+ <span class="text-xs text-tertiary">{u.kind}</span>
29
+ </div>
30
+ <div class="flex gap-2">
31
+ {#if assetDisplaysAsInputInFlowGraph(u)}
32
+ <div class="text-xs border text-tertiary max-w-fit p-1 rounded-md">Read</div>
33
+ {/if}
34
+ {#if assetDisplaysAsOutputInFlowGraph(u)}
35
+ <div class="text-xs border text-tertiary max-w-fit p-1 rounded-md">Write</div>
36
+ {/if}
37
+ </div>
38
+ </a>
39
+ </li>
40
+ {/each}
41
+ </ul>
42
+ </DrawerContent>
43
+ </Drawer>
@@ -0,0 +1,12 @@
1
+ import type { AssetUsageAccessType, AssetUsageKind } from '../../gen';
2
+ declare const AssetsUsageDrawer: import("svelte").Component<Record<string, never>, {
3
+ open: (data: {
4
+ usages: {
5
+ path: string;
6
+ kind: AssetUsageKind;
7
+ access_type?: AssetUsageAccessType;
8
+ }[];
9
+ } | undefined) => void;
10
+ }, "">;
11
+ type AssetsUsageDrawer = ReturnType<typeof AssetsUsageDrawer>;
12
+ export default AssetsUsageDrawer;
@@ -0,0 +1,16 @@
1
+ import type { AssetKind as _AssetKind, Asset as _Asset, ListAssetsResponse, AssetUsageAccessType } from '../../gen';
2
+ export type Asset = _Asset;
3
+ export type AssetKind = _AssetKind;
4
+ export type AssetWithAccessType = Asset & {
5
+ access_type?: AssetUsageAccessType;
6
+ };
7
+ export declare function formatAsset(asset: Asset): string;
8
+ export declare function getAssetUsagePageUri(usage: ListAssetsResponse[number]['usages'][number]): string | undefined;
9
+ export declare function assetEq(a: Asset | undefined, b: Asset | undefined): boolean;
10
+ export declare function parseAssetFromString(s: string): Asset | undefined;
11
+ export declare function formatAssetKind(asset: {
12
+ kind: AssetKind;
13
+ metadata?: {
14
+ resource_type?: string;
15
+ };
16
+ }): string;
@@ -0,0 +1,60 @@
1
+ import { capitalize } from '../../utils';
2
+ export function formatAsset(asset) {
3
+ switch (asset.kind) {
4
+ case 'resource':
5
+ return `res://${asset.path}`;
6
+ case 's3object':
7
+ return `s3://${asset.path}`;
8
+ case 'variable':
9
+ return `var://${asset.path}`;
10
+ }
11
+ }
12
+ export function getAssetUsagePageUri(usage) {
13
+ if (usage.kind === 'script') {
14
+ return `/scripts/get/${usage.path}`;
15
+ }
16
+ else if (usage.kind === 'flow') {
17
+ return `/flows/get/${usage.path}`;
18
+ }
19
+ }
20
+ export function assetEq(a, b) {
21
+ if (!a || !b)
22
+ return a === b;
23
+ return a.kind === b.kind && a.path === b.path;
24
+ }
25
+ export function parseAssetFromString(s) {
26
+ if (s.startsWith('res://')) {
27
+ return { kind: 'resource', path: s.slice(6) };
28
+ }
29
+ else if (s.startsWith('$res:')) {
30
+ return { kind: 'resource', path: s.slice(5) };
31
+ }
32
+ else if (s.startsWith('s3://')) {
33
+ return { kind: 's3object', path: s.slice(5) };
34
+ }
35
+ else if (s.startsWith('var://')) {
36
+ return { kind: 'variable', path: s.slice(6) };
37
+ }
38
+ return undefined;
39
+ }
40
+ export function formatAssetKind(asset) {
41
+ switch (asset.kind) {
42
+ case 'resource':
43
+ if (asset.metadata?.resource_type) {
44
+ if (asset.metadata.resource_type === 'state')
45
+ return 'State';
46
+ if (asset.metadata.resource_type === 'cache')
47
+ return 'Cache';
48
+ if (asset.metadata.resource_type === 'app_theme')
49
+ return 'App Theme';
50
+ return `${capitalize(asset.metadata.resource_type)} resource`;
51
+ }
52
+ else {
53
+ return 'metadata' in asset ? 'Invalid resource' : 'Resource';
54
+ }
55
+ case 's3object':
56
+ return 'S3 Object';
57
+ case 'variable':
58
+ return 'Variable';
59
+ }
60
+ }
@@ -13,6 +13,6 @@ interface Props {
13
13
  actionKind?: ActionKind | 'all';
14
14
  scope?: undefined | 'all_workspaces' | 'instance';
15
15
  }
16
- declare const AuditLogsFilters: import("svelte").Component<Props, {}, "username" | "operation" | "resource" | "before" | "after" | "perPage" | "hasMore" | "logs" | "pageIndex" | "actionKind" | "scope">;
16
+ declare const AuditLogsFilters: import("svelte").Component<Props, {}, "resource" | "username" | "operation" | "before" | "after" | "perPage" | "hasMore" | "logs" | "pageIndex" | "actionKind" | "scope">;
17
17
  type AuditLogsFilters = ReturnType<typeof AuditLogsFilters>;
18
18
  export default AuditLogsFilters;