Merge remote-tracking branch 'origin/main' into feature/link-external-login

This commit is contained in:
Jacob Overgaard
2024-05-15 09:17:46 +02:00
40 changed files with 303 additions and 233 deletions

View File

@@ -1247,8 +1247,8 @@ export default {
openMediaPicker: 'Open media picker',
},
propertyEditorPicker: {
title: 'Select Property Editor',
openPropertyEditorPicker: 'Select Property Editor',
title: 'Select a property editor',
openPropertyEditorPicker: 'Select a property editor UI',
},
relatedlinks: {
enterExternal: 'enter external link',

View File

@@ -2543,8 +2543,8 @@ export default {
searchResults: 'items returned',
},
propertyEditorPicker: {
title: 'Select Property Editor',
openPropertyEditorPicker: 'Select Property Editor',
title: 'Select a property editor',
openPropertyEditorPicker: 'Select a property editor UI',
},
analytics: {
consentForAnalytics: 'Consent for telemetry data',

View File

@@ -6,8 +6,6 @@ export * from './body-layout/body-layout.element.js';
export * from './code-block/index.js';
export * from './dropdown/index.js';
export * from './entity-actions-bundle/index.js';
export * from './extension-slot/index.js';
export * from './extension-with-api-slot/index.js';
export * from './footer-layout/index.js';
export * from './header-app/index.js';
export * from './history/index.js';

View File

@@ -29,6 +29,7 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
protected getFormElement() {
return undefined;
}
@property({ type: Number })
public set min(value: number) {
this.#min = value;

View File

@@ -1,8 +1,8 @@
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UUISliderEvent } from '@umbraco-cms/backoffice/external/uui';
import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import type { UUISliderEvent } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-input-slider')
export class UmbInputSliderElement extends UUIFormControlMixin(UmbLitElement, '') {
@@ -28,9 +28,9 @@ export class UmbInputSliderElement extends UUIFormControlMixin(UmbLitElement, ''
return undefined;
}
#onChange(e: UUISliderEvent) {
e.stopPropagation();
this.value = e.target.value as string;
#onChange(event: UUISliderEvent) {
event.stopPropagation();
this.value = event.target.value as string;
this.dispatchEvent(new UmbChangeEvent());
}
@@ -39,20 +39,27 @@ export class UmbInputSliderElement extends UUIFormControlMixin(UmbLitElement, ''
}
#renderSlider() {
return html`<uui-slider
.min="${this.min}"
.max="${this.max}"
.step="${this.step}"
.value="${this.valueLow.toString()}"
@change="${this.#onChange}"></uui-slider>`;
return html`
<uui-slider
.min=${this.min}
.max=${this.max}
.step=${this.step}
.value=${this.valueLow.toString()}
@change=${this.#onChange}>
</uui-slider>
`;
}
#renderRangeSlider() {
return html`<uui-range-slider
.min="${this.min}"
.max="${this.max}"
.step="${this.step}"
.value="${this.valueLow},${this.valueHigh}"
@change="${this.#onChange}"></uui-range-slider>`;
return html`
<uui-range-slider
.min=${this.min}
.max=${this.max}
.step=${this.step}
.value="${this.valueLow},${this.valueHigh}"
@change=${this.#onChange}>
</uui-range-slider>
`;
}
}

View File

