mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 08:02:38 +00:00
refactor: one operating-workspace context for editors acting on a session's workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
29abd63de6
commit
acbdb285c9
@@ -3,11 +3,13 @@
|
||||
import Select from './select/Select.svelte'
|
||||
import { fetchAvailableModels, AI_PROVIDERS } from './copilot/lib'
|
||||
import type { AIProvider, ProviderConfig } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import ResourcePicker from './ResourcePicker.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import { saveConfig, removeConfig, isSameAsStoredConfig } from './aiProviderStorage'
|
||||
import AIReasoningEffortPicker from './AIReasoningEffortPicker.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
value: ProviderConfig | undefined
|
||||
@@ -26,7 +28,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore ?? '')
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace ?? '')
|
||||
|
||||
let value = $derived.by(() => {
|
||||
if (!_uncheckedValue || typeof _uncheckedValue !== 'object') return undefined
|
||||
|
||||
@@ -41,12 +41,14 @@
|
||||
import { safeSelectItems } from './select/utils.svelte'
|
||||
import S3ArgInput from './common/fileUpload/S3ArgInput.svelte'
|
||||
import { base } from '$lib/base'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getJsonSchemaFromResource } from './schema/jsonSchemaResource.svelte'
|
||||
import AIProviderPicker from './AIProviderPicker.svelte'
|
||||
import TextInput from './text_input/TextInput.svelte'
|
||||
import FileInput from './common/fileInput/FileInput.svelte'
|
||||
import { randomUUID } from '$lib/utils/uuid'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
label?: string
|
||||
@@ -823,7 +825,7 @@
|
||||
/>
|
||||
{/await}
|
||||
{:else if inputCat == 'object' && format?.startsWith('jsonschema-')}
|
||||
{#await getJsonSchemaFromResource(format.substring('jsonschema-'.length), workspace ?? $workspaceStore ?? '')}
|
||||
{#await getJsonSchemaFromResource(format.substring('jsonschema-'.length), workspace ?? $operatingWorkspace ?? '')}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then schema}
|
||||
{#if !schema || !schema.properties}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<script lang="ts">
|
||||
import Select from './select/Select.svelte'
|
||||
import { WorkspaceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { RefreshCcw } from 'lucide-svelte'
|
||||
import { Button } from './common'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface ChannelItem {
|
||||
channel_id?: string
|
||||
@@ -21,8 +23,8 @@
|
||||
showRefreshButton?: boolean
|
||||
onError?: (error: Error) => void
|
||||
onSelectedChannelChange?: (channel: ChannelItem | undefined) => void
|
||||
/** Workspace to list Teams channels from; defaults to the nav
|
||||
* `$workspaceStore`. A forked session passes its acting workspace. */
|
||||
/** Workspace to list Teams channels from; defaults to the operating workspace (see
|
||||
* `useOperatingWorkspace`). */
|
||||
workspace?: string
|
||||
}
|
||||
|
||||
@@ -40,7 +42,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let isFetching = $state(false)
|
||||
let loadedChannels = $state<ChannelItem[]>([])
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
const bubble = createBubbler()
|
||||
import type { Schema } from '$lib/common'
|
||||
import { VariableService, type ScriptLang } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Button } from './common'
|
||||
import ItemPicker from './ItemPicker.svelte'
|
||||
import VariableEditor from './VariableEditor.svelte'
|
||||
@@ -36,6 +35,9 @@
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import Editor from './Editor.svelte'
|
||||
import AddPropertyV2 from './schema/AddPropertyV2.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
// export let openEditTab: () => void = () => {}
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -128,7 +130,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
$effect.pre(() => {
|
||||
if (args == undefined) {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
import type { Schema, SupportedLanguage } from '$lib/common'
|
||||
import { base } from '$lib/base'
|
||||
import { enterpriseLicense, workspaceStore } from '$lib/stores'
|
||||
import { enterpriseLicense } from '$lib/stores'
|
||||
import MsTeamsIcon from '$lib/components/icons/MSTeamsIcon.svelte'
|
||||
import { classNames, emptySchema, emptyString, sendUserToast, tryEvery } from '$lib/utils'
|
||||
import MultiSelect from '$lib/components/select/MultiSelect.svelte'
|
||||
@@ -61,6 +61,9 @@
|
||||
import SmtpConfigurationStatus from './common/smtp/SmtpConfigurationStatus.svelte'
|
||||
import { SettingService } from '$lib/gen'
|
||||
import { isSmtpSettingsValid } from './instanceSettings/SmtpSettings.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
const slackRecoveryHandler = hubPaths.slackRecoveryHandler
|
||||
const slackHandlerScriptPath = hubPaths.slackErrorHandler
|
||||
@@ -81,9 +84,8 @@
|
||||
customHandlerKind?: 'flow' | 'script'
|
||||
customTabTooltip?: import('svelte').Snippet
|
||||
noMargin?: boolean
|
||||
/** Workspace for handler lookup / settings / test jobs. Defaults to the
|
||||
* nav `$workspaceStore`; a trigger editor in a forked session passes its
|
||||
* acting workspace so the handler is resolved and saved there. */
|
||||
/** Workspace for handler lookup / settings / test jobs. Defaults to the operating
|
||||
* workspace (see `useOperatingWorkspace`). */
|
||||
workspace?: string
|
||||
/** Offer the instance critical alert channels as a destination. Workspace-level
|
||||
* error handling only: schedules and triggers have no such setting. */
|
||||
@@ -106,7 +108,7 @@
|
||||
showInstanceAlerts = false
|
||||
}: Props = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace)
|
||||
// Carry the acting workspace onto the "create from template" route when an
|
||||
// explicit override is set, so a forked session creates the handler script
|
||||
// there. `customScriptTemplate` already has a query string (`?hub=…`).
|
||||
|
||||
@@ -33,15 +33,13 @@
|
||||
import { Button, ButtonType } from '$lib/components/common'
|
||||
import S3FilePicker from '$lib/components/S3FilePicker.svelte'
|
||||
import { VolumeService } from '$lib/gen'
|
||||
import {
|
||||
globalDbManagerDrawer,
|
||||
globalS3FilePickerExplorer,
|
||||
userStore,
|
||||
workspaceStore
|
||||
} from '$lib/stores'
|
||||
import { globalDbManagerDrawer, globalS3FilePickerExplorer, userStore } from '$lib/stores'
|
||||
import { isS3Uri } from '$lib/utils'
|
||||
import { Database, File, HardDriveIcon } from 'lucide-svelte'
|
||||
import DucklakeIcon from './icons/DucklakeIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
const {
|
||||
asset,
|
||||
@@ -69,7 +67,7 @@
|
||||
} = $props()
|
||||
|
||||
let dbManagerDrawer = $derived(globalDbManagerDrawer.val)
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
const assetUri = $derived(formatAsset(asset))
|
||||
// Contexts with a select/upload flow pass their own picker; everything else
|
||||
// (e.g. the resources list) falls back to the global read-only explorer.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore, enterpriseLicense, userStore } from '$lib/stores'
|
||||
import { enterpriseLicense, userStore } from '$lib/stores'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import { Loader2, Github, RotateCw, Plus, Minus, Download, AlertTriangle } from 'lucide-svelte'
|
||||
@@ -18,6 +18,9 @@
|
||||
type GitHubAppState
|
||||
} from '$lib/githubApp'
|
||||
import RepositorySelector from './RepositorySelector.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
resourceType: string
|
||||
@@ -70,14 +73,14 @@
|
||||
|
||||
let showGitHubApp = $derived(
|
||||
resourceType === 'git_repository' &&
|
||||
$workspaceStore &&
|
||||
$operatingWorkspace &&
|
||||
($userStore?.is_admin || $userStore?.is_super_admin)
|
||||
)
|
||||
|
||||
// Load GitHub installations when conditions are met
|
||||
$effect(() => {
|
||||
if (showGitHubApp && $enterpriseLicense && $workspaceStore) {
|
||||
loadGithubInstallations(githubState, $workspaceStore).catch((error) => {
|
||||
if (showGitHubApp && $enterpriseLicense && $operatingWorkspace) {
|
||||
loadGithubInstallations(githubState, $operatingWorkspace).catch((error) => {
|
||||
console.error('Failed to load GitHub installations:', error)
|
||||
})
|
||||
}
|
||||
@@ -113,11 +116,11 @@
|
||||
}
|
||||
|
||||
async function handleDeleteInstallation(installationId: number) {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
try {
|
||||
await deleteInstallation($workspaceStore, installationId, () =>
|
||||
loadGithubInstallations(githubState, $workspaceStore!)
|
||||
await deleteInstallation($operatingWorkspace, installationId, () =>
|
||||
loadGithubInstallations(githubState, $operatingWorkspace!)
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('Failed to delete installation:', error)
|
||||
@@ -125,11 +128,11 @@
|
||||
}
|
||||
|
||||
async function handleAddInstallation(installationId: number, workspaceId: string) {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
try {
|
||||
await addInstallationToWorkspace($workspaceStore, installationId, workspaceId, () =>
|
||||
loadGithubInstallations(githubState, $workspaceStore!)
|
||||
await addInstallationToWorkspace($operatingWorkspace, installationId, workspaceId, () =>
|
||||
loadGithubInstallations(githubState, $operatingWorkspace!)
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('Failed to add installation:', error)
|
||||
@@ -137,22 +140,22 @@
|
||||
}
|
||||
|
||||
async function handleExportInstallation(installationId: number) {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
try {
|
||||
await exportInstallation($workspaceStore, installationId)
|
||||
await exportInstallation($operatingWorkspace, installationId)
|
||||
} catch (error) {
|
||||
console.error('Failed to export installation:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleImportInstallation() {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
try {
|
||||
await importInstallation($workspaceStore, githubState.importJwt, () => {
|
||||
await importInstallation($operatingWorkspace, githubState.importJwt, () => {
|
||||
githubState.importJwt = ''
|
||||
loadGithubInstallations(githubState, $workspaceStore!)
|
||||
loadGithubInstallations(githubState, $operatingWorkspace!)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to import installation:', error)
|
||||
@@ -160,17 +163,17 @@
|
||||
}
|
||||
|
||||
function handleRefreshInstallations() {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
loadGithubInstallations(githubState, $workspaceStore).catch((error) => {
|
||||
loadGithubInstallations(githubState, $operatingWorkspace).catch((error) => {
|
||||
console.error('Failed to refresh installations:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function handleInstallClickWithPopover() {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
handleInstallClick(githubState, $workspaceStore, () => {
|
||||
handleInstallClick(githubState, $operatingWorkspace, () => {
|
||||
githubAppPopover?.open()
|
||||
})
|
||||
}
|
||||
@@ -297,9 +300,9 @@
|
||||
target="_blank"
|
||||
disabled={githubState.isCheckingInstallation}
|
||||
on:click={() => {
|
||||
if ($workspaceStore) {
|
||||
startInstallationCheck(githubState, $workspaceStore, () =>
|
||||
loadGithubInstallations(githubState, $workspaceStore!)
|
||||
if ($operatingWorkspace) {
|
||||
startInstallationCheck(githubState, $operatingWorkspace, () =>
|
||||
loadGithubInstallations(githubState, $operatingWorkspace!)
|
||||
)
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore, userStore, enterpriseLicense } from '$lib/stores'
|
||||
import { userStore, enterpriseLicense } from '$lib/stores'
|
||||
import { GitSyncService, type GitlabProject } from '$lib/gen'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
@@ -8,6 +8,9 @@
|
||||
import TextInput from './text_input/TextInput.svelte'
|
||||
import Select from './select/Select.svelte'
|
||||
import { GitBranch, Gitlab, Loader2 } from 'lucide-svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
resourceType: string
|
||||
@@ -30,7 +33,7 @@
|
||||
onArgsUpdate
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let baseUrl = $state('https://gitlab.com')
|
||||
let token = $state('')
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { HelpersService, ResourceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Button, Drawer, DrawerContent } from './common'
|
||||
import { GitBranch, Loader2, FolderOpen } from 'lucide-svelte'
|
||||
import Select from './select/Select.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
open: boolean
|
||||
@@ -27,7 +29,7 @@
|
||||
workspace: workspaceProp = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspaceProp ?? $workspaceStore)
|
||||
let ws = $derived(workspaceProp ?? $operatingWorkspace)
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
selected: {
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
import { DataTable } from '$lib/components/table'
|
||||
import HistoricList from './HistoricList.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
runnableId?: string | undefined
|
||||
@@ -32,7 +34,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let historicList: HistoricList | undefined = $state(undefined)
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { VariableService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { watch } from 'runed'
|
||||
import { Plus } from 'lucide-svelte'
|
||||
import { Button } from './common'
|
||||
import ItemPicker from './ItemPicker.svelte'
|
||||
import VariableEditor from './VariableEditor.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
/** The transforms being edited. A picked variable is written into `pickForField`'s. */
|
||||
@@ -26,7 +28,7 @@
|
||||
variableEditor = $bindable()
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
watch(
|
||||
() => ws,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import { type InputTransform } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { allTrue, type DynamicInput as DynamicInputTypes } from '$lib/utils'
|
||||
import { untrack } from 'svelte'
|
||||
import StepInputsGen from './copilot/StepInputsGen.svelte'
|
||||
@@ -12,6 +11,9 @@
|
||||
import type ItemPicker from './ItemPicker.svelte'
|
||||
import type VariableEditor from './VariableEditor.svelte'
|
||||
import ResizeTransitionWrapper from './common/ResizeTransitionWrapper.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
schema: Schema | { properties?: Record<string, any> }
|
||||
@@ -54,7 +56,7 @@
|
||||
workspace
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let inputCheck: { [id: string]: boolean } = $state({})
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
import Badge from './common/badge/Badge.svelte'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import { Plus, Tag, X } from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
labels: string[] | undefined
|
||||
@@ -53,7 +55,7 @@
|
||||
|
||||
async function loadExistingLabels() {
|
||||
try {
|
||||
const resp = await fetch(`/api/w/${workspace ?? $workspaceStore}/labels/list`)
|
||||
const resp = await fetch(`/api/w/${workspace ?? $operatingWorkspace}/labels/list`)
|
||||
if (resp.ok) existingLabels = await resp.json()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { ResourceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getContext, untrack } from 'svelte'
|
||||
import DarkModeObserver from './DarkModeObserver.svelte'
|
||||
import { Button, Drawer, DrawerContent } from './common'
|
||||
@@ -11,6 +10,9 @@
|
||||
import IconedResourceType from './IconedResourceType.svelte'
|
||||
import { addResourceTitle } from './resourceTypeDisplay'
|
||||
import { loadResourceTypeDisplayName } from './displayNameLoaders'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
value: string | undefined
|
||||
@@ -35,7 +37,7 @@
|
||||
let open = $state(false)
|
||||
let refreshCount = $state(0)
|
||||
const appViewerContext = getContext<AppViewerContext>('AppViewerContext')
|
||||
let ws = $derived(workspace ?? appViewerContext?.workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? appViewerContext?.workspace ?? $operatingWorkspace)
|
||||
|
||||
let collection = $state(value ? [{ value, label: value }] : [])
|
||||
|
||||
@@ -139,7 +141,7 @@
|
||||
title="App connection"
|
||||
class="w-full h-full"
|
||||
src="{base}/embed_connect?resource_type={resourceType}&workspace={appViewerContext?.workspace ??
|
||||
$workspaceStore}&express=false"
|
||||
$operatingWorkspace}&express=false"
|
||||
/> -->
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { VariableService } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { ephemeralSecretPrefix, mintEphemeralSecret } from './secretArgUtils'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { Button } from './common'
|
||||
import Password from './Password.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
value?: string | undefined
|
||||
@@ -18,7 +21,7 @@
|
||||
|
||||
let { value = $bindable(undefined), disabled, minRows, workspace }: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let path = $state('')
|
||||
// Workspace the variable at `path` actually lives in; `ws` can move away from it.
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
AzureTriggerService,
|
||||
EmailTriggerService
|
||||
} from '$lib/gen'
|
||||
import { superadmin, userStore, workspaceStore, type UserExt } from '$lib/stores'
|
||||
import { superadmin, userStore, type UserExt } from '$lib/stores'
|
||||
import { createEventDispatcher, getContext, untrack } from 'svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
import { Alert, Button } from './common'
|
||||
@@ -45,6 +45,9 @@
|
||||
import Select from './select/Select.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import InputError from './InputError.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
type PathKind =
|
||||
| 'resource'
|
||||
@@ -81,10 +84,8 @@
|
||||
disableEditing?: boolean
|
||||
size?: 'sm' | 'md'
|
||||
drawerOffset?: number
|
||||
/** Workspace the folder list and path-existence checks run against.
|
||||
* Defaults to the navigation `$workspaceStore`; pass the session's acting
|
||||
* workspace when the editor operates on a workspace other than the one the
|
||||
* top nav points at (see the sessions preview / dev-workspace flows). */
|
||||
/** Workspace the folder list and path-existence checks run against. Defaults to the
|
||||
* operating workspace (see `useOperatingWorkspace`). */
|
||||
workspaceOverride?: string
|
||||
/** The user acting in `workspaceOverride`, for the owner suggestion and the folder
|
||||
* write flags. Omit it to stand in the navigation `$userStore`, who is a member of
|
||||
@@ -121,7 +122,7 @@
|
||||
warnOnRename = true
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspaceOverride ?? $workspaceStore)
|
||||
let ws = $derived(workspaceOverride ?? $operatingWorkspace)
|
||||
// Sole place this component falls back to the ambient user, and only for a caller that
|
||||
// passed none; everything below reads `user`, so a caller acting on another workspace is
|
||||
// never mixed with the navigation user's memberships.
|
||||
|
||||
@@ -87,7 +87,9 @@
|
||||
<script lang="ts">
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import Badge from '$lib/components/common/badge/Badge.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
import { untrack } from 'svelte'
|
||||
|
||||
type Props = {
|
||||
@@ -101,9 +103,8 @@
|
||||
error?: string | boolean
|
||||
textInputClass?: string
|
||||
onkeyup?: (e: KeyboardEvent) => void
|
||||
/** Workspace whose paths feed the autocomplete. Defaults to the navigation
|
||||
* `$workspaceStore`; pass the acting workspace when the editor operates on
|
||||
* a workspace other than the one the top nav points at. */
|
||||
/** Workspace whose paths feed the autocomplete. Defaults to the operating workspace
|
||||
* (see `useOperatingWorkspace`). */
|
||||
workspace?: string
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let inputEl: TextInput | undefined = $state(undefined)
|
||||
export function focus() {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
} from '$lib/gen'
|
||||
import { canWrite } from '$lib/utils'
|
||||
import { createEventDispatcher, onDestroy, untrack } from 'svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { clearJsonSchemaResourceCache } from './schema/jsonSchemaResource.svelte'
|
||||
import ResourceForm from './ResourceForm.svelte'
|
||||
@@ -22,6 +21,9 @@
|
||||
import { UserDraftDbSyncer } from '$lib/userDraftDbSyncer.svelte'
|
||||
import { setLocalDraftHint } from '$lib/localDraftHints.svelte'
|
||||
import { onUserInput } from '$lib/userDraftEditGate'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
canSave?: boolean
|
||||
@@ -74,7 +76,7 @@
|
||||
|
||||
// Sole ambient read in this file: the acting workspace is an input, and only its
|
||||
// default comes from the navigation store.
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore!)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace!)
|
||||
// Fallback to `effectiveWorkspace` insulates against reactify-style
|
||||
// parents that re-spread props without `selected` — otherwise it
|
||||
// transiently resets and the form below remounts on every keystroke.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { History, Loader2, Save } from 'lucide-svelte'
|
||||
import WsSpecificVersions from './WsSpecificVersions.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { isOwner } from '$lib/utils'
|
||||
import { useActingUser } from '$lib/actingUser.svelte'
|
||||
import LocalDraftBanner from './LocalDraftBanner.svelte'
|
||||
@@ -21,6 +20,9 @@
|
||||
import IconedResourceType from './IconedResourceType.svelte'
|
||||
import { addResourceTitle } from './resourceTypeDisplay'
|
||||
import { loadResourceTypeDisplayName } from './displayNameLoaders'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
let {
|
||||
workspace = undefined,
|
||||
@@ -64,7 +66,7 @@
|
||||
let selected: string | undefined = $state(undefined)
|
||||
let viewJsonSchema = $state(false)
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore!)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace!)
|
||||
// The editor renders whichever workspace-specific variant `selected` points at, so history has
|
||||
// to follow it too — otherwise a restore would write over the variant the user is not looking at.
|
||||
let historyWorkspace = $derived(selected ?? effectiveWorkspace)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Path from './Path.svelte'
|
||||
import LabelsInput from './LabelsInput.svelte'
|
||||
import Required from './Required.svelte'
|
||||
import { workspaceStore, type UserExt } from '$lib/stores'
|
||||
import { type UserExt } from '$lib/stores'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import SimpleEditor from './SimpleEditor.svelte'
|
||||
import FilesetEditor from './FilesetEditor.svelte'
|
||||
@@ -25,6 +25,9 @@
|
||||
import SyncResourceTypes from './SyncResourceTypes.svelte'
|
||||
import Label from './Label.svelte'
|
||||
import ResourcePathHint from './ResourcePathHint.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
path: string
|
||||
@@ -84,7 +87,7 @@
|
||||
onCredentialStored
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let editDescription = $state(false)
|
||||
let rawCode: string | undefined = $state(undefined)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { ResourceService, WorkspaceService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { onMount, untrack } from 'svelte'
|
||||
import AppConnect from './AppConnectDrawer.svelte'
|
||||
import ResourceEditorDrawer from './ResourceEditorDrawer.svelte'
|
||||
@@ -12,6 +11,9 @@
|
||||
import ExploreAssetButton, { assetCanBeExplored } from './ExploreAssetButton.svelte'
|
||||
import DropdownV2 from './DropdownV2.svelte'
|
||||
import { appIconComponent } from './icons'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
initialValue?: string | undefined
|
||||
@@ -62,7 +64,7 @@
|
||||
onValueChange = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore!)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace!)
|
||||
|
||||
if (initialValue && value == undefined) {
|
||||
value = initialValue
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import { ResourceService, type ResourceVersion } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Skeleton } from '$lib/components/common'
|
||||
import Button from './common/button/Button.svelte'
|
||||
import HighlightCode from './HighlightCode.svelte'
|
||||
@@ -12,6 +11,9 @@
|
||||
import VersionListItem from './VersionListItem.svelte'
|
||||
import { displayDate } from '$lib/utils'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
let {
|
||||
path,
|
||||
@@ -27,7 +29,7 @@
|
||||
onRestore?: () => void
|
||||
} = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore!)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace!)
|
||||
|
||||
let versions = $state<ResourceVersion[] | undefined>(undefined)
|
||||
// Which row is highlighted, updated on click. `loaded` is dropped the moment the selection
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
import Select from './select/Select.svelte'
|
||||
import { FileUp } from 'lucide-svelte'
|
||||
import { SettingService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
import { resource } from 'runed'
|
||||
|
||||
interface Props {
|
||||
@@ -54,7 +56,7 @@
|
||||
* asset lives in a different workspace than this picker was mounted for. */
|
||||
let workspaceOverride: string | undefined = $state(undefined)
|
||||
let effectiveWorkspace = $derived(workspaceOverride ?? workspace)
|
||||
let ws = $derived(effectiveWorkspace ?? $workspaceStore)
|
||||
let ws = $derived(effectiveWorkspace ?? $operatingWorkspace)
|
||||
let uploadModalOpen = $state(false)
|
||||
|
||||
let allFilesByKey: Record<
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
Trash,
|
||||
MoveRight
|
||||
} from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import {
|
||||
CancelablePromise,
|
||||
HelpersService,
|
||||
@@ -48,6 +47,9 @@
|
||||
import FileUploadModal from './common/fileUpload/FileUploadModal.svelte'
|
||||
import S3FilePreview from './S3FilePreview.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
let deletionModalOpen = $state(false)
|
||||
let fileDeletionInProgress = $state(false)
|
||||
@@ -137,7 +139,7 @@
|
||||
testConnectionRequest = HelpersService.datasetStorageTestConnection
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let rootPath = $state(initialRootPath)
|
||||
let rootPathNestingLevel = $derived(1 * (rootPath.split('/').length - 1))
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// need to hand it a `fileKey`. CSV separator/header are local state so
|
||||
// the user can re-preview the same file with different parsing flags.
|
||||
import { FileX2, Loader2 } from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import {
|
||||
HelpersService,
|
||||
type CancelablePromise,
|
||||
@@ -20,6 +19,9 @@
|
||||
import { displayDate, displaySize, emptyString } from '$lib/utils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import ExpandableImage from '$lib/components/common/image/ExpandableImage.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
fileKey: string | undefined
|
||||
@@ -115,7 +117,7 @@
|
||||
// existence after an upstream run completes — moving from the
|
||||
// "not yet materialized" empty state to the actual preview without
|
||||
// requiring the user to re-click the asset.
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
$effect(() => {
|
||||
const key = fileKey
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { displayDate } from '$lib/utils.js'
|
||||
import { InputService, type CreateInput, type RunnableType } from '$lib/gen/index.js'
|
||||
import { workspaceStore } from '$lib/stores.js'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { Save } from 'lucide-svelte'
|
||||
import { sendUserToast } from '$lib/utils.js'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -30,7 +32,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let savingInputs = $state(false)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Button } from '$lib/components/common'
|
||||
import { InputService, type Input, type RunnableType } from '$lib/gen/index.js'
|
||||
import { userStore, workspaceStore } from '$lib/stores.js'
|
||||
import { userStore } from '$lib/stores.js'
|
||||
import { sendUserToast } from '$lib/utils.js'
|
||||
import { createEventDispatcher, onDestroy, untrack } from 'svelte'
|
||||
import { Trash2, Save, Pencil } from 'lucide-svelte'
|
||||
@@ -12,6 +12,9 @@
|
||||
import InfiniteList from './InfiniteList.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import SavedInputsPickerViewer from './SavedInputsPickerViewer.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
previewArgs?: any
|
||||
@@ -36,7 +39,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
interface EditableInput extends Input {
|
||||
isEditing?: boolean
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
const bubble = createBubbler()
|
||||
import type { Schema } from '$lib/common'
|
||||
import { VariableService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { allTrue, computeShow, type DynamicInput } from '$lib/utils'
|
||||
import { Button } from './common'
|
||||
import ItemPicker from './ItemPicker.svelte'
|
||||
@@ -26,6 +25,9 @@
|
||||
import type { ComponentCustomCSS } from './apps/types'
|
||||
import ResizeTransitionWrapper from './common/ResizeTransitionWrapper.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
schema: Schema | any
|
||||
@@ -122,7 +124,7 @@
|
||||
actions: actions_render = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { ScriptService, FlowService, type Script, AppService } from '$lib/gen'
|
||||
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { base } from '$lib/base'
|
||||
import { createEventDispatcher, untrack } from 'svelte'
|
||||
|
||||
@@ -18,6 +17,9 @@
|
||||
import FlowIcon from './home/FlowIcon.svelte'
|
||||
import DarkModeObserver from './DarkModeObserver.svelte'
|
||||
import { truncate } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
initialPath?: string | undefined
|
||||
@@ -30,9 +32,8 @@
|
||||
allowEdit?: boolean
|
||||
allowView?: boolean
|
||||
clearable?: boolean
|
||||
/** Workspace to list runnables from. Defaults to the navigation
|
||||
* `$workspaceStore`; pass the session's acting workspace so a forked
|
||||
* session lists its own scripts/flows/apps rather than the parent's. */
|
||||
/** Workspace to list runnables from. Defaults to the operating workspace (see
|
||||
* `useOperatingWorkspace`). */
|
||||
workspace?: string
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let effectiveWorkspace = $derived(workspace ?? $workspaceStore)
|
||||
let effectiveWorkspace = $derived(workspace ?? $operatingWorkspace)
|
||||
// Only carry the workspace onto Edit/View routes when an explicit override
|
||||
// was passed, so existing callers' links are unchanged.
|
||||
let wsParam = $derived(workspace ? `?workspace=${encodeURIComponent(workspace)}` : '')
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
import Button from './common/button/Button.svelte'
|
||||
import Tooltip from './meltComponents/Tooltip.svelte'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
import { tryEvery } from '$lib/utils'
|
||||
|
||||
interface Props {
|
||||
@@ -268,7 +270,7 @@ export async function main(bucket: any, api_token: string) {
|
||||
loading = true
|
||||
|
||||
const resourceScript = scripts[resourceType]
|
||||
const workspace = workspaceOverride ?? $workspaceStore!
|
||||
const workspace = workspaceOverride ?? $operatingWorkspace!
|
||||
const objectStorageArgs: Record<string, any> | undefined =
|
||||
resourceType in objectStorageBody ? objectStorageBody[resourceType](args) : undefined
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { VariableService, WorkspaceService } from '$lib/gen'
|
||||
import { createEventDispatcher, untrack } from 'svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Button } from './common'
|
||||
import Drawer from './common/drawer/Drawer.svelte'
|
||||
import DrawerContent from './common/drawer/DrawerContent.svelte'
|
||||
@@ -26,6 +25,9 @@
|
||||
import LocalDraftBanner from './LocalDraftBanner.svelte'
|
||||
import { isEncryptedDraftValue } from '$lib/encryptedDraft'
|
||||
import { setLocalDraftHint } from '$lib/localDraftHints.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -53,7 +55,7 @@
|
||||
} = $props()
|
||||
// Sole ambient read in this file: the acting workspace is an input, and only its
|
||||
// default comes from the navigation store.
|
||||
let curWs = $derived(workspace ?? $workspaceStore)
|
||||
let curWs = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let editPath: string | undefined = $state(undefined)
|
||||
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
|
||||
import { Loader2, RotateCcw } from 'lucide-svelte'
|
||||
import autosize from '$lib/autosize'
|
||||
import { workspaceStore, type UserExt } from '$lib/stores'
|
||||
import { type UserExt } from '$lib/stores'
|
||||
import { isOwner } from '$lib/utils'
|
||||
import { isEncryptedDraftValue } from '$lib/encryptedDraft'
|
||||
import EncryptedDraftField from './EncryptedDraftField.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Variable {
|
||||
value: string
|
||||
@@ -56,7 +59,7 @@
|
||||
actingUser
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
// Loading the deployed secret overwrites the draft row this form shares with the AI
|
||||
// chat, so every path that would trigger it has to be blocked while that row stages a
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
import EmailTriggerEditor from '$lib/components/triggers/email/EmailTriggerEditor.svelte'
|
||||
import ScheduleEditor from '$lib/components/triggers/schedules/ScheduleEditor.svelte'
|
||||
import WebhookEditor from '$lib/components/triggers/webhook/WebhookEditor.svelte'
|
||||
import { setTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { setOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
// Owns the native-trigger drawer wiring for the pipeline canvas: the nine
|
||||
// editor instances, the create/edit dispatch by kind, and the delete
|
||||
@@ -40,9 +40,8 @@
|
||||
type Props = { onUpdate: () => void; mountTriggerEditors: boolean; workspace?: string }
|
||||
let { onUpdate, mountTriggerEditors, workspace: triggerWorkspace }: Props = $props()
|
||||
|
||||
// Register the trigger-workspace resolver for the whole editor subtree (the
|
||||
// nine editors + the delete handler below). See triggerWorkspace.ts.
|
||||
setTriggerWorkspace(() => triggerWorkspace ?? $workspaceStore)
|
||||
// The nine editors below act on this workspace (see operatingWorkspace.svelte.ts).
|
||||
setOperatingWorkspace(() => triggerWorkspace)
|
||||
|
||||
let kafkaEditor: KafkaTriggerEditor | undefined = $state()
|
||||
let mqttEditor: MqttTriggerEditor | undefined = $state()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { getContext, setContext } from 'svelte'
|
||||
import { fromStore, toStore, type Readable } from 'svelte/store'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
|
||||
// The workspace a subtree acts on. An AI session edits its (possibly forked) workspace while
|
||||
// `workspaceStore` stays on the navigation workspace, and a component that reads the navigation
|
||||
// store directly writes to the parent from inside a fork's editor. So the hosts that embed an
|
||||
// editor for another workspace set it once, and every component under them reads
|
||||
// `useOperatingWorkspace()` instead of `$workspaceStore` — nothing has to thread it through props.
|
||||
// Outside such a host it is the navigation store itself.
|
||||
|
||||
const KEY = Symbol('operatingWorkspace')
|
||||
const navigation = fromStore(workspaceStore)
|
||||
|
||||
/** Declare the workspace this subtree acts on. A getter, read wherever the workspace is used;
|
||||
* resolving to nothing defers to the enclosing host. Reads context: call during component
|
||||
* initialisation. */
|
||||
export function setOperatingWorkspace(resolve: () => string | undefined): void {
|
||||
const outer = getContext<(() => string | undefined) | undefined>(KEY)
|
||||
setContext(KEY, outer ? () => resolve() ?? outer() : resolve)
|
||||
}
|
||||
|
||||
/** The workspace this component acts on, as a store. Reads context: call during component
|
||||
* initialisation. Falls back to the navigation workspace where no host set one, or where the
|
||||
* host's resolves to nothing. */
|
||||
export function useOperatingWorkspace(): Readable<string | undefined> {
|
||||
const resolve = getContext<(() => string | undefined) | undefined>(KEY)
|
||||
return resolve ? toStore(() => resolve() ?? navigation.current) : workspaceStore
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { readdirSync, readFileSync } from 'node:fs'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
// Components an AI session mounts for a workspace other than the navigation one: every trigger
|
||||
// editor, and the pickers and forms they and the variable/resource editors are built from. One of
|
||||
// them reading the navigation store writes to the parent from inside a fork's editor, and nothing
|
||||
// else would catch it — so they read `useOperatingWorkspace()` instead.
|
||||
const LEAVES = [
|
||||
'AIProviderPicker.svelte',
|
||||
'ArgInput.svelte',
|
||||
'ChannelSelector.svelte',
|
||||
'EditableSchemaForm.svelte',
|
||||
'ErrorOrRecoveryHandler.svelte',
|
||||
'ExploreAssetButton.svelte',
|
||||
'GitHubAppIntegration.svelte',
|
||||
'GitLabIntegration.svelte',
|
||||
'GitRepoResourcePicker.svelte',
|
||||
'HistoricInputs.svelte',
|
||||
'InputTransformPickers.svelte',
|
||||
'InputTransformSchemaForm.svelte',
|
||||
'LabelsInput.svelte',
|
||||
'LightweightResourcePicker.svelte',
|
||||
'PasswordArgInput.svelte',
|
||||
'Path.svelte',
|
||||
'PathNameAutocomplete.svelte',
|
||||
'ResourceEditor.svelte',
|
||||
'ResourceEditorDrawer.svelte',
|
||||
'ResourceForm.svelte',
|
||||
'ResourcePicker.svelte',
|
||||
'ResourceVersionHistory.svelte',
|
||||
'S3FilePicker.svelte',
|
||||
'S3FilePickerInner.svelte',
|
||||
'S3FilePreview.svelte',
|
||||
'SaveInputsButton.svelte',
|
||||
'SavedInputsPicker.svelte',
|
||||
'SchemaForm.svelte',
|
||||
'ScriptPicker.svelte',
|
||||
'TestConnection.svelte',
|
||||
'VariableEditor.svelte',
|
||||
'VariableForm.svelte'
|
||||
]
|
||||
|
||||
function svelteFilesUnder(dir: string): string[] {
|
||||
return readdirSync(join(here, dir), { recursive: true, encoding: 'utf-8' })
|
||||
.filter((f) => f.endsWith('.svelte'))
|
||||
.map((f) => join(dir, f))
|
||||
}
|
||||
|
||||
describe('components under a session editor', () => {
|
||||
it('read the operating workspace, never the navigation store', () => {
|
||||
const offenders = [...svelteFilesUnder('triggers'), ...LEAVES].filter((f) =>
|
||||
/\bworkspaceStore\b/.test(readFileSync(join(here, f), 'utf-8'))
|
||||
)
|
||||
expect(offenders).toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,6 @@
|
||||
import { Settings } from 'lucide-svelte'
|
||||
import Popover from '$lib/components/meltComponents/Popover.svelte'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import {
|
||||
createDatatablesResource,
|
||||
createSchemasResource,
|
||||
@@ -10,10 +9,10 @@
|
||||
toSchemaItems
|
||||
} from './datatableUtils.svelte'
|
||||
import { Button } from '../common'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
interface Props {
|
||||
/** Currently selected datatable */
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { WorkspaceService } from '$lib/gen'
|
||||
import Drawer from '../common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '../common/drawer/DrawerContent.svelte'
|
||||
@@ -12,12 +11,12 @@
|
||||
import DBManagerContent from '../DBManagerContent.svelte'
|
||||
import type { DbInput } from '../dbTypes'
|
||||
import type { SelectedTable } from '../DBManager.svelte'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { useDbManagerTag } from '../dbManagerTag.svelte'
|
||||
import DbWorkerTagButton from '../DbWorkerTagButton.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
interface Props {
|
||||
onAdd?: (ref: DataTableRef) => void
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// import { addWmillClient } from './utils'
|
||||
import RawAppBackgroundRunner from './RawAppBackgroundRunner.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { setRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { setOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
import { useLocalStorageValue } from '$lib/svelte5Utils.svelte'
|
||||
import {
|
||||
WMILL_TS_PATH,
|
||||
@@ -210,9 +210,8 @@
|
||||
// embedded in a session preview (autosaveWorkspace), else the navigation
|
||||
// workspace. Deploy/save/background-runner must target it, not $workspaceStore.
|
||||
const opWorkspace = $derived(autosaveWorkspace ?? $workspaceStore)
|
||||
// Expose it to the sidebar sub-components (inline scripts, datatable/shared-UI
|
||||
// drawers, DB selector) so their lookups target the app's workspace too.
|
||||
setRawAppOperatingWorkspace(() => opWorkspace)
|
||||
// Everything under the editor acts on it too (see operatingWorkspace.svelte.ts).
|
||||
setOperatingWorkspace(() => opWorkspace)
|
||||
|
||||
// The path autosaves land on, which is what the session preview loads the app by.
|
||||
const draftStoragePath = $derived(autosavePath ?? liveEditorDraftStoragePath)
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
import { resource } from 'runed'
|
||||
import { usePreparedAssetSqlQueries } from '$lib/infer.svelte'
|
||||
import AssetsDropdownButton from '../assets/AssetsDropdownButton.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { SvelteSet } from 'svelte/reactivity'
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import { editor as meditor } from 'monaco-editor'
|
||||
@@ -42,6 +40,7 @@
|
||||
getDebugErrorMessage
|
||||
} from '$lib/components/debug'
|
||||
import TextInput from '../text_input/TextInput.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
inlineScript: (InlineScript & { language: ScriptLang }) | undefined
|
||||
@@ -78,8 +77,8 @@
|
||||
delete_after_secs = $bindable()
|
||||
}: Props = $props()
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
let diffEditor = $state() as DiffEditor | undefined
|
||||
let validCode = $state(true)
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
import LogViewer from '$lib/components/LogViewer.svelte'
|
||||
import DisplayResult from '$lib/components/DisplayResult.svelte'
|
||||
import RunButton from '$lib/components/RunButton.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { isHubFlowPath } from '$lib/utils'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
type RunnableWithInlineScript = RunnableWithFields & {
|
||||
inlineScript?: InlineScript & { language: ScriptLang }
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import RawAppInlineScripRunnable, { type Runnable } from './RawAppInlineScriptRunnable.svelte'
|
||||
import { createScriptFromInlineScript } from '../apps/editor/inlineScriptsPanel/utils'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
interface Props {
|
||||
runnables: Record<string, Runnable>
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
import { fieldTypeToTsType } from '../apps/utils'
|
||||
import type { InputType } from '../apps/inputType'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
// Build ctx properties with current user's actual values
|
||||
let ctxProperties = $derived([
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { WorkspaceService } from '$lib/gen'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Drawer from '../common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '../common/drawer/DrawerContent.svelte'
|
||||
import Editor from '$lib/components/Editor.svelte'
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
let open = $state(false)
|
||||
let files: Record<string, string> = $state({})
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Sparkles, Plus, List, Ban, ExternalLinkIcon, Loader2 } from 'lucide-svelte'
|
||||
import type { Policy } from '$lib/gen'
|
||||
import { superadmin, userStore, workspaceStore } from '$lib/stores'
|
||||
import { superadmin, userStore } from '$lib/stores'
|
||||
import { base } from '$lib/base'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { getRawAppOperatingWorkspace } from './rawAppWorkspace'
|
||||
import Modal from '$lib/components/common/modal/Modal.svelte'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
@@ -29,6 +28,7 @@
|
||||
import RawAppDataTableList from './RawAppDataTableList.svelte'
|
||||
import RawAppDataTableDrawer from './RawAppDataTableDrawer.svelte'
|
||||
import FileEditorIcon from './FileEditorIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
export type RawAppTemplatePickerResult = {
|
||||
files: Record<string, string>
|
||||
@@ -64,8 +64,8 @@
|
||||
let preWhitelistedTables = $state<DataTableRef[]>([])
|
||||
let dataTableDrawer: RawAppDataTableDrawer | undefined = $state()
|
||||
|
||||
const getOpWs = getRawAppOperatingWorkspace()
|
||||
let opWs = $derived(getOpWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
let opWs = $derived($operatingWorkspace)
|
||||
|
||||
const datatables = createDatatablesResource(() => opWs)
|
||||
const schemas = createSchemasResource(
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { getContext, setContext } from 'svelte'
|
||||
|
||||
// The workspace a raw-app editor operates on. In a session preview this is the
|
||||
// session's acting workspace, which differs from the navigation `$workspaceStore`
|
||||
// (a session deliberately leaves the nav store on the workspace the top nav
|
||||
// points at). RawAppEditor provides it once; the sidebar sub-components (inline
|
||||
// scripts, datatable/shared-UI drawers, DB selector, …) read it so their lookups
|
||||
// target the workspace the app actually lives in rather than the nav workspace.
|
||||
//
|
||||
// A getter (not a value) so the live `$derived` opWorkspace is read reactively at
|
||||
// each call site. Consumers fall back to `$workspaceStore` when unset — e.g. the
|
||||
// full-page app editor, where the nav workspace IS the operating workspace.
|
||||
|
||||
const KEY = 'RawAppOperatingWorkspace'
|
||||
|
||||
export function setRawAppOperatingWorkspace(get: () => string | undefined): void {
|
||||
setContext(KEY, get)
|
||||
}
|
||||
|
||||
export function getRawAppOperatingWorkspace(): (() => string | undefined) | undefined {
|
||||
return getContext(KEY)
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
import { ResourceService } from '$lib/gen'
|
||||
import VariableEditor from '$lib/components/VariableEditor.svelte'
|
||||
import ResourceEditorDrawer from '$lib/components/ResourceEditorDrawer.svelte'
|
||||
import { setTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { setOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
import { TRIGGER_PAGES, type PageItemRef, type TriggerKind } from './previewPaths'
|
||||
import type { SessionRuntime } from './sessionRuntime.svelte'
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
'aiChatManager',
|
||||
untrack(() => runtime.manager)
|
||||
)
|
||||
// A session acts on its (possibly forked) workspace without switching the navigation
|
||||
// store, and the trigger editors read theirs from this seam.
|
||||
setTriggerWorkspace(() => workspaceId)
|
||||
setOperatingWorkspace(() => workspaceId)
|
||||
|
||||
type TriggerEditorHandle = { openEdit: (path: string, isFlow: boolean) => Promise<void> }
|
||||
type EditorModule = { default: any }
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { itemDisplayName } from './previewRouter'
|
||||
import SessionItemNotFound from './SessionItemNotFound.svelte'
|
||||
import { setEditorStoragePath } from '../editorStoragePathContext'
|
||||
import { setOperatingWorkspace } from '../operatingWorkspace.svelte'
|
||||
|
||||
let {
|
||||
runtime,
|
||||
@@ -51,6 +52,7 @@
|
||||
// component instance keeps the first runtime's manager — so descendants may
|
||||
// rely on its presence, not its identity.
|
||||
setContext('aiChatManager', runtime.manager)
|
||||
setOperatingWorkspace(() => workspaceId)
|
||||
|
||||
// This tab's storage path, for the editor below: several tabs are mounted at
|
||||
// once and only this one knows which item each is open on.
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
import { isCloudHosted } from '$lib/cloud'
|
||||
import { CloudOff } from 'lucide-svelte'
|
||||
import { isServiceAvailable } from './native/utils'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
setDropdownWidthToButtonWidth?: boolean
|
||||
@@ -41,15 +43,15 @@
|
||||
let githubAvailable = $state(false)
|
||||
|
||||
async function setNextcloudState() {
|
||||
nextcloudAvailable = await isServiceAvailable('nextcloud', $workspaceStore!)
|
||||
nextcloudAvailable = await isServiceAvailable('nextcloud', $operatingWorkspace!)
|
||||
}
|
||||
|
||||
async function setGoogleState() {
|
||||
googleAvailable = await isServiceAvailable('google', $workspaceStore!)
|
||||
googleAvailable = await isServiceAvailable('google', $operatingWorkspace!)
|
||||
}
|
||||
|
||||
async function setGithubState() {
|
||||
githubAvailable = await isServiceAvailable('github', $workspaceStore!)
|
||||
githubAvailable = await isServiceAvailable('github', $operatingWorkspace!)
|
||||
}
|
||||
|
||||
setNextcloudState()
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import { Popover } from '$lib/components/meltComponents'
|
||||
import { CaptureService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { isObject, sendUserToast } from '$lib/utils'
|
||||
import { triggerIconMap } from './utils'
|
||||
import { formatDateShort } from '$lib/utils'
|
||||
@@ -37,6 +36,9 @@
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { FlaskConical } from 'lucide-svelte'
|
||||
import Alert from '../common/alert/Alert.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
disabled?: boolean | undefined
|
||||
@@ -139,7 +141,7 @@
|
||||
if (!captureInfo.path) return
|
||||
|
||||
const captures = await CaptureService.listCaptures({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
runnableKind: captureInfo.isFlow ? 'flow' : 'script',
|
||||
path: captureInfo.path,
|
||||
triggerKind: captureType,
|
||||
@@ -167,7 +169,7 @@
|
||||
|
||||
try {
|
||||
const captures = await CaptureService.listCaptures({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
runnableKind: captureInfo.isFlow ? 'flow' : 'script',
|
||||
path: captureInfo.path,
|
||||
triggerKind: captureType,
|
||||
@@ -213,7 +215,7 @@
|
||||
try {
|
||||
isLoadingBigPayload = true
|
||||
const fullCapture = await CaptureService.getCapture({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
id: capture.id
|
||||
})
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
import { createEventDispatcher, onDestroy, untrack } from 'svelte'
|
||||
import { type TriggerKind } from '../triggers'
|
||||
import { CaptureService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { type CaptureTriggerKind } from '$lib/gen'
|
||||
import CaptureButton from '$lib/components/triggers/CaptureButton.svelte'
|
||||
import InfiniteList from '../InfiniteList.svelte'
|
||||
@@ -19,6 +18,9 @@
|
||||
import type { Capture } from '$lib/gen'
|
||||
import { AwsIcon, MqttIcon, AmqpIcon } from '../icons'
|
||||
import GoogleCloudIcon from '../icons/GoogleCloudIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
path: string
|
||||
@@ -33,9 +35,8 @@
|
||||
limitPayloadSize?: boolean
|
||||
noBorder?: boolean
|
||||
captureActiveIndicator?: boolean | undefined
|
||||
// Workspace to scope capture list/get/delete calls to. Defaults to the nav
|
||||
// `$workspaceStore`; an AI-session live editor passes the session's acting
|
||||
// workspace (a fork) so captures hit the right workspace.
|
||||
// Workspace to scope capture list/get/delete calls to. Defaults to the operating
|
||||
// workspace (see `useOperatingWorkspace`).
|
||||
workspace?: string
|
||||
}
|
||||
|
||||
@@ -55,7 +56,7 @@
|
||||
workspace = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let ws = $derived(workspace ?? $workspaceStore)
|
||||
let ws = $derived(workspace ?? $operatingWorkspace)
|
||||
|
||||
let selected: number | undefined = $state(undefined)
|
||||
let testKind: 'preprocessor' | 'main' = $state('main')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { CaptureService, type CaptureConfig, type CaptureTriggerKind } from '$lib/gen'
|
||||
import { onDestroy, untrack } from 'svelte'
|
||||
import { sendUserToast, sleep } from '$lib/utils'
|
||||
@@ -18,6 +17,9 @@
|
||||
import GcpCapture from './gcp/GcpCapture.svelte'
|
||||
import AzureCapture from './azure/AzureCapture.svelte'
|
||||
import EmailCapture from './email/EmailCapture.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
isFlow: boolean
|
||||
@@ -63,7 +65,7 @@
|
||||
is_flow: isFlow,
|
||||
trigger_config: args && Object.keys(args).length > 0 ? args : undefined
|
||||
},
|
||||
workspace: $workspaceStore!
|
||||
workspace: $operatingWorkspace!
|
||||
})
|
||||
return true
|
||||
} catch (error) {
|
||||
@@ -94,7 +96,7 @@
|
||||
|
||||
async function getCaptureConfigs() {
|
||||
const captureConfigsList = await CaptureService.getCaptureConfigs({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
runnableKind: isFlow ? 'flow' : 'script',
|
||||
path
|
||||
})
|
||||
@@ -123,7 +125,7 @@
|
||||
while (captureActive) {
|
||||
if (i % 3 === 0) {
|
||||
await CaptureService.pingCaptureConfig({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
triggerKind: captureType,
|
||||
runnableKind: isFlow ? 'flow' : 'script',
|
||||
path
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
type OnBehalfOfDetails
|
||||
} from '$lib/components/OnBehalfOfSelector.svelte'
|
||||
import { useFolderDefaultPermissionedAs } from '$lib/components/useFolderDefaultPermissionedAs.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { AlertTriangle } from 'lucide-svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
/** Current permissioned_as value from the trigger (e.g., 'u/admin') */
|
||||
@@ -22,8 +22,8 @@
|
||||
}
|
||||
|
||||
let { permissionedAs, onPermissionedAsChange, path = undefined }: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const canPreserve = $derived(
|
||||
$userStore?.is_admin || ($userStore?.groups ?? []).includes('wm_deployers')
|
||||
|
||||
@@ -10,10 +10,9 @@
|
||||
WebsocketTriggerService,
|
||||
GcpTriggerService
|
||||
} from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Button from '../common/button/Button.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
kind: 'websocket' | 'nats' | 'kafka' | 'postgres' | 'sqs' | 'mqtt' | 'amqp' | 'gcp'
|
||||
@@ -23,8 +22,8 @@
|
||||
}
|
||||
|
||||
let { kind, args, noButton = false, testLoading = $bindable(false) }: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const kindToName: { [key: string]: string } = {
|
||||
websocket: 'WebSocket',
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
import { stripBase, TRIGGER_PAGES, SCHEDULES_PATH } from '$lib/components/sessions/previewPaths'
|
||||
import { pageDrawerSessionSource } from '../sessions/pageDrawerSession'
|
||||
import { page } from '$app/state'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
import TriggerHistoryButton from './TriggerHistoryButton.svelte'
|
||||
|
||||
interface Props {
|
||||
@@ -63,8 +62,8 @@
|
||||
triggerPath,
|
||||
triggerKind
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const canSave = $derived((permissions === 'write' && edit) || permissions === 'create')
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { History } from 'lucide-svelte'
|
||||
import { TriggerService, type TriggerHistoryEntry } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { displayDate } from '$lib/utils'
|
||||
import Button from '../common/button/Button.svelte'
|
||||
import Drawer from '../common/drawer/Drawer.svelte'
|
||||
@@ -9,8 +8,8 @@
|
||||
import Badge from '../common/badge/Badge.svelte'
|
||||
import Skeleton from '../common/skeleton/Skeleton.svelte'
|
||||
import TriggerHistoryChanges from './TriggerHistoryChanges.svelte'
|
||||
import { getTriggerWorkspace } from './triggerWorkspace'
|
||||
import type { TriggerType } from './utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
/** Trigger kind as the backend records it: `schedule`, `http`, `kafka`, … */
|
||||
@@ -22,8 +21,8 @@
|
||||
|
||||
// An AI session can edit a trigger in a workspace that is not the nav one;
|
||||
// the whole trigger subtree reads its workspace through this seam.
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state()
|
||||
let entries: TriggerHistoryEntry[] | undefined = $state(undefined)
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
TriggerMode
|
||||
} from '$lib/gen/types.gen'
|
||||
import Button from '../common/button/Button.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { JobService, TriggerService } from '$lib/gen'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Cell from '$lib/components/table/Cell.svelte'
|
||||
@@ -39,6 +37,7 @@
|
||||
errorHandlerArgs,
|
||||
slackErrorHandlerHubPathEnding
|
||||
} from '../ErrorOrRecoveryHandler.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
type Props = {
|
||||
triggerPath: string
|
||||
@@ -49,8 +48,8 @@
|
||||
}
|
||||
|
||||
let { triggerKind, triggerPath, onToggleMode, hasChanged, runnableConfig }: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let shouldShowModal = $state(false)
|
||||
let queuedJobs = $state<QueuedJob[]>([])
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
import { run } from 'svelte/legacy'
|
||||
|
||||
import { FlowService, ScriptService, UserService, type TruncatedToken } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { getContext } from 'svelte'
|
||||
import { Skeleton } from '../common'
|
||||
import Label from '../Label.svelte'
|
||||
import type { TriggerContext } from '../triggers'
|
||||
import { capitalize } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
isFlow: boolean
|
||||
@@ -17,8 +17,8 @@
|
||||
}
|
||||
|
||||
let { isFlow, path, labelPrefix }: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const { triggersCount } = getContext<TriggerContext>('TriggerContext')
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
import FlowCard from '../flows/common/FlowCard.svelte'
|
||||
import { getContext, onDestroy, createEventDispatcher } from 'svelte'
|
||||
import type { TriggerContext } from '$lib/components/triggers'
|
||||
@@ -38,6 +38,9 @@
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import Alert from '../common/alert/Alert.svelte'
|
||||
import type { FlowEditorContext } from '../flows/types'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
noEditor: boolean
|
||||
@@ -137,13 +140,13 @@
|
||||
try {
|
||||
if (nativeServiceName) {
|
||||
await NativeTriggerService.deleteNativeTrigger({
|
||||
workspace: $workspaceStore ?? '',
|
||||
workspace: $operatingWorkspace ?? '',
|
||||
serviceName: nativeServiceName,
|
||||
externalId: triggerPath ?? ''
|
||||
})
|
||||
} else if (deleteHandler) {
|
||||
await deleteHandler()({
|
||||
workspace: $workspaceStore ?? '',
|
||||
workspace: $operatingWorkspace ?? '',
|
||||
path: triggerPath ?? ''
|
||||
})
|
||||
} else {
|
||||
@@ -187,7 +190,7 @@
|
||||
if (triggerType === 'schedule') {
|
||||
await triggersState.fetchSchedules(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
undefined,
|
||||
@@ -196,7 +199,7 @@
|
||||
} else if (triggerType === 'websocket') {
|
||||
await triggersState.fetchWebsocketTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -204,7 +207,7 @@
|
||||
} else if (triggerType === 'postgres') {
|
||||
await triggersState.fetchPostgresTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -212,7 +215,7 @@
|
||||
} else if (triggerType === 'kafka') {
|
||||
await triggersState.fetchKafkaTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -220,7 +223,7 @@
|
||||
} else if (triggerType === 'nats') {
|
||||
await triggersState.fetchNatsTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -228,7 +231,7 @@
|
||||
} else if (triggerType === 'gcp') {
|
||||
await triggersState.fetchGcpTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -236,7 +239,7 @@
|
||||
} else if (triggerType === 'azure') {
|
||||
await triggersState.fetchAzureTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -244,7 +247,7 @@
|
||||
} else if (triggerType === 'sqs') {
|
||||
await triggersState.fetchSqsTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -252,7 +255,7 @@
|
||||
} else if (triggerType === 'mqtt') {
|
||||
await triggersState.fetchMqttTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -260,7 +263,7 @@
|
||||
} else if (triggerType === 'amqp') {
|
||||
await triggersState.fetchAmqpTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -268,7 +271,7 @@
|
||||
} else if (triggerType === 'http') {
|
||||
await triggersState.fetchHttpTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -276,7 +279,7 @@
|
||||
} else if (triggerType === 'email') {
|
||||
await triggersState.fetchEmailTriggers(
|
||||
triggersCount,
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -285,7 +288,7 @@
|
||||
await triggersState.fetchNativeTriggers(
|
||||
triggersCount,
|
||||
'nextcloud',
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -294,7 +297,7 @@
|
||||
await triggersState.fetchNativeTriggers(
|
||||
triggersCount,
|
||||
'google',
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
@@ -303,7 +306,7 @@
|
||||
await triggersState.fetchNativeTriggers(
|
||||
triggersCount,
|
||||
'github',
|
||||
$workspaceStore,
|
||||
$operatingWorkspace,
|
||||
currentPath,
|
||||
isFlow,
|
||||
$userStore
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
import TestTriggerConnection from '../TestTriggerConnection.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
can_write?: boolean
|
||||
@@ -36,8 +35,8 @@
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
// Toggling the exchange binding on/off. Off means the queue is consumed
|
||||
// directly with no exchange binding.
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -43,6 +42,7 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { useTriggerDraftSync } from '../useTriggerDraftSync.svelte'
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -82,8 +82,8 @@
|
||||
onReset = undefined,
|
||||
cloudDisabled = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let amqp_resource_path: string = $state('')
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
import type { AzureMode, AzureArmResource } from '$lib/gen'
|
||||
import { AzureTriggerService } from '$lib/gen'
|
||||
import { emptyStringTrimmed } from '$lib/utils'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
import { RefreshCw } from 'lucide-svelte'
|
||||
|
||||
interface Props {
|
||||
@@ -39,8 +38,8 @@
|
||||
event_type_filters = $bindable(),
|
||||
path = ''
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
type Edition = 'basic' | 'namespace'
|
||||
type Delivery = 'push' | 'pull'
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -41,6 +40,7 @@
|
||||
import Tab from '$lib/components/common/tabs/Tab.svelte'
|
||||
import TriggerRetriesAndErrorHandler from '../TriggerRetriesAndErrorHandler.svelte'
|
||||
import TriggerAdvancedBadges from '../TriggerAdvancedBadges.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let initialPath = $state('')
|
||||
@@ -115,8 +115,8 @@
|
||||
onReset?: () => void
|
||||
cloudDisabled?: boolean
|
||||
} = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let hasChanged = $derived(!deepEqual(getAzureConfig(), originalConfig ?? {}))
|
||||
const azureConfig = $derived.by(getAzureConfig)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { base32 } from 'rfc4648'
|
||||
import ClipboardPanel from '../../details/ClipboardPanel.svelte'
|
||||
import CaptureSection, { type CaptureInfo } from '../CaptureSection.svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
isFlow?: boolean
|
||||
@@ -26,7 +28,7 @@
|
||||
|
||||
function getCaptureEmail() {
|
||||
const cleanedPath = path.replaceAll('/', '.')
|
||||
const plainPrefix = `capture+${$workspaceStore}+${(isFlow ? 'flow.' : '') + cleanedPath}`
|
||||
const plainPrefix = `capture+${$operatingWorkspace}+${(isFlow ? 'flow.' : '') + cleanedPath}`
|
||||
const encodedPrefix = base32
|
||||
.stringify(new TextEncoder().encode(plainPrefix), {
|
||||
pad: false
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { AlertTriangle } from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { SCRIPT_VIEW_SHOW_CREATE_TOKEN_BUTTON } from '$lib/consts'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
@@ -13,12 +12,16 @@
|
||||
import { emptyString } from '$lib/utils'
|
||||
import UserSettings from '$lib/components/UserSettings.svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
let requestType: 'runnableVersion' | 'path' = $state('path')
|
||||
|
||||
function emailAddress() {
|
||||
const pathOrHash = requestType === 'runnableVersion' ? runnableVersion : path.replaceAll('/', '.')
|
||||
const plainPrefix = `${$workspaceStore}+${
|
||||
const pathOrHash =
|
||||
requestType === 'runnableVersion' ? runnableVersion : path.replaceAll('/', '.')
|
||||
const plainPrefix = `${$operatingWorkspace}+${
|
||||
(requestType === 'runnableVersion' ? 'hash.' : isFlow ? 'flow.' : '') + pathOrHash
|
||||
}+${token}`
|
||||
const encodedPrefix = base32
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { enterpriseLicense, userStore, workspaceStore } from '$lib/stores'
|
||||
import { enterpriseLicense, userStore } from '$lib/stores'
|
||||
import UserSettings from '../../UserSettings.svelte'
|
||||
import { generateRandomString } from '$lib/utils'
|
||||
import HighlightTheme from '../../HighlightTheme.svelte'
|
||||
@@ -10,6 +10,9 @@
|
||||
import Section from '../../Section.svelte'
|
||||
import DefaultEmailConfigSection from './DefaultEmailConfigSection.svelte'
|
||||
import { getEmailDomain } from './utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
let userSettings: UserSettings | undefined = $state(undefined)
|
||||
interface Props {
|
||||
@@ -55,7 +58,7 @@
|
||||
token = e.detail
|
||||
triggerTokens?.listTokens()
|
||||
}}
|
||||
newTokenWorkspace={$workspaceStore}
|
||||
newTokenWorkspace={$operatingWorkspace}
|
||||
newTokenLabel={`email-${$userStore?.username ?? 'superadmin'}-${generateRandomString(4)}`}
|
||||
{scopes}
|
||||
/>
|
||||
@@ -70,7 +73,14 @@
|
||||
<Skeleton layout={[[18]]} />
|
||||
{:else}
|
||||
{#if emailDomain}
|
||||
<DefaultEmailConfigSection {runnableVersion} {token} {path} {isFlow} {userSettings} {emailDomain} />
|
||||
<DefaultEmailConfigSection
|
||||
{runnableVersion}
|
||||
{token}
|
||||
{path}
|
||||
{isFlow}
|
||||
{userSettings}
|
||||
{emailDomain}
|
||||
/>
|
||||
{:else}
|
||||
<div>
|
||||
<Alert title="Email triggers are disabled" size="xs" type="warning">
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
// import { page } from '$app/state'
|
||||
import type { CaptureInfo } from '../CaptureSection.svelte'
|
||||
import CaptureSection from '../CaptureSection.svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
import ClipboardPanel from '$lib/components/details/ClipboardPanel.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
local_part: string | undefined
|
||||
@@ -27,7 +29,7 @@
|
||||
captureLoading = false
|
||||
}: Props = $props()
|
||||
|
||||
let captureEmail = $derived(`capture+${$workspaceStore}-${local_part}@${emailDomain}`)
|
||||
let captureEmail = $derived(`capture+${$operatingWorkspace}-${local_part}@${emailDomain}`)
|
||||
</script>
|
||||
|
||||
{#if captureInfo}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
import { Alert } from '$lib/components/common'
|
||||
import Required from '$lib/components/Required.svelte'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
// import { page } from '$app/state'
|
||||
import { getEmailAddress, getEmailDomain } from './utils'
|
||||
import { isCloudHosted } from '$lib/cloud'
|
||||
@@ -12,6 +11,7 @@
|
||||
import { untrack } from 'svelte'
|
||||
import { EmailTriggerService } from '$lib/gen'
|
||||
import ClipboardPanel from '$lib/components/details/ClipboardPanel.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
interface Props {
|
||||
initialTriggerPath?: string | undefined
|
||||
dirtyLocalPart?: boolean
|
||||
@@ -35,8 +35,8 @@
|
||||
isDraftOnly = true,
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let validateTimeout: number | undefined = undefined
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
type Retry,
|
||||
type TriggerMode
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -39,6 +38,7 @@
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import TriggerSuspendedJobsAlert from '../TriggerSuspendedJobsAlert.svelte'
|
||||
import TriggerSuspendedJobsModal from '../TriggerSuspendedJobsModal.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
@@ -57,8 +57,8 @@
|
||||
trigger = undefined,
|
||||
customSaveBehavior = undefined
|
||||
} = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
// Form data state
|
||||
let initialPath = $state('')
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script lang="ts">
|
||||
import type { CaptureInfo } from '../CaptureSection.svelte'
|
||||
import CaptureSection from '../CaptureSection.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Url } from '$lib/components/common'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { base } from '$lib/base'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
captureInfo?: CaptureInfo | undefined
|
||||
@@ -30,7 +32,7 @@
|
||||
if (!captureInfo) {
|
||||
return
|
||||
}
|
||||
return `${window.location.origin}${base}/api/w/${$workspaceStore}/capture_u/gcp/${
|
||||
return `${window.location.origin}${base}/api/w/${$operatingWorkspace}/capture_u/gcp/${
|
||||
captureInfo.isFlow ? 'flow' : 'script'
|
||||
}/${captureInfo.path}`
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import { base } from '$lib/base'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
|
||||
import { Button, Url } from '$lib/components/common'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
@@ -25,11 +24,12 @@
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { safeSelectItems } from '$lib/components/select/utils.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
// Declared before `DEFAULT_PUSH_CONFIG` / the `base_endpoint` prop default,
|
||||
// which call `getBaseUrl()` (a `wsId` reader) during component init.
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let topic_items: string[] = $state([])
|
||||
let subscription_items: string[] = $state([])
|
||||
@@ -274,7 +274,10 @@
|
||||
travel as `?project_id=`, dirty the config, and reach the column as a
|
||||
value `empty_as_none` does not trim away. -->
|
||||
<TextInput
|
||||
bind:value={() => project_id ?? '', (v) => (project_id = emptyStringTrimmed(v) ? undefined : v)}
|
||||
bind:value={
|
||||
() => project_id ?? '',
|
||||
(v) => (project_id = emptyStringTrimmed(v) ? undefined : v)
|
||||
}
|
||||
inputProps={{
|
||||
placeholder: 'my-gcp-project',
|
||||
disabled: !can_write,
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -44,6 +43,7 @@
|
||||
import TriggerAdvancedBadges from '../TriggerAdvancedBadges.svelte'
|
||||
import Subsection from '$lib/components/Subsection.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let initialPath = $state('')
|
||||
@@ -125,8 +125,8 @@
|
||||
onReset?: () => void
|
||||
cloudDisabled?: boolean
|
||||
} = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let hasChanged = $derived(!deepEqual(getGcpConfig(), originalConfig ?? {}))
|
||||
const gcpConfig = $derived.by(getGcpConfig)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
type OpenapiV3Info,
|
||||
type WebhookFilters
|
||||
} from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
@@ -35,6 +35,9 @@
|
||||
import CreateToken from '$lib/components/settings/CreateToken.svelte'
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import { safeSelectItems } from '$lib/components/select/utils.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
type HttpRouteAndWebhook = WebhookFilters | OpenapiHttpRouteFilters
|
||||
|
||||
@@ -148,7 +151,7 @@
|
||||
const info = buildInfo()
|
||||
isGeneratingOpenapiSpec = true
|
||||
openapiDocument = await OpenapiService.generateOpenapiSpec({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
requestBody: {
|
||||
openapi_spec_format,
|
||||
info,
|
||||
@@ -222,7 +225,7 @@
|
||||
{/snippet}
|
||||
<CopyableCodeBlock
|
||||
code={`token=${emptyString(token) ? '' : token}; \\
|
||||
curl -X POST "${window.location.origin}${base}/api/w/${$workspaceStore!}/openapi/generate" \\
|
||||
curl -X POST "${window.location.origin}${base}/api/w/${$operatingWorkspace!}/openapi/generate" \\
|
||||
-H "Authorization: Bearer $token" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '${JSON.stringify(obj)}'`}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import Label from '$lib/components/Label.svelte'
|
||||
import CopyableCodeBlock from '$lib/components/details/CopyableCodeBlock.svelte'
|
||||
import { bash } from 'svelte-highlight/languages'
|
||||
@@ -11,6 +9,7 @@
|
||||
import { isObject } from '$lib/utils'
|
||||
import { Url } from '$lib/components/common'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
route_path: string | undefined
|
||||
@@ -33,8 +32,8 @@
|
||||
isFlow = false,
|
||||
captureLoading = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let captureURL = $derived(
|
||||
`${location.origin}${base}/api/w/${wsId}/capture_u/http/${
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
import { HttpTriggerService, SettingService } from '$lib/gen'
|
||||
// import { page } from '$app/state'
|
||||
import { getHttpRoute } from './utils'
|
||||
@@ -14,6 +13,7 @@
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
initialTriggerPath?: string | undefined
|
||||
@@ -42,8 +42,8 @@
|
||||
isDraftOnly = true,
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let validateTimeout: number | undefined = undefined
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
type Retry,
|
||||
type TriggerMode
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import {
|
||||
canWrite,
|
||||
capitalize,
|
||||
@@ -78,6 +77,7 @@
|
||||
import TriggerSuspendedJobsModal from '../TriggerSuspendedJobsModal.svelte'
|
||||
import UserSettings from '$lib/components/UserSettings.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
@@ -96,8 +96,8 @@
|
||||
trigger = undefined,
|
||||
customSaveBehavior = undefined
|
||||
} = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
// Form data state
|
||||
let initialPath = $state('')
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
import RouteEditor from './RouteEditor.svelte'
|
||||
import { generateHttpTriggerFromOpenApi, type Source } from './utils'
|
||||
import { isCloudHosted } from '$lib/cloud'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import FileInput from '../../common/fileInput/FileInput.svelte'
|
||||
import { emptyStringTrimmed, sendUserToast } from '$lib/utils'
|
||||
import FolderPicker from '../../FolderPicker.svelte'
|
||||
import Required from '$lib/components/Required.svelte'
|
||||
import { Drawer, DrawerContent } from '$lib/components/common'
|
||||
import { get } from 'svelte/store'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
type Props = {
|
||||
closeFn: () => Promise<void>
|
||||
@@ -108,7 +111,7 @@
|
||||
try {
|
||||
isCreating = true
|
||||
const message = await HttpTriggerService.createHttpTriggers({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
requestBody: httpTriggers
|
||||
})
|
||||
sendUserToast(message)
|
||||
@@ -314,7 +317,7 @@
|
||||
<div class="text-primary">
|
||||
{httpTrigger.http_method.toUpperCase()}
|
||||
{isCloudHosted() || httpTrigger.workspaced_route || globalHttpWorkspacedRoute
|
||||
? $workspaceStore! + '/' + httpTrigger.route_path
|
||||
? $operatingWorkspace! + '/' + httpTrigger.route_path
|
||||
: httpTrigger.route_path}
|
||||
</div>
|
||||
<div class="text-secondary text-xs truncate text-left font-light">
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { KafkaTriggerService, type ErrorHandler, type Retry, type TriggerMode } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -38,6 +37,7 @@
|
||||
import type { FilterNode } from '../filters'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -77,8 +77,8 @@
|
||||
onDelete = undefined,
|
||||
onReset = undefined
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state()
|
||||
let is_flow: boolean = $state(false)
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import Subsection from '$lib/components/Subsection.svelte'
|
||||
import SchemaForm from '../../SchemaForm.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import TestTriggerConnection from '../TestTriggerConnection.svelte'
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
path: string
|
||||
@@ -26,8 +25,8 @@
|
||||
can_write = true,
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const kafkaConfigSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
@@ -103,7 +102,6 @@
|
||||
/>
|
||||
</Subsection>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Section>
|
||||
</div>
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
can_write?: boolean
|
||||
@@ -39,8 +38,8 @@
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const isValidSubscribeTopics = (subscribe_topics: MqttSubscribeTopic[]): boolean => {
|
||||
if (
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -47,6 +46,7 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { useTriggerDraftSync } from '../useTriggerDraftSync.svelte'
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -86,8 +86,8 @@
|
||||
onReset = undefined,
|
||||
cloudDisabled = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let mqtt_resource_path: string = $state('')
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
getTemplatePath,
|
||||
saveNativeTriggerFromCfg
|
||||
} from './utils'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { Button } from '$lib/components/common'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
@@ -27,6 +27,9 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import type { Snippet } from 'svelte'
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
service: NativeServiceName
|
||||
@@ -204,7 +207,7 @@
|
||||
|
||||
try {
|
||||
const fullTrigger = await NativeTriggerService.getNativeTrigger({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
serviceName: service,
|
||||
externalId: externalIdOrPath
|
||||
})
|
||||
@@ -308,7 +311,7 @@
|
||||
enabled = next
|
||||
try {
|
||||
await NativeTriggerService.setNativeTriggerEnabled({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
serviceName: service,
|
||||
externalId,
|
||||
requestBody: { enabled: next }
|
||||
@@ -335,7 +338,7 @@
|
||||
// before anything can pause it again.
|
||||
isRecreate ? { ...saveCfg, enabled } : saveCfg,
|
||||
!isNew,
|
||||
$workspaceStore!,
|
||||
$operatingWorkspace!,
|
||||
usedTriggerKinds
|
||||
)
|
||||
if (newExternalId) {
|
||||
@@ -345,7 +348,7 @@
|
||||
if (isRecreate && oldExternalIdToDelete) {
|
||||
try {
|
||||
await NativeTriggerService.deleteNativeTrigger({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
serviceName: service,
|
||||
externalId: oldExternalIdToDelete
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { ExtendedNativeTrigger } from './utils'
|
||||
import { getServiceConfig } from './utils'
|
||||
import { canWrite, sendUserToast } from '$lib/utils'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { userStore } from '$lib/stores'
|
||||
import TriggerModeToggle from '$lib/components/triggers/TriggerModeToggle.svelte'
|
||||
import Skeleton from '$lib/components/common/skeleton/Skeleton.svelte'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
@@ -16,6 +16,9 @@
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import GoogleDriveIcon from '$lib/components/icons/GoogleDriveIcon.svelte'
|
||||
import GoogleCalendarIcon from '$lib/components/icons/GoogleCalendarIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
type TriggerW = ExtendedNativeTrigger & { marked?: any }
|
||||
|
||||
@@ -51,7 +54,7 @@
|
||||
const enabled = mode === 'enabled'
|
||||
try {
|
||||
await NativeTriggerService.setNativeTriggerEnabled({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
serviceName: service,
|
||||
externalId: trigger.external_id,
|
||||
requestBody: { enabled }
|
||||
@@ -76,7 +79,7 @@
|
||||
isDeleting = true
|
||||
try {
|
||||
await NativeTriggerService.deleteNativeTrigger({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: $operatingWorkspace!,
|
||||
serviceName: service,
|
||||
externalId: triggerToDelete.external_id
|
||||
})
|
||||
|
||||
+6
-4
@@ -4,9 +4,11 @@
|
||||
import MultiSelect from '$lib/components/select/MultiSelect.svelte'
|
||||
import { NativeTriggerService } from '$lib/gen/services.gen'
|
||||
import type { GithubRepoEntry } from '$lib/gen/types.gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
serviceConfig: Record<string, any>
|
||||
@@ -57,14 +59,14 @@
|
||||
let selectedEvents = $state<string[]>(externalData?.events ?? serviceConfig.events ?? ['push'])
|
||||
|
||||
async function loadRepos() {
|
||||
if (!$workspaceStore) {
|
||||
if (!$operatingWorkspace) {
|
||||
repos = []
|
||||
return
|
||||
}
|
||||
loading = true
|
||||
try {
|
||||
repos = await NativeTriggerService.listGithubRepos({
|
||||
workspace: $workspaceStore
|
||||
workspace: $operatingWorkspace
|
||||
})
|
||||
} catch (err: any) {
|
||||
console.error('Failed to load GitHub repositories:', err)
|
||||
@@ -76,7 +78,7 @@
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if ($workspaceStore) {
|
||||
if ($operatingWorkspace) {
|
||||
loadRepos()
|
||||
}
|
||||
})
|
||||
|
||||
+7
-9
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { NativeTriggerService } from '$lib/gen/services.gen'
|
||||
import type { GoogleCalendarEntry } from '$lib/gen/types.gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { Badge } from '$lib/components/common'
|
||||
import { Loader2, X, RefreshCw } from 'lucide-svelte'
|
||||
import GoogleCalendarIcon from '$lib/components/icons/GoogleCalendarIcon.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
calendarId: string
|
||||
@@ -13,22 +15,18 @@
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
calendarId = $bindable(),
|
||||
calendarName = $bindable(),
|
||||
disabled = false
|
||||
}: Props = $props()
|
||||
let { calendarId = $bindable(), calendarName = $bindable(), disabled = false }: Props = $props()
|
||||
|
||||
let calendars = $state<GoogleCalendarEntry[]>([])
|
||||
let loading = $state(false)
|
||||
|
||||
async function loadCalendars() {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
loading = true
|
||||
try {
|
||||
calendars = await NativeTriggerService.listGoogleCalendars({
|
||||
workspace: $workspaceStore
|
||||
workspace: $operatingWorkspace
|
||||
})
|
||||
if (calendarId && !calendarName) {
|
||||
const found = calendars.find((c) => c.id === calendarId)
|
||||
@@ -55,7 +53,7 @@
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if ($workspaceStore) {
|
||||
if ($operatingWorkspace) {
|
||||
loadCalendars()
|
||||
}
|
||||
})
|
||||
|
||||
+41
-33
@@ -1,23 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { NativeTriggerService } from '$lib/gen/services.gen'
|
||||
import type { GoogleDriveFile, SharedDriveEntry } from '$lib/gen/types.gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { Button } from '$lib/components/common'
|
||||
import {
|
||||
Loader2,
|
||||
Folder,
|
||||
File,
|
||||
ChevronRight,
|
||||
Search,
|
||||
X,
|
||||
RefreshCw,
|
||||
Check
|
||||
} from 'lucide-svelte'
|
||||
import { Loader2, Folder, File, ChevronRight, Search, X, RefreshCw, Check } from 'lucide-svelte'
|
||||
import GoogleDriveIcon from '$lib/components/icons/GoogleDriveIcon.svelte'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { Debounced, watch } from 'runed'
|
||||
import { untrack } from 'svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
resourceId: string
|
||||
@@ -25,11 +18,7 @@
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
resourceId = $bindable(),
|
||||
resourceName = $bindable(),
|
||||
disabled = false
|
||||
}: Props = $props()
|
||||
let { resourceId = $bindable(), resourceName = $bindable(), disabled = false }: Props = $props()
|
||||
|
||||
type BreadcrumbItem = { id: string; name: string }
|
||||
type DriveTab = 'my_drive' | 'shared_with_me' | 'shared_drives'
|
||||
@@ -49,7 +38,7 @@
|
||||
let loadVersion = 0
|
||||
|
||||
async function loadFiles(pageToken?: string) {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
const version = ++loadVersion
|
||||
|
||||
@@ -63,7 +52,7 @@
|
||||
|
||||
try {
|
||||
const params: Parameters<typeof NativeTriggerService.listGoogleDriveFiles>[0] = {
|
||||
workspace: $workspaceStore,
|
||||
workspace: $operatingWorkspace,
|
||||
pageToken
|
||||
}
|
||||
|
||||
@@ -101,7 +90,7 @@
|
||||
}
|
||||
|
||||
async function loadSharedDrives() {
|
||||
if (!$workspaceStore) return
|
||||
if (!$operatingWorkspace) return
|
||||
|
||||
loadingFiles = true
|
||||
files = []
|
||||
@@ -109,7 +98,7 @@
|
||||
|
||||
try {
|
||||
sharedDrives = await NativeTriggerService.listGoogleSharedDrives({
|
||||
workspace: $workspaceStore
|
||||
workspace: $operatingWorkspace
|
||||
})
|
||||
} catch (err: any) {
|
||||
sendUserToast(`Failed to load shared drives: ${err.body || err.message}`, true)
|
||||
@@ -161,7 +150,7 @@
|
||||
|
||||
// Initial load when workspace is available
|
||||
$effect(() => {
|
||||
if ($workspaceStore) {
|
||||
if ($operatingWorkspace) {
|
||||
untrack(() => loadFiles())
|
||||
}
|
||||
})
|
||||
@@ -169,28 +158,37 @@
|
||||
// React to debounced search changes (skip initial)
|
||||
watch(
|
||||
() => debouncedSearch.current,
|
||||
() => { loadFiles() },
|
||||
() => {
|
||||
loadFiles()
|
||||
},
|
||||
{ lazy: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2 border rounded-md p-2 bg-surface">
|
||||
{#if resourceId}
|
||||
<div class="flex items-center gap-2 px-2 py-1 rounded bg-surface-selected text-secondary text-xs border">
|
||||
<div
|
||||
class="flex items-center gap-2 px-2 py-1 rounded bg-surface-selected text-secondary text-xs border"
|
||||
>
|
||||
<GoogleDriveIcon width="14px" height="14px" />
|
||||
<span>
|
||||
Selected: <strong>{resourceName || resourceId}</strong>
|
||||
</span>
|
||||
<button
|
||||
class="ml-auto text-tertiary hover:text-secondary"
|
||||
onclick={() => { resourceId = ''; resourceName = '' }}
|
||||
onclick={() => {
|
||||
resourceId = ''
|
||||
resourceName = ''
|
||||
}}
|
||||
{disabled}
|
||||
>
|
||||
<X size={14} />
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center gap-2 px-2 py-1 rounded text-tertiary text-xs border border-dashed">
|
||||
<div
|
||||
class="flex items-center gap-2 px-2 py-1 rounded text-tertiary text-xs border border-dashed"
|
||||
>
|
||||
<GoogleDriveIcon width="14px" height="14px" />
|
||||
<span>No file selected</span>
|
||||
</div>
|
||||
@@ -198,21 +196,27 @@
|
||||
|
||||
<div class="flex items-center gap-1 text-2xs">
|
||||
<button
|
||||
class="px-2 py-0.5 rounded {activeTab === 'my_drive' ? 'bg-surface-selected font-semibold' : 'hover:bg-surface-hover'}"
|
||||
class="px-2 py-0.5 rounded {activeTab === 'my_drive'
|
||||
? 'bg-surface-selected font-semibold'
|
||||
: 'hover:bg-surface-hover'}"
|
||||
onclick={() => switchTab('my_drive')}
|
||||
{disabled}
|
||||
>
|
||||
My Drive
|
||||
</button>
|
||||
<button
|
||||
class="px-2 py-0.5 rounded {activeTab === 'shared_with_me' ? 'bg-surface-selected font-semibold' : 'hover:bg-surface-hover'}"
|
||||
class="px-2 py-0.5 rounded {activeTab === 'shared_with_me'
|
||||
? 'bg-surface-selected font-semibold'
|
||||
: 'hover:bg-surface-hover'}"
|
||||
onclick={() => switchTab('shared_with_me')}
|
||||
{disabled}
|
||||
>
|
||||
Shared with me
|
||||
</button>
|
||||
<button
|
||||
class="px-2 py-0.5 rounded {activeTab === 'shared_drives' ? 'bg-surface-selected font-semibold' : 'hover:bg-surface-hover'}"
|
||||
class="px-2 py-0.5 rounded {activeTab === 'shared_drives'
|
||||
? 'bg-surface-selected font-semibold'
|
||||
: 'hover:bg-surface-hover'}"
|
||||
onclick={() => switchTab('shared_drives')}
|
||||
{disabled}
|
||||
>
|
||||
@@ -222,7 +226,10 @@
|
||||
<button
|
||||
class="p-1 text-tertiary hover:text-secondary"
|
||||
title="Refresh"
|
||||
onclick={() => activeTab === 'shared_drives' && currentParentId === 'root' ? loadSharedDrives() : loadFiles()}
|
||||
onclick={() =>
|
||||
activeTab === 'shared_drives' && currentParentId === 'root'
|
||||
? loadSharedDrives()
|
||||
: loadFiles()}
|
||||
{disabled}
|
||||
>
|
||||
<RefreshCw size={12} />
|
||||
@@ -237,7 +244,10 @@
|
||||
size="xs"
|
||||
class="!pl-7"
|
||||
/>
|
||||
<Search size={14} class="absolute left-2 top-1/2 -translate-y-1/2 text-tertiary pointer-events-none" />
|
||||
<Search
|
||||
size={14}
|
||||
class="absolute left-2 top-1/2 -translate-y-1/2 text-tertiary pointer-events-none"
|
||||
/>
|
||||
{#if searchQuery}
|
||||
<button
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 text-tertiary hover:text-secondary"
|
||||
@@ -277,9 +287,7 @@
|
||||
</div>
|
||||
{:else if activeTab === 'shared_drives' && currentParentId === 'root'}
|
||||
{#if sharedDrives.length === 0}
|
||||
<div class="text-center py-4 text-xs text-tertiary">
|
||||
No shared drives found
|
||||
</div>
|
||||
<div class="text-center py-4 text-xs text-tertiary"> No shared drives found </div>
|
||||
{:else}
|
||||
{#each sharedDrives as drive (drive.id)}
|
||||
<div
|
||||
|
||||
+6
-4
@@ -1,13 +1,15 @@
|
||||
<script lang="ts">
|
||||
import { NativeTriggerService } from '$lib/gen/services.gen'
|
||||
import type { NextCloudEventType } from '$lib/gen/types.gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { Button } from '$lib/components/common'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { getNextcloudSchema } from '../../utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
serviceConfig: Record<string, any>
|
||||
@@ -38,7 +40,7 @@
|
||||
let eventsError = $state<string | undefined>(undefined)
|
||||
|
||||
async function loadAvailableEvents() {
|
||||
if (!$workspaceStore) {
|
||||
if (!$operatingWorkspace) {
|
||||
availableEvents = []
|
||||
return
|
||||
}
|
||||
@@ -47,7 +49,7 @@
|
||||
eventsError = undefined
|
||||
try {
|
||||
const events = await NativeTriggerService.listNextCloudEvents({
|
||||
workspace: $workspaceStore!
|
||||
workspace: $operatingWorkspace!
|
||||
})
|
||||
availableEvents = events
|
||||
serviceSchema = getNextcloudSchema(events)
|
||||
@@ -84,7 +86,7 @@
|
||||
let externalDataApplied = $state(false)
|
||||
|
||||
$effect(() => {
|
||||
if ($workspaceStore) {
|
||||
if ($operatingWorkspace) {
|
||||
loadAvailableEvents()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import TriggerRunnablePicker from '$lib/components/triggers/TriggerRunnablePicker.svelte'
|
||||
import { NatsTriggerService, type ErrorHandler, type Retry, type TriggerMode } from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -33,6 +32,7 @@
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import TriggerSuspendedJobsAlert from '../TriggerSuspendedJobsAlert.svelte'
|
||||
import TriggerSuspendedJobsModal from '../TriggerSuspendedJobsModal.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -73,8 +73,8 @@
|
||||
onDelete = undefined,
|
||||
onReset = undefined
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let is_flow: boolean = $state(false)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import Subsection from '$lib/components/Subsection.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import ResourcePicker from '$lib/components/ResourcePicker.svelte'
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
import TestTriggerConnection from '../TestTriggerConnection.svelte'
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import { createEventDispatcher, untrack } from 'svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
defaultValues?: Record<string, any> | undefined
|
||||
@@ -35,8 +34,8 @@
|
||||
can_write = true,
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let otherArgsValid = $state(false)
|
||||
let globalError = $derived(
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
import { Button } from '$lib/components/common'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { PostgresTriggerService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { emptyString } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let loadingConfiguration = $state(false)
|
||||
|
||||
@@ -49,14 +48,14 @@
|
||||
}
|
||||
|
||||
interface Props {
|
||||
can_write: boolean;
|
||||
postgres_resource_path: string;
|
||||
checkConnection?: any | undefined;
|
||||
can_write: boolean
|
||||
postgres_resource_path: string
|
||||
checkConnection?: any | undefined
|
||||
}
|
||||
|
||||
let { can_write, postgres_resource_path, checkConnection = undefined }: Props = $props();
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
let { can_write, postgres_resource_path, checkConnection = undefined }: Props = $props()
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
</script>
|
||||
|
||||
{#if postgres_resource_path}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
type Retry,
|
||||
type TriggerMode
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, emptyString, emptyStringTrimmed, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -55,6 +54,7 @@
|
||||
import { useTriggerDraftSync } from '../useTriggerDraftSync.svelte'
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import { capitalize } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -94,8 +94,8 @@
|
||||
onDelete = undefined,
|
||||
onReset = undefined
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let is_flow: boolean = $state(false)
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
import { run } from 'svelte/legacy'
|
||||
|
||||
import { Button } from '$lib/components/common'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { safeSelectItems } from '$lib/components/select/utils.svelte'
|
||||
import type { Relations } from '$lib/gen'
|
||||
import { PostgresTriggerService } from '$lib/gen/services.gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { emptyString } from '$lib/utils'
|
||||
import { RefreshCw } from 'lucide-svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
items?: string[];
|
||||
can_write?: boolean;
|
||||
publication_name?: string;
|
||||
postgres_resource_path?: string;
|
||||
relations?: Relations[] | undefined;
|
||||
transaction_to_track?: string[];
|
||||
disabled?: boolean;
|
||||
items?: string[]
|
||||
can_write?: boolean
|
||||
publication_name?: string
|
||||
postgres_resource_path?: string
|
||||
relations?: Relations[] | undefined
|
||||
transaction_to_track?: string[]
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -30,9 +29,9 @@
|
||||
relations = $bindable(undefined),
|
||||
transaction_to_track = $bindable([]),
|
||||
disabled = false
|
||||
}: Props = $props();
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
}: Props = $props()
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let loadingPublication: boolean = $state(false)
|
||||
let deletingPublication: boolean = $state(false)
|
||||
@@ -113,7 +112,7 @@
|
||||
listDatabasePublication()
|
||||
run(() => {
|
||||
publication_name && getAllRelations()
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex gap-1">
|
||||
|
||||
@@ -3,17 +3,16 @@
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { safeSelectItems } from '$lib/components/select/utils.svelte'
|
||||
import { PostgresTriggerService } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { sendUserToast } from '$lib/toast'
|
||||
import { emptyString } from '$lib/utils'
|
||||
import { RefreshCw } from 'lucide-svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
edit: boolean;
|
||||
replication_slot_name?: string;
|
||||
postgres_resource_path?: string;
|
||||
disabled?: boolean;
|
||||
edit: boolean
|
||||
replication_slot_name?: string
|
||||
postgres_resource_path?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -21,9 +20,9 @@
|
||||
replication_slot_name = $bindable(''),
|
||||
postgres_resource_path = '',
|
||||
disabled = false
|
||||
}: Props = $props();
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
}: Props = $props()
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let deletingSlot: boolean = $state(false)
|
||||
let loadingSlot: boolean = $state(false)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
type Schedule,
|
||||
type ErrorHandler
|
||||
} from '$lib/gen'
|
||||
import { enterpriseLicense, workspaceStore } from '$lib/stores'
|
||||
import { enterpriseLicense } from '$lib/stores'
|
||||
import { canWrite, emptyString, formatCron, sendUserToast, cronV1toV2 } from '$lib/utils'
|
||||
import { base } from '$lib/base'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -50,8 +50,8 @@
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import PermissionedAsLine from '../PermissionedAsLine.svelte'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { useActingUser } from '$lib/actingUser.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
let {
|
||||
useDrawer = true,
|
||||
@@ -138,8 +138,8 @@
|
||||
let selectedPermissionedAs = $state<string | undefined>(undefined)
|
||||
let preservePermissionedAs = $state(false)
|
||||
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
// `undefined` while the lookup is in flight or after it failed; the checks below then
|
||||
// refuse rather than fall back to rights that belong to another workspace.
|
||||
const acting = useActingUser(() => wsId)
|
||||
@@ -159,9 +159,9 @@
|
||||
emptyString(errorHandlerExtraArgs['channel'])) ||
|
||||
!can_write
|
||||
)
|
||||
// Carry the acting workspace onto "create from template" routes when a
|
||||
// session override is set, so the script is created in the session workspace.
|
||||
const wsParam = $derived(triggerWs?.() ? `&workspace=${encodeURIComponent(wsId!)}` : '')
|
||||
// Carry the acting workspace onto "create from template" routes, so the script is created
|
||||
// in the workspace this schedule lives in.
|
||||
const wsParam = $derived(wsId ? `&workspace=${encodeURIComponent(wsId)}` : '')
|
||||
const scheduleCfg = $derived.by(getScheduleCfg)
|
||||
|
||||
const draftSync = useTriggerDraftSync({
|
||||
|
||||
@@ -13,11 +13,10 @@
|
||||
import VariableEditor from '$lib/components/VariableEditor.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { VariableService, type AwsAuthResourceType } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import TestingBadge from '../testingBadge.svelte'
|
||||
import MultiSelect from '$lib/components/select/MultiSelect.svelte'
|
||||
import { safeSelectItems } from '$lib/components/select/utils.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
can_write?: boolean
|
||||
@@ -40,8 +39,8 @@
|
||||
message_attributes = $bindable([]),
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
async function loadVariables() {
|
||||
return await VariableService.listVariable({ workspace: wsId ?? '' })
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
|
||||
import DrawerContent from '$lib/components/common/drawer/DrawerContent.svelte'
|
||||
import Path from '$lib/components/Path.svelte'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, capitalize, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
@@ -39,6 +38,7 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { useTriggerDraftSync } from '../useTriggerDraftSync.svelte'
|
||||
import LocalDraftBanner from '$lib/components/LocalDraftBanner.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -78,8 +78,8 @@
|
||||
onDelete = undefined,
|
||||
onReset = undefined
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state(undefined)
|
||||
let is_flow: boolean = $state(false)
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { getContext, setContext } from 'svelte'
|
||||
|
||||
const TRIGGER_WORKSPACE_KEY = 'triggerWorkspace'
|
||||
|
||||
/**
|
||||
* Context seam letting the native-trigger editors operate on a workspace other
|
||||
* than the globally-active `$workspaceStore`. An AI session can run against a
|
||||
* (possibly forked) workspace that differs from the nav workspace WITHOUT
|
||||
* switching `$workspaceStore` (see `SessionPicker`), so a host that embeds the
|
||||
* trigger editors in that context registers a resolver here.
|
||||
*
|
||||
* Every workspace-scoped backend call / navigation inside the trigger subtree
|
||||
* reads its workspace via {@link getTriggerWorkspace} and falls back to
|
||||
* `$workspaceStore` when no resolver is set — the default everywhere outside
|
||||
* such a host, so behavior there is unchanged. Mirrors the AI chat manager's
|
||||
* `operatingWorkspace` resolver.
|
||||
*/
|
||||
export function setTriggerWorkspace(resolver: () => string | undefined): void {
|
||||
setContext(TRIGGER_WORKSPACE_KEY, resolver)
|
||||
}
|
||||
|
||||
/**
|
||||
* The trigger-workspace resolver set by an embedding host, or `undefined` when
|
||||
* none is set (fall back to `$workspaceStore`). Read once during component init;
|
||||
* use in a `$derived`: `const ws = $derived(triggerWs?.() ?? $workspaceStore)`.
|
||||
*/
|
||||
export function getTriggerWorkspace(): (() => string | undefined) | undefined {
|
||||
return getContext<(() => string | undefined) | undefined>(TRIGGER_WORKSPACE_KEY)
|
||||
}
|
||||
@@ -4,9 +4,11 @@
|
||||
import { isObject } from '$lib/utils'
|
||||
import CopyableCodeBlock from '../../details/CopyableCodeBlock.svelte'
|
||||
import CaptureSection, { type CaptureInfo } from '../CaptureSection.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Url } from '$lib/components/common'
|
||||
import { fade } from 'svelte/transition'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
|
||||
interface Props {
|
||||
isFlow?: boolean
|
||||
@@ -33,7 +35,7 @@
|
||||
)
|
||||
|
||||
let captureUrl = $derived(
|
||||
`${location.origin}/api/w/${$workspaceStore}/capture_u/webhook/${
|
||||
`${location.origin}/api/w/${$operatingWorkspace}/capture_u/webhook/${
|
||||
isFlow ? 'flow' : 'script'
|
||||
}/${path}`
|
||||
)
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
// import { page } from '$app/state'
|
||||
import { base } from '$lib/base'
|
||||
import TriggerTokens from '../TriggerTokens.svelte'
|
||||
import { workspaceStore, userStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { userStore } from '$lib/stores'
|
||||
import UserSettings from '../../UserSettings.svelte'
|
||||
import { generateRandomString } from '$lib/utils'
|
||||
import TextInput from '$lib/components/text_input/TextInput.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
isFlow?: boolean
|
||||
@@ -43,8 +43,8 @@
|
||||
triggerTokens = $bindable(undefined),
|
||||
scopes = []
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
const WEBHOOK_BASE_URL = $derived(`${location.origin}${base}/api/w/${wsId}/jobs`)
|
||||
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import type { Schema } from '$lib/common'
|
||||
import { FlowService, ScriptService, type Flow, type Script } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import TestTriggerConnection from '../TestTriggerConnection.svelte'
|
||||
import TestingBadge from '$lib/components/triggers/testingBadge.svelte'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
url: string | undefined
|
||||
@@ -32,8 +31,8 @@
|
||||
isValid = $bindable(false),
|
||||
showTestingBadge = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let areRunnableArgsValid: boolean = $state(true)
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
type ErrorHandler,
|
||||
type TriggerMode
|
||||
} from '$lib/gen'
|
||||
import { usedTriggerKinds, userStore, workspaceStore } from '$lib/stores'
|
||||
import { getTriggerWorkspace } from '$lib/components/triggers/triggerWorkspace'
|
||||
import { usedTriggerKinds, userStore } from '$lib/stores'
|
||||
import { canWrite, emptySchema, emptyString, sendUserToast } from '$lib/utils'
|
||||
import { withForkConflictRetry } from '$lib/utils/forkConflict'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
@@ -55,6 +54,7 @@
|
||||
import TriggerSuspendedJobsAlert from '../TriggerSuspendedJobsAlert.svelte'
|
||||
import TriggerSuspendedJobsModal from '../TriggerSuspendedJobsModal.svelte'
|
||||
import { capitalize } from '$lib/utils'
|
||||
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
|
||||
|
||||
interface Props {
|
||||
useDrawer?: boolean
|
||||
@@ -95,8 +95,8 @@
|
||||
onReset = undefined,
|
||||
cloudDisabled = false
|
||||
}: Props = $props()
|
||||
const triggerWs = getTriggerWorkspace()
|
||||
const wsId = $derived(triggerWs?.() ?? $workspaceStore)
|
||||
const operatingWorkspace = useOperatingWorkspace()
|
||||
const wsId = $derived($operatingWorkspace)
|
||||
|
||||
let drawer: Drawer | undefined = $state()
|
||||
let is_flow: boolean = $state(false)
|
||||
|
||||
Reference in New Issue
Block a user