Skip to content

Commit 0210e94

Browse files
Folder Workspace: Support menu expansion and breadcrumbs (closes #20675) (#20712)
* add menu context and breadcrumbs for document type folders * add menu context and breadcrumbs for media type folders * add menu context and breadcrumbs for media type folders * add menu context and breadcrumbs for partial view folders * add menu context and breadcrumbs for partial view folders * add menu context and breadcrumbs for script folders * Register menu structure workspace contexts and breadcrumbs for document blueprints * fix menu alias * remove from blueprints * fix wrong path when navigating from an inner folder to an outer * remove debugger * fix structure link between variant to invariant * fix up path generation --------- Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
1 parent bbc0f1f commit 0210e94

File tree

13 files changed

+270
-38
lines changed

13 files changed

+270
-38
lines changed

src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-tree-structure-workspace-context-base.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex
3535
#ancestorContext = new UmbAncestorsEntityContext(this);
3636
#sectionSidebarMenuContext?: typeof UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT.TYPE;
3737
#isModalContext: boolean = false;
38+
#isNew: boolean | undefined = undefined;
3839

3940
constructor(host: UmbControllerHost, args: UmbMenuTreeStructureWorkspaceContextBaseArgs) {
4041
super(host, UMB_MENU_STRUCTURE_WORKSPACE_CONTEXT);
@@ -52,15 +53,27 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex
5253

5354
this.consumeContext(UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT, (instance) => {
5455
this.#workspaceContext = instance;
55-
this.observe(this.#workspaceContext?.unique, (value) => {
56-
if (!value) return;
57-
this.#requestStructure();
58-
});
59-
60-
this.observe(this.#workspaceContext?.isNew, (value) => {
61-
if (value === undefined) return;
62-
this.#requestStructure();
63-
});
56+
this.observe(
57+
this.#workspaceContext?.unique,
58+
(value) => {
59+
if (!value) return;
60+
this.#requestStructure();
61+
},
62+
'observeUnique',
63+
);
64+
65+
this.observe(
66+
this.#workspaceContext?.isNew,
67+
(value) => {
68+
// Workspace has changed from new to existing
69+
if (value === false && this.#isNew === true) {
70+
// TODO: We do not need to request here as we already know the structure and unique
71+
this.#requestStructure();
72+
}
73+
this.#isNew = value;
74+
},
75+
'observeIsNew',
76+
);
6477
});
6578
}
6679

src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-variant-tree-structure-workspace-context-base.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { UmbAncestorsEntityContext, UmbParentEntityContext, type UmbEntityModel
1010
import {
1111
UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT,
1212
UMB_VARIANT_WORKSPACE_CONTEXT,
13+
UMB_WORKSPACE_PATH_PATTERN,
1314
} from '@umbraco-cms/backoffice/workspace';
1415
import { linkEntityExpansionEntries } from '@umbraco-cms/backoffice/utils';
1516
import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal';
@@ -83,19 +84,46 @@ export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends Um
8384
'observeUnique',
8485
);
8586

86-
this.observe(this.#workspaceContext?.isNew, (value) => {
87-
// Workspace has changed from new to existing
88-
if (value === false && this.#isNew === true) {
89-
// TODO: We do not need to request here as we already know the structure and unique
90-
this.#requestStructure();
91-
}
92-
this.#isNew = value;
93-
});
87+
this.observe(
88+
this.#workspaceContext?.isNew,
89+
(value) => {
90+
// Workspace has changed from new to existing
91+
if (value === false && this.#isNew === true) {
92+
// TODO: We do not need to request here as we already know the structure and unique
93+
this.#requestStructure();
94+
}
95+
this.#isNew = value;
96+
},
97+
'observeIsNew',
98+
);
9499
});
95100
}
96101

97102
getItemHref(structureItem: UmbVariantStructureItemModel): string | undefined {
98-
return `section/${this._sectionContext?.getPathname()}/workspace/${structureItem.entityType}/edit/${structureItem.unique}/${this.#workspaceActiveVariantId?.toCultureString()}`;
103+
const sectionName = this._sectionContext?.getPathname();
104+
if (!sectionName) {
105+
return undefined;
106+
}
107+
UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({
108+
sectionName,
109+
entityType: structureItem.entityType,
110+
});
111+
const path = `section/${this._sectionContext!.getPathname()}/workspace/${structureItem.entityType}/edit/${structureItem.unique}`;
112+
113+
// find related variant id from structure item:
114+
const itemVariantFit = structureItem.variants.find((variant) => {
115+
return (
116+
variant.culture === this.#workspaceActiveVariantId?.culture &&
117+
variant.segment === this.#workspaceActiveVariantId?.segment
118+
);
119+
});
120+
if (itemVariantFit) {
121+
const variantId = UmbVariantId.CreateFromPartial(itemVariantFit);
122+
return `${path}/${variantId.toString()}`;
123+
}
124+
125+
// If no related variantID, then lets the redirect go to the main-variant:
126+
return path;
99127
}
100128