@@ -1,5 +1,5 @@
import { UmbLitElement } from "@umbraco-cms/backoffice/lit-element";
import { customElement, html, css, property, classMap } from "@umbraco-cms/backoffice/external/lit";
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { classMap, customElement, css, html, property } from '@umbraco-cms/backoffice/external/lit';
/**
* @element umb-stack
@@ -7,72 +7,73 @@ import { customElement, html, css, property, classMap } from "@umbraco-cms/backo
* @extends LitElement
*/
@customElement('umb-stack')
export class UmbStackElement extends UmbLitElement
{
/**
* Look
* @type {String}
* @memberof UmbStackElement
*/
@property({ type:String })
look: 'compact' | 'default' = 'default';
export class UmbStackElement extends UmbLitElement {
/**
* Look
* @type {String}
* @memberof UmbStackElement
*/
@property({ type: String })
look: 'compact' | 'default' = 'default';
/**
* Divide
* @type {Boolean}
* @memberof UmbStackElement
*/
@property({ type:Boolean })
divide: boolean = false;
/**
* Divide
* @type {Boolean}
* @memberof UmbStackElement
*/
@property({ type: Boolean })
divide: boolean = false;
render() {
return html`<div class=${classMap({ divide: this.divide, compact: this.look === 'compact' })}>
<slot></slot>
</div>`;
}
render() {
return html`
<div class=${classMap({ divide: this.divide, compact: this.look === 'compact' })}>
<slot></slot>
</div>
`;
}
static styles = [
css`
div {
display: block;
position: relative;
}
static styles = [
css`
div {
display: block;
position: relative;
}
::slotted(*) {
position: relative;
margin-top: var(--uui-size-space-6);
}
::slotted(*) {
position: relative;
margin-top: var(--uui-size-space-6);
}
.divide ::slotted(*)::before {
content: '';
position: absolute;
top: calc((var(--uui-size-space-6) / 2) * -1);
height: 0;
width: 100%;
border-top: solid 1px var(--uui-color-divider-standalone);
}
.divide ::slotted(*)::before {
content: '';
position: absolute;
top: calc((var(--uui-size-space-6) / 2) * -1);
height: 0;
width: 100%;
border-top: solid 1px var(--uui-color-divider-standalone);
}
::slotted(*:first-child) {
margin-top: 0;
}
::slotted(*:first-child) {
margin-top: 0;
}
.divide ::slotted(*:first-child)::before {
display: none;
}
.divide ::slotted(*:first-child)::before {
display: none;
}
.compact ::slotted(*) {
margin-top: var(--uui-size-space-3);
}
.compact ::slotted(*) {
margin-top: var(--uui-size-space-3);
}
.compact ::slotted(*:first-child) {
margin-top: 0;
}
.compact ::slotted(*:first-child) {
margin-top: 0;
}
.compact.divide ::slotted(*)::before {
display: none;
}
`
];
.compact.divide ::slotted(*)::before {
display: none;
}
`,
];
}
export default UmbStackElement;

View File

@@ -8,6 +8,7 @@ import { UmbExtensionsApiInitializer, type UmbEntryPointOnInit } from '@umbraco-
// TODO temp relative import until modules ship a component sub module
import './menu/components/index.js';
import './extension-registry/components/index.js';
export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => {
new UmbExtensionsApiInitializer(host, extensionRegistry, 'globalContext', [host]);

View File

@@ -1,4 +1,4 @@
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
import { umbExtensionsRegistry } from '../../registry.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { TemplateResult } from '@umbraco-cms/backoffice/external/lit';
import { css, repeat, customElement, property, state, html } from '@umbraco-cms/backoffice/external/lit';

View File

@@ -1,4 +1,4 @@
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
import { umbExtensionsRegistry } from '../../registry.js';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { TemplateResult } from '@umbraco-cms/backoffice/external/lit';
import { css, repeat, customElement, property, state, html } from '@umbraco-cms/backoffice/external/lit';

View File

@@ -0,0 +1,2 @@
export * from './extension-slot/index.js';
export * from './extension-with-api-slot/index.js';

View File

@@ -1,7 +1,10 @@
import type { UmbMenuItemElement } from '../interfaces/menu-item-element.interface.js';
import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api';
import type { ConditionTypes } from '../conditions/types.js';
import type { ManifestWithDynamicConditions, ManifestElement } from '@umbraco-cms/backoffice/extension-api';
export interface ManifestMenuItem extends ManifestElement<UmbMenuItemElement> {
export interface ManifestMenuItem
extends ManifestElement<UmbMenuItemElement>,
ManifestWithDynamicConditions<ConditionTypes> {
type: 'menuItem';
meta: MetaMenuItem;
}

View File

@@ -1,13 +1,11 @@
import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui';
import { css, html, customElement, state, repeat, query, nothing } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbIconPickerModalData, UmbIconPickerModalValue } from '@umbraco-cms/backoffice/modal';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import { css, customElement, html, nothing, query, repeat, state } from '@umbraco-cms/backoffice/external/lit';
import { extractUmbColorVariable, umbracoColors } from '@umbraco-cms/backoffice/resources';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_ICON_REGISTRY_CONTEXT, type UmbIconDefinition } from '@umbraco-cms/backoffice/icon';
import type { UmbIconPickerModalData, UmbIconPickerModalValue } from '@umbraco-cms/backoffice/modal';
import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-icon-picker-modal')
export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPickerModalData, UmbIconPickerModalValue> {
@@ -106,12 +104,12 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
<uui-button
slot="actions"
label=${this.localize.term('general_close')}
@click="${this._rejectModal}"></uui-button>
@click=${this._rejectModal}></uui-button>
<uui-button
slot="actions"
color="positive"
look="primary"
@click="${this._submitModal}"
@click=${this._submitModal}
label=${this.localize.term('general_submit')}></uui-button>
</umb-body-layout>
`;
@@ -123,7 +121,7 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
placeholder=${this.localize.term('placeholders_filter')}
label=${this.localize.term('placeholders_filter')}
id="search"
@keyup="${this.#filterIcons}"
@keyup=${this.#filterIcons}
${umbFocus()}>
<uui-icon name="search" slot="prepend" id="search_icon"></uui-icon>
</uui-input>`;
@@ -136,15 +134,14 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
(icon) => icon.name,
(icon) => html`
<uui-button
label="${icon.name}"
title="${icon.name}"
class="${icon.name === this._currentIcon ? 'selected' : ''}"
label=${icon.name}
title=${icon.name}
class=${icon.name === this._currentIcon ? 'selected' : ''}
@click=${(e: InputEvent) => this.#changeIcon(e, icon.name)}
@keyup=${(e: KeyboardEvent) => this.#changeIcon(e, icon.name)}>
<uui-icon
style="--uui-icon-color: var(${extractUmbColorVariable(this._currentColor)})"
name="${icon.name}">
</uui-icon>
name=${icon.name}></uui-icon>
</uui-button>
`,
)

View File

@@ -1,5 +1,6 @@
import { umbExtensionsRegistry, type ManifestPropertyEditorUi } from '../../extension-registry/index.js';
import { UmbPropertyContext } from './property.context.js';
import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement, property, state, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit';
import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api';

View File

@@ -1,8 +1,8 @@
import { html, customElement, state, ifDefined, map } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, customElement, html, ifDefined, map, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section';
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import type { UmbMenuStructureWorkspaceContext, UmbStructureItemModel } from '@umbraco-cms/backoffice/menu';
@customElement('umb-workspace-breadcrumb')
@@ -84,7 +84,14 @@ export class UmbWorkspaceBreadcrumbElement extends UmbLitElement {
`;
}
static styles = [UmbTextStyles];
static styles = [
UmbTextStyles,
css`
:host {
margin-left: var(--uui-size-layout-1);
}
`,
];
}
export default UmbWorkspaceBreadcrumbElement;

View File

@@ -1,12 +1,12 @@
import { html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, customElement, html, ifDefined, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbVariantDatasetWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language';
import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language';
import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section';
import { UMB_VARIANT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language';
import type { UmbVariantDatasetWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
import type { UmbVariantStructureItemModel } from '@umbraco-cms/backoffice/menu';
@customElement('umb-workspace-variant-menu-breadcrumb')
@@ -124,7 +124,14 @@ export class UmbWorkspaceVariantMenuBreadcrumbElement extends UmbLitElement {
`;
}
static styles = [UmbTextStyles];
static styles = [
UmbTextStyles,
css`
:host {
margin-left: var(--uui-size-layout-1);
}
`,
];
}
export default UmbWorkspaceVariantMenuBreadcrumbElement;

