@tutti-os/workspace-app-center 0.0.12 → 0.0.13
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/{chunk-PD2WLRHE.js → chunk-7BJAJ7F3.js} +1 -1
- package/dist/chunk-7BJAJ7F3.js.map +1 -0
- package/dist/{chunk-O3XCZVHE.js → chunk-DPJRK63W.js} +203 -31
- package/dist/chunk-DPJRK63W.js.map +1 -0
- package/dist/contracts/index.d.ts +7 -3
- package/dist/contracts/index.js +1 -1
- package/dist/core/index.d.ts +8 -3
- package/dist/core/index.js +1 -1
- package/dist/i18n/index.js +115 -147
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-DT5o9P2u.d.ts → index-Clfpl59g.d.ts} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/ui/index.d.ts +3 -2
- package/dist/ui/index.js +228 -109
- package/dist/ui/index.js.map +1 -1
- package/dist/{viewModel-BpgU7_M1.d.ts → viewModel-D_kMlhKv.d.ts} +13 -1
- package/package.json +3 -3
- package/dist/chunk-O3XCZVHE.js.map +0 -1
- package/dist/chunk-PD2WLRHE.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contracts/runtime.ts"],"sourcesContent":["export const workspaceAppRuntimeStatuses = [\n \"idle\",\n \"installing\",\n \"preparing\",\n \"starting\",\n \"running\",\n \"failed\",\n \"stopping\",\n \"unavailable\"\n] as const;\n\nexport type WorkspaceAppRuntimeStatus =\n (typeof workspaceAppRuntimeStatuses)[number];\n\nexport interface WorkspaceAppRuntimeError {\n readonly code?: string;\n readonly message: string;\n}\n\nexport type WorkspaceAppInstallUserPhase =\n | \"downloading\"\n | \"installing\"\n | \"starting\";\n\nexport interface WorkspaceAppInstallProgress {\n readonly userPhase: WorkspaceAppInstallUserPhase;\n readonly overallPercent: number;\n readonly downloadedBytes?: number | null;\n readonly totalBytes?: number | null;\n readonly indeterminate: boolean;\n}\n\nexport interface WorkspaceAppRuntimeState {\n readonly runtimeId?: string;\n readonly installationId?: string;\n readonly appId: string;\n readonly status: WorkspaceAppRuntimeStatus;\n readonly launchUrl?: string | null;\n readonly installProgress?: WorkspaceAppInstallProgress | null;\n readonly error?: WorkspaceAppRuntimeError | null;\n readonly startedAt?: string | null;\n readonly updatedAt?: string | null;\n}\n"],"mappings":";AAAO,IAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|
|
@@ -30,13 +30,25 @@ function mergeWorkspaceAppCatalogFields(currentApp, snapshotApp) {
|
|
|
30
30
|
updateAvailable: snapshotApp.updateAvailable
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
function areWorkspaceAppInstallProgressEqual(left, right) {
|
|
34
|
+
if (left == null && right == null) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (left == null || right == null) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return left.userPhase === right.userPhase && left.overallPercent === right.overallPercent && left.downloadedBytes === right.downloadedBytes && left.totalBytes === right.totalBytes && left.indeterminate === right.indeterminate;
|
|
41
|
+
}
|
|
33
42
|
function areWorkspaceAppCenterAppsEqual(left, right) {
|
|
34
43
|
if (left.length !== right.length) {
|
|
35
44
|
return false;
|
|
36
45
|
}
|
|
37
46
|
return left.every((leftApp, index) => {
|
|
38
47
|
const rightApp = right[index];
|
|
39
|
-
return rightApp !== void 0 && leftApp.appId === rightApp.appId && leftApp.availableIconUrl === rightApp.availableIconUrl && leftApp.availableVersion === rightApp.availableVersion && leftApp.createdAtUnixMs === rightApp.createdAtUnixMs && leftApp.description === rightApp.description && leftApp.enabled === rightApp.enabled && leftApp.exportable === rightApp.exportable && leftApp.iconUrl === rightApp.iconUrl && leftApp.installed === rightApp.installed &&
|
|
48
|
+
return rightApp !== void 0 && leftApp.appId === rightApp.appId && leftApp.availableIconUrl === rightApp.availableIconUrl && leftApp.availableVersion === rightApp.availableVersion && leftApp.createdAtUnixMs === rightApp.createdAtUnixMs && leftApp.description === rightApp.description && leftApp.enabled === rightApp.enabled && leftApp.exportable === rightApp.exportable && leftApp.iconUrl === rightApp.iconUrl && leftApp.installed === rightApp.installed && areWorkspaceAppInstallProgressEqual(
|
|
49
|
+
leftApp.installProgress,
|
|
50
|
+
rightApp.installProgress
|
|
51
|
+
) && leftApp.installationId === rightApp.installationId && areWorkspaceAppCenterLocalizationsEqual(
|
|
40
52
|
leftApp.localizations ?? [],
|
|
41
53
|
rightApp.localizations ?? []
|
|
42
54
|
) && leftApp.minimizeBehavior === rightApp.minimizeBehavior && leftApp.name === rightApp.name && leftApp.references.listSupported === rightApp.references.listSupported && leftApp.runtimeId === rightApp.runtimeId && leftApp.runtimeStatus === rightApp.runtimeStatus && leftApp.source === rightApp.source && leftApp.stateRevision === rightApp.stateRevision && areStringArraysEqual(leftApp.tags ?? [], rightApp.tags ?? []) && (leftApp.updateAvailable ?? false) === (rightApp.updateAvailable ?? false) && leftApp.launchUrl === rightApp.launchUrl && leftApp.version === rightApp.version && leftApp.windowMinHeight === rightApp.windowMinHeight && leftApp.windowMinWidth === rightApp.windowMinWidth;
|
|
@@ -276,6 +288,85 @@ var WorkspaceAppCenterControllerBase = class {
|
|
|
276
288
|
}
|
|
277
289
|
};
|
|
278
290
|
|
|
291
|
+
// src/core/installProgressMerge.ts
|
|
292
|
+
var installUserPhaseOrder = {
|
|
293
|
+
downloading: 0,
|
|
294
|
+
installing: 1,
|
|
295
|
+
starting: 2
|
|
296
|
+
};
|
|
297
|
+
var defaultDownloadCompletePercent = 70;
|
|
298
|
+
var defaultInstallingPartialPercent = 79;
|
|
299
|
+
var defaultStartingPartialPercent = 96;
|
|
300
|
+
function reconcilePendingInstallProgress(input) {
|
|
301
|
+
const runtimePhase = runtimeStatusToInstallUserPhase(input.runtimeStatus);
|
|
302
|
+
const progress = input.incoming ?? input.previous ?? (runtimePhase == null ? null : createProgressForRuntimePhase(runtimePhase));
|
|
303
|
+
if (progress == null) {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
if (runtimePhase == null) {
|
|
307
|
+
return clearDownloadBytesUnlessDownloading(progress);
|
|
308
|
+
}
|
|
309
|
+
if (compareInstallUserPhase(progress.userPhase, runtimePhase) >= 0) {
|
|
310
|
+
return clearDownloadBytesUnlessDownloading(progress);
|
|
311
|
+
}
|
|
312
|
+
return advanceInstallProgressToPhase(progress, runtimePhase);
|
|
313
|
+
}
|
|
314
|
+
function runtimeStatusToInstallUserPhase(runtimeStatus) {
|
|
315
|
+
switch (runtimeStatus) {
|
|
316
|
+
case "preparing":
|
|
317
|
+
return "installing";
|
|
318
|
+
case "starting":
|
|
319
|
+
return "starting";
|
|
320
|
+
default:
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function compareInstallUserPhase(left, right) {
|
|
325
|
+
return installUserPhaseOrder[left] - installUserPhaseOrder[right];
|
|
326
|
+
}
|
|
327
|
+
function advanceInstallProgressToPhase(progress, targetPhase) {
|
|
328
|
+
let overallPercent = progress.overallPercent;
|
|
329
|
+
let userPhase = progress.userPhase;
|
|
330
|
+
if (targetPhase === "installing" || targetPhase === "starting") {
|
|
331
|
+
overallPercent = Math.max(overallPercent, defaultDownloadCompletePercent);
|
|
332
|
+
userPhase = "installing";
|
|
333
|
+
}
|
|
334
|
+
if (targetPhase === "starting") {
|
|
335
|
+
overallPercent = Math.max(overallPercent, defaultStartingPartialPercent);
|
|
336
|
+
userPhase = "starting";
|
|
337
|
+
} else if (targetPhase === "installing") {
|
|
338
|
+
overallPercent = Math.max(overallPercent, defaultInstallingPartialPercent);
|
|
339
|
+
}
|
|
340
|
+
return clearDownloadBytesUnlessDownloading({
|
|
341
|
+
...progress,
|
|
342
|
+
indeterminate: false,
|
|
343
|
+
overallPercent,
|
|
344
|
+
userPhase
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function createProgressForRuntimePhase(userPhase) {
|
|
348
|
+
return advanceInstallProgressToPhase(
|
|
349
|
+
{
|
|
350
|
+
downloadedBytes: null,
|
|
351
|
+
indeterminate: false,
|
|
352
|
+
overallPercent: 0,
|
|
353
|
+
totalBytes: null,
|
|
354
|
+
userPhase: "downloading"
|
|
355
|
+
},
|
|
356
|
+
userPhase
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
function clearDownloadBytesUnlessDownloading(progress) {
|
|
360
|
+
if (progress.userPhase === "downloading") {
|
|
361
|
+
return progress;
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
...progress,
|
|
365
|
+
downloadedBytes: null,
|
|
366
|
+
totalBytes: null
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
279
370
|
// src/core/appCenterControllerState.ts
|
|
280
371
|
var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControllerBase {
|
|
281
372
|
applySnapshot(workspaceId, snapshot) {
|
|
@@ -371,11 +462,16 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
371
462
|
return;
|
|
372
463
|
}
|
|
373
464
|
const appIdsToClose = currentApp?.installed === true && !nextApp.installed ? [nextApp.appId] : [];
|
|
465
|
+
const mergedApp = this.mergeActiveInstallAppState(
|
|
466
|
+
workspaceId,
|
|
467
|
+
nextApp,
|
|
468
|
+
currentApp
|
|
469
|
+
);
|
|
374
470
|
const nextApps = sortWorkspaceAppCenterApps([
|
|
375
471
|
...this.store.apps.filter(
|
|
376
472
|
(candidate) => candidate.appId !== nextApp.appId
|
|
377
473
|
),
|
|
378
|
-
|
|
474
|
+
mergedApp
|
|
379
475
|
]);
|
|
380
476
|
if (areWorkspaceAppCenterAppsEqual(this.store.apps, nextApps)) {
|
|
381
477
|
return;
|
|
@@ -385,8 +481,8 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
385
481
|
this.store.loadStatus = "ready";
|
|
386
482
|
this.bumpRevision();
|
|
387
483
|
this.settlePendingInstallReport({
|
|
388
|
-
app:
|
|
389
|
-
failureReason: options.installFailureReason ??
|
|
484
|
+
app: mergedApp,
|
|
485
|
+
failureReason: options.installFailureReason ?? mergedApp.failureReason ?? mergedApp.lastError ?? null,
|
|
390
486
|
workspaceId
|
|
391
487
|
});
|
|
392
488
|
this.closeWorkspaceAppViews(workspaceId, appIdsToClose);
|
|
@@ -495,15 +591,24 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
495
591
|
this.bumpRevision();
|
|
496
592
|
}
|
|
497
593
|
}
|
|
498
|
-
isPendingInstallSettled(installKey, app) {
|
|
594
|
+
isPendingInstallSettled(installKey, app, previousApp) {
|
|
595
|
+
if (this.isPendingInstallAbandoned(installKey, app, previousApp)) {
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
499
598
|
if (app.runtimeStatus === "failed") {
|
|
500
599
|
return true;
|
|
501
600
|
}
|
|
601
|
+
if (this.isRuntimeInstallBusy(app.runtimeStatus)) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
502
604
|
if (this.pendingInstallReportKeys.has(installKey)) {
|
|
503
605
|
return app.installed;
|
|
504
606
|
}
|
|
505
607
|
return app.installed && !app.updateAvailable && !app.availableVersion;
|
|
506
608
|
}
|
|
609
|
+
isRuntimeInstallBusy(runtimeStatus) {
|
|
610
|
+
return runtimeStatus === "installing" || runtimeStatus === "preparing" || runtimeStatus === "starting";
|
|
611
|
+
}
|
|
507
612
|
mergeSnapshotAppsByStateRevision(workspaceId, snapshotApps) {
|
|
508
613
|
if (this.store.workspaceId !== workspaceId) {
|
|
509
614
|
return [...snapshotApps];
|
|
@@ -520,7 +625,8 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
520
625
|
if (this.pendingInstallKeys.has(installKey)) {
|
|
521
626
|
const pendingSettled = this.isPendingInstallSettled(
|
|
522
627
|
installKey,
|
|
523
|
-
snapshotApp
|
|
628
|
+
snapshotApp,
|
|
629
|
+
currentApp
|
|
524
630
|
);
|
|
525
631
|
if (pendingSettled && currentApp.stateRevision <= snapshotApp.stateRevision) {
|
|
526
632
|
return snapshotApp;
|
|
@@ -545,22 +651,50 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
545
651
|
void this.refresh(workspaceId);
|
|
546
652
|
}, this.dependencies.catalogLoadingRefreshDelayMs ?? defaultCatalogLoadingRefreshDelayMs);
|
|
547
653
|
}
|
|
654
|
+
mergeActiveInstallAppState(workspaceId, app, previousApp) {
|
|
655
|
+
const installKey = appRuntimeKey(workspaceId, app.appId);
|
|
656
|
+
if (!this.pendingInstallKeys.has(installKey)) {
|
|
657
|
+
return app;
|
|
658
|
+
}
|
|
659
|
+
if (this.isPendingInstallSettled(installKey, app, previousApp)) {
|
|
660
|
+
return app;
|
|
661
|
+
}
|
|
662
|
+
const incomingRuntimeStatus = app.runtimeStatus;
|
|
663
|
+
const runtimeStatus = this.isRuntimeInstallLifecycleStatus(
|
|
664
|
+
incomingRuntimeStatus
|
|
665
|
+
) ? incomingRuntimeStatus : "installing";
|
|
666
|
+
return {
|
|
667
|
+
...app,
|
|
668
|
+
enabled: true,
|
|
669
|
+
installed: this.pendingInstallReportKeys.has(installKey) ? false : app.installed,
|
|
670
|
+
installProgress: reconcilePendingInstallProgress({
|
|
671
|
+
incoming: app.installProgress,
|
|
672
|
+
previous: previousApp?.installProgress ?? null,
|
|
673
|
+
runtimeStatus: incomingRuntimeStatus
|
|
674
|
+
}),
|
|
675
|
+
runtimeStatus
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
isRuntimeInstallLifecycleStatus(runtimeStatus) {
|
|
679
|
+
return runtimeStatus === "installing" || runtimeStatus === "preparing" || runtimeStatus === "starting";
|
|
680
|
+
}
|
|
681
|
+
isPendingInstallAbandoned(installKey, app, previousApp) {
|
|
682
|
+
return this.pendingInstallReportKeys.has(installKey) && !app.installed && app.runtimeStatus === "idle" && app.installProgress == null && this.hasObservedInstallActivity(previousApp);
|
|
683
|
+
}
|
|
684
|
+
hasObservedInstallActivity(app) {
|
|
685
|
+
return app?.installProgress != null || app?.runtimeStatus === "preparing" || app?.runtimeStatus === "starting";
|
|
686
|
+
}
|
|
548
687
|
withPendingInstallState(workspaceId, apps) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
enabled: true,
|
|
560
|
-
installed: this.pendingInstallReportKeys.has(installKey) ? false : app.installed,
|
|
561
|
-
runtimeStatus: "installing"
|
|
562
|
-
};
|
|
563
|
-
});
|
|
688
|
+
const previousAppsById = new Map(
|
|
689
|
+
this.store.apps.map((app) => [app.appId, app])
|
|
690
|
+
);
|
|
691
|
+
return apps.map(
|
|
692
|
+
(app) => this.mergeActiveInstallAppState(
|
|
693
|
+
workspaceId,
|
|
694
|
+
app,
|
|
695
|
+
previousAppsById.get(app.appId)
|
|
696
|
+
)
|
|
697
|
+
);
|
|
564
698
|
}
|
|
565
699
|
async refreshInstallState(workspaceId, appId) {
|
|
566
700
|
try {
|
|
@@ -595,6 +729,9 @@ var WorkspaceAppCenterControllerState = class extends WorkspaceAppCenterControll
|
|
|
595
729
|
this.dependencies.hooks?.onAppInstalled?.(input.app);
|
|
596
730
|
return;
|
|
597
731
|
}
|
|
732
|
+
if (input.app.runtimeStatus === "idle" && input.app.installProgress == null && input.failureReason == null && input.app.failureReason == null && input.app.lastError == null) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
598
735
|
this.dependencies.hooks?.onAppInstallFailed?.({
|
|
599
736
|
app: input.app,
|
|
600
737
|
appId: input.app.appId,
|
|
@@ -954,11 +1091,16 @@ var WorkspaceAppCenterController = class extends WorkspaceAppCenterControllerSta
|
|
|
954
1091
|
this.pendingInstallKeys.add(installKey);
|
|
955
1092
|
this.markAppInstalling(input.appId, { preserveInstalled: true });
|
|
956
1093
|
try {
|
|
1094
|
+
const restartRunning = app?.installed === true && app.runtimeStatus === "running";
|
|
957
1095
|
const snapshot = await this.dependencies.gateway.installWorkspaceApp(
|
|
958
1096
|
input.workspaceId,
|
|
959
|
-
input.appId
|
|
1097
|
+
input.appId,
|
|
1098
|
+
restartRunning ? { restartRunning: true } : void 0
|
|
960
1099
|
);
|
|
961
1100
|
this.applySnapshot(input.workspaceId, snapshot);
|
|
1101
|
+
if (restartRunning) {
|
|
1102
|
+
this.closeWorkspaceAppViews(input.workspaceId, [input.appId]);
|
|
1103
|
+
}
|
|
962
1104
|
this.dependencies.hooks?.onAppUpdated?.({
|
|
963
1105
|
app,
|
|
964
1106
|
trigger: input.trigger
|
|
@@ -1600,9 +1742,11 @@ function createAppCenterViewModel({
|
|
|
1600
1742
|
manifest: app.manifest
|
|
1601
1743
|
});
|
|
1602
1744
|
const factoryAgentSessionId = factoryJob?.agentSessionId?.trim() || null;
|
|
1603
|
-
const
|
|
1745
|
+
const factoryEditAction = factoryJob && factoryAgentSessionId ? factoryJob.status === "published" ? "prepare_modification" : "open_session" : null;
|
|
1746
|
+
const status = resolveRuntimeStatusForViewModel(runtime);
|
|
1604
1747
|
const presentation = resolveWorkspaceAppStatusPresentation(status);
|
|
1605
1748
|
const installed = Boolean(app.install);
|
|
1749
|
+
const installBusy = runtime?.installProgress != null || status === "installing";
|
|
1606
1750
|
const sourceKind = resolveCatalogSourceKind(app.catalog);
|
|
1607
1751
|
const localApp = sourceKind === "local";
|
|
1608
1752
|
const runtimeId = normalizeOptionalString(runtime?.runtimeId);
|
|
@@ -1624,6 +1768,7 @@ function createAppCenterViewModel({
|
|
|
1624
1768
|
installed,
|
|
1625
1769
|
status
|
|
1626
1770
|
});
|
|
1771
|
+
const iconUrl = resolveWorkspaceAppIconUrl(app);
|
|
1627
1772
|
return {
|
|
1628
1773
|
id: app.manifest.appId,
|
|
1629
1774
|
installationId,
|
|
@@ -1636,30 +1781,37 @@ function createAppCenterViewModel({
|
|
|
1636
1781
|
...app.availableVersion && !comingSoon ? { availableVersion: app.availableVersion } : {},
|
|
1637
1782
|
...app.category?.trim() ? { category: app.category.trim() } : {},
|
|
1638
1783
|
updateAvailable: app.updateAvailable ?? false,
|
|
1639
|
-
...
|
|
1784
|
+
...iconUrl ? {
|
|
1785
|
+
icon: {
|
|
1786
|
+
type: "asset",
|
|
1787
|
+
src: iconUrl
|
|
1788
|
+
}
|
|
1789
|
+
} : {},
|
|
1640
1790
|
tags: metadata.tags,
|
|
1641
1791
|
installed,
|
|
1642
1792
|
status,
|
|
1643
1793
|
statusLabelKey: comingSoon ? "status.comingSoon" : resolvePrimaryActionLabelKey(primaryAction, presentation.labelKey),
|
|
1644
1794
|
statusTone: presentation.tone,
|
|
1645
|
-
statusPulse: presentation.pulse,
|
|
1795
|
+
statusPulse: runtime?.installProgress ? false : presentation.pulse,
|
|
1646
1796
|
primaryAction,
|
|
1647
1797
|
sourceKind,
|
|
1648
1798
|
canOpen,
|
|
1649
1799
|
canExport: localApp,
|
|
1650
1800
|
canDelete: localApp,
|
|
1651
1801
|
canReplaceIcon: replaceableIconAppIdSet.has(app.manifest.appId),
|
|
1652
|
-
canOpenFolder: installed,
|
|
1653
|
-
canOpenPackageFolder: installed && localApp && Boolean(displayVersion),
|
|
1802
|
+
canOpenFolder: installed && !installBusy,
|
|
1803
|
+
canOpenPackageFolder: installed && localApp && Boolean(displayVersion) && !installBusy,
|
|
1654
1804
|
canOpenFactorySession: Boolean(factoryAgentSessionId),
|
|
1655
1805
|
canPublishFactoryUpdate: installed && factoryJob?.status === "ready" && Boolean(factoryJob.publishedVersion?.trim()),
|
|
1656
|
-
canUninstall: installed,
|
|
1806
|
+
canUninstall: installed && !installBusy,
|
|
1657
1807
|
canRetry,
|
|
1658
1808
|
canUpdate,
|
|
1659
1809
|
...factoryAgentSessionId ? { factoryAgentSessionId } : {},
|
|
1810
|
+
...factoryEditAction ? { factoryEditAction } : {},
|
|
1660
1811
|
...factoryJob?.jobId ? { factoryJobId: factoryJob.jobId } : {},
|
|
1661
1812
|
...factoryJob?.provider ? { factoryProvider: factoryJob.provider } : {},
|
|
1662
|
-
...runtime?.error?.message ? { errorMessage: runtime.error.message } : {}
|
|
1813
|
+
...runtime?.error?.message ? { errorMessage: runtime.error.message } : {},
|
|
1814
|
+
...runtime?.installProgress ? { installProgress: runtime.installProgress } : {}
|
|
1663
1815
|
};
|
|
1664
1816
|
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
1665
1817
|
return {
|
|
@@ -1677,7 +1829,8 @@ function createRuntimeStateMaps(runtimeStates) {
|
|
|
1677
1829
|
for (const state of runtimeStates) {
|
|
1678
1830
|
const runtime = {
|
|
1679
1831
|
...state,
|
|
1680
|
-
status: mapWorkspaceAppRuntimeStatus(state.status)
|
|
1832
|
+
status: mapWorkspaceAppRuntimeStatus(state.status),
|
|
1833
|
+
installProgress: state.installProgress ?? null
|
|
1681
1834
|
};
|
|
1682
1835
|
const installationId = normalizeOptionalString(runtime.installationId);
|
|
1683
1836
|
if (installationId) {
|
|
@@ -1703,6 +1856,15 @@ function findRuntimeStateForApp(maps, appId, installationId) {
|
|
|
1703
1856
|
}
|
|
1704
1857
|
return maps.fallbackByAppId.get(appId);
|
|
1705
1858
|
}
|
|
1859
|
+
function resolveRuntimeStatusForViewModel(runtime) {
|
|
1860
|
+
if (!runtime) {
|
|
1861
|
+
return "idle";
|
|
1862
|
+
}
|
|
1863
|
+
if (runtime.installProgress != null && runtime.status === "idle") {
|
|
1864
|
+
return "installing";
|
|
1865
|
+
}
|
|
1866
|
+
return runtime.status;
|
|
1867
|
+
}
|
|
1706
1868
|
function resolveCatalogSourceKind(catalog) {
|
|
1707
1869
|
return catalog?.source?.kind ?? "bundled";
|
|
1708
1870
|
}
|
|
@@ -1749,6 +1911,16 @@ function normalizeOptionalString(value) {
|
|
|
1749
1911
|
const normalized = value?.trim() ?? "";
|
|
1750
1912
|
return normalized.length > 0 ? normalized : null;
|
|
1751
1913
|
}
|
|
1914
|
+
function resolveWorkspaceAppIconUrl(app) {
|
|
1915
|
+
const manifestIconUrl = normalizeOptionalString(app.manifest.icon?.src);
|
|
1916
|
+
if (manifestIconUrl && isResolvedIconUrl(manifestIconUrl)) {
|
|
1917
|
+
return manifestIconUrl;
|
|
1918
|
+
}
|
|
1919
|
+
return normalizeOptionalString(app.availableIconUrl) ?? manifestIconUrl;
|
|
1920
|
+
}
|
|
1921
|
+
function isResolvedIconUrl(value) {
|
|
1922
|
+
return /^[a-z][a-z0-9+.-]*:/iu.test(value) || value.startsWith("/");
|
|
1923
|
+
}
|
|
1752
1924
|
function resolvePrimaryAction(input) {
|
|
1753
1925
|
if (input.comingSoon) {
|
|
1754
1926
|
return "none";
|
|
@@ -1869,4 +2041,4 @@ export {
|
|
|
1869
2041
|
resolveWorkspaceAppCatalogMetadata,
|
|
1870
2042
|
createWorkspaceAppRecord
|
|
1871
2043
|
};
|
|
1872
|
-
//# sourceMappingURL=chunk-
|
|
2044
|
+
//# sourceMappingURL=chunk-DPJRK63W.js.map
|