Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Redirect when server file is renamed #17663

Merged
merged 23 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
216e310
make args protected + type generic
madsrasmussen Nov 28, 2024
f3fabef
add rename event
madsrasmussen Nov 28, 2024
0144695
get new name and unique from modal
madsrasmussen Nov 28, 2024
f4e0e95
dispatch event when file is renamed
madsrasmussen Nov 28, 2024
1669414
get unique from entity context
madsrasmussen Nov 28, 2024
579535b
poc redirect after rename
madsrasmussen Nov 28, 2024
e4c65b3
move logic to controller
madsrasmussen Nov 28, 2024
78e0a0b
dont render code editor if content is undefined
madsrasmussen Nov 28, 2024
5c2d2ba
remove unused styling
madsrasmussen Nov 28, 2024
03ae594
set unique after create
madsrasmussen Nov 28, 2024
cbaa65c
use replace state
madsrasmussen Nov 28, 2024
14ab80b
set additionalOptions for rename action
madsrasmussen Nov 28, 2024
683fe43
Update workspace-redirect.controller.ts
madsrasmussen Nov 28, 2024
6df05af
add focus to name input
madsrasmussen Nov 28, 2024
02de9b4
add rename redirect controller
madsrasmussen Nov 28, 2024
21c9b02
clean up
madsrasmussen Nov 28, 2024
ee58b2d
split render methods
madsrasmussen Nov 28, 2024
7387107
Update script-workspace.context.ts
madsrasmussen Nov 28, 2024
154e69f
implement EntityDetailWorkspaceBase for stylesheets
madsrasmussen Nov 28, 2024
8ddc3da
remove unused
madsrasmussen Nov 28, 2024
456cfa6
don't render code editor if there is no content
madsrasmussen Nov 28, 2024
aa8527d
add rename redirect controller
madsrasmussen Nov 28, 2024
210f2aa
Merge branch 'v15/dev' into v15/bugfix/rename-server-file-redirect
nielslyngsoe Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface UmbEntityActionEventArgs extends UmbEntityModel {}