View File

@@ -1,11 +1,10 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, nothing, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import type { UmbRoute, UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/backoffice/router';
import type { ManifestWorkspaceView } from '@umbraco-cms/backoffice/extension-registry';
import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit';
import { createExtensionElement, UmbExtensionsManifestInitializer } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbExtensionsManifestInitializer, createExtensionElement } from '@umbraco-cms/backoffice/extension-api';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { ManifestWorkspaceView } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbRoute, UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/backoffice/router';
/**
* @element umb-workspace-editor
@@ -92,14 +91,15 @@ export class UmbWorkspaceEditorElement extends UmbLitElement {
<slot name="action-menu" slot="action-menu"></slot>
${this.#renderRoutes()}
<slot></slot>
${this.enforceNoFooter
? ''
: html`
<umb-workspace-footer slot="footer">
<slot name="footer-info"></slot>
<slot name="actions" slot="actions"></slot>
</umb-workspace-footer>
`}
${when(
!this.enforceNoFooter,
() => html`
<umb-workspace-footer slot="footer">
<slot name="footer-info"></slot>
<slot name="actions" slot="actions"></slot>
</umb-workspace-footer>
`,
)}
</umb-body-layout>
`;
}
@@ -114,10 +114,10 @@ export class UmbWorkspaceEditorElement extends UmbLitElement {
(view) => view.alias,
(view) => html`
<uui-tab
.label="${view.meta.label ? this.localize.string(view.meta.label) : view.name}"
href="${this._routerPath}/view/${view.meta.pathname}"
?active="${'view/' + view.meta.pathname === this._activePath}">
<umb-icon slot="icon" name="${view.meta.icon}"></umb-icon>
.label="${view.meta.label ? this.localize.string(view.meta.label) : view.name}"
?active=${'view/' + view.meta.pathname === this._activePath}>
<umb-icon slot="icon" name=${view.meta.icon}></umb-icon>
${view.meta.label ? this.localize.string(view.meta.label) : view.name}
</uui-tab>
`,
@@ -132,8 +132,8 @@ export class UmbWorkspaceEditorElement extends UmbLitElement {
if (!this.backPath) return nothing;
return html`
<uui-button
class="back-button"
slot="header"
class="back-button"
compact
href=${this.backPath}
label=${this.localize.term('general_back')}>
@@ -143,20 +143,17 @@ export class UmbWorkspaceEditorElement extends UmbLitElement {
}
#renderRoutes() {
if (!this._routes || this._routes.length === 0) return nothing;
return html`
${this._routes && this._routes.length > 0
? html`
<umb-router-slot
id="router-slot"
.routes="${this._routes}"
@init=${(event: UmbRouterSlotInitEvent) => {
this._routerPath = event.target.absoluteRouterPath;
}}
@change=${(event: UmbRouterSlotChangeEvent) => {
this._activePath = event.target.localActiveViewPath;
}}></umb-router-slot>
`
: nothing}
<umb-router-slot
id="router-slot"
.routes=${this._routes}
@init=${(event: UmbRouterSlotInitEvent) => {
this._routerPath = event.target.absoluteRouterPath;
}}
@change=${(event: UmbRouterSlotChangeEvent) => {
this._activePath = event.target.localActiveViewPath;
}}></umb-router-slot>
`;
}

View File

@@ -84,7 +84,7 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbModalBaseElement<
render() {
return html`
<umb-body-layout headline="Select Property Editor UI">
<umb-body-layout headline=${this.localize.term('propertyEditorPicker_openPropertyEditorPicker')}>
<uui-box> ${this._renderFilter()} ${this._renderGrid()} </uui-box>
<div slot="actions">
<uui-button label="Close" @click=${this._rejectModal}></uui-button>

View File

@@ -38,11 +38,8 @@ export class UmbDictionaryWorkspaceEditorElement extends UmbLitElement {
render() {
return html`
<umb-workspace-editor alias="Umb.Workspace.Dictionary">
<umb-workspace-editor alias="Umb.Workspace.Dictionary" back-path="section/dictionary/dashboard">
<div id="header" slot="header">
<uui-button href="section/dictionary/dashboard" label=${this.localize.term('general_backToOverview')} compact>
<uui-icon name="icon-arrow-left"></uui-icon>
</uui-button>
<uui-input
placeholder=${this.localize.term('placeholders_entername')}
.value=${this._name ?? ''}

View File

@@ -430,20 +430,6 @@ export class UmbDocumentBlueprintWorkspaceContext
}
}
/*
concept notes:
public saveAndPreview() {
}
*/
/*public createPropertyDatasetContext(host: UmbControllerHost, variantId: UmbVariantId) {
// TODO: [LK] Temporary workaround/hack to get the workspace to load.
const docCxt = new UmbDocumentWorkspaceContext(host);
return new UmbDocumentPropertyDataContext(host, docCxt, variantId);
}*/
public createPropertyDatasetContext(host: UmbControllerHost, variantId: UmbVariantId) {
return new UmbDocumentBlueprintPropertyDataContext(host, this, variantId);
}

