Proff of concept for navigating to edit path when created
This commit is contained in:
@@ -5,6 +5,7 @@ export declare class UmbControllerHostElement extends HTMLElement {
|
||||
hasController(controller: UmbControllerInterface): boolean;
|
||||
getControllers(filterMethod: (ctrl: UmbControllerInterface) => boolean): UmbControllerInterface[];
|
||||
addController(controller: UmbControllerInterface): void;
|
||||
removeControllerByUnique(unique: UmbControllerInterface['unique']): void;
|
||||
removeController(controller: UmbControllerInterface): void;
|
||||
}
|
||||
|
||||
@@ -43,13 +44,7 @@ export const UmbControllerHostMixin = <T extends HTMLElementConstructor>(superCl
|
||||
*/
|
||||
addController(ctrl: UmbControllerInterface): void {
|
||||
// Check if there is one already with same unique
|
||||
if (ctrl.unique) {
|
||||
this.#controllers.forEach((x) => {
|
||||
if (x.unique === ctrl.unique) {
|
||||
this.removeController(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.removeControllerByUnique(ctrl.unique);
|
||||
|
||||
this.#controllers.push(ctrl);
|
||||
if (this.#attached) {
|
||||
@@ -57,6 +52,20 @@ export const UmbControllerHostMixin = <T extends HTMLElementConstructor>(superCl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a controller from this element, by its unique/alias.
|
||||
* @param {unknown} unique/alias
|
||||
*/
|
||||
removeControllerByUnique(unique: UmbControllerInterface['unique']): void {
|
||||
if (unique) {
|
||||
this.#controllers.forEach((x) => {
|
||||
if (x.unique === unique) {
|
||||
this.removeController(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a controller from this element.
|
||||
* Notice this will also destroy the controller.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { ISlashOptions } from '@umbraco-cms/internal/router';
|
||||
|
||||
const PARAM_IDENTIFIER = /:([^\\/]+)/g;
|
||||
|
||||
function stripSlash(path: string): string {
|
||||
return slashify(path, { start: false, end: false });
|
||||
}
|
||||
|
||||
function slashify(path: string, { start = true, end = true }: Partial<ISlashOptions> = {}): string {
|
||||
path = start && !path.startsWith('/') ? `/${path}` : !start && path.startsWith('/') ? path.slice(1) : path;
|
||||
return end && !path.endsWith('/') ? `${path}/` : !end && path.endsWith('/') ? path.slice(0, path.length - 1) : path;
|
||||
}
|
||||
|
||||
export function generateRoutePathBuilder(path: string) {
|
||||
return (params: { [key: string]: string | number }) =>
|
||||
stripSlash(
|
||||
path.replace(PARAM_IDENTIFIER, (substring: string, ...args: string[]) => {
|
||||
return params[args[0]].toString();
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './route-location.interface';
|
||||
export * from './route.context';
|
||||
export * from './route.interface';
|
||||
export * from './generate-route-path-builder.function';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { IRoutingInfo, ISlashOptions } from 'router-slot';
|
||||
import { UmbRoute } from './route.interface';
|
||||
import { generateRoutePathBuilder } from '.';
|
||||
import {
|
||||
UmbContextConsumerController,
|
||||
UmbContextProviderController,
|
||||
@@ -10,17 +11,6 @@ import { UMB_MODAL_CONTEXT_TOKEN, UmbModalRouteRegistration } from '@umbraco-cms
|
||||
|
||||
const EmptyDiv = document.createElement('div');
|
||||
|
||||
const PARAM_IDENTIFIER = /:([^\\/]+)/g;
|
||||
|
||||
function stripSlash(path: string): string {
|
||||
return slashify(path, { start: false, end: false });
|
||||
}
|
||||
|
||||
function slashify(path: string, { start = true, end = true }: Partial<ISlashOptions> = {}): string {
|
||||
path = start && !path.startsWith('/') ? `/${path}` : !start && path.startsWith('/') ? path.slice(1) : path;
|
||||
return end && !path.endsWith('/') ? `${path}/` : !end && path.endsWith('/') ? path.slice(0, path.length - 1) : path;
|
||||
}
|
||||
|
||||
export class UmbRouteContext {
|
||||
#modalRegistrations: UmbModalRouteRegistration[] = [];
|
||||
#modalContext?: typeof UMB_MODAL_CONTEXT_TOKEN.TYPE;
|
||||
@@ -125,16 +115,9 @@ export class UmbRouteContext {
|
||||
if (!this.#routerBasePath) return;
|
||||
|
||||
const routeBasePath = this.#routerBasePath.endsWith('/') ? this.#routerBasePath : this.#routerBasePath + '/';
|
||||
const localPath = `modal/${modalRegistration.alias.toString()}/${modalRegistration.path}`;
|
||||
const localPath = routeBasePath + `modal/${modalRegistration.alias.toString()}/${modalRegistration.path}`;
|
||||
|
||||
const urlBuilder = (params: { [key: string]: string | number }) => {
|
||||
const localRoutePath = stripSlash(
|
||||
localPath.replace(PARAM_IDENTIFIER, (substring: string, ...args: string[]) => {
|
||||
return params[args[0]].toString();
|
||||
})
|
||||
);
|
||||
return routeBasePath + localRoutePath;
|
||||
};
|
||||
const urlBuilder = generateRoutePathBuilder(localPath);
|
||||
|
||||
modalRegistration._internal_setRouteBuilder(urlBuilder);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controlle
|
||||
export class UmbSaveWorkspaceAction extends UmbWorkspaceActionBase<UmbWorkspaceContextInterface> {
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host);
|
||||
|
||||
// TODO: Could we make change label depending on the state?
|
||||
// So its called 'Create' when the workspace is new and 'Save' when the workspace is not new.
|
||||
}
|
||||
|
||||
/* TODO: we need a solution for all actions to notify the system that is has been executed.
|
||||
@@ -14,35 +17,7 @@ export class UmbSaveWorkspaceAction extends UmbWorkspaceActionBase<UmbWorkspaceC
|
||||
*/
|
||||
async execute() {
|
||||
if (!this.workspaceContext) return;
|
||||
// TODO: it doesn't get the updated value
|
||||
const data = this.workspaceContext.getData();
|
||||
// TODO: handle errors
|
||||
if (!data) return;
|
||||
|
||||
this.workspaceContext.getIsNew() ? this.#create(data) : this.#update(data);
|
||||
}
|
||||
|
||||
async #create(data: any) {
|
||||
if (!this.workspaceContext) return;
|
||||
|
||||
// TODO: preferably the actions dont talk directly with repository, but instead with its context.
|
||||
// We just need to consider how third parties can extend the system.
|
||||
const { error } = await this.workspaceContext.repository.create(data);
|
||||
|
||||
// TODO: this is temp solution to bubble validation errors to the UI
|
||||
if (error) {
|
||||
if (error.type === 'validation') {
|
||||
this.workspaceContext.setValidationErrors?.(error.errors);
|
||||
}
|
||||
} else {
|
||||
this.workspaceContext.setValidationErrors?.(undefined);
|
||||
// TODO: do not make it the buttons responsibility to set the workspace to not new.
|
||||
this.workspaceContext.setIsNew(false);
|
||||
}
|
||||
}
|
||||
|
||||
#update(data: any) {
|
||||
if (!this.workspaceContext) return;
|
||||
this.workspaceContext.repository?.save(data);
|
||||
this.workspaceContext.save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller';
|
||||
export interface UmbWorkspaceContextInterface<DataType = unknown> {
|
||||
host: UmbControllerHostElement;
|
||||
repository: any; // TODO: add type
|
||||
isNew: Observable<boolean>;
|
||||
getIsNew(): boolean;
|
||||
isNew: Observable<boolean | undefined>;
|
||||
getIsNew(): boolean | undefined;
|
||||
setIsNew(value: boolean): void;
|
||||
// TODO: should we consider another name than entity type. File system files are not entities but still have this type.
|
||||
getEntityType(): string;
|
||||
getData(): DataType | undefined;
|
||||
save(): Promise<void>;
|
||||
destroy(): void;
|
||||
// TODO: temp solution to bubble validation errors to the UI
|
||||
setValidationErrors?(errorMap: any): void;
|
||||
|
||||
Reference in New Issue
Block a user