export class UmbEntityActionEvent extends UmbControllerEvent {
#args: UmbEntityActionEventArgs;
export class UmbEntityActionEvent<
ArgsType extends UmbEntityActionEventArgs = UmbEntityActionEventArgs,
> extends UmbControllerEvent {
protected _args: ArgsType;

public constructor(type: string, args: UmbEntityActionEventArgs) {
public constructor(type: string, args: ArgsType) {
super(type);
this.#args = args;
this._args = args;
}

getEntityType(): string {
return this.#args.entityType;
return this._args.entityType;
}

getUnique(): string | null {
return this.#args.unique;
return this._args.unique;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './server-file-renamed.entity-event.js';
export type * from './types.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { UmbServerFileRenamedEventArgs } from './types.js';
import { UmbEntityActionEvent } from '@umbraco-cms/backoffice/entity-action';

export class UmbServerFileRenamedEntityEvent extends UmbEntityActionEvent<UmbServerFileRenamedEventArgs> {
static readonly TYPE = 'server-file-renamed';

constructor(args: UmbServerFileRenamedEventArgs) {
super(UmbServerFileRenamedEntityEvent.TYPE, args);
}

getNewUnique(): string {
return this._args.newUnique;
}

getNewName(): string {
return this._args.newName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { UmbEntityActionEventArgs } from '@umbraco-cms/backoffice/entity-action';

export interface UmbServerFileRenamedEventArgs extends UmbEntityActionEventArgs {
newUnique: string;
newName: string;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export type * from './types.js';
export * from './rename-server-file.action.js';
export * from './rename-server-file-repository-base.js';
export * from './event/index.js';
export * from './workspace-redirect/index.js';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';

@customElement('umb-rename-modal')
export class UmbRenameModalElement extends UmbModalBaseElement<UmbRenameModalData, UmbRenameServerFileModalValue> {
Expand Down Expand Up @@ -81,6 +82,11 @@ export class UmbRenameModalElement extends UmbModalBaseElement<UmbRenameModalDat
const { data } = await this.#renameRepository.rename(this.data.unique, name);

if (data) {
this.value = {
name: data.name,
unique: data.unique,
};

this._submitModal();
} else {
this._rejectModal();
Expand All @@ -102,7 +108,8 @@ export class UmbRenameModalElement extends UmbModalBaseElement<UmbRenameModalDat
value=${this._name}
placeholder="Enter new name..."
required
required-message="Name is required"></uui-input>
required-message="Name is required"
${umbFocus()}></uui-input>
</uui-form-layout-item>
</form>
</uui-form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ export interface UmbRenameModalData {
unique: string;
}

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface UmbRenameServerFileModalValue {}
export interface UmbRenameServerFileModalValue {
unique: string;
name: string;
}

export const UMB_RENAME_SERVER_FILE_MODAL = new UmbModalToken<UmbRenameModalData, UmbRenameServerFileModalValue>(
UMB_RENAME_SERVER_FILE_MODAL_ALIAS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const manifest: UmbExtensionManifestKind = {
meta: {
icon: 'icon-edit',
label: '#actions_rename',
additionalOptions: true,
renameRepositoryAlias: '',
itemRepositoryAlias: '',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UMB_RENAME_SERVER_FILE_MODAL } from './modal/rename-server-file-modal.token.js';
import type { MetaEntityActionRenameServerFileKind } from './types.js';
import { UmbServerFileRenamedEntityEvent } from './event/index.js';
import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
Expand All @@ -17,15 +18,29 @@ export class UmbRenameEntityAction extends UmbEntityActionBase<MetaEntityActionR
},
});

await modalContext.onSubmit();
try {
const res = await modalContext.onSubmit();

const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
const event = new UmbRequestReloadStructureForEntityEvent({
unique: this.args.unique,
entityType: this.args.entityType,
});
const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
const event = new UmbRequestReloadStructureForEntityEvent({
unique: this.args.unique,
entityType: this.args.entityType,
});

actionEventContext.dispatchEvent(event);

const event2 = new UmbServerFileRenamedEntityEvent({
unique: this.args.unique,
entityType: this.args.entityType,
newName: res.name,
newUnique: res.unique,
});

actionEventContext.dispatchEvent(event);
actionEventContext.dispatchEvent(event2);
} catch (error) {
// TODO: Handle error
console.log(error);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './workspace-redirect.controller.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { UmbServerFileRenamedEntityEvent } from '../event/index.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbRouterSlotElement } from '@umbraco-cms/backoffice/router';
import { ensurePathEndsWithSlash, umbUrlPatternToString } from '@umbraco-cms/backoffice/utils';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import type { UmbSubmittableWorkspaceContextBase } from '@umbraco-cms/backoffice/workspace';

export const UmbServerFileRenameWorkspaceRedirectControllerAlias = Symbol(
'ServerFileRenameWorkspaceRedirectControllerAlias',
);

export class UmbServerFileRenameWorkspaceRedirectController extends UmbControllerBase {
#actionEventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE;
#workspaceContext: UmbSubmittableWorkspaceContextBase<unknown>;
#router: UmbRouterSlotElement;

constructor(
host: UmbControllerHost,
workspaceContext: UmbSubmittableWorkspaceContextBase<unknown>,
router: UmbRouterSlotElement,
) {
super(host, UmbServerFileRenameWorkspaceRedirectControllerAlias);

this.#workspaceContext = workspaceContext;
this.#router = router;

this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (context) => {
this.#actionEventContext = context;

if (this.#actionEventContext) {
this.#actionEventContext.removeEventListener(UmbServerFileRenamedEntityEvent.TYPE, this.#onFileRenamed);
this.#actionEventContext.addEventListener(UmbServerFileRenamedEntityEvent.TYPE, this.#onFileRenamed);
}
});
}

#onFileRenamed = ((event: UmbServerFileRenamedEntityEvent) => {
if (!this.#router) throw new Error('Router is required for this controller.');

// Don't redirect if the event is not for the current entity
const currentUnique = this.#workspaceContext.getUnique();
const eventUnique = event.getUnique();
if (currentUnique !== eventUnique) return;

const newUnique = event.getNewUnique();
if (!newUnique) throw new Error('New unique is required for this event.');

const routerPath = this.#router.absoluteRouterPath;
if (!routerPath) throw new Error('Router path is required for this controller.');

const newPath: string = umbUrlPatternToString(ensurePathEndsWithSlash(routerPath) + 'edit/:unique', {
unique: newUnique,
});

this.destroy();
window.history.replaceState(null, '', newPath);
}) as EventListener;

public override destroy(): void {
super.destroy();
this.#actionEventContext?.removeEventListener(UmbServerFileRenamedEntityEvent.TYPE, this.#onFileRenamed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
* @returns { string | undefined } The unique identifier
*/
getUnique(): UmbEntityUnique | undefined {
return this.getData()?.unique;
return this.#entityContext.getUnique();
}

setUnique(unique: string) {
Expand Down Expand Up @@ -242,6 +242,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
throw error?.message ?? 'Repository did not return data after create.';
}

this.#entityContext.setUnique(data.unique);
this._data.setPersisted(data);
this._data.setCurrent(data);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getQuerySnippet } from '../../utils/index.js';
import type { UmbTemplatingInsertMenuElement } from '../../local-components/insert-menu/index.js';
import { UMB_PARTIAL_VIEW_WORKSPACE_CONTEXT } from './partial-view-workspace.context-token.js';
import { css, customElement, html, query, state } from '@umbraco-cms/backoffice/external/lit';
import { css, customElement, html, nothing, query, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_TEMPLATE_QUERY_BUILDER_MODAL } from '@umbraco-cms/backoffice/template';
Expand Down Expand Up @@ -107,6 +107,10 @@ export class UmbPartialViewWorkspaceEditorElement extends UmbLitElement {
}

#renderCodeEditor() {
if (this._content === undefined) {
return nothing;
}

return html`
<umb-code-editor
id="content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { PartialViewService } from '@umbraco-cms/backoffice/external/backend-api';
import type { IRoutingInfo, PageComponent } from '@umbraco-cms/backoffice/router';
import { UmbServerFileRenameWorkspaceRedirectController } from '@umbraco-cms/backoffice/server-file-system';

export interface UmbPartialViewWorkspaceContextCreateArgs
extends UmbEntityDetailWorkspaceContextCreateArgs<UmbPartialViewDetailModel> {
Expand Down Expand Up @@ -73,6 +74,12 @@ export class UmbPartialViewWorkspaceContext
setup: (component: PageComponent, info: IRoutingInfo) => {
const unique = info.match.params.unique;
this.load(unique);

new UmbServerFileRenameWorkspaceRedirectController(
this,
this,
this.getHostElement().shadowRoot!.querySelector('umb-router-slot')!,
);
},
},
]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UMB_SCRIPT_WORKSPACE_CONTEXT } from './script-workspace.context-token.js';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element';
import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor';
import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui';
Expand All @@ -24,18 +24,9 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement {

this.consumeContext(UMB_SCRIPT_WORKSPACE_CONTEXT, (context) => {
this.#context = context;

this.observe(this.#context.name, (name) => {
this._name = name;
});

this.observe(this.#context.content, (content) => {
this._content = content;
});

this.observe(this.#context.isNew, (isNew) => {
this._isNew = isNew;
});
this.observe(this.#context.name, (name) => (this._name = name));
this.observe(this.#context.content, (content) => (this._content = content));
this.observe(this.#context.isNew, (isNew) => (this._isNew = isNew));
});
}

Expand All @@ -54,26 +45,41 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement {
override render() {
return html`
<umb-entity-detail-workspace-editor>
<div id="workspace-header" slot="header">
<uui-input
placeholder=${this.localize.term('placeholders_entername')}
.value=${this._name}
@input=${this.#onNameInput}
label=${this.localize.term('placeholders_entername')}
?readonly=${this._isNew === false}
${umbFocus()}>
</uui-input>
</div>
<uui-box>
<!-- the div below in the header is to make the box display nicely with code editor -->
<div slot="header"></div>
${this.#renderCodeEditor()}
</uui-box>
${this.#renderHeader()} ${this.#renderBody()}
</umb-entity-detail-workspace-editor>
`;
}

#renderHeader() {
return html`
<div id="workspace-header" slot="header">
<uui-input
placeholder=${this.localize.term('placeholders_entername')}
.value=${this._name}
@input=${this.#onNameInput}
label=${this.localize.term('placeholders_entername')}
?readonly=${this._isNew === false}
${umbFocus()}>
</uui-input>
</div>
`;
}

#renderBody() {
return html`
<uui-box>
<!-- the div below in the header is to make the box display nicely with code editor -->
<div slot="header"></div>
${this.#renderCodeEditor()}
</uui-box>
`;
}

#renderCodeEditor() {
if (this._content === undefined) {
return nothing;
}

return html`
<umb-code-editor
id="content"
Expand All @@ -85,11 +91,6 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement {

static override styles = [
css`
:host {
display: block;
width: 100%;
}

umb-code-editor {
--editor-height: calc(100dvh - 260px);
}
Expand Down
Loading
Loading