View File

@@ -83,10 +83,8 @@ export class UmbDocumentTypeWorkspaceViewStructureElement extends UmbLitElement
<umb-input-document-type
.documentTypesOnly=${true}
.selection=${this._allowedContentTypeUniques ?? []}
@change="${(e: CustomEvent) => {
const sortedContentTypesList: Array<UmbContentTypeSortModel> = (
e.target as UmbInputDocumentTypeElement
).selection.map((id, index) => ({
@change="${(e: CustomEvent & { target: UmbInputDocumentTypeElement }) => {
const sortedContentTypesList: Array<UmbContentTypeSortModel> = e.target.selection.map((id, index) => ({
contentType: { unique: id },
sortOrder: index,
}));

View File

@@ -0,0 +1,25 @@
import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type {
UmbConditionConfigBase,
UmbConditionControllerArguments,
UmbExtensionCondition,
} from '@umbraco-cms/backoffice/extension-api';
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
export class UmbAllowDocumentRecycleBinCurrentUserCondition
extends UmbConditionBase<UmbConditionConfigBase>
implements UmbExtensionCondition
{
constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<UmbConditionConfigBase>) {
super(host, args);
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(context.hasDocumentRootAccess, (hasAccess) => {
this.permitted = hasAccess === true;
});
});
}
}
export { UmbAllowDocumentRecycleBinCurrentUserCondition as api };

