@loomweaver/shell 0.7.6 → 0.7.7
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/fesm2022/loomweaver-shell.mjs +37 -11
- package/fesm2022/loomweaver-shell.mjs.map +1 -1
- package/i18n/de.json +3 -3
- package/i18n/en.json +2 -2
- package/package.json +2 -2
|
@@ -4300,6 +4300,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
4300
4300
|
type: Service
|
|
4301
4301
|
}], ctorParameters: () => [] });
|
|
4302
4302
|
|
|
4303
|
+
function popoutNavigationRefusal(path) {
|
|
4304
|
+
return (`Content navigation to "${path}" was ignored: this is a pop-out window, which shows one ` +
|
|
4305
|
+
`surface and has no content area to navigate. A command reaches a pop-out's palette only ` +
|
|
4306
|
+
`if it declares popout: true, so leave that off anything that navigates.`);
|
|
4307
|
+
}
|
|
4308
|
+
|
|
4303
4309
|
class OpenTabsService {
|
|
4304
4310
|
router = inject(Router);
|
|
4305
4311
|
registry = inject(ContributionRegistry);
|
|
@@ -4438,9 +4444,11 @@ class OpenTabsService {
|
|
|
4438
4444
|
this.paneTree.hydrated();
|
|
4439
4445
|
untracked(() => {
|
|
4440
4446
|
if (url !== this.lastUrl) {
|
|
4447
|
+
const previous = this.lastUrl;
|
|
4441
4448
|
this.lastUrl = url;
|
|
4442
4449
|
if (this.ownNavigation !== normalizePath(url)) {
|
|
4443
4450
|
this.viewTabSelection.set(null);
|
|
4451
|
+
this.focusHolderOf(path, this.rootFor(previous).root);
|
|
4444
4452
|
}
|
|
4445
4453
|
this.ownNavigation = null;
|
|
4446
4454
|
}
|
|
@@ -4459,14 +4467,12 @@ class OpenTabsService {
|
|
|
4459
4467
|
navigate(path) {
|
|
4460
4468
|
if (this.inPopout) {
|
|
4461
4469
|
if (isDevMode()) {
|
|
4462
|
-
console.warn(
|
|
4463
|
-
`surface and has no content area to navigate. A command reaches a pop-out's palette only ` +
|
|
4464
|
-
`if it declares popout: true, so leave that off anything that navigates.`);
|
|
4470
|
+
console.warn(popoutNavigationRefusal(path));
|
|
4465
4471
|
}
|
|
4466
4472
|
return Promise.resolve(false);
|
|
4467
4473
|
}
|
|
4468
4474
|
const target = normalizePath(path);
|
|
4469
|
-
this.focusHolderOf(target);
|
|
4475
|
+
this.focusHolderOf(target, this.activeTabRoot());
|
|
4470
4476
|
this.ownNavigation = target;
|
|
4471
4477
|
this.viewTabSelection.set(null);
|
|
4472
4478
|
return this.router.navigateByUrl('/' + target + suffixOf(path));
|
|
@@ -4522,7 +4528,7 @@ class OpenTabsService {
|
|
|
4522
4528
|
return (owner.rest === true ||
|
|
4523
4529
|
segmentsOf(owner.path).length === segmentsOf(address).length);
|
|
4524
4530
|
}
|
|
4525
|
-
focusHolderOf(target) {
|
|
4531
|
+
focusHolderOf(target, previousContent) {
|
|
4526
4532
|
const routes = this.registry.contentRoutes();
|
|
4527
4533
|
const root = tabRootOf(routes, target);
|
|
4528
4534
|
if (root === '') {
|
|
@@ -4540,7 +4546,7 @@ class OpenTabsService {
|
|
|
4540
4546
|
return;
|
|
4541
4547
|
}
|
|
4542
4548
|
this.paneTree.setActiveTab(CONTENT_DOCK, holder.id, held.path);
|
|
4543
|
-
this.paneTree.focusPane(CONTENT_DOCK, holder.id,
|
|
4549
|
+
this.paneTree.focusPane(CONTENT_DOCK, holder.id, previousContent);
|
|
4544
4550
|
}
|
|
4545
4551
|
stampActive(root) {
|
|
4546
4552
|
const next = new Map(this.lastActive());
|
|
@@ -11363,7 +11369,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImpor
|
|
|
11363
11369
|
// GENERATED — do not edit by hand.
|
|
11364
11370
|
// Written by tools/stamp-version.mjs from <Version> in Directory.Build.props.
|
|
11365
11371
|
// Single source of truth: Directory.Build.props (bump via scripts/bump-version.sh).
|
|
11366
|
-
const APP_VERSION = '0.7.
|
|
11372
|
+
const APP_VERSION = '0.7.7';
|
|
11367
11373
|
|
|
11368
11374
|
/**
|
|
11369
11375
|
* The running build's version, sourced from `<Version>` in Directory.Build.props
|
|
@@ -13861,6 +13867,8 @@ class CommandPalette {
|
|
|
13861
13867
|
? 'tabs'
|
|
13862
13868
|
: 'commands', /* @ts-ignore */
|
|
13863
13869
|
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
13870
|
+
title = computed(() => this.mode() === 'tabs' ? 'palette.quickOpenTitle' : 'palette.title', /* @ts-ignore */
|
|
13871
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
13864
13872
|
query = signal('', /* @ts-ignore */
|
|
13865
13873
|
...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
|
|
13866
13874
|
rawIndex = signal(0, /* @ts-ignore */
|
|
@@ -14026,11 +14034,11 @@ class CommandPalette {
|
|
|
14026
14034
|
}
|
|
14027
14035
|
}
|
|
14028
14036
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CommandPalette, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14029
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: CommandPalette, isStandalone: true, selector: "lw-command-palette", ngImport: i0, template: "<div class=\"flex max-h-[60vh] w-full flex-col overflow-hidden\">\n <div class=\"flex items-center gap-2 border-b border-border px-4\">\n <lw-icon name=\"search\" size=\"1.1rem\" class=\"text-content-muted\" />\n <input\n data-lw-autofocus\n type=\"text\"\n role=\"combobox\"\n aria-controls=\"lw-palette-list\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"
|
|
14037
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: CommandPalette, isStandalone: true, selector: "lw-command-palette", ngImport: i0, template: "<div class=\"flex max-h-[60vh] w-full flex-col overflow-hidden\">\n <div class=\"flex items-center gap-2 border-b border-border px-4\">\n <lw-icon name=\"search\" size=\"1.1rem\" class=\"text-content-muted\" />\n <input\n data-lw-autofocus\n type=\"text\"\n role=\"combobox\"\n aria-controls=\"lw-palette-list\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"title() | transloco\"\n [value]=\"query()\"\n [placeholder]=\"\n (mode() === 'tabs' ? 'palette.tabsPlaceholder' : 'palette.placeholder')\n | transloco\n \"\n class=\"flex-1 bg-transparent py-3 text-sm text-content outline-none placeholder:text-content-faint\"\n (input)=\"onQuery($event)\"\n (keydown.arrowdown)=\"move($event, 1)\"\n (keydown.arrowup)=\"move($event, -1)\"\n (keydown.arrowright)=\"openTabActions($event)\"\n (keydown.enter)=\"runActive($event)\"\n />\n </div>\n\n <ul\n id=\"lw-palette-list\"\n role=\"listbox\"\n class=\"min-h-0 flex-1 overflow-y-auto p-1\"\n >\n @for (entry of results(); track entry.id; let i = $index) {\n @if (recentCount() > 0 && i === 0) {\n <li\n role=\"presentation\"\n data-testid=\"palette-section-recent\"\n class=\"px-3 pt-2 pb-1 text-xs font-medium text-content-faint\"\n >\n {{ 'palette.recent' | transloco }}\n </li>\n }\n @if (recentCount() > 0 && i === recentCount()) {\n <li\n role=\"presentation\"\n data-testid=\"palette-section-all\"\n class=\"px-3 pt-2 pb-1 text-xs font-medium text-content-faint\"\n >\n {{ 'palette.all' | transloco }}\n </li>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"i === activeIndex()\"\n class=\"flex cursor-pointer items-center gap-3 rounded-md px-3 py-2 text-sm\"\n [class]=\"\n i === activeIndex()\n ? 'bg-brand/10 text-brand-text'\n : 'text-content hover:bg-surface-overlay'\n \"\n (click)=\"select(entry)\"\n (mouseenter)=\"setActive(i)\"\n >\n @if (entry.icon; as icon) {\n <lw-icon [name]=\"icon\" size=\"1rem\" class=\"text-content-muted\" />\n }\n <span class=\"flex-1 truncate\">{{ entry.label }}</span>\n @if (timeOf(entry); as time) {\n <span class=\"shrink-0 text-xs text-content-faint\">{{ time }}</span>\n }\n @if (shortcutOf(entry); as shortcut) {\n <kbd\n class=\"rounded border border-border px-1.5 py-0.5 text-xs text-content-muted\"\n >{{ shortcut }}</kbd\n >\n }\n </li>\n } @empty {\n <li class=\"px-3 py-6 text-center text-sm text-content-muted\">\n {{\n (mode() === 'tabs' ? 'palette.tabsEmpty' : 'palette.empty') | transloco\n }}\n </li>\n }\n </ul>\n\n <div\n data-testid=\"palette-footer\"\n class=\"flex items-center gap-4 border-t border-border px-4 py-2 text-xs text-content-faint\"\n >\n <span class=\"flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u2191\u2193</kbd>\n {{ 'palette.hint.navigate' | transloco }}\n </span>\n <span class=\"flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u21B5</kbd>\n {{ 'palette.hint.run' | transloco }}\n </span>\n @if (mode() === 'tabs') {\n <span class=\"flex items-center gap-1.5\" data-testid=\"palette-hint-actions\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u2192</kbd>\n {{ 'palette.hint.actions' | transloco }}\n </span>\n }\n <span class=\"ml-auto flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">Esc</kbd>\n {{ 'palette.hint.close' | transloco }}\n </span>\n </div>\n</div>\n", dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
14030
14038
|
}
|
|
14031
14039
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: CommandPalette, decorators: [{
|
|
14032
14040
|
type: Component,
|
|
14033
|
-
args: [{ selector: 'lw-command-palette', schemas: [CUSTOM_ELEMENTS_SCHEMA], imports: [TranslocoPipe], template: "<div class=\"flex max-h-[60vh] w-full flex-col overflow-hidden\">\n <div class=\"flex items-center gap-2 border-b border-border px-4\">\n <lw-icon name=\"search\" size=\"1.1rem\" class=\"text-content-muted\" />\n <input\n data-lw-autofocus\n type=\"text\"\n role=\"combobox\"\n aria-controls=\"lw-palette-list\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"
|
|
14041
|
+
args: [{ selector: 'lw-command-palette', schemas: [CUSTOM_ELEMENTS_SCHEMA], imports: [TranslocoPipe], template: "<div class=\"flex max-h-[60vh] w-full flex-col overflow-hidden\">\n <div class=\"flex items-center gap-2 border-b border-border px-4\">\n <lw-icon name=\"search\" size=\"1.1rem\" class=\"text-content-muted\" />\n <input\n data-lw-autofocus\n type=\"text\"\n role=\"combobox\"\n aria-controls=\"lw-palette-list\"\n [attr.aria-expanded]=\"true\"\n [attr.aria-activedescendant]=\"activeId()\"\n [attr.aria-label]=\"title() | transloco\"\n [value]=\"query()\"\n [placeholder]=\"\n (mode() === 'tabs' ? 'palette.tabsPlaceholder' : 'palette.placeholder')\n | transloco\n \"\n class=\"flex-1 bg-transparent py-3 text-sm text-content outline-none placeholder:text-content-faint\"\n (input)=\"onQuery($event)\"\n (keydown.arrowdown)=\"move($event, 1)\"\n (keydown.arrowup)=\"move($event, -1)\"\n (keydown.arrowright)=\"openTabActions($event)\"\n (keydown.enter)=\"runActive($event)\"\n />\n </div>\n\n <ul\n id=\"lw-palette-list\"\n role=\"listbox\"\n class=\"min-h-0 flex-1 overflow-y-auto p-1\"\n >\n @for (entry of results(); track entry.id; let i = $index) {\n @if (recentCount() > 0 && i === 0) {\n <li\n role=\"presentation\"\n data-testid=\"palette-section-recent\"\n class=\"px-3 pt-2 pb-1 text-xs font-medium text-content-faint\"\n >\n {{ 'palette.recent' | transloco }}\n </li>\n }\n @if (recentCount() > 0 && i === recentCount()) {\n <li\n role=\"presentation\"\n data-testid=\"palette-section-all\"\n class=\"px-3 pt-2 pb-1 text-xs font-medium text-content-faint\"\n >\n {{ 'palette.all' | transloco }}\n </li>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"i === activeIndex()\"\n class=\"flex cursor-pointer items-center gap-3 rounded-md px-3 py-2 text-sm\"\n [class]=\"\n i === activeIndex()\n ? 'bg-brand/10 text-brand-text'\n : 'text-content hover:bg-surface-overlay'\n \"\n (click)=\"select(entry)\"\n (mouseenter)=\"setActive(i)\"\n >\n @if (entry.icon; as icon) {\n <lw-icon [name]=\"icon\" size=\"1rem\" class=\"text-content-muted\" />\n }\n <span class=\"flex-1 truncate\">{{ entry.label }}</span>\n @if (timeOf(entry); as time) {\n <span class=\"shrink-0 text-xs text-content-faint\">{{ time }}</span>\n }\n @if (shortcutOf(entry); as shortcut) {\n <kbd\n class=\"rounded border border-border px-1.5 py-0.5 text-xs text-content-muted\"\n >{{ shortcut }}</kbd\n >\n }\n </li>\n } @empty {\n <li class=\"px-3 py-6 text-center text-sm text-content-muted\">\n {{\n (mode() === 'tabs' ? 'palette.tabsEmpty' : 'palette.empty') | transloco\n }}\n </li>\n }\n </ul>\n\n <div\n data-testid=\"palette-footer\"\n class=\"flex items-center gap-4 border-t border-border px-4 py-2 text-xs text-content-faint\"\n >\n <span class=\"flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u2191\u2193</kbd>\n {{ 'palette.hint.navigate' | transloco }}\n </span>\n <span class=\"flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u21B5</kbd>\n {{ 'palette.hint.run' | transloco }}\n </span>\n @if (mode() === 'tabs') {\n <span class=\"flex items-center gap-1.5\" data-testid=\"palette-hint-actions\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">\u2192</kbd>\n {{ 'palette.hint.actions' | transloco }}\n </span>\n }\n <span class=\"ml-auto flex items-center gap-1.5\">\n <kbd class=\"rounded border border-border px-1 py-0.5\">Esc</kbd>\n {{ 'palette.hint.close' | transloco }}\n </span>\n </div>\n</div>\n" }]
|
|
14034
14042
|
}] });
|
|
14035
14043
|
|
|
14036
14044
|
class WorkspaceDialog {
|
|
@@ -14264,7 +14272,12 @@ function seedHostCommands(registry, layout, deps) {
|
|
|
14264
14272
|
shortcut: 'mod+k',
|
|
14265
14273
|
popout: true,
|
|
14266
14274
|
run: () => {
|
|
14267
|
-
dialogs.open(CommandPalette, {
|
|
14275
|
+
dialogs.open(CommandPalette, {
|
|
14276
|
+
bare: true,
|
|
14277
|
+
size: 'lg',
|
|
14278
|
+
align: 'top',
|
|
14279
|
+
title: 'palette.title',
|
|
14280
|
+
});
|
|
14268
14281
|
},
|
|
14269
14282
|
});
|
|
14270
14283
|
registry.addCommand({
|
|
@@ -14289,6 +14302,7 @@ function seedHostCommands(registry, layout, deps) {
|
|
|
14289
14302
|
bare: true,
|
|
14290
14303
|
size: 'lg',
|
|
14291
14304
|
align: 'top',
|
|
14305
|
+
title: 'palette.quickOpenTitle',
|
|
14292
14306
|
data: { mode: 'tabs' },
|
|
14293
14307
|
});
|
|
14294
14308
|
},
|
|
@@ -14801,6 +14815,16 @@ function accessCanMatch(access) {
|
|
|
14801
14815
|
};
|
|
14802
14816
|
}
|
|
14803
14817
|
|
|
14818
|
+
const keepPopout = (_route, state) => {
|
|
14819
|
+
if (!isPopoutUrl(inject(BootAddress).path)) {
|
|
14820
|
+
return true;
|
|
14821
|
+
}
|
|
14822
|
+
if (isDevMode()) {
|
|
14823
|
+
console.warn(popoutNavigationRefusal(normalizePath(state.url)));
|
|
14824
|
+
}
|
|
14825
|
+
return false;
|
|
14826
|
+
};
|
|
14827
|
+
|
|
14804
14828
|
const settleWorkspace = async (_route, state) => {
|
|
14805
14829
|
const claims = inject(WORKSPACE_CLAIMS);
|
|
14806
14830
|
await claims.settle(normalizePath(state.url));
|
|
@@ -14841,6 +14865,7 @@ function buildContentRoutes(contentRoutes, omitted = [], retention = 'destroy')
|
|
|
14841
14865
|
const placeholders = omitted.map((route) => ({
|
|
14842
14866
|
path: route.path,
|
|
14843
14867
|
component: RouteUnavailableView,
|
|
14868
|
+
canActivate: [keepPopout],
|
|
14844
14869
|
data: { content: true, routePlaceholder: true },
|
|
14845
14870
|
}));
|
|
14846
14871
|
return [...buildRegisteredRoutes(contentRoutes, retention), ...placeholders];
|
|
@@ -14886,7 +14911,7 @@ function buildRegisteredRoutes(contentRoutes, retention) {
|
|
|
14886
14911
|
const angular = {
|
|
14887
14912
|
path: route.path,
|
|
14888
14913
|
...surfaceRoute(route, retained),
|
|
14889
|
-
canActivate: [settleWorkspace],
|
|
14914
|
+
canActivate: [keepPopout, settleWorkspace],
|
|
14890
14915
|
data: {
|
|
14891
14916
|
content: true,
|
|
14892
14917
|
chromeless: route.chromeless,
|
|
@@ -14905,6 +14930,7 @@ function buildRegisteredRoutes(contentRoutes, retention) {
|
|
|
14905
14930
|
const placeholder = {
|
|
14906
14931
|
path: route.path,
|
|
14907
14932
|
component: AuthRequiredView,
|
|
14933
|
+
canActivate: [keepPopout],
|
|
14908
14934
|
data: {
|
|
14909
14935
|
content: true,
|
|
14910
14936
|
authPlaceholder: true,
|