Merge remote-tracking branch 'origin/main' into feature/unpublish-with-references
This commit is contained in:
@@ -1,10 +1,55 @@
|
||||
import type { UmbDocumentTreeItemModel } from '../types.js';
|
||||
import { css, html, nothing, customElement } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbDocumentTreeItemModel, UmbDocumentTreeItemVariantModel } from '../types.js';
|
||||
import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language';
|
||||
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
@customElement('umb-document-tree-item')
|
||||
export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase<UmbDocumentTreeItemModel> {
|
||||
#appLanguageContext?: UmbAppLanguageContext;
|
||||
|
||||
@state()
|
||||
_currentCulture?: string;
|
||||
|
||||
@state()
|
||||
_defaultCulture?: string;
|
||||
|
||||
@state()
|
||||
_variant?: UmbDocumentTreeItemVariantModel;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => {
|
||||
this.#appLanguageContext = instance;
|
||||
this.#observeAppCulture();
|
||||
this.#observeDefaultCulture();
|
||||
});
|
||||
}
|
||||
|
||||
#observeAppCulture() {
|
||||
this.observe(this.#appLanguageContext!.appLanguageCulture, (value) => {
|
||||
this._currentCulture = value;
|
||||
this._variant = this.#getVariant(value);
|
||||
});
|
||||
}
|
||||
|
||||
#observeDefaultCulture() {
|
||||
this.observe(this.#appLanguageContext!.appDefaultLanguage, (value) => {
|
||||
this._defaultCulture = value?.unique;
|
||||
});
|
||||
}
|
||||
|
||||
#getVariant(culture: string | undefined) {
|
||||
return this.item?.variants.find((x) => x.culture === culture);
|
||||
}
|
||||
|
||||
#getLabel() {
|
||||
const fallbackName = this.#getVariant(this._defaultCulture)?.name ?? this._item?.variants[0].name ?? 'Unknown';
|
||||
return this._variant?.name ?? `(${fallbackName})`;
|
||||
}
|
||||
|
||||
// TODO: implement correct status symbol
|
||||
renderIconContainer() {
|
||||
return html`
|
||||
@@ -13,16 +58,15 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase<UmbDocume
|
||||
? html`
|
||||
<umb-icon id="icon" slot="icon" name="${this.item.documentType.icon}"></umb-icon>
|
||||
<span id="status-symbol"></span>
|
||||
`
|
||||
`
|
||||
: nothing}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
// TODO: lower opacity if item is not published
|
||||
// TODO: get correct variant name
|
||||
renderLabel() {
|
||||
return html`<span id="label" slot="label">${this.item?.variants[0].name}</span> `;
|
||||
return html`<span id="label" slot="label">${this.#getLabel()}</span> `;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
|
||||
@@ -97,7 +97,7 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
|
||||
<uui-menu-item
|
||||
label=${ifDefined(language.name)}
|
||||
@click-label=${this.#onLabelClick}
|
||||
data-iso-code=${ifDefined(language.unique)}
|
||||
data-unique=${ifDefined(language.unique)}
|
||||
?active=${language.unique === this._appLanguage?.unique}></uui-menu-item>
|
||||
`,
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UmbLanguageCollectionRepository } from '../collection/index.js';
|
||||
import type { UmbLanguageDetailModel } from '../types.js';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbArrayState, UmbObjectState, createObservablePart } from '@umbraco-cms/backoffice/observable-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
@@ -8,11 +8,17 @@ import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbAppLanguageContext extends UmbControllerBase implements UmbApi {
|
||||
#languageCollectionRepository: UmbLanguageCollectionRepository;
|
||||
#languages: Array<UmbLanguageDetailModel> = [];
|
||||
#languages = new UmbArrayState<UmbLanguageDetailModel>([], (x) => x.unique);
|
||||
|
||||
#appLanguage = new UmbObjectState<UmbLanguageDetailModel | undefined>(undefined);
|
||||
appLanguage = this.#appLanguage.asObservable();
|
||||
|
||||
appLanguageCulture = this.#appLanguage.asObservablePart((x) => x?.unique);
|
||||
|
||||
appDefaultLanguage = createObservablePart(this.#languages.asObservable(), (languages) =>
|
||||
languages.find((language) => language.isDefault),
|
||||
);
|
||||
|
||||
getAppCulture() {
|
||||
return this.#appLanguage.getValue()?.unique;
|
||||
}
|
||||
@@ -25,7 +31,8 @@ export class UmbAppLanguageContext extends UmbControllerBase implements UmbApi {
|
||||
}
|
||||
|
||||
setLanguage(unique: string) {
|
||||
const language = this.#languages.find((x) => x.unique === unique);
|
||||
const languages = this.#languages.getValue();
|
||||
const language = languages.find((x) => x.unique === unique);
|
||||
this.#appLanguage.update(language);
|
||||
}
|
||||
|
||||
@@ -34,7 +41,7 @@ export class UmbAppLanguageContext extends UmbControllerBase implements UmbApi {
|
||||
|
||||
// TODO: make this observable / update when languages are added/removed/updated
|
||||
if (data) {
|
||||
this.#languages = data.items;
|
||||
this.#languages.setValue(data.items);
|
||||
|
||||
// If the app language is not set, set it to the default language
|
||||
if (!this.#appLanguage.getValue()) {
|
||||
@@ -44,7 +51,7 @@ export class UmbAppLanguageContext extends UmbControllerBase implements UmbApi {
|
||||
}
|
||||
|
||||
#initAppLanguage() {
|
||||
const defaultLanguage = this.#languages.find((x) => x.isDefault);
|
||||
const defaultLanguage = this.#languages.getValue().find((x) => x.isDefault);
|
||||
// TODO: do we always have a default language?
|
||||
// do we always get the default language on the first request, or could it be on page 2?
|
||||
// in that case do we then need an endpoint to get the default language?
|
||||
|
||||
@@ -6,9 +6,11 @@ import type {
|
||||
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
export const UMB_MEDIA_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.MediaType';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
type: 'workspace',
|
||||
alias: 'Umb.Workspace.MediaType',
|
||||
alias: UMB_MEDIA_TYPE_WORKSPACE_ALIAS,
|
||||
name: 'Media Type Workspace',
|
||||
js: () => import('./media-type-workspace.element.js'),
|
||||
meta: {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { UmbSaveableWorkspaceContextInterface } from '@umbraco-cms/backoffi
|
||||
import { UmbEditableWorkspaceContextBase } from '@umbraco-cms/backoffice/workspace';
|
||||
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import type {
|
||||
UmbContentTypeCompositionModel,
|
||||
UmbContentTypeSortModel,
|
||||
@@ -46,9 +46,6 @@ export class UmbMediaTypeWorkspaceContext
|
||||
|
||||
readonly structure = new UmbContentTypeStructureManager<EntityType>(this, this.repository);
|
||||
|
||||
#isSorting = new UmbBooleanState(undefined);
|
||||
isSorting = this.#isSorting.asObservable();
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, 'Umb.Workspace.MediaType');
|
||||
|
||||
@@ -66,17 +63,9 @@ export class UmbMediaTypeWorkspaceContext
|
||||
this.collection = this.structure.ownerContentTypeObservablePart((data) => data?.collection);
|
||||
}
|
||||
|
||||
protected resetState() {
|
||||
this.#persistedData.setValue(undefined);
|
||||
protected resetState(): void {
|
||||
super.resetState();
|
||||
}
|
||||
|
||||
getIsSorting() {
|
||||
return this.#isSorting.getValue();
|
||||
}
|
||||
|
||||
setIsSorting(isSorting: boolean) {
|
||||
this.#isSorting.setValue(isSorting);
|
||||
this.#persistedData.setValue(undefined);
|
||||
}
|
||||
|
||||
getData() {
|
||||
@@ -112,6 +101,18 @@ export class UmbMediaTypeWorkspaceContext
|
||||
this.structure.updateOwnerContentType({ allowedAtRoot });
|
||||
}
|
||||
|
||||
setVariesByCulture(variesByCulture: boolean) {
|
||||
this.structure.updateOwnerContentType({ variesByCulture });
|
||||
}
|
||||
|
||||
setVariesBySegment(variesBySegment: boolean) {
|
||||
this.structure.updateOwnerContentType({ variesBySegment });
|
||||
}
|
||||
|
||||
setIsElement(isElement: boolean) {
|
||||
this.structure.updateOwnerContentType({ isElement });
|
||||
}
|
||||
|
||||
setAllowedContentTypes(allowedContentTypes: Array<UmbContentTypeSortModel>) {
|
||||
this.structure.updateOwnerContentType({ allowedContentTypes });
|
||||
}
|
||||
@@ -131,7 +132,6 @@ export class UmbMediaTypeWorkspaceContext
|
||||
if (!data) return undefined;
|
||||
|
||||
this.setIsNew(true);
|
||||
this.setIsSorting(false);
|
||||
this.#persistedData.setValue(data);
|
||||
return data;
|
||||
}
|
||||
@@ -142,7 +142,6 @@ export class UmbMediaTypeWorkspaceContext
|
||||
|
||||
if (data) {
|
||||
this.setIsNew(false);
|
||||
this.setIsSorting(false);
|
||||
this.#persistedData.update(data);
|
||||
}
|
||||
|
||||
@@ -199,7 +198,6 @@ export class UmbMediaTypeWorkspaceContext
|
||||
public destroy(): void {
|
||||
this.#persistedData.destroy();
|
||||
this.structure.destroy();
|
||||
this.#isSorting.destroy();
|
||||
this.repository.destroy();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export const UMB_MEMBER_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.MemberType';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
type: 'workspace',
|
||||
alias: 'Umb.Workspace.MemberType',
|
||||
alias: UMB_MEMBER_TYPE_WORKSPACE_ALIAS,
|
||||
name: 'Member Type Workspace',
|
||||
js: () => import('./member-type-workspace.element.js'),
|
||||
meta: {
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
import { UmbMemberTypeDetailRepository } from '../repository/detail/index.js';
|
||||
import type { UmbMemberTypeDetailModel } from '../types.js';
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../index.js';
|
||||
import {
|
||||
type UmbSaveableWorkspaceContextInterface,
|
||||
UmbEditableWorkspaceContextBase,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type';
|
||||
import {
|
||||
type UmbContentTypeCompositionModel,
|
||||
UmbContentTypeStructureManager,
|
||||
type UmbContentTypeWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/content-type';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
import { UmbReloadTreeItemChildrenRequestEntityActionEvent } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
type EntityType = UmbMemberTypeDetailModel;
|
||||
export class UmbMemberTypeWorkspaceContext
|
||||
extends UmbEditableWorkspaceContextBase<EntityType>
|
||||
implements UmbSaveableWorkspaceContextInterface
|
||||
implements UmbContentTypeWorkspaceContext<EntityType>
|
||||
{
|
||||
#isSorting = new UmbBooleanState(undefined);
|
||||
isSorting = this.#isSorting.asObservable();
|
||||
readonly IS_CONTENT_TYPE_WORKSPACE_CONTEXT = true;
|
||||
|
||||
public readonly repository = new UmbMemberTypeDetailRepository(this);
|
||||
#parent?: { entityType: string; unique: string | null };
|
||||
@@ -57,10 +61,6 @@ export class UmbMemberTypeWorkspaceContext
|
||||
this.compositions = this.structure.ownerContentTypeObservablePart((data) => data?.compositions);
|
||||
}
|
||||
|
||||
setIsSorting(isSorting: boolean) {
|
||||
this.#isSorting.setValue(isSorting);
|
||||
}
|
||||
|
||||
set<PropertyName extends keyof EntityType>(propertyName: PropertyName, value: EntityType[PropertyName]) {
|
||||
this.structure.updateOwnerContentType({ [propertyName]: value });
|
||||
}
|
||||
@@ -68,7 +68,50 @@ export class UmbMemberTypeWorkspaceContext
|
||||
protected resetState(): void {
|
||||
super.resetState();
|
||||
this.#persistedData.setValue(undefined);
|
||||
this.#isSorting.setValue(false);
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.structure.getOwnerContentType();
|
||||
}
|
||||
|
||||
getUnique() {
|
||||
return this.getData()?.unique;
|
||||
}
|
||||
|
||||
getEntityType() {
|
||||
return UMB_MEMBER_TYPE_ENTITY_TYPE;
|
||||
}
|
||||
|
||||
setName(name: string) {
|
||||
this.structure.updateOwnerContentType({ name });
|
||||
}
|
||||
|
||||
setAlias(alias: string) {
|
||||
this.structure.updateOwnerContentType({ alias });
|
||||
}
|
||||
|
||||
setDescription(description: string) {
|
||||
this.structure.updateOwnerContentType({ description });
|
||||
}
|
||||
|
||||
// TODO: manage setting icon color alias?
|
||||
setIcon(icon: string) {
|
||||
this.structure.updateOwnerContentType({ icon });
|
||||
}
|
||||
|
||||
setCompositions(compositions: Array<UmbContentTypeCompositionModel>) {
|
||||
this.structure.updateOwnerContentType({ compositions });
|
||||
}
|
||||
|
||||
async create(parent: { entityType: string; unique: string | null }) {
|
||||
this.resetState();
|
||||
this.#parent = parent;
|
||||
const { data } = await this.structure.createScaffold();
|
||||
if (!data) return undefined;
|
||||
|
||||
this.setIsNew(true);
|
||||
this.#persistedData.setValue(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
async load(unique: string) {
|
||||
@@ -77,7 +120,6 @@ export class UmbMemberTypeWorkspaceContext
|
||||
|
||||
if (data) {
|
||||
this.setIsNew(false);
|
||||
this.setIsSorting(false);
|
||||
this.#persistedData.update(data);
|
||||
}
|
||||
|
||||
@@ -93,18 +135,6 @@ export class UmbMemberTypeWorkspaceContext
|
||||
}
|
||||
}
|
||||
|
||||
async create(parent: { entityType: string; unique: string | null }) {
|
||||
this.resetState();
|
||||
this.#parent = parent;
|
||||
const { data } = await this.structure.createScaffold();
|
||||
if (!data) return undefined;
|
||||
|
||||
this.setIsNew(true);
|
||||
this.setIsSorting(false);
|
||||
this.#persistedData.setValue(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
async save() {
|
||||
const data = this.getData();
|
||||
if (data === undefined) throw new Error('Cannot save, no data');
|
||||
@@ -137,31 +167,11 @@ export class UmbMemberTypeWorkspaceContext
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.#persistedData.destroy();
|
||||
this.structure.destroy();
|
||||
this.repository.destroy();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.structure.getOwnerContentType();
|
||||
}
|
||||
|
||||
getUnique() {
|
||||
return this.getData()?.unique || '';
|
||||
}
|
||||
|
||||
getEntityType() {
|
||||
return 'member-type';
|
||||
}
|
||||
|
||||
setName(name: string) {
|
||||
this.structure.updateOwnerContentType({ name });
|
||||
}
|
||||
setAlias(alias: string) {
|
||||
this.structure.updateOwnerContentType({ alias });
|
||||
}
|
||||
setDescription(description: string) {
|
||||
this.structure.updateOwnerContentType({ description });
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_MEMBER_TYPE_WORKSPACE_CONTEXT = new UmbContextToken<
|
||||
|
||||
Reference in New Issue
Block a user