View File

@@ -5,6 +5,12 @@ import { manifests as treeManifests } from './tree/manifests.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const manifests: Array<ManifestTypes> = [
{
type: 'condition',
name: 'Allow Document Recycle Bin Current User Condition',
alias: 'Umb.Condition.CurrentUser.AllowDocumentRecycleBin',
api: () => import('./allow-document-recycle-bin.condition.js'),
},
...entityActionManifests,
...menuItemManifests,
...repositoryManifests,

View File

@@ -14,6 +14,11 @@ const menuItem: ManifestMenuItemTreeKind = {
icon: 'icon-trash',
menus: [UMB_CONTENT_MENU_ALIAS],
},
conditions: [
{
alias: 'Umb.Condition.CurrentUser.AllowDocumentRecycleBin',
},
],
};
export const manifests: Array<ManifestTypes> = [menuItem];

View File

@@ -45,11 +45,10 @@ export class UmbLanguageWorkspaceEditorElement extends UmbLitElement {
}
render() {
return html`<umb-workspace-editor alias="Umb.Workspace.Language">
return html`<umb-workspace-editor
alias="Umb.Workspace.Language"
back-path="section/settings/workspace/language-root">
<div id="header" slot="header">
<uui-button label="Navigate back" href="section/settings/workspace/language-root" compact>
<uui-icon name="icon-arrow-left"></uui-icon>
</uui-button>
${this._isNew
? html`<strong>Add language</strong>`
: html`<uui-input
@@ -66,7 +65,6 @@ export class UmbLanguageWorkspaceEditorElement extends UmbLitElement {
css`
#header {
display: flex;
padding: 0 var(--uui-size-space-6);
gap: var(--uui-size-space-4);
width: 100%;
}

View File

@@ -544,20 +544,23 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement,
}
render() {
return html` <div id="actions">${this._renderBasicActions()}</div>
return html`
<div id="actions">${this._renderBasicActions()}</div>
<umb-code-editor
language="markdown"
theme="umb-light"
.code=${this.value as string}
@keypress=${this.onKeyPress}
@input=${this.#onInput}
theme="umb-light"></umb-code-editor>
${when(this.preview && this.value, () => this.renderPreview(this.value as string))}`;
@input=${this.#onInput}>
</umb-code-editor>
${when(this.preview && this.value, () => this.renderPreview(this.value as string))}
`;
}
renderPreview(markdown: string) {
const markdownAsHtml = marked.parse(markdown) as string;
const sanitizedHtml = markdownAsHtml ? DOMPurify.sanitize(markdownAsHtml) : '';
return html`<uui-scroll-container id="preview"> ${unsafeHTML(sanitizedHtml)} </uui-scroll-container>`;
return html`<uui-scroll-container id="preview">${unsafeHTML(sanitizedHtml)}</uui-scroll-container>`;
}
static styles = [

View File

@@ -27,17 +27,19 @@ export class UmbPropertyEditorUIMarkdownEditorElement extends UmbLitElement impl
this._overlaySize = config?.getValueByAlias('overlaySize') ?? undefined;
}
#onChange(e: Event) {
this.value = (e.target as UmbInputMarkdownElement).value as string;
#onChange(event: Event & { target: UmbInputMarkdownElement }) {
this.value = event.target.value as string;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`<umb-input-markdown
?preview=${this._preview}
.overlaySize=${this._overlaySize}
@change=${this.#onChange}
.value=${this.value}></umb-input-markdown>`;
return html`
<umb-input-markdown
value=${this.value}
.overlaySize=${this._overlaySize}
?preview=${this._preview}
@change=${this.#onChange}></umb-input-markdown>
`;
}
}

