render tag in app language selector

This commit is contained in:
Mads Rasmussen
2024-10-21 16:07:35 +02:00
parent 4bcca9928b
commit 99deec9ac2
2 changed files with 80 additions and 14 deletions

View File

@@ -26,6 +26,9 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
@state()
private _appLanguage?: UmbLanguageDetailModel;
@state()
private _appLanguageIsReadOnly = false;
@state()
private _isOpen = false;
@@ -77,6 +80,10 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
this.observe(this.#appLanguageContext.appLanguage, (language) => {
this._appLanguage = language;
});
this.observe(this.#appLanguageContext.appLanguageReadOnlyState.isReadOnly, (isReadOnly) => {
this._appLanguageIsReadOnly = isReadOnly;
});
}
async #observeLanguages() {
@@ -123,7 +130,11 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
#renderTrigger() {
return html`<button id="toggle" popovertarget="dropdown-popover">
${this._appLanguage?.name} <uui-symbol-expand .open=${this._isOpen}></uui-symbol-expand>
<span
>${this._appLanguage?.name}
${this._appLanguageIsReadOnly ? this.#renderReadOnlyTag(this._appLanguage?.unique) : nothing}</span
>
<uui-symbol-expand .open=${this._isOpen}></uui-symbol-expand>
</button>`;
}
@@ -139,7 +150,7 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
@click-label=${this.#onLabelClick}
data-unique=${ifDefined(language.unique)}
?active=${language.unique === this._appLanguage?.unique}>
${this.#renderReadOnlyTag(language.unique)}
${this.#isLanguageReadOnly(language.unique) ? this.#renderReadOnlyTag(language.unique) : nothing}
</uui-menu-item>
`,
)}
@@ -147,14 +158,14 @@ export class UmbAppLanguageSelectElement extends UmbLitElement {
</uui-popover-container>`;
}
#isReadOnly(culture: string | null) {
#isLanguageReadOnly(culture?: string) {
if (!culture) return false;
return this._disallowedLanguages.find((language) => language.unique === culture) ? true : false;
}
#renderReadOnlyTag(culture?: string | null) {
#renderReadOnlyTag(culture?: string) {
if (!culture) return nothing;
return this.#isReadOnly(culture) ? html`<uui-tag slot="badge" look="secondary">Read-only</uui-tag>` : nothing;
return html`<uui-tag slot="badge" look="secondary">Read-only</uui-tag>`;
}
static override styles = [

View File

@@ -6,30 +6,34 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth';
import { UmbReadOnlyStateManager } from '@umbraco-cms/backoffice/utils';
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
// TODO: Make a store for the App Languages.
// TODO: Implement default language end-point, in progress at backend team, so we can avoid getting all languages.
export class UmbAppLanguageContext extends UmbContextBase<UmbAppLanguageContext> implements UmbApi {
#languageCollectionRepository: UmbLanguageCollectionRepository;
#languages = new UmbArrayState<UmbLanguageDetailModel>([], (x) => x.unique);
moreThanOneLanguage = this.#languages.asObservablePart((x) => x.length > 1);
#appLanguage = new UmbObjectState<UmbLanguageDetailModel | undefined>(undefined);
appLanguage = this.#appLanguage.asObservable();
public readonly appLanguage = this.#appLanguage.asObservable();
public readonly appLanguageCulture = this.#appLanguage.asObservablePart((x) => x?.unique);
appLanguageCulture = this.#appLanguage.asObservablePart((x) => x?.unique);
public readonly appLanguageReadOnlyState = new UmbReadOnlyStateManager(this);
appDefaultLanguage = createObservablePart(this.#languages.asObservable(), (languages) =>
public readonly appDefaultLanguage = createObservablePart(this.#languages.asObservable(), (languages) =>
languages.find((language) => language.isDefault),
);
getAppCulture() {
return this.#appLanguage.getValue()?.unique;
}
public readonly moreThanOneLanguage = this.#languages.asObservablePart((x) => x.length > 1);
#languageCollectionRepository = new UmbLanguageCollectionRepository(this);
#currentUserAllowedLanguages: Array<string> = [];
#currentUserHasAccessToAllLanguages = false;
#readOnlyStateIdentifier = 'UMB_LANGUAGE_PERMISSION_';
constructor(host: UmbControllerHost) {
super(host, UMB_APP_LANGUAGE_CONTEXT);
this.#languageCollectionRepository = new UmbLanguageCollectionRepository(this);
// TODO: We need to ensure this request is called every time the user logs in, but this should be done somewhere across the app and not here [JOV]
this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => {
@@ -38,12 +42,39 @@ export class UmbAppLanguageContext extends UmbContextBase<UmbAppLanguageContext>
this.#observeLanguages();
});
});
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(context.languages, (languages) => {
this.#currentUserAllowedLanguages = languages || [];
this.#setIsReadOnly();
});
this.observe(context.hasAccessToAllLanguages, (hasAccessToAllLanguages) => {
this.#currentUserHasAccessToAllLanguages = hasAccessToAllLanguages || false;
this.#setIsReadOnly();
});
});
}
getAppCulture() {
return this.#appLanguage.getValue()?.unique;
}
setLanguage(unique: string) {
const appLanguage = this.#appLanguage.getValue();
// clear the previous read-only state
if (appLanguage?.unique) {
this.appLanguageReadOnlyState.removeState(this.#readOnlyStateIdentifier + appLanguage.unique);
}
// set the new language
const languages = this.#languages.getValue();
const language = languages.find((x) => x.unique === unique);
this.#appLanguage.update(language);
// set the new read-only state
this.#setIsReadOnly();
}
async #observeLanguages() {
@@ -67,6 +98,30 @@ export class UmbAppLanguageContext extends UmbContextBase<UmbAppLanguageContext>
// in that case do we then need an endpoint to get the default language?
if (!defaultLanguage?.unique) return;
this.setLanguage(defaultLanguage.unique);
this.#setIsReadOnly();
}
#setIsReadOnly() {
const appLanguage = this.#appLanguage.getValue();
if (!appLanguage) {
this.appLanguageReadOnlyState.clear();
return;
}
const unique = this.#readOnlyStateIdentifier + appLanguage.unique;
this.appLanguageReadOnlyState.removeState(unique);
const isReadOnly = !this.#currentUserAllowedLanguages.includes(appLanguage.unique);
if (isReadOnly) {
const readOnlyState = {
unique,
message: 'You do not have permission to edit to this culture',
};
this.appLanguageReadOnlyState.addState(readOnlyState);
}
}
}