This commit is contained in:
Diego Imbert
2026-03-26 18:23:09 +01:00
parent 48cffa17ec
commit 849da088ad
3 changed files with 389 additions and 363 deletions

View File

@@ -60,6 +60,7 @@
import { base } from '$lib/base'
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
import DatatableSchemaDiff from './DatatableSchemaDiff.svelte'
interface Props {
currentWorkspaceId: string
@@ -709,382 +710,409 @@
{@const selectedConflicts = conflictingDiffs.filter((e) =>
selectedItems.includes(getItemKey(e))
).length}
<WorkspaceDeployLayout
items={deployableItems}
{selectedItems}
{deploymentStatus}
selectablePredicate={(item) => selectableDiffs.some((d) => getItemKey(d) === item.key)}
{allSelected}
onToggleItem={(item) => {
const diff = comparison?.diffs.find((d) => getItemKey(d) === item.key)
if (diff) toggleItem(diff)
}}
onSelectAll={selectAll}
onDeselectAll={deselectAll}
emptyMessage="No comparison data available"
>
{#snippet header()}
<div class="flex items-center justify-between">
<div
class="flex flex-col gap-2 border bg-surface-tertiary w-full p-4 border-radius-5 rounded"
>
<div class="flex flex-row gap-1 items-center">
<ToggleButtonGroup
disabled={deploying}
selected="deploy_to"
onSelected={toggleDeploymentDirection}
noWFull
>
{#snippet children({ item })}
<ToggleButton
value="deploy_to"
label="Deploy to {parentWorkspaceId}"
icon={ArrowUp}
{item}
/>
<ToggleButton value="update" label="Update current" icon={ArrowDown} {item} />
{/snippet}
</ToggleButtonGroup>
{#if currentWorkspaceInfo && parentWorkspaceInfo}
<Badge
color="transparent"
class="ml-5 font-semibold"
title={mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
>
<span class="text-secondary">merge:</span>
{#if mergeIntoParent}
<GitFork size={14} />
<span class="text-emphasis">{currentWorkspaceInfo.id}</span>
{:else}
<Building size={14} />
<span class="text-emphasis">{parentWorkspaceInfo.id}</span>
<div class="flex flex-col gap-4">
<div class="bg-surface-tertiary p-4 rounded-md border">
<WorkspaceDeployLayout
items={deployableItems}
{selectedItems}
{deploymentStatus}
selectablePredicate={(item) => selectableDiffs.some((d) => getItemKey(d) === item.key)}
{allSelected}
onToggleItem={(item) => {
const diff = comparison?.diffs.find((d) => getItemKey(d) === item.key)
if (diff) toggleItem(diff)
}}
onSelectAll={selectAll}
onDeselectAll={deselectAll}
emptyMessage="No comparison data available"
>
{#snippet header()}
<div class="flex items-center justify-between bg-surface-tertiary">
<div class="flex flex-col gap-2 w-full pb-4 border-b">
<div class="flex flex-wrap gap-1 items-center">
<ToggleButtonGroup
disabled={deploying}
selected="deploy_to"
onSelected={toggleDeploymentDirection}
noWFull
>
{#snippet children({ item })}
<ToggleButton
value="deploy_to"
label="Deploy to {parentWorkspaceId}"
icon={ArrowUp}
{item}
/>
<ToggleButton value="update" label="Update current" icon={ArrowDown} {item} />
{/snippet}
</ToggleButtonGroup>
{#if currentWorkspaceInfo && parentWorkspaceInfo}
<div class="flex-1 flex gap-1 items-center">
<Badge
color="transparent"
class="ml-5 font-semibold"
title={mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
>
<span class="text-secondary">merge:</span>
{#if mergeIntoParent}
<GitFork size={14} />
<span class="text-emphasis">{currentWorkspaceInfo.id}</span>
{:else}
<Building size={14} />
<span class="text-emphasis">{parentWorkspaceInfo.id}</span>
{/if}
</Badge>
<ArrowRight size={16} />
<Badge
color="transparent"
class="font-semibold"
title={!mergeIntoParent
? currentWorkspaceInfo.name
: parentWorkspaceInfo.name}
>
<span class="text-secondary">into:</span>
{#if !mergeIntoParent}
<GitFork size={14} />
<span class="text-emphasis">{currentWorkspaceInfo.id}</span>
{:else}
<Building size={14} />
<span class="text-emphasis">{parentWorkspaceInfo.id}</span>
{/if}
</Badge>
</div>
{/if}
</Badge>
<ArrowRight size={16} />
<Badge
color="transparent"
class="font-semibold"
title={!mergeIntoParent ? currentWorkspaceInfo.name : parentWorkspaceInfo.name}
>
<span class="text-secondary">into:</span>
{#if !mergeIntoParent}
<GitFork size={14} />
<span class="text-emphasis">{currentWorkspaceInfo.id}</span>
{:else}
<Building size={14} />
<span class="text-emphasis">{parentWorkspaceInfo.id}</span>
{/if}
</Badge>
{/if}
<div class="flex items-center gap-2 text-sm">
<Badge color="transparent">
{comparison.summary.total_diffs} total items
</Badge>
<Badge color="transparent">
{selectableDiffs.length}
{mergeIntoParent ? 'deployable' : 'updateable'}
</Badge>
{#if conflictingDiffs.length > 0}
<Badge color="orange">
<AlertTriangle class="w-3 h-3 inline mr-1" />
{conflictingDiffs.length} conflicts
</Badge>
{/if}
</div>
</div>
</div>
</div>
<div class="flex items-center gap-2 text-sm">
<Badge color="transparent">
{comparison.summary.total_diffs} total items
</Badge>
<Badge color="transparent">
{selectableDiffs.length}
{mergeIntoParent ? 'deployable' : 'updateable'}
</Badge>
{#if conflictingDiffs.length > 0}
<Badge color="orange">
<AlertTriangle class="w-3 h-3 inline mr-1" />
{conflictingDiffs.length} conflicts
</Badge>
{/if}
</div>
</div>
</div>
{/snippet}
{/snippet}
{#snippet alerts()}
{#if mergeIntoParent}
<ParentWorkspaceProtectionAlert
{parentWorkspaceId}
onUpdateCanDeploy={(canDeploy) => {
canDeployToParent = canDeploy
}}
/>
{/if}
{#if conflictingDiffs.length > 0}
<Alert title="Conflicting changes detected" type="warning" class="mt-2">
<span>
{conflictingDiffs.length} item{conflictingDiffs.length !== 1 ? 's have' : ' has'} conflicting
changes, it was modified on the original workspace while changes were made on this fork.
Make sure to resolve these before merging.
</span>
</Alert>
{/if}
{#if hasBehindChanges && hasAheadChanges && !(mergeIntoParent && !canDeployToParent)}
<Alert
title="This fork is behind {parentWorkspaceId} and needs to be up to date before deploying"
type="warning"
class="my-2"
>
You have items behind '{parentWorkspaceId}'. You need to update and test your changes
before being able to deploy.
<span class="font-medium flex flex-row gap-1 text-red-500">
<input
type="checkbox"
bind:checked={allowBehindChangesOverride}
class="rounded max-w-4"
{#snippet alerts()}
{#if mergeIntoParent}
<ParentWorkspaceProtectionAlert
{parentWorkspaceId}
onUpdateCanDeploy={(canDeploy) => {
canDeployToParent = canDeploy
}}
/>
Override: Deploy despite {itemsWithBehindChanges.length} outdated item{itemsWithBehindChanges.length !==
1
? 's'
: ''}
</span>
</Alert>
{/if}
{#if !comparison.all_ahead_items_visible || !comparison.all_behind_items_visible}
<Alert title="This fork has changes not visible to your user" type="warning" class="my-2">
{#if !comparison.all_ahead_items_visible && !comparison.all_behind_items_visible}
This fork is ahead and behind its parent
{:else if !comparison.all_behind_items_visible}
This fork is behind of its parent
{:else if !comparison.all_ahead_items_visible}
This fork is ahead of its parent
{/if}
and some of the changes are not visible by you. Only a user with access to the whole context
may deploy or update this fork. You can share the link to this page to someone with proper
permissions to get it deployed.
</Alert>
{/if}
{/snippet}
{#snippet itemSummary(item)}
{@const diff = item.diff as WorkspaceItemDiff}
{@const key = item.key}
{@const isSelectable = selectableDiffs.includes(diff)}
{@const oldSummary = mergeIntoParent ? summaryCache[key]?.parent : summaryCache[key]?.current}
{@const newSummary = mergeIntoParent ? summaryCache[key]?.current : summaryCache[key]?.parent}
{@const existsInBothWorkspaces = !(
(diff.exists_in_fork && !diff.exists_in_source) ||
(!diff.exists_in_fork && diff.exists_in_source)
)}
{#if oldSummary != newSummary && isSelectable && existsInBothWorkspaces}
<span class="line-through text-secondary">{oldSummary || diff.path}</span>
{newSummary || diff.path}
{:else if !existsInBothWorkspaces}
{newSummary || oldSummary || diff.path}
{:else}
{newSummary || diff.path}
{/if}
{/snippet}
{#snippet itemActions(item)}
{@const diff = item.diff as WorkspaceItemDiff}
{@const key = item.key}
{@const targetOnBehalfOf = getTargetOnBehalfOf(key)}
{@const isConflict = diff.ahead > 0 && diff.behind > 0}
{@const existsInBothWorkspaces = !(
(diff.exists_in_fork && !diff.exists_in_source) ||
(!diff.exists_in_fork && diff.exists_in_source)
)}
<!-- On-behalf-of selector -->
{#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
<OnBehalfOfSelector
targetWorkspace={deployTargetWorkspace}
targetValue={targetOnBehalfOf}
selected={onBehalfOfChoice[key]}
onSelect={(choice, details) => {
onBehalfOfChoice[key] = choice
if (details) customOnBehalfOf[key] = details
}}
kind={diff.kind}
canPreserve={canPreserveOnBehalfOf}
customValue={customOnBehalfOf[key]?.permissionedAs}
/>
{/if}
{#if diff.kind === 'raw_app'}
<Badge small icon={{ icon: FileJson }}>Raw</Badge>
{/if}
<!-- Status badges -->
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
<Badge
title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
color="indigo"
size="xs">New</Badge
>
{/if}
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
<Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
>Deleted</Badge
>
{/if}
{#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
<Badge
title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
color="red"
size="xs">Deleted</Badge
>
{/if}
{#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
<Badge
title="This item was newly created in '{currentWorkspaceId}'"
color="indigo"
size="xs">New</Badge
>
{/if}
{#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
<div class="flex items-center gap-2">
{#if isConflict || existsInBothWorkspaces}
{#if diff.ahead > 0}
<Badge color="green" size="xs">
<ArrowUpRight class="w-3 h-3 inline" />
{diff.ahead} ahead
</Badge>
{/if}
{#if diff.behind > 0}
<Badge color="blue" size="xs">
<ArrowDownRight class="w-3 h-3 inline" />
{diff.behind} behind
</Badge>
{/if}
{#if isConflict}
<Badge color="orange" size="xs">
<AlertTriangle class="w-3 h-3 inline" />
Conflict
</Badge>
{/if}
{/if}
</div>
<div class:invisible={!existsInBothWorkspaces}>
<Button size="xs" variant="subtle" onclick={() => showDiff(diff.kind as Kind, diff.path)}>
<DiffIcon class="w-3 h-3" />
Show diff
</Button>
</div>
{/if}
{/snippet}
{#snippet footer()}
<div class="flex items-center justify-between">
<div></div>
<div class="flex flex-col items-end gap-2">
{#if comparison.all_behind_items_visible && comparison.all_ahead_items_visible}
{#if !(mergeIntoParent && !canDeployToParent)}
<Button
color="blue"
disabled={selectedItems.length === 0 ||
deploying ||
(hasBehindChanges && !allowBehindChangesOverride) ||
(mergeIntoParent && !canDeployToParent) ||
hasUnselectedOnBehalfOf}
loading={deploying}
on:click={deployChanges}
>
{mergeIntoParent ? 'Deploy' : 'Update'}
{selectedItems.length} Item{selectedItems.length !== 1 ? 's' : ''}
{#if selectedConflicts != 0}
({selectedConflicts} conflicts)
{/if}
</Button>
{#if hasUnselectedOnBehalfOf}
<span class="text-xs text-yellow-600">
You must set the "on behalf of" user for all items before deploying
<Tooltip class="text-yellow-600">
The "run on behalf of" field defines which user's permissions will be applied
during execution. Make sure this is set to an appropriate user before deploying.
</Tooltip>
</span>
{/if}
{/if}
{/if}
{#if deploymentErrorMessage != ''}
<Alert
title="Cannot {mergeIntoParent ? 'deploy these changes' : 'update these items'}"
type="error"
class="my-2 max-w-80"
>
{#if conflictingDiffs.length > 0}
<Alert title="Conflicting changes detected" type="warning" class="mt-2">
<span>
{deploymentErrorMessage}
{conflictingDiffs.length} item{conflictingDiffs.length !== 1 ? 's have' : ' has'} conflicting
changes, it was modified on the original workspace while changes were made on this fork.
Make sure to resolve these before merging.
</span>
</Alert>
{/if}
</div>
</div>
{/snippet}
</WorkspaceDeployLayout>
<!-- Fork Triggers Section -->
<div class="mt-6">
<div class="flex items-center gap-2 mb-2">
<h3 class="text-sm font-semibold">Triggers created in this fork</h3>
{#if !loadingTriggers}
<Badge color="indigo" size="xs"
>{forkTriggers.length} trigger{forkTriggers.length !== 1 ? 's' : ''}</Badge
>
{/if}
</div>
<Alert title="Deploy and/or delete these triggers" type="info" class="mb-2">
When forking a workspace, triggers are not forked to avoid unnecessary executions or
collisions. If you created this triggers with the intention of deploying them to the parent
workspace, you can do so here. Otherwise it is recommended to delete them or disable them.
</Alert>
{#if loadingTriggers}
<div class="flex items-center gap-2 text-secondary text-sm p-4">
<Loader2 class="animate-spin w-4 h-4" />
Loading triggers...
</div>
{:else if forkTriggers.length === 0}
<div class="text-secondary text-sm p-4 border rounded-md bg-surface-tertiary">
No triggers in this fork workspace.
</div>
{:else}
<div class="border rounded-md bg-surface-tertiary">
{#each forkTriggers as trigger (trigger.triggerKind + ':' + trigger.path)}
<Row
kind="trigger"
triggerKind={trigger.triggerKind}
path={trigger.path}
href={getTriggerHref(trigger.triggerKind)}
marked={undefined}
isSelectable={false}
canFavorite={false}
workspaceId={currentWorkspaceId}
>
{#snippet customSummary()}
<span>{getTriggerDisplayName(trigger.triggerKind)}</span>
<span class="text-secondary mx-1">&rarr;</span>
<span class="text-secondary">{trigger.scriptPath}</span>
{#if trigger.isFlow}
<Badge color="blue" size="xs">flow</Badge>
{#if hasBehindChanges && hasAheadChanges && !(mergeIntoParent && !canDeployToParent)}
<Alert
title="This fork is behind {parentWorkspaceId} and needs to be up to date before deploying"
type="warning"
class="my-2"
>
You have items behind '{parentWorkspaceId}'. You need to update and test your changes
before being able to deploy.
<span class="font-medium flex flex-row gap-1 text-red-500">
<input
type="checkbox"
bind:checked={allowBehindChangesOverride}
class="rounded max-w-4"
/>
Override: Deploy despite {itemsWithBehindChanges.length} outdated item{itemsWithBehindChanges.length !==
1
? 's'
: ''}
</span>
</Alert>
{/if}
{#if !comparison.all_ahead_items_visible || !comparison.all_behind_items_visible}
<Alert
title="This fork has changes not visible to your user"
type="warning"
class="my-2"
>
{#if !comparison.all_ahead_items_visible && !comparison.all_behind_items_visible}
This fork is ahead and behind its parent
{:else if !comparison.all_behind_items_visible}
This fork is behind of its parent
{:else if !comparison.all_ahead_items_visible}
This fork is ahead of its parent
{/if}
{#if trigger.extraLabel}
<span class="text-tertiary text-xs">({trigger.extraLabel})</span>
{/if}
{/snippet}
{#snippet actions()}
{#if trigger.enabled != null}
<Badge color={trigger.enabled ? 'green' : 'gray'} size="xs">
{trigger.enabled ? 'Enabled' : 'Disabled'}
</Badge>
and some of the changes are not visible by you. Only a user with access to the whole context
may deploy or update this fork. You can share the link to this page to someone with proper
permissions to get it deployed.
</Alert>
{/if}
{/snippet}
{#snippet itemSummary(item)}
{@const diff = item.diff as WorkspaceItemDiff}
{@const key = item.key}
{@const isSelectable = selectableDiffs.includes(diff)}
{@const oldSummary = mergeIntoParent
? summaryCache[key]?.parent
: summaryCache[key]?.current}
{@const newSummary = mergeIntoParent
? summaryCache[key]?.current
: summaryCache[key]?.parent}
{@const existsInBothWorkspaces = !(
(diff.exists_in_fork && !diff.exists_in_source) ||
(!diff.exists_in_fork && diff.exists_in_source)
)}
{#if oldSummary != newSummary && isSelectable && existsInBothWorkspaces}
<span class="line-through text-secondary">{oldSummary || diff.path}</span>
{newSummary || diff.path}
{:else if !existsInBothWorkspaces}
{newSummary || oldSummary || diff.path}
{:else}
{newSummary || diff.path}
{/if}
{/snippet}
{#snippet itemActions(item)}
{@const diff = item.diff as WorkspaceItemDiff}
{@const key = item.key}
{@const targetOnBehalfOf = getTargetOnBehalfOf(key)}
{@const isConflict = diff.ahead > 0 && diff.behind > 0}
{@const existsInBothWorkspaces = !(
(diff.exists_in_fork && !diff.exists_in_source) ||
(!diff.exists_in_fork && diff.exists_in_source)
)}
<!-- On-behalf-of selector -->
{#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
<OnBehalfOfSelector
targetWorkspace={deployTargetWorkspace}
targetValue={targetOnBehalfOf}
selected={onBehalfOfChoice[key]}
onSelect={(choice, details) => {
onBehalfOfChoice[key] = choice
if (details) customOnBehalfOf[key] = details
}}
kind={diff.kind}
canPreserve={canPreserveOnBehalfOf}
customValue={customOnBehalfOf[key]?.permissionedAs}
/>
{/if}
{#if diff.kind === 'raw_app'}
<Badge small icon={{ icon: FileJson }}>Raw</Badge>
{/if}
<!-- Status badges -->
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
<Badge
title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
color="indigo"
size="xs">New</Badge
>
{/if}
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
<Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
>Deleted</Badge
>
{/if}
{#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
<Badge
title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
color="red"
size="xs">Deleted</Badge
>
{/if}
{#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
<Badge
title="This item was newly created in '{currentWorkspaceId}'"
color="indigo"
size="xs">New</Badge
>
{/if}
{#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
<div class="flex items-center gap-2">
{#if isConflict || existsInBothWorkspaces}
{#if diff.ahead > 0}
<Badge color="green" size="xs">
<ArrowUpRight class="w-3 h-3 inline" />
{diff.ahead} ahead
</Badge>
{/if}
{#if diff.behind > 0}
<Badge color="blue" size="xs">
<ArrowDownRight class="w-3 h-3 inline" />
{diff.behind} behind
</Badge>
{/if}
{#if isConflict}
<Badge color="orange" size="xs">
<AlertTriangle class="w-3 h-3 inline" />
Conflict
</Badge>
{/if}
{/if}
</div>
<div class:invisible={!existsInBothWorkspaces}>
<Button
size="xs"
variant="subtle"
onclick={() => {
deploymentDrawer?.openDrawer(trigger.path, 'trigger', {
triggers: { kind: trigger.triggerKind }
})
}}
onclick={() => showDiff(diff.kind as Kind, diff.path)}
>
<Upload size={12} />
Deploy
<DiffIcon class="w-3 h-3" />
Show diff
</Button>
<Button size="xs" variant="subtle" color="red" onclick={() => deleteTrigger(trigger)}>
<Trash2 size={12} />
</Button>
{/snippet}
</Row>
{/each}
</div>
{/if}
{/snippet}
{#snippet footer()}
<div class="flex items-center justify-between">
<div></div>
<div class="flex flex-col items-end gap-2">
{#if comparison.all_behind_items_visible && comparison.all_ahead_items_visible}
{#if !(mergeIntoParent && !canDeployToParent)}
<Button
color="blue"
disabled={selectedItems.length === 0 ||
deploying ||
(hasBehindChanges && !allowBehindChangesOverride) ||
(mergeIntoParent && !canDeployToParent) ||
hasUnselectedOnBehalfOf}
loading={deploying}
on:click={deployChanges}
>
{mergeIntoParent ? 'Deploy' : 'Update'}
{selectedItems.length} Item{selectedItems.length !== 1 ? 's' : ''}
{#if selectedConflicts != 0}
({selectedConflicts} conflicts)
{/if}
</Button>
{#if hasUnselectedOnBehalfOf}
<span class="text-xs text-yellow-600">
You must set the "on behalf of" user for all items before deploying
<Tooltip class="text-yellow-600">
The "run on behalf of" field defines which user's permissions will be
applied during execution. Make sure this is set to an appropriate user
before deploying.
</Tooltip>
</span>
{/if}
{/if}
{/if}
{#if deploymentErrorMessage != ''}
<Alert
title="Cannot {mergeIntoParent ? 'deploy these changes' : 'update these items'}"
type="error"
class="my-2 max-w-80"
>
<span>
{deploymentErrorMessage}
</span>
</Alert>
{/if}
</div>
</div>
{/snippet}
</WorkspaceDeployLayout>
</div>
<!-- Fork Triggers Section -->
<div class="bg-surface-tertiary p-4 rounded-md border">
<div class="flex items-center gap-2 mb-2">
<h3 class="text-sm font-semibold">Triggers created in this fork</h3>
{#if !loadingTriggers}
<Badge color="indigo" size="xs"
>{forkTriggers.length} trigger{forkTriggers.length !== 1 ? 's' : ''}</Badge
>
{/if}
</div>
{/if}
<Alert title="Deploy and/or delete these triggers" type="info" class="mb-2">
When forking a workspace, triggers are not forked to avoid unnecessary executions or
collisions. If you created this triggers with the intention of deploying them to the parent
workspace, you can do so here. Otherwise it is recommended to delete them or disable them.
</Alert>
{#if loadingTriggers}
<div class="flex items-center gap-2 text-secondary text-sm p-4">
<Loader2 class="animate-spin w-4 h-4" />
Loading triggers...
</div>
{:else if forkTriggers.length === 0}
<div class="text-secondary text-sm p-4 border rounded-md bg-surface-tertiary">
No triggers in this fork workspace.
</div>
{:else}
<div class="border rounded-md bg-surface-tertiary">
{#each forkTriggers as trigger (trigger.triggerKind + ':' + trigger.path)}
<Row
kind="trigger"
triggerKind={trigger.triggerKind}
path={trigger.path}
href={getTriggerHref(trigger.triggerKind)}
marked={undefined}
isSelectable={false}
canFavorite={false}
workspaceId={currentWorkspaceId}
>
{#snippet customSummary()}
<span>{getTriggerDisplayName(trigger.triggerKind)}</span>
<span class="text-secondary mx-1">&rarr;</span>
<span class="text-secondary">{trigger.scriptPath}</span>
{#if trigger.isFlow}
<Badge color="blue" size="xs">flow</Badge>
{/if}
{#if trigger.extraLabel}
<span class="text-tertiary text-xs">({trigger.extraLabel})</span>
{/if}
{/snippet}
{#snippet actions()}
{#if trigger.enabled != null}
<Badge color={trigger.enabled ? 'green' : 'gray'} size="xs">
{trigger.enabled ? 'Enabled' : 'Disabled'}
</Badge>
{/if}
<Button
size="xs"
variant="subtle"
onclick={() => {
deploymentDrawer?.openDrawer(trigger.path, 'trigger', {
triggers: { kind: trigger.triggerKind }
})
}}
>
<Upload size={12} />
Deploy
</Button>
<Button
size="xs"
variant="subtle"
color="red"
onclick={() => deleteTrigger(trigger)}
>
<Trash2 size={12} />
</Button>
{/snippet}
</Row>
{/each}
</div>
{/if}
</div>
<div class="bg-surface-tertiary p-4 rounded-md border">
<DatatableSchemaDiff {currentWorkspaceId} {parentWorkspaceId} />
</div>
</div>
<DeployWorkspaceDrawer bind:this={deploymentDrawer} />

View File

@@ -73,7 +73,7 @@
<!-- Select all row -->
<div class="px-4 py-2 flex items-center justify-between">
<div
class="flex items-center gap-2 text-secondary text-sm"
class="flex items-center gap-2 text-secondary text-xs"
class:opacity-50={!hasSelectableItems}
>
<input
@@ -149,7 +149,7 @@
<!-- Footer -->
{#if footer}
<div class="p-4 bg-surface">
<div class="p-4">
{@render footer()}
</div>
{/if}

View File

@@ -1,6 +1,5 @@
<script lang="ts">
import CompareWorkspaces from '$lib/components/CompareWorkspaces.svelte'
import DatatableSchemaDiff from '$lib/components/DatatableSchemaDiff.svelte'
import { WorkspaceService, type WorkspaceComparison } from '$lib/gen'
import { page } from '$app/state'
import { userWorkspaces } from '$lib/stores'
@@ -63,7 +62,6 @@
<!-- }} -->
<!-- /> -->
<CompareWorkspaces {currentWorkspaceId} {parentWorkspaceId} {comparison} />
<DatatableSchemaDiff {currentWorkspaceId} {parentWorkspaceId} />
{/if}
{#if !currentWorkspaceId}
No workspace selected