View File

@@ -0,0 +1,25 @@
import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type {
UmbConditionConfigBase,
UmbConditionControllerArguments,
UmbExtensionCondition,
} from '@umbraco-cms/backoffice/extension-api';
import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user';
export class UmbAllowMediaRecycleBinCurrentUserCondition
extends UmbConditionBase<UmbConditionConfigBase>
implements UmbExtensionCondition
{
constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<UmbConditionConfigBase>) {
super(host, args);
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(context.hasMediaRootAccess, (hasAccess) => {
this.permitted = hasAccess === true;
});
});
}
}
export { UmbAllowMediaRecycleBinCurrentUserCondition as api };

View File

@@ -5,6 +5,12 @@ import { manifests as treeManifests } from './tree/manifests.js';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
export const manifests: Array<ManifestTypes> = [
{
type: 'condition',
name: 'Allow Media Recycle Bin Current User Condition',
alias: 'Umb.Condition.CurrentUser.AllowMediaRecycleBin',
api: () => import('./allow-media-recycle-bin.condition.js'),
},
...entityActionManifests,
...menuItemManifests,
...repositoryManifests,

View File

@@ -14,6 +14,11 @@ const menuItem: ManifestMenuItemTreeKind = {
icon: 'icon-trash',
menus: [UMB_MEDIA_MENU_ALIAS],
},
conditions: [
{
alias: 'Umb.Condition.CurrentUser.AllowMediaRecycleBin',
},
],
};
export const manifests: Array<ManifestTypes> = [menuItem];

View File

