{#if menuOpen} goto('/schedules')} bind:this={scheduleEditor} /> {/if} {#snippet badges()} {#if script.lock_error_logs} Deployment failed {/if} {#if script.archived} Archived {/if} {#if script.auto_kind === 'lib' && script.kind !== 'preprocessor'} {/if} {#if script.auto_kind === 'wac'} {#snippet text()} Workflow-as-Code {/snippet} wac {/if} {#if script.auto_kind === 'test'} {#snippet text()} CI test script {/snippet} CI test {/if} {#if script.kind && script.kind !== 'script'} {script.kind === 'failure' ? 'Error handler' : capitalize(script.kind)} {/if} dispatch('change')} /> {#if script.labels?.length} {#each script.labels.slice(0, 3) as label} {label} {/each} {#if script.labels.length > 3} 'Label: ' + l) .join('\n')}>+{script.labels.length - 3} {/if} {/if} {/snippet} {#snippet actions()} {#if !$userStore?.operator} {#if showEditButton} {#if script.use_codebase} bundleThis script is deployed as a bundle and can only be deployed from the CLI for now {:else if script.canWrite && !script.archived} 0 ? script.summary : script.path}`} aiDescription={`Edits the script ${script.summary?.length > 0 ? script.summary : script.path}`} variant="subtle" wrapperClasses="w-20" unifiedSize="md" startIcon={{ icon: Pen }} href="{base}/scripts/edit/{script.path}" > Edit {/if} {/if} {#if !isCloudHosted() && editInForkAllowed($workspaceStore, $userWorkspaces) && (!showEditButton || !script.canWrite)} {/if} {/if} 0 ? script.summary : script.path}`} aiDescription={`Open dropdown for script ${script.summary?.length > 0 ? script.summary : script.path} options`} items={async () => { let owner = isOwner(script.path, $userStore, $workspaceStore) const canEdit = script.canWrite && showEditButton if (script.draft_only) { return [ ...selectMenuItems(rowSelection), { displayName: 'View code', icon: Code, action: () => { showCode(script.path, script.summary) } }, { displayName: 'Move/Rename', icon: FolderOpen, action: () => { // Addressed by the generated path its draft row sits at, but // named by the path typed in the editor. moveDrawer.openDrawer(script.draft_path ?? script.path, script.summary, 'script', { storagePath: script.path }) }, disabled: !showEditButton, hide: $userStore?.operator }, { displayName: 'Delete', icon: Trash, action: (event) => { // TODO // @ts-ignore if (event?.shiftKey) { deleteScript(script.path) } else { deleteConfirmedCallback = () => { deleteScript(script.path) } } }, type: dlt, // A draft-only row is always the authed user's own draft (the // list endpoint only surfaces own/legacy draft-only rows), so // discarding it never requires write permission on the path. disabled: !showEditButton } ] } return [ ...selectMenuItems(rowSelection), { displayName: 'View code', icon: Code, action: () => { showCode(script.path, script.summary) } }, ...(script.auto_kind === 'wac' ? [ { displayName: 'View JSON/YAML', icon: FileText, action: async () => { const fullScript = await ScriptService.getScriptByPath({ workspace: $workspaceStore!, path: script.path }) wacExportDrawer?.open(fullScript) } } ] : []), { displayName: 'Duplicate/Fork', icon: GitFork, href: `${base}/scripts/add?template=${script.path}`, disabled: !showEditButton, hide: $userStore?.operator }, { displayName: editInForkLabel($workspaceStore, $userWorkspaces), icon: Pen, // No `href`: the handler resolves the destination asynchronously. action: (e) => onEditInForkClick(e, 'script', script.path), hide: $userStore?.operator || isCloudHosted() || !editInForkAllowed($workspaceStore, $userWorkspaces) }, { displayName: 'Move/Rename', icon: FolderOpen, action: () => { moveDrawer.openDrawer(script.path, script.summary, 'script') }, disabled: !owner || script.archived || !canEdit, hide: $userStore?.operator }, ...(isDeployable('script', script.path, await getDeployUiSettings()) ? [ { displayName: 'Deploy to staging/prod', icon: ChevronUpSquare, action: () => { deploymentDrawer.openDrawer(script.path, 'script') }, disabled: script.archived, hide: $userStore?.operator } ] : []), { displayName: 'View runs', icon: List, href: `${base}/runs/${script.path}` }, { displayName: 'Versions', icon: History, action: () => { versionsDrawerOpen = true } }, { displayName: 'Audit logs', icon: Eye, href: `${base}/audit_logs?resource=${script.path}`, hide: $userStore?.operator }, { displayName: 'Schedule', icon: Calendar, action: () => { scheduleEditor?.openNew(false, script.path) }, disabled: script.archived, hide: $userStore?.operator }, { displayName: 'Permissions', icon: Shield, action: () => { shareModal.openDrawer && shareModal.openDrawer(script.path, 'script') }, disabled: script.archived, hide: $userStore?.operator }, { displayName: 'Copy path', icon: Copy, action: () => { copyToClipboard(script.path) } }, { displayName: 'Publish to Hub', icon: Globe2, action: async () => { // The row only carries metadata, so the code has to be fetched first; the tab is // claimed before that, since Safari won't open one after an await. const tab = claimTab() try { const fullScript = await ScriptService.getScriptByPath({ workspace: $workspaceStore!, path: script.path }) const url = scriptToHubUrl(fullScript, $hubBaseUrlStore).toString() if (tab) { tab.show(url) } else if (!window.open(url)) { sendUserToast('Allow popups to publish this script to the Hub', true) } } catch (e: any) { tab?.discard() sendUserToast(`Could not load ${script.path}: ${e?.body ?? e?.message ?? e}`, true) } }, // Operators can't write scripts, so they have nothing to publish. hide: $disableHubStore || $userStore?.operator }, { displayName: script.archived ? 'Unarchive' : 'Archive', icon: Archive, action: () => { script.archived ? script.path && unarchiveScript(script.path) : script.path && archiveScript(script.path) }, type: 'delete', disabled: !owner || !canEdit, hide: $userStore?.operator }, ...($userStore?.is_admin || $userStore?.is_super_admin ? [ { displayName: 'Delete', icon: Trash, action: (event) => { if (event?.shiftKey) { deleteScript(script.path) } else { deleteConfirmedCallback = () => { deleteScript(script.path) } } }, type: dlt, disabled: !canEdit, hide: $userStore?.operator } ] : []) ] }} on:open={() => { menuOpen = true }} /> {/snippet} {#if script} (versionsDrawerOpen = false)}> { if (script) { goto(`/scripts/get/${e.detail.version}?workspace=${$workspaceStore}`) } versionsDrawerOpen = false }} /> {/if}