Merge pull request #628 from umbraco/feature/create-language
Feature/create language
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -55,7 +55,6 @@ export class UmbLanguageServerDataSource
|
||||
name: '',
|
||||
isDefault: false,
|
||||
isMandatory: false,
|
||||
fallbackIsoCode: '',
|
||||
isoCode: '',
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ export class UmbLanguageRootTableDeleteColumnLayoutElement extends UmbLitElement
|
||||
|
||||
return html`
|
||||
<umb-dropdown .open="${this._isOpen}" @close=${this.#onClose}>
|
||||
<uui-button slot="trigger" compact @click=${this.#onClick}><uui-symbol-more></uui-symbol-more></uui-button>
|
||||
<uui-button label="actions" slot="trigger" compact @click=${this.#onClick}>
|
||||
<uui-symbol-more></uui-symbol-more>
|
||||
</uui-button>
|
||||
<umb-entity-action-list
|
||||
slot="dropdown"
|
||||
@executed=${this.#onActionExecuted}
|
||||
|
||||
@@ -65,6 +65,7 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement {
|
||||
private _tableItems: Array<UmbTableItem> = [];
|
||||
|
||||
#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,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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`<umb-workspace-layout alias="Umb.Workspace.Language">
|
||||
<div id="header" slot="header">
|
||||
<uui-button href="/section/settings/workspace/language-root" compact>
|
||||
<uui-button label="Navigate back" href="section/settings/workspace/language-root" compact>
|
||||
<uui-icon name="umb:arrow-left"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-input value=${ifDefined(this._language?.name)} @input="${this.#handleInput}"></uui-input>
|
||||
${this._isNew
|
||||
? html`<strong>Add language</strong>`
|
||||
: html`<uui-input
|
||||
label="Language name"
|
||||
value=${ifDefined(this._language?.name)}
|
||||
@input="${this.#handleInput}"></uui-input>`}
|
||||
</div>
|
||||
<div slot="footer" id="footer">
|
||||
<a href="section/settings/workspace/language-root">Languages</a> /
|
||||
${this._isNew ? 'Create' : this._language?.name}
|
||||
</div>
|
||||
</umb-workspace-layout>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbLanguageWorkspaceThingyElement;
|
||||
export default UmbLanguageWorkspaceEditElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-language-workspace-thingy': UmbLanguageWorkspaceThingyElement;
|
||||
'umb-language-workspace-edit': UmbLanguageWorkspaceEditElement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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`
|
||||
<uui-box>
|
||||
<umb-workspace-property-layout label="Language">
|
||||
<div slot="editor">
|
||||
<!-- TODO: disable already created cultures in the select -->
|
||||
<umb-input-culture-select
|
||||
value=${ifDefined(this._language.isoCode)}
|
||||
value=${ifDefined(this._language?.isoCode)}
|
||||
@change=${this.#handleCultureChange}
|
||||
?readonly=${this._isNew === false}></umb-input-culture-select>
|
||||
|
||||
@@ -163,14 +166,15 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement {
|
||||
</umb-workspace-property-layout>
|
||||
|
||||
<umb-workspace-property-layout label="ISO Code">
|
||||
<div slot="editor">${this._language.isoCode}</div>
|
||||
<div slot="editor">${this._language?.isoCode}</div>
|
||||
</umb-workspace-property-layout>
|
||||
|
||||
<umb-workspace-property-layout label="Settings">
|
||||
<div slot="editor">
|
||||
<uui-toggle
|
||||
label="Default language"
|
||||
?disabled=${this._isDefaultLanguage}
|
||||
?checked=${this._language.isDefault || false}
|
||||
?checked=${this._language?.isDefault || false}
|
||||
@change=${this.#handleDefaultChange}>
|
||||
<div>
|
||||
<b>Default language</b>
|
||||
@@ -178,14 +182,17 @@ export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement {
|
||||
</div>
|
||||
</uui-toggle>
|
||||
<!-- TODO: we need a UUI component for this -->
|
||||
${this._language.isDefault !== this._isDefaultLanguage
|
||||
${this._language?.isDefault && this._language?.isDefault !== this._isDefaultLanguage
|
||||
? html`<div id="default-language-warning">
|
||||
Switching default language may result in default content missing.
|
||||
</div>`
|
||||
: nothing}
|
||||
|
||||
<hr />
|
||||
<uui-toggle ?checked=${this._language.isMandatory || false} @change=${this.#handleMandatoryChange}>
|
||||
<uui-toggle
|
||||
label="Mandatory language"
|
||||
?checked=${this._language?.isMandatory || false}
|
||||
@change=${this.#handleMandatoryChange}>
|
||||
<div>
|
||||
<b>Mandatory language</b>
|
||||
<div>Properties on this language have to be filled out before the node can be published.</div>
|
||||
@@ -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.">
|
||||
<umb-input-language-picker
|
||||
value=${ifDefined(this._language.fallbackIsoCode === null ? undefined : this._language.fallbackIsoCode)}
|
||||
value=${ifDefined(this._language?.fallbackIsoCode === null ? undefined : this._language?.fallbackIsoCode)}
|
||||
slot="editor"
|
||||
max="1"
|
||||
@change=${this.#handleFallbackChange}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
* @element umb-workspace-layout
|
||||
* @description
|
||||
* @slot icon - Slot for icon
|
||||
* @slot header - Slot for workspace header
|
||||
* @slot name - Slot for name
|
||||
* @slot footer - Slot for workspace footer
|
||||
* @slot actions - Slot for workspace footer actions
|
||||
|
||||
Reference in New Issue
Block a user