Skip to content

Commit 05cab2a

Browse files
committed
impl edit workspace route
1 parent 44f4ff7 commit 05cab2a

File tree

6 files changed

+115
-58
lines changed

6 files changed

+115
-58
lines changed

src/packages/core/content-type/structure/content-type-structure-manager.class.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ export class UmbContentTypeStructureManager<
463463
property = { ...property, container: { id: container.id } };
464464
}
465465

466+
if (property.sortOrder === undefined) {
467+
property.sortOrder = 0;
468+
}
469+
466470
const frozenProperties =
467471
this.#contentTypes.getValue().find((x) => x.unique === contentTypeUnique)?.properties ?? [];
468472

src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,16 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
9999
return this._containerId;
100100
}
101101
public set containerId(value: string | null | undefined) {
102-
const oldValue = this._containerId;
103-
if (value === oldValue) return;
102+
if (value === this._containerId) return;
104103
this._containerId = value;
105-
this.createAddPropertyRoute();
104+
this.createPropertyTypeWorkspaceRoutes();
106105
this.#propertyStructureHelper.setContainerId(value);
107106
this.#addPropertyModal?.setUniquePathValue('container-id', value === null ? 'root' : value);
108-
this.requestUpdate('containerId', oldValue);
107+
this.#editPropertyModal?.setUniquePathValue('container-id', value === null ? 'root' : value);
109108
}
110109

111110
#addPropertyModal?: UmbModalRouteRegistrationController;
111+
#editPropertyModal?: UmbModalRouteRegistrationController;
112112

113113
#propertyStructureHelper = new UmbContentTypePropertyStructureHelper<UmbContentTypeModel>(this);
114114

@@ -124,6 +124,9 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
124124
@state()
125125
private _newPropertyPath?: string;
126126

127+
@state()
128+
private _editPropertyTypePath?: string;
129+
127130
@state()
128131
private _sortModeActive?: boolean;
129132

@@ -154,6 +157,7 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
154157
workspaceContext.structure.ownerContentType,
155158
(contentType) => {
156159
this._ownerContentType = contentType;
160+
this.createPropertyTypeWorkspaceRoutes();
157161
},
158162
'observeOwnerContentType',
159163
);
@@ -164,32 +168,67 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
164168
});
165169
}
166170

167-
createAddPropertyRoute() {
171+
createPropertyTypeWorkspaceRoutes() {
172+
if (!this._ownerContentType || this._containerId === undefined) return;
168173
// Note: Route for adding a new property
169174
this.#addPropertyModal?.destroy();
170-
this.#addPropertyModal = new UmbModalRouteRegistrationController(this, UMB_PROPERTY_TYPE_WORKSPACE_MODAL)
175+
this.#addPropertyModal = new UmbModalRouteRegistrationController(
176+
this,
177+
UMB_PROPERTY_TYPE_WORKSPACE_MODAL,
178+
'addPropertyModal',
179+
)
171180
.addUniquePaths(['container-id'])
172-
.addAdditionalPath('add-property')
181+
.addAdditionalPath('add-property/:sortOrder')
173182
.onSetup(async (params) => {
174183
// TODO: Make a onInit promise, that can be awaited here.
175184
if (!this._ownerContentType || this._containerId === undefined) return false;
176185

177186
const preset: Partial<UmbPropertyTypeModel> = {};
178187
if (params.sortOrder !== undefined) {
179-
let sortOrderInt = parseInt(params.sortOrder, 10);
188+
let sortOrderInt = parseInt(params.sortOrder);
180189
if (sortOrderInt === -1) {
181190
// Find the highest sortOrder and add 1 to it:
182-
sortOrderInt = Math.max(...this._propertyStructure.map((x) => x.sortOrder), -1);
191+
sortOrderInt = Math.max(...this._propertyStructure.map((x) => x.sortOrder), -1) + 1;
183192
}
184-
preset.sortOrder = sortOrderInt + 1;
193+
preset.sortOrder = sortOrderInt;
185194
}
186-
return { data: { contentTypeUnique: this._ownerContentType.unique, preset } };
195+
return { data: { contentTypeUnique: this._ownerContentType.unique, preset: undefined } };
187196
})
188197
.observeRouteBuilder((routeBuilder) => {
189198
this._newPropertyPath =
190-
routeBuilder({}) +
191-
UMB_CREATE_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({ containerUnique: this._containerId! });
199+
routeBuilder({ sortOrder: '-1' }) +
200+
UMB_CREATE_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({
201+
containerUnique: this._containerId!,
202+
});
203+
});
204+
if (this._containerId !== undefined) {
205+
this.#addPropertyModal?.setUniquePathValue(
206+
'container-id',
207+
this._containerId === null ? 'root' : this._containerId,
208+
);
209+
}
210+
211+
this.#editPropertyModal?.destroy();
212+
this.#editPropertyModal = new UmbModalRouteRegistrationController(
213+
this,
214+
UMB_PROPERTY_TYPE_WORKSPACE_MODAL,
215+
'editPropertyModal',
216+
)
217+
.addUniquePaths(['container-id'])
218+
.addAdditionalPath('edit-property')
219+
.onSetup(async () => {
220+
if (!this._ownerContentType || this._containerId === undefined) return false;
221+
return { data: { contentTypeUnique: this._ownerContentType.unique, preset: undefined } };
222+
})
223+
.observeRouteBuilder((routeBuilder) => {
224+
this._editPropertyTypePath = routeBuilder(null);
192225
});
226+
if (this._containerId !== undefined) {
227+
this.#editPropertyModal?.setUniquePathValue(
228+
'container-id',
229+
this._containerId === null ? 'root' : this._containerId,
230+
);
231+
}
193232
}
194233

