windmill-components 1.695.0 → 1.698.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +2 -0
- package/dist/sharedUtils/base.d.ts +1 -0
- package/dist/sharedUtils/cloud.d.ts +1 -0
- package/dist/sharedUtils/common.d.ts +111 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +13 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +11 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +95 -0
- package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +6 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +33 -0
- package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +10 -0
- package/dist/sharedUtils/components/apps/editor/component/components.d.ts +5371 -0
- package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/index.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +3 -0
- package/dist/sharedUtils/components/apps/gridUtils.d.ts +14 -0
- package/dist/sharedUtils/components/apps/inputType.d.ts +178 -0
- package/dist/sharedUtils/components/apps/rx.d.ts +29 -0
- package/dist/sharedUtils/components/apps/sharedTypes.d.ts +21 -0
- package/dist/sharedUtils/components/apps/types.d.ts +274 -0
- package/dist/sharedUtils/components/assets/lib.d.ts +25 -0
- package/dist/sharedUtils/components/common/alert/model.d.ts +2 -0
- package/dist/sharedUtils/components/common/badge/model.d.ts +8 -0
- package/dist/sharedUtils/components/common/button/model.d.ts +45 -0
- package/dist/sharedUtils/components/common/fileInput/model.d.ts +1 -0
- package/dist/sharedUtils/components/common/index.d.ts +24 -0
- package/dist/sharedUtils/components/common/skeleton/model.d.ts +21 -0
- package/dist/sharedUtils/components/dbTypes.d.ts +14 -0
- package/dist/sharedUtils/components/diff_drawer.d.ts +26 -0
- package/dist/sharedUtils/components/ducklake.d.ts +1 -0
- package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +7 -0
- package/dist/sharedUtils/components/icons/index.d.ts +101 -0
- package/dist/sharedUtils/components/random_positive_adjetive.d.ts +1 -0
- package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +10 -0
- package/dist/sharedUtils/components/raw_apps/utils.d.ts +15 -0
- package/dist/sharedUtils/components/triggers/email/utils.d.ts +4 -0
- package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/http/utils.d.ts +11 -0
- package/dist/sharedUtils/components/triggers/kafka/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/nats/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +8 -0
- package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +32 -0
- package/dist/sharedUtils/components/triggers/utils.d.ts +80 -0
- package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers.d.ts +20 -0
- package/dist/sharedUtils/gen/core/ApiError.d.ts +10 -0
- package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +13 -0
- package/dist/sharedUtils/gen/core/ApiResult.d.ts +7 -0
- package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +26 -0
- package/dist/sharedUtils/gen/core/OpenAPI.d.ts +27 -0
- package/dist/sharedUtils/gen/core/request.d.ts +29 -0
- package/dist/sharedUtils/gen/index.d.ts +6 -0
- package/dist/sharedUtils/gen/schemas.gen.d.ts +7036 -0
- package/dist/sharedUtils/gen/services.gen.d.ts +6047 -0
- package/dist/sharedUtils/gen/types.gen.d.ts +21881 -0
- package/dist/sharedUtils/history.svelte.d.ts +9 -0
- package/dist/sharedUtils/hub.d.ts +49 -0
- package/dist/sharedUtils/jsr.json +6 -0
- package/dist/sharedUtils/lib.d.ts +5 -0
- package/dist/sharedUtils/lib.es.js +1588 -0
- package/dist/sharedUtils/package.json +12 -0
- package/dist/sharedUtils/schema.d.ts +3 -0
- package/dist/sharedUtils/stores.d.ts +97 -0
- package/dist/sharedUtils/svelte5Utils.svelte.d.ts +80 -0
- package/dist/sharedUtils/toast.d.ts +8 -0
- package/dist/sharedUtils/utils.d.ts +265 -0
- package/package/components/AppConnectInner.svelte +38 -5
- package/package/components/CompareWorkspaces.svelte +142 -486
- package/package/components/Editor.svelte +5 -4
- package/package/components/Editor.svelte.d.ts +1 -0
- package/package/components/FilterSearchbar.svelte +3 -1
- package/package/components/FilterSearchbar.svelte.d.ts +1 -0
- package/package/components/ForkWorkspaceBanner.svelte +16 -0
- package/package/components/LogViewer.svelte +51 -60
- package/package/components/OnBehalfOfSelector.svelte +10 -7
- package/package/components/ResourceEditor.svelte +198 -311
- package/package/components/ResourceEditor.svelte.d.ts +3 -3
- package/package/components/ResourceEditorDrawer.svelte +17 -6
- package/package/components/ResourceForm.svelte +235 -0
- package/package/components/ResourceForm.svelte.d.ts +25 -0
- package/package/components/RunsPage.svelte +1 -0
- package/package/components/ScriptBuilder.svelte +1 -0
- package/package/components/ScriptEditor.svelte +10 -3
- package/package/components/ScriptEditor.svelte.d.ts +1 -0
- package/package/components/TaggedTextInput.svelte +4 -1
- package/package/components/TaggedTextInput.svelte.d.ts +2 -0
- package/package/components/VariableEditor.svelte +177 -199
- package/package/components/VariableEditor.svelte.d.ts +1 -2
- package/package/components/VariableForm.svelte +133 -0
- package/package/components/VariableForm.svelte.d.ts +22 -0
- package/package/components/WsSpecificVersions.svelte +39 -0
- package/package/components/WsSpecificVersions.svelte.d.ts +9 -0
- package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +0 -1
- package/package/components/apps/editor/AppEditorHeaderDeploy.svelte.d.ts +1 -1
- package/package/components/common/table/AppRow.svelte +2 -1
- package/package/components/common/table/AppRow.svelte.d.ts +1 -0
- package/package/components/common/table/FlowRow.svelte +2 -1
- package/package/components/common/table/FlowRow.svelte.d.ts +1 -0
- package/package/components/common/table/RawAppRow.svelte +2 -1
- package/package/components/common/table/RawAppRow.svelte.d.ts +1 -0
- package/package/components/common/table/Row.svelte +11 -3
- package/package/components/common/table/Row.svelte.d.ts +2 -1
- package/package/components/common/table/RowIcon.svelte +18 -2
- package/package/components/common/table/RowIcon.svelte.d.ts +1 -1
- package/package/components/common/table/ScriptRow.svelte +2 -1
- package/package/components/common/table/ScriptRow.svelte.d.ts +1 -0
- package/package/components/copilot/autocomplete/Autocompletor.d.ts +3 -1
- package/package/components/copilot/autocomplete/Autocompletor.js +5 -2
- package/package/components/copilot/autocomplete/request.d.ts +1 -0
- package/package/components/copilot/autocomplete/request.js +1 -1
- package/package/components/copilot/chat/AIChatManager.svelte.js +14 -4
- package/package/components/copilot/chat/AiChatLayout.svelte +2 -0
- package/package/components/copilot/chat/ContextManager.svelte.d.ts +1 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte +129 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte.d.ts +4 -0
- package/package/components/copilot/chat/ToolExecutionDisplay.svelte +14 -6
- package/package/components/copilot/chat/ToolMessageActions.svelte +73 -0
- package/package/components/copilot/chat/ToolMessageActions.svelte.d.ts +7 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.d.ts +6 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.js +29 -0
- package/package/components/copilot/chat/script/core.d.ts +6 -2
- package/package/components/copilot/chat/script/core.js +13 -7
- package/package/components/copilot/chat/script/wacPrompt.test.d.ts +1 -0
- package/package/components/copilot/chat/script/wacPrompt.test.js +25 -0
- package/package/components/copilot/chat/shared.d.ts +12 -0
- package/package/components/copilot/chat/shared.test.js +23 -2
- package/package/components/copilot/chat/workspaceTools.js +34 -4
- package/package/components/flows/content/ScriptEditorDrawer.svelte +1 -0
- package/package/components/graph/wacToFlow.js +1 -1
- package/package/components/graph/wacToFlow.test.d.ts +1 -0
- package/package/components/graph/wacToFlow.test.js +17 -0
- package/package/components/home/Item.svelte +5 -1
- package/package/components/home/Item.svelte.d.ts +1 -0
- package/package/components/home/ItemsList.svelte +260 -3
- package/package/components/instanceSettings/SecretBackendConfig.svelte +457 -88
- package/package/components/runs/useJobsLoader.svelte.js +5 -11
- package/package/components/sidebar/WorkspaceMenu.svelte +19 -5
- package/package/externalDomain.d.ts +2 -0
- package/package/externalDomain.js +16 -0
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/types.gen.d.ts +0 -112
- package/package/hubPaths.json +2 -2
- package/package/system_prompts/index.d.ts +1 -1
- package/package/system_prompts/index.js +22 -3
- package/package/system_prompts/prompts.d.ts +2 -2
- package/package/system_prompts/prompts.js +6 -3
- package/package/utils_deployable.d.ts +162 -638
- package/package/utils_deployable.js +75 -143
- package/package/utils_workspace_deploy.d.ts +10 -4
- package/package/utils_workspace_deploy.js +167 -42
- package/package.json +7 -3
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
<script lang="ts">import { AlertTriangle, ArrowDown, ArrowDownRight, ArrowRight, ArrowUp, ArrowUpRight, Building, CircleCheck, CircleX, DiffIcon, FileJson, FlaskConical, GitFork, Loader2, UserPlus } from 'lucide-svelte';
|
|
2
2
|
import { Alert, Badge } from './common';
|
|
3
|
-
import { AppService,
|
|
3
|
+
import { AppService, FlowService, FolderService, ScriptService, UserService, WorkspaceService } from '../gen';
|
|
4
4
|
import Button from './common/button/Button.svelte';
|
|
5
5
|
import DiffDrawer from './DiffDrawer.svelte';
|
|
6
|
-
import DiffEditor from './DiffEditor.svelte';
|
|
7
|
-
import Drawer from './common/drawer/Drawer.svelte';
|
|
8
|
-
import DrawerContent from './common/drawer/DrawerContent.svelte';
|
|
9
6
|
import ParentWorkspaceProtectionAlert from './ParentWorkspaceProtectionAlert.svelte';
|
|
10
7
|
import { userWorkspaces, workspaceStore } from '../stores';
|
|
11
8
|
import { deployItem, deleteItemInWorkspace, getItemValue, getOnBehalfOf } from '../utils_workspace_deploy';
|
|
9
|
+
import { isTriggerOrScheduleKind } from 'windmill-utils-internal';
|
|
12
10
|
import Tooltip from './Tooltip.svelte';
|
|
13
11
|
import OnBehalfOfSelector, { needsOnBehalfOfSelection } from './OnBehalfOfSelector.svelte';
|
|
14
12
|
import { sendUserToast } from '../toast';
|
|
15
13
|
import { deepEqual } from 'fast-equals';
|
|
16
|
-
import { orderedJsonStringify, orderedYamlStringify } from '../utils';
|
|
17
14
|
import WorkspaceDeployLayout from './WorkspaceDeployLayout.svelte';
|
|
18
15
|
import DeploymentRequestPanel from './deploymentRequest/DeploymentRequestPanel.svelte';
|
|
19
16
|
import { userStore } from '../stores';
|
|
20
|
-
import { triggerDisplayNamesMap, triggerKindToTriggerType } from './triggers/utils';
|
|
21
|
-
import { getEmailAddress, getEmailDomain } from './triggers/email/utils';
|
|
22
17
|
import { base } from '../base';
|
|
23
18
|
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte';
|
|
24
19
|
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte';
|
|
@@ -110,8 +105,11 @@ async function fetchSummaries(diffs) {
|
|
|
110
105
|
}
|
|
111
106
|
}
|
|
112
107
|
async function fetchOnBehalfOfInfo(diffs) {
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
// Runnables carry an email; triggers/schedules carry `permissioned_as`.
|
|
109
|
+
// `getOnBehalfOf` handles the dispatch — we just need to skip kinds that
|
|
110
|
+
// have no on_behalf_of concept (resource, variable, folder, resource_type).
|
|
111
|
+
const itemsWithOnBehalfOf = diffs.filter((d) => ['flow', 'script', 'app', 'raw_app'].includes(d.kind) || isTriggerOrScheduleKind(d.kind));
|
|
112
|
+
for (const diff of itemsWithOnBehalfOf) {
|
|
115
113
|
for (const workspace of [currentWorkspaceId, parentWorkspaceId]) {
|
|
116
114
|
const workspacedKey = getWorkspacedKey(workspace, getItemKey(diff));
|
|
117
115
|
if (onBehalfOfInfo[workspacedKey] !== undefined)
|
|
@@ -156,7 +154,8 @@ function getOnBehalfOfForDeploy(itemKey, kind) {
|
|
|
156
154
|
return getTargetOnBehalfOf(itemKey);
|
|
157
155
|
if (choice === 'custom') {
|
|
158
156
|
const details = customOnBehalfOf[itemKey];
|
|
159
|
-
|
|
157
|
+
const wantsPermissionedAs = kind === 'trigger' || isTriggerOrScheduleKind(kind);
|
|
158
|
+
return wantsPermissionedAs ? details?.permissionedAs : details?.email;
|
|
160
159
|
}
|
|
161
160
|
// 'me' or undefined = don't pass, backend will use deploying user's identity
|
|
162
161
|
return undefined;
|
|
@@ -193,17 +192,11 @@ async function selectAll() {
|
|
|
193
192
|
function deselectAll() {
|
|
194
193
|
selectedItems = [];
|
|
195
194
|
}
|
|
196
|
-
async function selectAllNonConflicts() {
|
|
197
|
-
selectedItems = selectableDiffs
|
|
198
|
-
.filter((d) => !(d.ahead > 0 && d.behind > 0))
|
|
199
|
-
.map((d) => getItemKey(d))
|
|
200
|
-
.filter((k) => !(deploymentStatus[k]?.status == 'deployed'));
|
|
201
|
-
}
|
|
202
195
|
const deploymentStatus = $state({});
|
|
203
196
|
function getWorkspacedKey(workspace, key) {
|
|
204
197
|
return `${workspace}/${key}`;
|
|
205
198
|
}
|
|
206
|
-
async function deploy(kind, path, workspaceToDeployTo, workspaceFrom, statusKey
|
|
199
|
+
async function deploy(kind, path, workspaceToDeployTo, workspaceFrom, statusKey) {
|
|
207
200
|
deploymentStatus[statusKey] = { status: 'loading' };
|
|
208
201
|
// Check if the item was deleted in the source workspace.
|
|
209
202
|
// If so, archive/delete it in the target workspace instead of copying.
|
|
@@ -217,16 +210,6 @@ async function deploy(kind, path, workspaceToDeployTo, workspaceFrom, statusKey,
|
|
|
217
210
|
if (itemDeletedInSource) {
|
|
218
211
|
result = await deleteItemInWorkspace(kind, path, workspaceToDeployTo);
|
|
219
212
|
}
|
|
220
|
-
else if (trigger) {
|
|
221
|
-
result = await deployItem({
|
|
222
|
-
kind: 'trigger',
|
|
223
|
-
path,
|
|
224
|
-
workspaceFrom,
|
|
225
|
-
workspaceTo: workspaceToDeployTo,
|
|
226
|
-
additionalInformation: { triggers: { kind: trigger.triggerKind } },
|
|
227
|
-
onBehalfOf: getOnBehalfOfForDeploy(statusKey, 'trigger')
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
213
|
else {
|
|
231
214
|
result = await deployItem({
|
|
232
215
|
kind,
|
|
@@ -294,7 +277,7 @@ async function deployChanges() {
|
|
|
294
277
|
}
|
|
295
278
|
const to = mergeIntoParent ? parent : current;
|
|
296
279
|
const from = mergeIntoParent ? current : parent;
|
|
297
|
-
await deploy(deployable.kind, deployable.path, to, from, itemKey
|
|
280
|
+
await deploy(deployable.kind, deployable.path, to, from, itemKey);
|
|
298
281
|
if (deploymentStatus[itemKey]?.status === 'failed') {
|
|
299
282
|
anyFailed = true;
|
|
300
283
|
}
|
|
@@ -330,12 +313,17 @@ function toggleKey(key) {
|
|
|
330
313
|
}
|
|
331
314
|
}
|
|
332
315
|
function selectDefault() {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
316
|
+
// Triggers and schedules are opt-in: they often share runtime state with the
|
|
317
|
+
// parent (kafka group_id, postgres replication slot, schedule firing time)
|
|
318
|
+
// and pushing them by default would surprise users running a routine "Deploy
|
|
319
|
+
// to parent" flow. The user picks them à la carte by clicking the row.
|
|
320
|
+
const filtered = selectableDiffs.filter((d) => !isTriggerOrScheduleKind(d.kind));
|
|
321
|
+
const conflictSafe = mergeIntoParent
|
|
322
|
+
? filtered
|
|
323
|
+
: filtered.filter((d) => !(d.ahead > 0 && d.behind > 0));
|
|
324
|
+
selectedItems = conflictSafe
|
|
325
|
+
.map((d) => getItemKey(d))
|
|
326
|
+
.filter((k) => !(deploymentStatus[k]?.status == 'deployed'));
|
|
339
327
|
}
|
|
340
328
|
function toggleDeploymentDirection(v) {
|
|
341
329
|
deselectAll();
|
|
@@ -386,14 +374,11 @@ $effect(() => {
|
|
|
386
374
|
[selectedItems, mergeIntoParent];
|
|
387
375
|
allowBehindChangesOverride = false;
|
|
388
376
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
// Transform diffs + fork triggers to deployable item format for the
|
|
393
|
-
// shared layout. Triggers render as inline rows alongside diff items;
|
|
394
|
-
// they carry no ahead/behind info and are selectable à la carte.
|
|
377
|
+
// Trigger and schedule rows now flow through `comparison.diffs` like every
|
|
378
|
+
// other deployable kind — the backend's `compareWorkspaces` populates them
|
|
379
|
+
// from `workspace_diff`, with runtime fields ignored by `compare_two_*`.
|
|
395
380
|
let deployableItems = $derived.by(() => {
|
|
396
|
-
|
|
381
|
+
return (comparison?.diffs ?? [])
|
|
397
382
|
.filter((diff) => {
|
|
398
383
|
const key = getItemKey(diff);
|
|
399
384
|
const isSelectable = selectableDiffs.includes(diff);
|
|
@@ -404,25 +389,8 @@ let deployableItems = $derived.by(() => {
|
|
|
404
389
|
key: getItemKey(diff),
|
|
405
390
|
path: diff.path,
|
|
406
391
|
kind: diff.kind,
|
|
407
|
-
diff
|
|
408
|
-
trigger: undefined
|
|
392
|
+
diff
|
|
409
393
|
}));
|
|
410
|
-
const triggerItems = forkTriggers
|
|
411
|
-
.filter((t) => {
|
|
412
|
-
if (!isTriggerRelevantForDirection(t, mergeIntoParent))
|
|
413
|
-
return false;
|
|
414
|
-
const key = getTriggerKey(t);
|
|
415
|
-
return deploymentStatus[key]?.status !== 'deployed';
|
|
416
|
-
})
|
|
417
|
-
.map((trigger) => ({
|
|
418
|
-
key: getTriggerKey(trigger),
|
|
419
|
-
path: trigger.path,
|
|
420
|
-
kind: 'trigger',
|
|
421
|
-
triggerKind: trigger.triggerKind,
|
|
422
|
-
diff: undefined,
|
|
423
|
-
trigger
|
|
424
|
-
}));
|
|
425
|
-
return [...diffItems, ...triggerItems];
|
|
426
394
|
});
|
|
427
395
|
let ciTestResults = $state({});
|
|
428
396
|
async function fetchCiTests() {
|
|
@@ -475,268 +443,22 @@ let allCiTests = $derived.by(() => {
|
|
|
475
443
|
}
|
|
476
444
|
return [...seen.values()];
|
|
477
445
|
});
|
|
478
|
-
let forkTriggers = $state([]);
|
|
479
446
|
let deploymentRequestPanel = $state(undefined);
|
|
480
447
|
let hasOpenDeploymentRequest = $state(false);
|
|
481
|
-
/**
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
routes: {
|
|
495
|
-
list: (ws) => HttpTriggerService.listHttpTriggers({ workspace: ws }),
|
|
496
|
-
normalize: (item) => ({
|
|
497
|
-
path: item.path,
|
|
498
|
-
triggerKind: 'routes',
|
|
499
|
-
scriptPath: item.script_path,
|
|
500
|
-
isFlow: item.is_flow,
|
|
501
|
-
extraLabel: `${(item.http_method ?? 'get').toUpperCase()} ${item.route_path ?? ''}`
|
|
502
|
-
})
|
|
503
|
-
},
|
|
504
|
-
websockets: {
|
|
505
|
-
list: (ws) => WebsocketTriggerService.listWebsocketTriggers({ workspace: ws }),
|
|
506
|
-
normalize: (item) => ({
|
|
507
|
-
path: item.path,
|
|
508
|
-
triggerKind: 'websockets',
|
|
509
|
-
scriptPath: item.script_path,
|
|
510
|
-
isFlow: item.is_flow,
|
|
511
|
-
extraLabel: item.url,
|
|
512
|
-
raw: item
|
|
513
|
-
})
|
|
514
|
-
},
|
|
515
|
-
kafka: {
|
|
516
|
-
list: (ws) => KafkaTriggerService.listKafkaTriggers({ workspace: ws }),
|
|
517
|
-
normalize: (item) => ({
|
|
518
|
-
path: item.path,
|
|
519
|
-
triggerKind: 'kafka',
|
|
520
|
-
scriptPath: item.script_path,
|
|
521
|
-
isFlow: item.is_flow,
|
|
522
|
-
extraLabel: item.topics?.join(', '),
|
|
523
|
-
raw: item
|
|
524
|
-
})
|
|
525
|
-
},
|
|
526
|
-
postgres: {
|
|
527
|
-
list: (ws) => PostgresTriggerService.listPostgresTriggers({ workspace: ws }),
|
|
528
|
-
normalize: (item) => ({
|
|
529
|
-
path: item.path,
|
|
530
|
-
triggerKind: 'postgres',
|
|
531
|
-
scriptPath: item.script_path,
|
|
532
|
-
isFlow: item.is_flow,
|
|
533
|
-
raw: item
|
|
534
|
-
})
|
|
535
|
-
},
|
|
536
|
-
nats: {
|
|
537
|
-
list: (ws) => NatsTriggerService.listNatsTriggers({ workspace: ws }),
|
|
538
|
-
normalize: (item) => ({
|
|
539
|
-
path: item.path,
|
|
540
|
-
triggerKind: 'nats',
|
|
541
|
-
scriptPath: item.script_path,
|
|
542
|
-
isFlow: item.is_flow,
|
|
543
|
-
extraLabel: item.subjects?.join(', '),
|
|
544
|
-
raw: item
|
|
545
|
-
})
|
|
546
|
-
},
|
|
547
|
-
mqtt: {
|
|
548
|
-
list: (ws) => MqttTriggerService.listMqttTriggers({ workspace: ws }),
|
|
549
|
-
normalize: (item) => ({
|
|
550
|
-
path: item.path,
|
|
551
|
-
triggerKind: 'mqtt',
|
|
552
|
-
scriptPath: item.script_path,
|
|
553
|
-
isFlow: item.is_flow,
|
|
554
|
-
raw: item
|
|
555
|
-
})
|
|
556
|
-
},
|
|
557
|
-
sqs: {
|
|
558
|
-
list: (ws) => SqsTriggerService.listSqsTriggers({ workspace: ws }),
|
|
559
|
-
normalize: (item) => ({
|
|
560
|
-
path: item.path,
|
|
561
|
-
triggerKind: 'sqs',
|
|
562
|
-
scriptPath: item.script_path,
|
|
563
|
-
isFlow: item.is_flow,
|
|
564
|
-
extraLabel: item.queue_url,
|
|
565
|
-
raw: item
|
|
566
|
-
})
|
|
567
|
-
},
|
|
568
|
-
gcp: {
|
|
569
|
-
list: (ws) => GcpTriggerService.listGcpTriggers({ workspace: ws }),
|
|
570
|
-
normalize: (item) => ({
|
|
571
|
-
path: item.path,
|
|
572
|
-
triggerKind: 'gcp',
|
|
573
|
-
scriptPath: item.script_path,
|
|
574
|
-
isFlow: item.is_flow,
|
|
575
|
-
extraLabel: item.topic_id,
|
|
576
|
-
raw: item
|
|
577
|
-
})
|
|
578
|
-
},
|
|
579
|
-
azure: {
|
|
580
|
-
list: (ws) => AzureTriggerService.listAzureTriggers({ workspace: ws }),
|
|
581
|
-
normalize: (item) => ({
|
|
582
|
-
path: item.path,
|
|
583
|
-
triggerKind: 'azure',
|
|
584
|
-
scriptPath: item.script_path,
|
|
585
|
-
isFlow: item.is_flow,
|
|
586
|
-
extraLabel: item.topic_name ?? item.scope_resource_id,
|
|
587
|
-
raw: item
|
|
588
|
-
})
|
|
589
|
-
},
|
|
590
|
-
emails: {
|
|
591
|
-
list: (ws) => EmailTriggerService.listEmailTriggers({ workspace: ws }),
|
|
592
|
-
normalize: (item) => ({
|
|
593
|
-
path: item.path,
|
|
594
|
-
triggerKind: 'emails',
|
|
595
|
-
scriptPath: item.script_path,
|
|
596
|
-
isFlow: item.is_flow,
|
|
597
|
-
extraLabel: getEmailAddress(item.local_part, item.workspaced_local_part, currentWorkspaceId, emailDomain ?? ''),
|
|
598
|
-
raw: item
|
|
599
|
-
})
|
|
600
|
-
}
|
|
448
|
+
/** Display labels for trigger/schedule kinds in the merge UI. */
|
|
449
|
+
const KIND_DISPLAY_NAMES = {
|
|
450
|
+
schedule: 'Schedule',
|
|
451
|
+
http_trigger: 'HTTP route',
|
|
452
|
+
websocket_trigger: 'Websocket trigger',
|
|
453
|
+
kafka_trigger: 'Kafka trigger',
|
|
454
|
+
nats_trigger: 'NATS trigger',
|
|
455
|
+
postgres_trigger: 'Postgres trigger',
|
|
456
|
+
mqtt_trigger: 'MQTT trigger',
|
|
457
|
+
sqs_trigger: 'SQS trigger',
|
|
458
|
+
gcp_trigger: 'GCP trigger',
|
|
459
|
+
azure_trigger: 'Azure trigger',
|
|
460
|
+
email_trigger: 'Email trigger'
|
|
601
461
|
};
|
|
602
|
-
let emailDomain = $state(undefined);
|
|
603
|
-
/**
|
|
604
|
-
* Fields that should not count as a "change" between the parent and the
|
|
605
|
-
* fork. Mode/enabled are forced to 'disabled'/false on clone and stripped
|
|
606
|
-
* by the fork-export filter; the rest are runtime state or per-row
|
|
607
|
-
* metadata that always diverges. Comparing without these matches the
|
|
608
|
-
* semantics of "is this trigger configured the same way?" rather than
|
|
609
|
-
* "are these two rows byte-identical?".
|
|
610
|
-
*/
|
|
611
|
-
const TRIGGER_COMPARE_IGNORE = new Set([
|
|
612
|
-
'workspace_id',
|
|
613
|
-
'mode',
|
|
614
|
-
'enabled',
|
|
615
|
-
'edited_at',
|
|
616
|
-
'edited_by',
|
|
617
|
-
'last_server_ping',
|
|
618
|
-
'server_id',
|
|
619
|
-
'error',
|
|
620
|
-
'extra_perms',
|
|
621
|
-
'permissioned_as'
|
|
622
|
-
]);
|
|
623
|
-
function stripIgnoredFields(row) {
|
|
624
|
-
if (!row || typeof row !== 'object')
|
|
625
|
-
return row;
|
|
626
|
-
const out = {};
|
|
627
|
-
for (const [k, v] of Object.entries(row)) {
|
|
628
|
-
if (!TRIGGER_COMPARE_IGNORE.has(k))
|
|
629
|
-
out[k] = v;
|
|
630
|
-
}
|
|
631
|
-
return out;
|
|
632
|
-
}
|
|
633
|
-
function rowsHaveSameConfig(a, b) {
|
|
634
|
-
return (orderedJsonStringify(stripIgnoredFields(a)) === orderedJsonStringify(stripIgnoredFields(b)));
|
|
635
|
-
}
|
|
636
|
-
async function fetchAllTriggers() {
|
|
637
|
-
try {
|
|
638
|
-
emailDomain = await getEmailDomain();
|
|
639
|
-
const entries = Object.entries(triggerServices);
|
|
640
|
-
// Fetch fork + parent in parallel for each kind. Either side may
|
|
641
|
-
// fail (e.g. permission denied on parent) — fall back to empty.
|
|
642
|
-
const results = await Promise.allSettled(entries.map(async ([kind, svc]) => {
|
|
643
|
-
const [forkItems, parentItems] = await Promise.all([
|
|
644
|
-
svc.list(currentWorkspaceId).catch(() => []),
|
|
645
|
-
svc.list(parentWorkspaceId).catch(() => [])
|
|
646
|
-
]);
|
|
647
|
-
const byPath = new Map();
|
|
648
|
-
for (const item of forkItems) {
|
|
649
|
-
byPath.set(item.path, { fork: item });
|
|
650
|
-
}
|
|
651
|
-
for (const item of parentItems) {
|
|
652
|
-
const entry = byPath.get(item.path) ?? {};
|
|
653
|
-
entry.parent = item;
|
|
654
|
-
byPath.set(item.path, entry);
|
|
655
|
-
}
|
|
656
|
-
const merged = [];
|
|
657
|
-
for (const [path, entry] of byPath) {
|
|
658
|
-
const sourceItem = entry.fork ?? entry.parent;
|
|
659
|
-
const normalized = svc.normalize(sourceItem);
|
|
660
|
-
let changeKind;
|
|
661
|
-
let hasChanges = false;
|
|
662
|
-
if (entry.fork && !entry.parent) {
|
|
663
|
-
changeKind = 'new';
|
|
664
|
-
}
|
|
665
|
-
else if (!entry.fork && entry.parent) {
|
|
666
|
-
changeKind = 'deleted-in-source';
|
|
667
|
-
}
|
|
668
|
-
else if (entry.fork && entry.parent) {
|
|
669
|
-
hasChanges = !rowsHaveSameConfig(entry.fork, entry.parent);
|
|
670
|
-
if (hasChanges)
|
|
671
|
-
changeKind = 'modified';
|
|
672
|
-
}
|
|
673
|
-
merged.push({
|
|
674
|
-
...normalized,
|
|
675
|
-
raw: sourceItem,
|
|
676
|
-
hasChanges,
|
|
677
|
-
changeKind,
|
|
678
|
-
sourceRaw: entry.fork,
|
|
679
|
-
targetRaw: entry.parent,
|
|
680
|
-
path
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
return merged;
|
|
684
|
-
}));
|
|
685
|
-
forkTriggers = results.flatMap((r) => (r.status === 'fulfilled' ? r.value : []));
|
|
686
|
-
}
|
|
687
|
-
catch (e) {
|
|
688
|
-
console.error('Failed to fetch fork triggers:', e);
|
|
689
|
-
forkTriggers = [];
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Triggers worth showing in the merge UI given the current direction.
|
|
694
|
-
* - "Deploy to parent": rows that exist in fork and either don't exist in
|
|
695
|
-
* parent or have config differences.
|
|
696
|
-
* - "Update current" (pull from parent): mirror.
|
|
697
|
-
* Triggers that exist on both sides with identical config are filtered
|
|
698
|
-
* out — they would generate a no-op deploy and only add noise.
|
|
699
|
-
*/
|
|
700
|
-
function isTriggerRelevantForDirection(t, deployingToParent) {
|
|
701
|
-
const existsInFork = !!t.sourceRaw;
|
|
702
|
-
const existsInParent = !!t.targetRaw;
|
|
703
|
-
if (deployingToParent) {
|
|
704
|
-
return existsInFork && (!existsInParent || !!t.hasChanges);
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
return existsInParent && (!existsInFork || !!t.hasChanges);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
function getTriggerDisplayName(triggerKind) {
|
|
711
|
-
const triggerType = triggerKindToTriggerType(triggerKind);
|
|
712
|
-
return triggerType ? triggerDisplayNamesMap[triggerType] : triggerKind;
|
|
713
|
-
}
|
|
714
|
-
let triggerDiffOpen = $state(false);
|
|
715
|
-
let triggerDiffPayload = $state(undefined);
|
|
716
|
-
function openTriggerDiff(t) {
|
|
717
|
-
// `sourceRaw` is the fork row, `targetRaw` is the parent row regardless
|
|
718
|
-
// of direction (set in fetchAllTriggers). The diff reads from the
|
|
719
|
-
// destination (left) to the source (right), matching the deploy arrow.
|
|
720
|
-
const sourceWorkspace = mergeIntoParent ? currentWorkspaceId : parentWorkspaceId;
|
|
721
|
-
const targetWorkspace = mergeIntoParent ? parentWorkspaceId : currentWorkspaceId;
|
|
722
|
-
const fromRow = mergeIntoParent ? t.sourceRaw : t.targetRaw;
|
|
723
|
-
const toRow = mergeIntoParent ? t.targetRaw : t.sourceRaw;
|
|
724
|
-
triggerDiffPayload = {
|
|
725
|
-
kindLabel: getTriggerDisplayName(t.triggerKind),
|
|
726
|
-
path: t.path,
|
|
727
|
-
originalLabel: `${targetWorkspace} (target)`,
|
|
728
|
-
modifiedLabel: `${sourceWorkspace} (source)`,
|
|
729
|
-
original: orderedYamlStringify(stripIgnoredFields(toRow ?? {})),
|
|
730
|
-
modified: orderedYamlStringify(stripIgnoredFields(fromRow ?? {}))
|
|
731
|
-
};
|
|
732
|
-
triggerDiffOpen = true;
|
|
733
|
-
}
|
|
734
|
-
// Fetch triggers when workspace is available
|
|
735
|
-
$effect(() => {
|
|
736
|
-
if (currentWorkspaceId) {
|
|
737
|
-
fetchAllTriggers();
|
|
738
|
-
}
|
|
739
|
-
});
|
|
740
462
|
</script>
|
|
741
463
|
|
|
742
464
|
{#if $workspaceStore != currentWorkspaceId}
|
|
@@ -760,8 +482,7 @@ $effect(() => {
|
|
|
760
482
|
items={deployableItems}
|
|
761
483
|
{selectedItems}
|
|
762
484
|
{deploymentStatus}
|
|
763
|
-
selectablePredicate={(item) =>
|
|
764
|
-
item.trigger != null || selectableDiffs.some((d) => getItemKey(d) === item.key)}
|
|
485
|
+
selectablePredicate={(item) => selectableDiffs.some((d) => getItemKey(d) === item.key)}
|
|
765
486
|
{allSelected}
|
|
766
487
|
onToggleItem={(item) => toggleKey(item.key)}
|
|
767
488
|
onSelectAll={selectAll}
|
|
@@ -935,17 +656,15 @@ $effect(() => {
|
|
|
935
656
|
{/snippet}
|
|
936
657
|
|
|
937
658
|
{#snippet itemSummary(item)}
|
|
938
|
-
{
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
659
|
+
{@const diff = item.diff as WorkspaceItemDiff}
|
|
660
|
+
{@const key = item.key}
|
|
661
|
+
{#if isTriggerOrScheduleKind(diff.kind)}
|
|
662
|
+
<span class="text-emphasis">
|
|
663
|
+
{KIND_DISPLAY_NAMES[diff.kind as string] ?? diff.kind}
|
|
664
|
+
</span>
|
|
944
665
|
<span class="text-tertiary mx-1">→</span>
|
|
945
|
-
<span class="text-secondary">{
|
|
666
|
+
<span class="text-secondary">{diff.path}</span>
|
|
946
667
|
{:else}
|
|
947
|
-
{@const diff = item.diff as WorkspaceItemDiff}
|
|
948
|
-
{@const key = item.key}
|
|
949
668
|
{@const isSelectable = selectableDiffs.includes(diff)}
|
|
950
669
|
{@const oldSummary = mergeIntoParent
|
|
951
670
|
? summaryCache[key]?.parent
|
|
@@ -969,140 +688,102 @@ $effect(() => {
|
|
|
969
688
|
{/snippet}
|
|
970
689
|
|
|
971
690
|
{#snippet itemActions(item)}
|
|
972
|
-
{
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
691
|
+
{@const diff = item.diff as WorkspaceItemDiff}
|
|
692
|
+
{@const key = item.key}
|
|
693
|
+
{@const targetOnBehalfOf = getTargetOnBehalfOf(key)}
|
|
694
|
+
{@const isConflict = diff.ahead > 0 && diff.behind > 0}
|
|
695
|
+
{@const existsInBothWorkspaces = !(
|
|
696
|
+
(diff.exists_in_fork && !diff.exists_in_source) ||
|
|
697
|
+
(!diff.exists_in_fork && diff.exists_in_source)
|
|
698
|
+
)}
|
|
699
|
+
<!-- On-behalf-of selector -->
|
|
700
|
+
{#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
|
|
701
|
+
<OnBehalfOfSelector
|
|
702
|
+
targetWorkspace={deployTargetWorkspace}
|
|
703
|
+
targetValue={targetOnBehalfOf}
|
|
704
|
+
selected={onBehalfOfChoice[key]}
|
|
705
|
+
onSelect={(choice, details) => {
|
|
706
|
+
onBehalfOfChoice[key] = choice
|
|
707
|
+
if (details) customOnBehalfOf[key] = details
|
|
708
|
+
}}
|
|
709
|
+
kind={diff.kind}
|
|
710
|
+
canPreserve={canPreserveOnBehalfOf}
|
|
711
|
+
customValue={customOnBehalfOf[key]?.permissionedAs}
|
|
712
|
+
/>
|
|
713
|
+
{/if}
|
|
714
|
+
{#if diff.kind === 'raw_app'}
|
|
715
|
+
<Badge small icon={{ icon: FileJson }}>Raw</Badge>
|
|
716
|
+
{/if}
|
|
717
|
+
<!-- Status badges -->
|
|
718
|
+
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
|
|
719
|
+
<Badge
|
|
720
|
+
title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
|
|
721
|
+
color="indigo"
|
|
722
|
+
size="xs">New</Badge
|
|
723
|
+
>
|
|
724
|
+
{/if}
|
|
725
|
+
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
|
|
726
|
+
<Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
|
|
727
|
+
>Deleted</Badge
|
|
728
|
+
>
|
|
729
|
+
{/if}
|
|
730
|
+
{#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
|
|
731
|
+
<Badge
|
|
732
|
+
title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
|
|
733
|
+
color="red"
|
|
734
|
+
size="xs">Deleted</Badge
|
|
735
|
+
>
|
|
736
|
+
{/if}
|
|
737
|
+
{#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
|
|
738
|
+
<Badge
|
|
739
|
+
title="This item was newly created in '{currentWorkspaceId}'"
|
|
740
|
+
color="indigo"
|
|
741
|
+
size="xs">New</Badge
|
|
742
|
+
>
|
|
743
|
+
{/if}
|
|
744
|
+
{@const ciStatus = getCiTestStatus(diff)}
|
|
745
|
+
{#if ciStatus === 'pass'}
|
|
746
|
+
<Badge color="green" size="xs"><CircleCheck size={10} class="mr-0.5" />CI pass</Badge>
|
|
747
|
+
{:else if ciStatus === 'fail'}
|
|
748
|
+
<Badge color="red" size="xs"><CircleX size={10} class="mr-0.5" />CI fail</Badge>
|
|
749
|
+
{:else if ciStatus === 'running'}
|
|
750
|
+
<Badge color="yellow" size="xs"
|
|
751
|
+
><Loader2 size={10} class="mr-0.5 animate-spin" />CI</Badge
|
|
752
|
+
>
|
|
753
|
+
{/if}
|
|
754
|
+
{#if !deploymentStatus[key] || deploymentStatus[key].status != 'deployed'}
|
|
755
|
+
<div class="flex items-center gap-2">
|
|
756
|
+
{#if isConflict || existsInBothWorkspaces}
|
|
757
|
+
{#if diff.ahead > 0}
|
|
758
|
+
<Badge color="green" size="xs">
|
|
759
|
+
<ArrowUpRight class="w-3 h-3 inline" />
|
|
760
|
+
{diff.ahead} ahead
|
|
761
|
+
</Badge>
|
|
762
|
+
{/if}
|
|
763
|
+
{#if diff.behind > 0}
|
|
764
|
+
<Badge color="blue" size="xs">
|
|
765
|
+
<ArrowDownRight class="w-3 h-3 inline" />
|
|
766
|
+
{diff.behind} behind
|
|
767
|
+
</Badge>
|
|
768
|
+
{/if}
|
|
769
|
+
{#if isConflict}
|
|
770
|
+
<Badge color="orange" size="xs">
|
|
771
|
+
<AlertTriangle class="w-3 h-3 inline" />
|
|
772
|
+
Conflict
|
|
773
|
+
</Badge>
|
|
774
|
+
{/if}
|
|
1006
775
|
{/if}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
{@const existsInBothWorkspaces = !(
|
|
1014
|
-
(diff.exists_in_fork && !diff.exists_in_source) ||
|
|
1015
|
-
(!diff.exists_in_fork && diff.exists_in_source)
|
|
1016
|
-
)}
|
|
1017
|
-
<!-- On-behalf-of selector -->
|
|
1018
|
-
{#if itemNeedsOnBehalfOfSelection(key, diff.kind)}
|
|
1019
|
-
<OnBehalfOfSelector
|
|
1020
|
-
targetWorkspace={deployTargetWorkspace}
|
|
1021
|
-
targetValue={targetOnBehalfOf}
|
|
1022
|
-
selected={onBehalfOfChoice[key]}
|
|
1023
|
-
onSelect={(choice, details) => {
|
|
1024
|
-
onBehalfOfChoice[key] = choice
|
|
1025
|
-
if (details) customOnBehalfOf[key] = details
|
|
1026
|
-
}}
|
|
1027
|
-
kind={diff.kind}
|
|
1028
|
-
canPreserve={canPreserveOnBehalfOf}
|
|
1029
|
-
customValue={customOnBehalfOf[key]?.permissionedAs}
|
|
1030
|
-
/>
|
|
1031
|
-
{/if}
|
|
1032
|
-
{#if diff.kind === 'raw_app'}
|
|
1033
|
-
<Badge small icon={{ icon: FileJson }}>Raw</Badge>
|
|
1034
|
-
{/if}
|
|
1035
|
-
<!-- Status badges -->
|
|
1036
|
-
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead == 0 && diff.behind > 0}
|
|
1037
|
-
<Badge
|
|
1038
|
-
title="This item was newly created in the parent workspace '{parentWorkspaceId}'"
|
|
1039
|
-
color="indigo"
|
|
1040
|
-
size="xs">New</Badge
|
|
1041
|
-
>
|
|
1042
|
-
{/if}
|
|
1043
|
-
{#if !diff.exists_in_fork && diff.exists_in_source && diff.ahead > 0}
|
|
1044
|
-
<Badge title="This item was deleted in '{currentWorkspaceId}'" color="red" size="xs"
|
|
1045
|
-
>Deleted</Badge
|
|
1046
|
-
>
|
|
1047
|
-
{/if}
|
|
1048
|
-
{#if diff.exists_in_fork && !diff.exists_in_source && diff.behind > 0}
|
|
1049
|
-
<Badge
|
|
1050
|
-
title="This item was deleted in the parent workspace '{parentWorkspaceId}'"
|
|
1051
|
-
color="red"
|
|
1052
|
-
size="xs">Deleted</Badge
|
|
1053
|
-
>
|
|
1054
|
-
{/if}
|
|
1055
|
-
{#if diff.exists_in_fork && !diff.exists_in_source && diff.ahead > 0 && diff.behind == 0}
|
|
1056
|
-
<Badge
|
|
1057
|
-
title="This item was newly created in '{currentWorkspaceId}'"
|
|
1058
|
-
color="indigo"
|
|
1059
|
-
size="xs">New</Badge
|
|
1060
|
-
>
|
|
1061
|
-
{/if}
|
|
1062
|
-
{@const ciStatus = getCiTestStatus(diff)}
|
|
1063
|
-
{#if ciStatus === 'pass'}
|
|
1064
|
-
<Badge color="green" size="xs"><CircleCheck size={10} class="mr-0.5" />CI pass</Badge>
|
|
1065
|
-
{:else if ciStatus === 'fail'}
|
|
1066
|
-
<Badge color="red" size="xs"><CircleX size={10} class="mr-0.5" />CI fail</Badge>
|
|
1067
|
-
{:else if ciStatus === 'running'}
|
|
1068
|
-
<Badge color="yellow" size="xs"
|
|
1069
|
-
><Loader2 size={10} class="mr-0.5 animate-spin" />CI</Badge
|
|
776
|
+
</div>
|
|
777
|
+
<div class:invisible={!existsInBothWorkspaces}>
|
|
778
|
+
<Button
|
|
779
|
+
size="xs"
|
|
780
|
+
variant="subtle"
|
|
781
|
+
onclick={() => showDiff(diff.kind as Kind, diff.path)}
|
|
1070
782
|
>
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
{#if diff.ahead > 0}
|
|
1076
|
-
<Badge color="green" size="xs">
|
|
1077
|
-
<ArrowUpRight class="w-3 h-3 inline" />
|
|
1078
|
-
{diff.ahead} ahead
|
|
1079
|
-
</Badge>
|
|
1080
|
-
{/if}
|
|
1081
|
-
{#if diff.behind > 0}
|
|
1082
|
-
<Badge color="blue" size="xs">
|
|
1083
|
-
<ArrowDownRight class="w-3 h-3 inline" />
|
|
1084
|
-
{diff.behind} behind
|
|
1085
|
-
</Badge>
|
|
1086
|
-
{/if}
|
|
1087
|
-
{#if isConflict}
|
|
1088
|
-
<Badge color="orange" size="xs">
|
|
1089
|
-
<AlertTriangle class="w-3 h-3 inline" />
|
|
1090
|
-
Conflict
|
|
1091
|
-
</Badge>
|
|
1092
|
-
{/if}
|
|
1093
|
-
{/if}
|
|
1094
|
-
</div>
|
|
1095
|
-
<div class:invisible={!existsInBothWorkspaces}>
|
|
1096
|
-
<Button
|
|
1097
|
-
size="xs"
|
|
1098
|
-
variant="subtle"
|
|
1099
|
-
onclick={() => showDiff(diff.kind as Kind, diff.path)}
|
|
1100
|
-
>
|
|
1101
|
-
<DiffIcon class="w-3 h-3" />
|
|
1102
|
-
Show diff
|
|
1103
|
-
</Button>
|
|
1104
|
-
</div>
|
|
1105
|
-
{/if}
|
|
783
|
+
<DiffIcon class="w-3 h-3" />
|
|
784
|
+
Show diff
|
|
785
|
+
</Button>
|
|
786
|
+
</div>
|
|
1106
787
|
{/if}
|
|
1107
788
|
{/snippet}
|
|
1108
789
|
|
|
@@ -1185,31 +866,6 @@ $effect(() => {
|
|
|
1185
866
|
</div>
|
|
1186
867
|
|
|
1187
868
|
<DiffDrawer bind:this={diffDrawer} {isFlow} />
|
|
1188
|
-
|
|
1189
|
-
<Drawer bind:open={triggerDiffOpen} size="900px">
|
|
1190
|
-
<DrawerContent
|
|
1191
|
-
title={triggerDiffPayload
|
|
1192
|
-
? `${triggerDiffPayload.kindLabel} ${triggerDiffPayload.path}`
|
|
1193
|
-
: 'Trigger diff'}
|
|
1194
|
-
on:close={() => (triggerDiffOpen = false)}
|
|
1195
|
-
>
|
|
1196
|
-
{#if triggerDiffPayload}
|
|
1197
|
-
<div class="flex flex-col h-full">
|
|
1198
|
-
<div class="flex-1 min-h-0">
|
|
1199
|
-
<DiffEditor
|
|
1200
|
-
open={triggerDiffOpen}
|
|
1201
|
-
className="!h-full"
|
|
1202
|
-
defaultLang="yaml"
|
|
1203
|
-
defaultOriginal={triggerDiffPayload.original}
|
|
1204
|
-
defaultModified={triggerDiffPayload.modified}
|
|
1205
|
-
readOnly
|
|
1206
|
-
inlineDiff={false}
|
|
1207
|
-
/>
|
|
1208
|
-
</div>
|
|
1209
|
-
</div>
|
|
1210
|
-
{/if}
|
|
1211
|
-
</DrawerContent>
|
|
1212
|
-
</Drawer>
|
|
1213
869
|
{:else}
|
|
1214
870
|
<div class="flex items-center justify-center h-full">
|
|
1215
871
|
<div class="text-gray-500">No comparison data available</div>
|