diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-builder/workspace/workspace-package-builder.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-builder/workspace/workspace-package-builder.element.ts index 2039464360..2ec7087884 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-builder/workspace/workspace-package-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-builder/workspace/workspace-package-builder.element.ts @@ -1,68 +1,78 @@ -import type { UmbInputDocumentElement } from '../../../documents/documents/components/input-document/input-document.element.js'; -import type { UmbInputMediaElement } from '../../../media/media/components/input-media/input-media.element.js'; +import { UmbPackageRepository } from '../../package/repository/index.js'; +import type { UmbCreatedPackageDefinition } from '../../types.js'; import type { UmbInputLanguageElement } from '../../../language/components/input-language/input-language.element.js'; -import type { UUIBooleanInputEvent, UUIInputElement, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, - nothing, customElement, property, query, state, + when, + nothing, ifDefined, } from '@umbraco-cms/backoffice/external/lit'; -// TODO: update to module imports when ready import { blobDownload } from '@umbraco-cms/backoffice/utils'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { PackageDefinitionResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; -import { PackageResource } from '@umbraco-cms/backoffice/external/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; -import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; -import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import { UmbServerFilePathUniqueSerializer } from '@umbraco-cms/backoffice/server-file-system'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document'; +import type { UmbInputDocumentTypeElement } from '@umbraco-cms/backoffice/document-type'; +import type { UmbInputEntityElement } from '@umbraco-cms/backoffice/components'; +import type { UmbInputMediaTypeElement } from '@umbraco-cms/backoffice/media-type'; +import type { UmbMediaItemModel } from '@umbraco-cms/backoffice/media'; +import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; +import type { + UUIBooleanInputEvent, + UUIButtonState, + UUIInputElement, + UUIInputEvent, +} from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-workspace-package-builder') export class UmbWorkspacePackageBuilderElement extends UmbLitElement { @property() - entityId?: string; + entityUnique?: string; + + @property() + workspaceAlias?: string; @state() - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - private _package: PackageDefinitionResponseModel = {}; + private _package?: UmbCreatedPackageDefinition; @query('#package-name-input') - private _packageNameInput!: UUIInputElement; + private _packageNameInput?: UUIInputElement; - private _notificationContext?: UmbNotificationContext; + @state() + private _submitState?: UUIButtonState; + + #notificationContext?: UmbNotificationContext; + #packageRepository = new UmbPackageRepository(this); + #serverFilePathUniqueSerializer = new UmbServerFilePathUniqueSerializer(); constructor() { super(); - this.consumeContext(UMB_NOTIFICATION_CONTEXT, (instance) => { - this._notificationContext = instance; + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => { + this.#notificationContext = context; }); } connectedCallback(): void { super.connectedCallback(); - if (this.entityId) this.#getPackageCreated(); + this.#getPackageCreated(); + requestAnimationFrame(() => this._packageNameInput?.focus()); } async #getPackageCreated() { - if (!this.entityId) return; - const { data } = await tryExecuteAndNotify(this, PackageResource.getPackageCreatedById({ id: this.entityId })); - if (!data) return; - this._package = data as PackageDefinitionResponseModel; + this._package = await this.#packageRepository.getCreatedPackage(this.entityUnique); + this.requestUpdate('_package'); } async #download() { - if (!this._package?.id) return; - const { data } = await tryExecuteAndNotify( - this, - PackageResource.getPackageCreatedByIdDownload({ id: this._package.id }), - ); + if (!this._package?.unique) return; + const data = await this.#packageRepository.getCreatePackageDownload(this._package.unique); if (!data) return; // TODO: [LK] Need to review what the server is doing, as different data is returned depending on schema configuration. @@ -71,85 +81,99 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { blobDownload(data, 'package.zip', 'application/zip'); } - #nameDefined() { - const valid = this._packageNameInput.checkValidity(); - if (!valid) this._notificationContext?.peek('danger', { data: { message: 'Package missing a name' } }); + #isNameDefined() { + const valid = this._packageNameInput?.checkValidity() ?? false; + if (!valid) this.#notificationContext?.peek('danger', { data: { message: 'Package missing a name' } }); return valid; } async #save() { - if (!this.#nameDefined()) return; - const response = await tryExecuteAndNotify( - this, - PackageResource.postPackageCreated({ requestBody: this._package }), - ); - if (!response.data || response.error) return; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - this._package = response.data as PackageDefinitionResponseModel; - this.#navigateBack(); + if (!this.#isNameDefined()) return; + if (!this._package) return; + + this._submitState = 'waiting'; + + const unique = await this.#packageRepository.saveCreatedPackage(this._package); + if (!unique) return; + + this._package.unique = unique; + this.requestUpdate('_package'); + + this._submitState = 'success'; + + this.#notificationContext?.peek('positive', { data: { message: 'Package saved' } }); } async #update() { - if (!this.#nameDefined()) return; - if (!this._package?.id) return; - const response = await tryExecuteAndNotify( - this, - PackageResource.putPackageCreatedById({ id: this._package.id, requestBody: this._package }), - ); + if (!this.#isNameDefined()) return; + if (!this._package?.unique) return; - if (response.error) return; - this.#navigateBack(); - } + this._submitState = 'waiting'; - #navigateBack() { - window.history.pushState({}, '', 'section/packages/view/created'); + const success = await this.#packageRepository.updateCreatedPackage(this._package); + if (!success) return; + + this._submitState = 'success'; + + this.#notificationContext?.peek('positive', { data: { message: 'Package updated' } }); } render() { + if (!this.workspaceAlias) return nothing; return html` - + ${this.#renderHeader()} - ${this.#renderEditors()} + ${this.#renderEditors()} ${this.#renderActions()} `; } #renderHeader() { - return html`
- - - - -
`; + if (!this._package) return nothing; + return html` + + `; } #renderActions() { - return html`
- ${this._package?.id - ? html` - Download - ` - : nothing} - - Save - -
`; + return html` +
+ ${when( + this._package?.unique, + () => html` + + `, + )} + +
+ `; } #renderEditors() { - return html` + return html` + + ${this.#renderContentSection()} @@ -177,7 +201,9 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { ${this.#renderPartialViewSection()} - `; + + + `; } #renderContentSection() { @@ -282,14 +308,19 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { height: 100%; } - .header { - margin: 0 var(--uui-size-layout-1); + #header { display: flex; gap: var(--uui-size-space-4); + margin-right: var(--uui-size-layout-1); + width: 100%; + } + + uui-input { + width: 100%; } uui-box { - margin: var(--uui-size-layout-1); + margin: var(--uui-size-layout-2); } uui-checkbox { diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/created-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/created-packages-section-view.element.ts index 978a5723f6..20dbcde6b9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/created-packages-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/created-packages-section-view.element.ts @@ -37,17 +37,23 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement implemen // TODO: find a way to make this reuseable across: this.#workspaces?.map((workspace: ManifestWorkspace) => { routes.push({ - path: `${workspace.meta.entityType}/:id`, + path: `${workspace.meta.entityType}/:unique`, component: () => createExtensionElement(workspace), setup: (component, info) => { if (component) { - (component as any).entityId = info.match.params.id; + (component as any).entityUnique = info.match.params.unique; + (component as any).workspaceAlias = workspace.alias; } }, }); routes.push({ path: workspace.meta.entityType, component: () => createExtensionElement(workspace), + setup: (component, info) => { + if (component) { + (component as any).workspaceAlias = workspace.alias; + } + }, }); });