101129
async #requestStructure() {

src/Umbraco.Web.UI.Client/src/packages/data-type/menu/manifests.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { UMB_DATA_TYPE_WORKSPACE_ALIAS } from '../workspace/constants.js';
2+
import { UMB_DATA_TYPE_FOLDER_WORKSPACE_ALIAS } from '../tree/constants.js';
13
import { UMB_DATA_TYPE_MENU_ITEM_ALIAS } from './constants.js';
24
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
35

@@ -27,7 +29,7 @@ export const manifests: Array<UmbExtensionManifest> = [
2729
conditions: [
2830
{
2931
alias: UMB_WORKSPACE_CONDITION_ALIAS,
30-
match: 'Umb.Workspace.DataType',
32+
match: UMB_DATA_TYPE_WORKSPACE_ALIAS,
3133
},
3234
],
3335
},
@@ -39,7 +41,35 @@ export const manifests: Array<UmbExtensionManifest> = [
3941
conditions: [
4042
{
4143
alias: UMB_WORKSPACE_CONDITION_ALIAS,
42-
match: 'Umb.Workspace.DataType',
44+
match: UMB_DATA_TYPE_WORKSPACE_ALIAS,
45+
},
46+
],
47+
},
48+
{
49+
type: 'workspaceContext',
50+
kind: 'menuStructure',
51+
name: 'Data Type Folder Menu Structure Workspace Context',
52+
alias: 'Umb.Context.DataTypeFolder.Menu.Structure',
53+
api: () => import('./data-type-menu-structure.context.js'),
54+
meta: {
55+
menuItemAlias: UMB_DATA_TYPE_MENU_ITEM_ALIAS,
56+
},
57+
conditions: [
58+
{
59+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
60+
match: UMB_DATA_TYPE_FOLDER_WORKSPACE_ALIAS,
61+
},
62+
],
63+
},
64+
{
65+
type: 'workspaceFooterApp',
66+
kind: 'menuBreadcrumb',
67+
alias: 'Umb.WorkspaceFooterApp.DataTypeFolder.Breadcrumb',
68+
name: 'Data Type Folder Breadcrumb Workspace Footer App',
69+
conditions: [
70+
{
71+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
72+
match: UMB_DATA_TYPE_FOLDER_WORKSPACE_ALIAS,
4373
},
4474
],
4575
},