195234
override render() {
@@ -204,6 +243,7 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement {
204243
<umb-content-type-design-editor-property
205244
data-umb-property-id=${property.id}
206245
.editContentTypePath=${this.editContentTypePath}
246+
.editPropertyTypePath=${this._editPropertyTypePath}
207247
?sort-mode-active=${this._sortModeActive}
208248
.propertyStructureHelper=${this.#propertyStructureHelper}
209249
.property=${property}>

src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { UmbPropertyTypeContext } from './content-type-design-editor-property.co
22
import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type';
33
import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui';
44
import { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
5-
import { css, html, customElement, property, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit';
5+
import { css, html, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit';
66
import { umbConfirmModal } from '@umbraco-cms/backoffice/modal';
7-
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
87
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
98
import { generateAlias } from '@umbraco-cms/backoffice/utils';
109
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@@ -14,7 +13,7 @@ import {
1413
type UmbPropertyTypeModel,
1514
type UmbPropertyTypeScaffoldModel,
1615
} from '@umbraco-cms/backoffice/content-type';
17-
import { UMB_PROPERTY_TYPE_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/property-type';
16+
import { UMB_EDIT_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/property-type';
1817

1918
/**
2019
* @element umb-content-type-design-editor-property
@@ -25,7 +24,6 @@ import { UMB_PROPERTY_TYPE_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/prope
2524
export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
2625
//
2726
#dataTypeDetailRepository = new UmbDataTypeDetailRepository(this);
28-
#settingsModal;
2927
#dataTypeUnique?: string;
3028
#context = new UmbPropertyTypeContext(this);
3129

@@ -57,7 +55,6 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
5755
this.#context.setAlias(value?.alias);
5856
this.#context.setLabel(value?.name);
5957
this.#checkInherited();
60-
this.#settingsModal.setUniquePathValue('propertyId', value?.id);
6158
this.#setDataType(this._property?.dataType?.unique);
6259
this.requestUpdate('property', oldValue);
6360
}
@@ -78,33 +75,15 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
7875
@state()
7976
public _inheritedContentTypeName?: string;
8077

81-
@state()
82-
protected _modalRoute?: string;
78+
@property({ type: String, reflect: false })
79+
protected editPropertyTypePath?: string;
8380

8481
@state()
8582
private _dataTypeName?: string;
8683

8784
@state()
8885
private _aliasLocked = true;
8986

90-
constructor() {
91-
super();
92-
93-
// TODO: consider if this can be registered more globally/contextually. [NL]
94-
this.#settingsModal = new UmbModalRouteRegistrationController(this, UMB_PROPERTY_TYPE_WORKSPACE_MODAL)
95-
.addUniquePaths(['propertyId'])
96-
.onSetup(() => {
97-
const id = this._inheritedContentTypeId;
98-
if (id === undefined) return false;
99-
const propertyData = this.property;
100-
if (propertyData === undefined) return false;
101-
return { data: { contentTypeUnique: id, preset: {} } };
102-
})
103-
.observeRouteBuilder((routeBuilder) => {
104-
this._modalRoute = routeBuilder(null);
105-
});
106-
}
107-
10887
async #checkInherited() {
10988
if (this._propertyStructureHelper && this._property) {
11089
// We can first match with something if we have a name [NL]
@@ -228,7 +207,7 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
228207
}
229208

230209
renderEditableProperty() {
231-
if (!this.property) return;
210+
if (!this.property || !this.editPropertyTypePath) return;
232211

233212
if (this.sortModeActive) {
234213
return this.renderSortableProperty();
@@ -260,7 +239,8 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement {
260239
id="editor"
261240
look="secondary"
262241
label=${this.localize.term('contentTypeEditor_editorSettings')}
263-
href=${ifDefined(this._modalRoute)}>
242+
href=${this.editPropertyTypePath +
243+
UMB_EDIT_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({ unique: this.property.id })}>
264244
${this.renderPropertyTags()}
265245
<uui-action-bar>
266246
<uui-button label="${this.localize.term('actions_delete')}" @click="${this.#requestRemove}">

src/packages/core/property-type/workspace/property-type-workspace.context.ts

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
2323
// Just for context token safety:
2424
public readonly IS_PROPERTY_TYPE_WORKSPACE_CONTEXT = true;
2525

26+
#init: Promise<unknown>;
27+
#contentTypeContext?: typeof UMB_CONTENT_TYPE_WORKSPACE_CONTEXT.TYPE;
28+
2629
#entityType: string;
30+
31+
// #persistedData
32+
// #currentData
2733
#data = new UmbObjectState<PropertyTypeData | undefined>(undefined);
2834
readonly data = this.#data.asObservable();
2935

@@ -35,6 +41,12 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
3541
const manifest = args.manifest;
3642
this.#entityType = manifest.meta?.entityType;
3743

44+
this.#init = this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (context) => {
45+
this.#contentTypeContext = context;
46+
})
47+
.skipHost()
48+
.asPromise();
49+
3850
this.routes.setRoutes([
3951
{
4052
// Would it make more sense to have groupKey before elementTypeKey?
@@ -70,6 +82,8 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
7082
protected override resetState() {
7183
super.resetState();
7284
this.#data.setValue(undefined);
85+
this.removeUmbControllerByAlias('isNewRedirectController');
86+
this.removeUmbControllerByAlias('observePropertyTypeData');
7387
}
7488

7589
createPropertyDatasetContext(host: UmbControllerHost): UmbPropertyDatasetContext {
@@ -78,14 +92,23 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
7892

7993
async load(unique: string) {
8094
this.resetState();
81-
const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
82-
this.observe(await context.structure.propertyStructureById(unique), (property) => {
83-
if (property) {
84-
this.#data.setValue(property as PropertyTypeData);
85-
}
86-
// Fallback to undefined:
87-
this.#data.setValue(undefined);
88-
});
95+
await this.#init;
96+
this.observe(
97+
await this.#contentTypeContext?.structure.propertyStructureById(unique),
98+
(property) => {
99+
if (property) {
100+
this.#data.setValue(property as PropertyTypeData);
101+
//this.#persistedData.setValue(property);
102+
//this.#currentData.setValue(property);
103+
104+
this.setIsNew(false);
105+
} else {
106+
// Fallback to undefined:
107+
this.#data.setValue(undefined);
108+
}
109+
},
110+
'observePropertyTypeData',
111+
);
89112
}
90113

91114
async create(containerId?: string | null) {
@@ -116,9 +139,10 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
116139
data = { ...data, ...this.modalContext.data.preset };
117140
}
118141

119-
this.setIsNew(true);
120142
this.#data.setValue(data);
121-
return { data };
143+
//this.#persistedData.setValue(property);
144+
//this.#currentData.setValue(property);
145+
this.setIsNew(true);
122146
}
123147

124148
getData() {
@@ -169,11 +193,14 @@ export class UmbPropertyTypeWorkspaceContext<PropertyTypeData extends UmbPropert
169193
throw new Error('No data to submit.');
170194
}
171195

172-
const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT);
196+
await this.#init;
197+
if (this.#contentTypeContext) {
198+
await this.#contentTypeContext.structure.insertProperty(contentTypeUnique, data);
173199

174-
context.structure.insertProperty(contentTypeUnique, data);
175-
176-
this.setIsNew(false);
200+
this.setIsNew(false);
201+
} else {
202+
throw new Error('Failed to find content type context.');
203+
}
177204
}
178205

179206
public override destroy(): void {

src/packages/core/property-type/workspace/views/settings/property-workspace-view-settings.element.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ export class UmbPropertyTypeWorkspaceViewSettingsElement extends UmbLitElement i
5252

5353
this.consumeContext(UMB_PROPERTY_TYPE_WORKSPACE_CONTEXT, (instance) => {
5454
this.#context = instance;
55-
this.observe(instance.data, (data) => (this._data = data));
55+
this.observe(instance.data, (data) => {
56+
this._data = data;
57+
});
5658
});
5759

5860
this.consumeContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT, (instance) => {

src/packages/core/router/modal-registration/modal-route-registration.controller.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type {
88
UmbModalManagerContext,
99
UmbModalToken,
1010
} from '@umbraco-cms/backoffice/modal';
11-
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
11+
import type { UmbControllerAlias, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
1212
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
1313
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
1414
import { UmbId } from '@umbraco-cms/backoffice/id';
@@ -80,8 +80,12 @@ export class UmbModalRouteRegistrationController<
8080
* @param {UmbModalToken} alias - The alias of the modal, this is used to identify the modal.
8181
* @memberof UmbModalRouteRegistrationController
8282
*/
83-
constructor(host: UmbControllerHost, alias: UmbModalToken<UmbModalTokenData, UmbModalTokenValue> | string) {
84-
super(host, alias.toString());
83+
constructor(
84+
host: UmbControllerHost,
85+
alias: UmbModalToken<UmbModalTokenData, UmbModalTokenValue> | string,
86+
ctrlAlias?: UmbControllerAlias,
87+
) {
88+
super(host, ctrlAlias ?? alias.toString());
8589
this.#key = UmbId.new();
8690
this.#modalAlias = alias;
8791
//this.#path = path;

0 commit comments

Comments
 (0)