@@ -125,10 +125,8 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement {
render() {
if (!this.workspaceAlias) return nothing;
return html`
<umb-workspace-editor alias=${this.workspaceAlias}>
${this.#renderHeader()}
${this.#renderEditors()}
${this.#renderActions()}
<umb-workspace-editor alias=${this.workspaceAlias} back-path="section/packages/view/created">
${this.#renderHeader()} ${this.#renderEditors()} ${this.#renderActions()}
</umb-workspace-editor>
`;
}
@@ -137,9 +135,6 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement {
if (!this._package) return nothing;
return html`
<div id="header" slot="header">
<uui-button href="section/packages/view/created" label=${this.localize.term('general_backToOverview')} compact>
<uui-icon name="icon-arrow-left"></uui-icon>
</uui-button>
<uui-input
id="package-name-input"
required
@@ -178,17 +173,10 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement {
#renderEditors() {
return html`
<uui-box headline="Package Content">
${this.#renderDocumentSection()}
${this.#renderMediaSection()}
${this.#renderDocumentTypeSection()}
${this.#renderMediaTypeSection()}
${this.#renderLanguageSection()}
${this.#renderDictionarySection()}
${this.#renderDataTypeSection()}
${this.#renderTemplateSection()}
${this.#renderStylesheetsSection()}
${this.#renderScriptsSection()}
${this.#renderPartialViewSection()}
${this.#renderDocumentSection()} ${this.#renderMediaSection()} ${this.#renderDocumentTypeSection()}
${this.#renderMediaTypeSection()} ${this.#renderLanguageSection()} ${this.#renderDictionarySection()}
${this.#renderDataTypeSection()} ${this.#renderTemplateSection()} ${this.#renderStylesheetsSection()}
${this.#renderScriptsSection()} ${this.#renderPartialViewSection()}
</uui-box>
`;
}

View File

@@ -36,7 +36,9 @@ export class UmbRelationTypeWorkspaceEditorElement extends UmbLitElement {
render() {
return html`
<umb-workspace-editor alias="Umb.Workspace.RelationType">
<umb-workspace-editor
alias="Umb.Workspace.RelationType"
back-path="section/settings/workspace/relation-type-root">
<div id="header" slot="header">
<uui-input id="name" .value=${this._name} readonly>
<div id="alias" slot="append">${this._alias}</div>

View File

@@ -14,6 +14,8 @@ export class UmbCurrentUserContext extends UmbContextBase<UmbCurrentUserContext>
readonly unique = this.#currentUser.asObservablePart((user) => user?.unique);
readonly languageIsoCode = this.#currentUser.asObservablePart((user) => user?.languageIsoCode);
readonly hasDocumentRootAccess = this.#currentUser.asObservablePart((user) => user?.hasDocumentRootAccess);
readonly hasMediaRootAccess = this.#currentUser.asObservablePart((user) => user?.hasMediaRootAccess);
#authContext?: typeof UMB_AUTH_CONTEXT.TYPE;
#currentUserRepository = new UmbCurrentUserRepository(this);

View File

@@ -30,20 +30,22 @@ export class UmbCurrentUserServerDataSource {
if (data) {
const user: UmbCurrentUserModel = {
unique: data.id,
email: data.email,
userName: data.userName,
name: data.name,
languageIsoCode: data.languageIsoCode || 'en-us', // TODO: make global variable
documentStartNodeUniques: data.documentStartNodeIds,
mediaStartNodeUniques: data.mediaStartNodeIds,
avatarUrls: data.avatarUrls,
languages: data.languages,
hasAccessToAllLanguages: data.hasAccessToAllLanguages,
fallbackPermissions: data.fallbackPermissions,
permissions: data.permissions,
allowedSections: data.allowedSections,
avatarUrls: data.avatarUrls,
documentStartNodeUniques: data.documentStartNodeIds,
email: data.email,
fallbackPermissions: data.fallbackPermissions,
hasAccessToAllLanguages: data.hasAccessToAllLanguages,
hasDocumentRootAccess: data.hasDocumentRootAccess,
hasMediaRootAccess: data.hasMediaRootAccess,
isAdmin: data.isAdmin,
languageIsoCode: data.languageIsoCode || 'en-us', // TODO: make global variable
languages: data.languages,
mediaStartNodeUniques: data.mediaStartNodeIds,
name: data.name,
permissions: data.permissions,
unique: data.id,
userName: data.userName,
};
return { data: user };
}

View File

@@ -49,11 +49,7 @@ export class UmbCurrentUserThemeUserProfileAppElement extends UmbLitElement {
if (!this._themes.length) return nothing;
return html`
<uui-box headline="Select theme">
<uui-select
label="Select theme"
.options=${this._themes}
.value=${this._themeAlias}
@change=${this.#onThemeChange}></uui-select>
<uui-select label="Select theme" .options=${this._themes} @change=${this.#onThemeChange}></uui-select>
</uui-box>
`;
}

View File

@@ -8,20 +8,22 @@ import type {
} from '@umbraco-cms/backoffice/external/backend-api';
export interface UmbCurrentUserModel {
unique: string;
email: string;
userName: string;
name: string;
languageIsoCode: string;
documentStartNodeUniques: Array<string>;
mediaStartNodeUniques: Array<string>;
avatarUrls: Array<string>;
languages: Array<string>;
hasAccessToAllLanguages: boolean;
allowedSections: Array<string>;
avatarUrls: Array<string>;
documentStartNodeUniques: Array<string>;
email: string;
fallbackPermissions: Array<string>;
permissions: Array<DocumentPermissionPresentationModel | UnknownTypePermissionPresentationModel>;
hasAccessToAllLanguages: boolean;
hasDocumentRootAccess: boolean;
hasMediaRootAccess: boolean;
isAdmin: boolean;
languageIsoCode: string;
languages: Array<string>;
mediaStartNodeUniques: Array<string>;
name: string;
permissions: Array<DocumentPermissionPresentationModel | UnknownTypePermissionPresentationModel>;
unique: string;
userName: string;
}
export type UmbCurrentUserExternalLoginProviderModel = LinkedLoginModel;

View File

@@ -135,8 +135,8 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '')
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label="${this.localize.term('general_choose')}"></uui-button>
label=${this.localize.term('general_choose')}
@click=${this.#openPicker}></uui-button>
`;
}