src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/constants.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
export * from './property-dataset-context/document-blueprint-property-dataset-context.token.js';
21
export * from './entity-actions/constants.js';
2+
export * from './menu/constants.js';
3+
export * from './paths.js';
4+
export * from './property-dataset-context/document-blueprint-property-dataset-context.token.js';
35
export * from './repository/constants.js';
46
export * from './tree/constants.js';
57
export * from './workspace/constants.js';
6-
export * from './paths.js';
78
export {
89
UMB_DOCUMENT_BLUEPRINT_ROOT_ENTITY_TYPE,
910
UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE,

src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/manifests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { manifests as entityActionManifests } from './entity-actions/manifests.js';
2-
import { manifests as menuItemManifests } from './menu-item/manifests.js';
2+
import { manifests as menuManifests } from './menu/manifests.js';
33
import { manifests as repositoryManifests } from './repository/manifests.js';
44
import { manifests as treeManifests } from './tree/manifests.js';
55
import { manifests as workspaceManifests } from './workspace/manifests.js';
66

77
export const manifests: Array<UmbExtensionManifest> = [
88
...entityActionManifests,
9-
...menuItemManifests,
9+
...menuManifests,
1010
...repositoryManifests,
1111
...treeManifests,
1212
...workspaceManifests,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const UMB_DOCUMENT_BLUEPRINT_MENU_ITEM_ALIAS = 'Umb.MenuItem.DocumentBlueprints';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { UMB_DOCUMENT_BLUEPRINT_TREE_REPOSITORY_ALIAS } from '../tree/index.js';
2+
import { UmbMenuTreeStructureWorkspaceContextBase } from '@umbraco-cms/backoffice/menu';
3+
4+
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
5+
6+
export class UmbDocumentBlueprintMenuStructureWorkspaceContext extends UmbMenuTreeStructureWorkspaceContextBase {
7+
constructor(host: UmbControllerHost) {
8+
super(host, { treeRepositoryAlias: UMB_DOCUMENT_BLUEPRINT_TREE_REPOSITORY_ALIAS });
9+
}
10+
}
11+
12+
export { UmbDocumentBlueprintMenuStructureWorkspaceContext as api };
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { UMB_DOCUMENT_BLUEPRINT_TREE_ALIAS } from '../tree/constants.js';
2+
import { UMB_DOCUMENT_BLUEPRINT_MENU_ITEM_ALIAS } from './constants.js';
23

34
export const manifests: Array<UmbExtensionManifest> = [
45
{
56
type: 'menuItem',
67
kind: 'tree',
7-
alias: 'Umb.MenuItem.DocumentBlueprints',
8+
alias: UMB_DOCUMENT_BLUEPRINT_MENU_ITEM_ALIAS,
89
name: 'Document Blueprints Menu Item',
910
weight: 100,
1011
meta: {

src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/manifests.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { UMB_DOCUMENT_TYPE_TREE_ALIAS } from '../tree/index.js';
1+
import { UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS } from '../constants.js';
2+
import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS, UMB_DOCUMENT_TYPE_TREE_ALIAS } from '../tree/index.js';
23
import { UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS } from './constants.js';
34
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
45

@@ -27,7 +28,7 @@ export const manifests: Array<UmbExtensionManifest> = [
2728
conditions: [
2829
{
2930
alias: UMB_WORKSPACE_CONDITION_ALIAS,
30-
match: 'Umb.Workspace.DocumentType',
31+
match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS,
3132
},
3233
],
3334
},
@@ -43,4 +44,32 @@ export const manifests: Array<UmbExtensionManifest> = [
4344
},
4445
],
4546
},
47+
{
48+
type: 'workspaceContext',
49+
kind: 'menuStructure',
50+
name: 'Document Type Folder Menu Structure Workspace Context',
51+
alias: 'Umb.Context.DocumentTypeFolder.Menu.Structure',
52+
api: () => import('./document-type-menu-structure.context.js'),
53+
meta: {
54+
menuItemAlias: UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS,
55+
},
56+
conditions: [
57+
{
58+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
59+
match: UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS,
60+
},
61+
],
62+
},
63+
{
64+
type: 'workspaceFooterApp',
65+
kind: 'menuBreadcrumb',
66+
alias: 'Umb.WorkspaceFooterApp.DocumentTypeFolder.Breadcrumb',
67+
name: 'Document Type Folder Breadcrumb Workspace Footer App',
68+
conditions: [
69+
{
70+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
71+
match: UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS,
72+
},
73+
],
74+
},
4675
];

src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { UMB_MEDIA_TYPE_TREE_ALIAS } from '../constants.js';
1+
import { UMB_MEDIA_TYPE_TREE_ALIAS, UMB_MEDIA_TYPE_FOLDER_WORKSPACE_ALIAS } from '../tree/constants.js';
2+
import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from '../workspace/constants.js';
23
import { UMB_MEDIA_TYPE_MENU_ITEM_ALIAS } from './constants.js';
34
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
45

@@ -27,7 +28,7 @@ export const manifests: Array<UmbExtensionManifest> = [
2728
conditions: [
2829
{
2930
alias: UMB_WORKSPACE_CONDITION_ALIAS,
30-
match: 'Umb.Workspace.MediaType',
31+
match: UMB_MEDIA_TYPE_WORKSPACE_ALIAS,
3132
},
3233
],
3334
},
@@ -39,7 +40,35 @@ export const manifests: Array<UmbExtensionManifest> = [
3940
conditions: [
4041
{
4142
alias: UMB_WORKSPACE_CONDITION_ALIAS,
42-
match: 'Umb.Workspace.MediaType',
43+
match: UMB_MEDIA_TYPE_WORKSPACE_ALIAS,
44+
},
45+
],
46+
},
47+
{
48+
type: 'workspaceContext',
49+
kind: 'menuStructure',
50+
name: 'Media Type Folder Menu Structure Workspace Context',
51+
alias: 'Umb.Context.MediaTypeFolder.Menu.Structure',
52+
api: () => import('./media-type-menu-structure.context.js'),
53+
meta: {
54+
menuItemAlias: UMB_MEDIA_TYPE_MENU_ITEM_ALIAS,
55+
},
56+
conditions: [
57+
{
58+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
59+
match: UMB_MEDIA_TYPE_FOLDER_WORKSPACE_ALIAS,
60+
},
61+
],
62+
},
63+
{
64+
type: 'workspaceFooterApp',
65+
kind: 'menuBreadcrumb',
66+
alias: 'Umb.WorkspaceFooterApp.MediaTypeFolder.Breadcrumb',
67+
name: 'Media Type Folder Breadcrumb Workspace Footer App',
68+
conditions: [
69+
{
70+
alias: UMB_WORKSPACE_CONDITION_ALIAS,
71+
match: UMB_MEDIA_TYPE_FOLDER_WORKSPACE_ALIAS,
4372
},
4473
],
4574
},

0 commit comments

Comments
 (0)