diff --git a/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts b/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts index c323c76d2a..2432b6fe96 100644 --- a/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts +++ b/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts @@ -39,8 +39,17 @@ export class UmbResourceController extends UmbController { */ static toProblemDetailsModel(error: unknown): ProblemDetailsModel | undefined { if (error instanceof ApiError) { - const errorDetails = error.body as ProblemDetailsModel; - return errorDetails; + try { + const errorDetails = ( + typeof error.body === 'string' ? JSON.parse(error.body) : error.body + ) as ProblemDetailsModel; + return errorDetails; + } catch { + return { + title: error.name, + detail: error.message, + }; + } } else if (error instanceof Error) { return { title: error.name, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts index af2231bbe1..6764a51dea 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts @@ -55,7 +55,6 @@ export class UmbLanguageServerDataSource name: '', isDefault: false, isMandatory: false, - fallbackIsoCode: '', isoCode: '', }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts index 2da293c6b0..56493b1112 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts @@ -34,7 +34,9 @@ export class UmbLanguageRootTableDeleteColumnLayoutElement extends UmbLitElement return html` - + + + = []; #languageRepository = new UmbLanguageRepository(this); + private _cultureNames = new Intl.DisplayNames('en', { type: 'language' }); connectedCallback() { super.connectedCallback(); @@ -88,7 +89,7 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement { { columnAlias: 'languageName', value: { - name: language.name, + name: language.name ? language.name : this._cultureNames.of(language.isoCode ?? ''), isoCode: language.isoCode, }, }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts index 93a00c19ef..2647b15a1c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts @@ -8,8 +8,8 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; -@customElement('umb-language-workspace-thingy') -export class UmbLanguageWorkspaceThingyElement extends UmbLitElement { +@customElement('umb-language-workspace-edit') +export class UmbLanguageWorkspaceEditElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -19,9 +19,23 @@ export class UmbLanguageWorkspaceThingyElement extends UmbLitElement { gap: var(--uui-size-space-4); width: 100%; } + uui-input { width: 100%; } + + strong { + display: flex; + align-items: center; + } + + #footer { + padding: 0 var(--uui-size-layout-1); + } + + uui-input:not(:focus) { + border: 1px solid transparent; + } `, ]; @@ -30,6 +44,9 @@ export class UmbLanguageWorkspaceThingyElement extends UmbLitElement { @state() _language?: LanguageResponseModel; + @state() + _isNew = false; + constructor() { super(); @@ -44,6 +61,9 @@ export class UmbLanguageWorkspaceThingyElement extends UmbLitElement { this.observe(this.#workspaceContext.data, (data) => { this._language = data; }); + this.observe(this.#workspaceContext.isNew, (isNew) => { + this._isNew = isNew; + }); } #handleInput(event: UUIInputEvent) { @@ -59,19 +79,28 @@ export class UmbLanguageWorkspaceThingyElement extends UmbLitElement { render() { return html` + `; } } -export default UmbLanguageWorkspaceThingyElement; +export default UmbLanguageWorkspaceEditElement; declare global { interface HTMLElementTagNameMap { - 'umb-language-workspace-thingy': UmbLanguageWorkspaceThingyElement; + 'umb-language-workspace-edit': UmbLanguageWorkspaceEditElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.element.ts index 3eb52b81f3..7574254fbe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.element.ts @@ -6,24 +6,33 @@ import { UmbLanguageWorkspaceContext } from './language-workspace.context'; import { UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import './language-workspace-edit.element'; + @customElement('umb-language-workspace') export class UmbLanguageWorkspaceElement extends UmbLitElement { static styles = [UUITextStyles, css``]; #languageWorkspaceContext = new UmbLanguageWorkspaceContext(this); + #element = document.createElement('umb-language-workspace-edit'); #routerPath? = ''; - // TODO: add create route @state() _routes = [ { path: 'edit/:isoCode', - component: () => import('./language-workspace-edit.element'), + component: () => this.#element, setup: (component: HTMLElement, info: IRoutingInfo) => { this.#languageWorkspaceContext.load(info.match.params.isoCode); }, }, + { + path: 'create', + component: () => this.#element, + setup: async () => { + this.#languageWorkspaceContext.createScaffold(); + }, + }, ]; render() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts index db03dd5f15..a2c0d105d7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts @@ -4,8 +4,8 @@ import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbLanguageWorkspaceContext } from '../../language-workspace.context'; -import UmbInputCultureSelectElement from '../../../../../../shared/components/input-culture-select/input-culture-select.element'; -import UmbInputLanguagePickerElement from '../../../../../../shared/components/input-language-picker/input-language-picker.element'; +import { UmbInputCultureSelectElement } from '../../../../../../shared/components/input-culture-select/input-culture-select.element'; +import { UmbInputLanguagePickerElement } from '../../../../../../shared/components/input-language-picker/input-language-picker.element'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; @@ -98,6 +98,11 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement { const isoCode = target.value.toString(); const cultureName = target.selectedCultureName; + // If there is no cultureName, it was probably an unknown event that triggered the change event, so ignore it. + if (!cultureName) { + return; + } + if (!isoCode) { // If the isoCode is empty, we reset the value to the original value. // Provides a way better UX @@ -143,15 +148,13 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement { } render() { - if (!this._language) return nothing; - return html`
@@ -163,14 +166,15 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement { -
${this._language.isoCode}
+
${this._language?.isoCode}
Default language @@ -178,14 +182,17 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement {
- ${this._language.isDefault !== this._isDefaultLanguage + ${this._language?.isDefault && this._language?.isDefault !== this._isDefaultLanguage ? html`
Switching default language may result in default content missing.
` : nothing}
- +
Mandatory language
Properties on this language have to be filled out before the node can be published.
@@ -198,7 +205,7 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement { label="Fallback language" description="To allow multi-lingual content to fall back to another language if not present in the requested language, select it here.">