From 7b8988de4f86143d3cf96cb8533318ec7c0b0f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 15:35:11 +0200 Subject: [PATCH 01/11] only single block type create label --- .../property-editor-ui-block-list.element.ts | 21 +++++++++++-------- .../block/context/block-manager.context.ts | 11 +++++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts index 7c8a9a9297..37270913ec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts @@ -82,20 +82,23 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement const blocks = config.getValueByAlias>('blocks') ?? []; this.#managerContext.setBlockTypes(blocks); + const useInlineEditingAsDefault = config.getValueByAlias('useInlineEditingAsDefault'); + this.#managerContext.setInlineEditingMode(useInlineEditingAsDefault); + this.style.maxWidth = config.getValueByAlias('maxPropertyWidth') ?? ''; + // TODO: + //config.useSingleBlockMode, not done jet + + this.#managerContext.setEditorConfiguration(config); + const customCreateButtonLabel = config.getValueByAlias('createLabel'); if (customCreateButtonLabel) { this._createButtonLabel = customCreateButtonLabel; } else if (blocks.length === 1) { - this._createButtonLabel = `${this.localize.term('general_add')} ${blocks[0].label}`; + this.#managerContext.contentTypesLoaded.then(() => { + const firstContentTypeName = this.#managerContext.getContentTypeNameOf(blocks[0].contentElementTypeKey); + this._createButtonLabel = `${this.localize.term('general_add')} ${firstContentTypeName}`; + }); } - - const useInlineEditingAsDefault = config.getValueByAlias('useInlineEditingAsDefault'); - this.#managerContext.setInlineEditingMode(useInlineEditingAsDefault); - // TODO: - //config.useSingleBlockMode, not done jet - this.style.maxWidth = config.getValueByAlias('maxPropertyWidth') ?? ''; - - this.#managerContext.setEditorConfiguration(config); } @state() diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index 03d5ec7a0e..c8c9ab528b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -26,6 +26,10 @@ export abstract class UmbBlockManagerContext< BlockLayoutType extends UmbBlockLayoutBaseModel = UmbBlockLayoutBaseModel, > extends UmbContextBase { // + get contentTypesLoaded() { + return Promise.all(this.#contentTypeRequests); + } + #contentTypeRequests: Array> = []; #contentTypeRepository = new UmbDocumentTypeDetailRepository(this); #propertyAlias = new UmbStringState(undefined); @@ -115,7 +119,9 @@ export abstract class UmbBlockManagerContext< async #ensureContentType(unique: string) { if (this.#contentTypes.getValue().find((x) => x.unique === unique)) return; - const { data } = await this.#contentTypeRepository.requestByUnique(unique); + const contentTypeRequest = this.#contentTypeRepository.requestByUnique(unique); + this.#contentTypeRequests.push(contentTypeRequest); + const { data } = await contentTypeRequest; if (!data) { this.#contentTypes.removeOne(unique); return; @@ -132,6 +138,9 @@ export abstract class UmbBlockManagerContext< contentTypeNameOf(contentTypeKey: string) { return this.#contentTypes.asObservablePart((source) => source.find((x) => x.unique === contentTypeKey)?.name); } + getContentTypeNameOf(contentTypeKey: string) { + return this.#contentTypes.getValue().find((x) => x.unique === contentTypeKey)?.name; + } blockTypeOf(contentTypeKey: string) { return this.#blockTypes.asObservablePart((source) => source.find((x) => x.contentElementTypeKey === contentTypeKey), From 9891a052591fc4aa21eff10367cd3c9e6db312e8 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 15 May 2024 16:37:55 +0200 Subject: [PATCH 02/11] Feature: Imaging Endpoint --- src/Umbraco.Web.UI.Client/package.json | 1 + .../src/external/backend-api/src/models.ts | 36 ++++++++++++ .../src/external/backend-api/src/services.ts | 46 +++++++++++++++- .../core/imaging/imaging.repository.ts | 40 ++++++++++++++ .../core/imaging/imaging.server.data.ts | 53 ++++++++++++++++++ .../packages/core/imaging/imaging.store.ts | 26 +++++++++ .../src/packages/core/imaging/index.ts | 2 + .../src/packages/core/imaging/manifests.ts | 13 +++++ .../src/packages/core/imaging/types.ts | 8 +++ .../src/packages/core/manifests.ts | 2 + .../collection/media-collection.context.ts | 26 +++++++++ .../packages/media/media/collection/types.ts | 2 +- .../media-grid-collection-view.element.ts | 10 +++- .../media-table-collection-view.element.ts | 1 - .../media-picker-folder-path.element.ts | 55 +++++++++---------- .../media-picker-modal.element.ts | 51 ++++++++++++----- .../media/media/modals/media-picker/types.ts | 2 +- .../packages/media/media/repository/index.ts | 1 + src/Umbraco.Web.UI.Client/tsconfig.json | 1 + 19 files changed, 327 insertions(+), 49 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 8eb55c55d8..8f052df085 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -41,6 +41,7 @@ "./extension-registry": "./dist-cms/packages/core/extension-registry/index.js", "./icon": "./dist-cms/packages/core/icon-registry/index.js", "./id": "./dist-cms/packages/core/id/index.js", + "./imaging": "./dist-cms/packages/core/imaging/index.js", "./language": "./dist-cms/packages/language/index.js", "./lit-element": "./dist-cms/packages/core/lit-element/index.js", "./localization": "./dist-cms/packages/core/localization/index.js", diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models.ts index da4e84c5d8..1eb1880137 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models.ts @@ -991,6 +991,15 @@ url?: string | null type?: string | null }; +export enum ImageCropModeModel { + CROP = 'Crop', + MAX = 'Max', + STRETCH = 'Stretch', + PAD = 'Pad', + BOX_PAD = 'BoxPad', + MIN = 'Min' +} + export type ImportDictionaryRequestModel = { temporaryFile: ReferenceByIdModel parent?: ReferenceByIdModel | null @@ -2574,6 +2583,12 @@ value: string key: string }; +export type UserExternalLoginProviderModel = { + providerSchemeName: string +isLinkedOnUser: boolean +hasManualLinkingEnabled: boolean + }; + export type UserGroupItemResponseModel = { id: string name: string @@ -3510,6 +3525,26 @@ tree?: string } +export type ImagingData = { + + payloads: { + GetImagingResizeUrls: { + height?: number +id?: Array +mode?: ImageCropModeModel +width?: number + + }; + } + + + responses: { + GetImagingResizeUrls: Array + + } + + } + export type IndexerData = { payloads: { @@ -5205,6 +5240,7 @@ PostUserUnlock: { ,PostUserCurrentAvatar: string ,PostUserCurrentChangePassword: string ,GetUserCurrentConfiguration: CurrenUserConfigurationResponseModel + ,GetUserCurrentLoginProviders: Array ,GetUserCurrentLogins: LinkedLoginsRequestModel ,GetUserCurrentPermissions: UserPermissionsResponseModel ,GetUserCurrentPermissionsDocument: Array diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services.ts index 84d88c42c7..c634a46642 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services.ts @@ -1,7 +1,7 @@ import type { CancelablePromise } from './core/CancelablePromise'; import { OpenAPI } from './core/OpenAPI'; import { request as __request } from './core/request'; -import type { CultureData, DataTypeData, DictionaryData, DocumentBlueprintData, DocumentTypeData, DocumentVersionData, DocumentData, DynamicRootData, HealthCheckData, HelpData, IndexerData, InstallData, LanguageData, LogViewerData, ManifestData, MediaTypeData, MediaData, MemberGroupData, MemberTypeData, MemberData, ModelsBuilderData, ObjectTypesData, OembedData, PackageData, PartialViewData, PreviewData, ProfilingData, PropertyTypeData, PublishedCacheData, RedirectManagementData, RelationTypeData, RelationData, ScriptData, SearcherData, SecurityData, SegmentData, ServerData, StaticFileData, StylesheetData, TagData, TelemetryData, TemplateData, TemporaryFileData, UpgradeData, UserDataData, UserGroupData, UserData, WebhookData } from './models'; +import type { CultureData, DataTypeData, DictionaryData, DocumentBlueprintData, DocumentTypeData, DocumentVersionData, DocumentData, DynamicRootData, HealthCheckData, HelpData, ImagingData, IndexerData, InstallData, LanguageData, LogViewerData, ManifestData, MediaTypeData, MediaData, MemberGroupData, MemberTypeData, MemberData, ModelsBuilderData, ObjectTypesData, OembedData, PackageData, PartialViewData, PreviewData, ProfilingData, PropertyTypeData, PublishedCacheData, RedirectManagementData, RelationTypeData, RelationData, ScriptData, SearcherData, SecurityData, SegmentData, ServerData, StaticFileData, StylesheetData, TagData, TelemetryData, TemplateData, TemporaryFileData, UpgradeData, UserDataData, UserGroupData, UserData, WebhookData } from './models'; export class CultureService { @@ -2917,6 +2917,35 @@ baseUrl } +export class ImagingService { + + /** + * @returns unknown Success + * @throws ApiError + */ + public static getImagingResizeUrls(data: ImagingData['payloads']['GetImagingResizeUrls'] = {}): CancelablePromise { + const { + + id, +height, +width, +mode + } = data; + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/imaging/resize/urls', + query: { + id, height, width, mode + }, + errors: { + 401: `The resource is protected and requires an authentication token`, + 403: `The authenticated user do not have access to this resource`, + }, + }); + } + +} + export class IndexerService { /** @@ -8657,6 +8686,21 @@ requestBody }); } + /** + * @returns unknown Success + * @throws ApiError + */ + public static getUserCurrentLoginProviders(): CancelablePromise { + + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/user/current/login-providers', + errors: { + 401: `The resource is protected and requires an authentication token`, + }, + }); + } + /** * @returns unknown Success * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts new file mode 100644 index 0000000000..aae7b477f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts @@ -0,0 +1,40 @@ +import type { UmbImagingModel } from './types.js'; +import { UmbImagingServerDataSource } from './imaging.server.data.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export class UmbImagingRepository extends UmbControllerBase implements UmbApi { + //protected _init: Promise; + //protected _itemStore?: UmbImagingStore; + #itemSource: UmbImagingServerDataSource; + + constructor(host: UmbControllerHost) { + super(host); + this.#itemSource = new UmbImagingServerDataSource(host); + + /*this._init = this.consumeContext(UMB_IMAGING_STORE_CONTEXT, (instance) => { + this._itemStore = instance as UmbImagingStore; + }).asPromise();*/ + } + + /** + * Requests the items for the given uniques + * @param {Array} uniques + * @return {*} + * @memberof UmbImagingRepository + */ + async requestResizedItems({ uniques, height, width, mode }: UmbImagingModel) { + if (!uniques.length) throw new Error('Uniques are missing'); + //await this._init; + + const { data, error: _error } = await this.#itemSource.getItems({ uniques, height, width, mode }); + const error: any = _error; + /*if (data) { + this._itemStore!.appendItems(data); + } + return { data, error, asObservable: () => this._itemStore!.items(uniques) };*/ + + return { data, error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts new file mode 100644 index 0000000000..ab297cff99 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts @@ -0,0 +1,53 @@ +import type { UmbImagingModel } from './types.js'; +import { ImagingService, type MediaUrlInfoResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbMediaUrlModel } from '@umbraco-cms/backoffice/media'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for the Imaging Service that resizes a media item from the server + * @export + * @class UmbImagingServerDataSource + * @implements {RepositoryDetailDataSource} + */ +export class UmbImagingServerDataSource { + #host: UmbControllerHost; + + /** + * Creates an instance of UmbImagingServerDataSource. + * @param {UmbControllerHost} host + * @memberof UmbImagingServerDataSource + */ + constructor(host: UmbControllerHost) { + this.#host = host; + } + + /** + * Fetches the URL for the given media items as resized images + * @param {string} unique + * @memberof UmbImagingServerDataSource + */ + async getItems({ uniques, width, height, mode }: UmbImagingModel) { + if (!uniques.length) throw new Error('Uniques are missing'); + + const { data, error } = await tryExecuteAndNotify( + this.#host, + ImagingService.getImagingResizeUrls({ id: uniques, width, height, mode }), + ); + + if (data) { + const items = data.map((item) => this.#mapper(item)); + return { data: items }; + } + + return { error }; + } + + #mapper(item: MediaUrlInfoResponseModel): UmbMediaUrlModel { + const url = item.urlInfos[0]?.url; + return { + unique: item.id, + url: url, + }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts new file mode 100644 index 0000000000..acbb9b5f6e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts @@ -0,0 +1,26 @@ +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store'; +import type { UmbMediaUrlModel } from '@umbraco-cms/backoffice/media'; + +/** + * @export + * @class UmbImagingStore + * @extends {UmbStoreBase} + * @description - Data Store for Imaging Items + */ + +export class UmbImagingStore extends UmbItemStoreBase { + /** + * Creates an instance of UmbImagingStore. + * @param {UmbControllerHost} host + * @memberof UmbImagingStore + */ + constructor(host: UmbControllerHost) { + super(host, UMB_IMAGING_STORE_CONTEXT.toString()); + } +} + +export default UmbImagingStore; + +export const UMB_IMAGING_STORE_CONTEXT = new UmbContextToken('UmbImagingStore'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/index.ts new file mode 100644 index 0000000000..e775891ff3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/index.ts @@ -0,0 +1,2 @@ +export { UmbImagingRepository } from './imaging.repository.js'; +export { UMB_IMAGING_REPOSITORY_ALIAS } from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/manifests.ts new file mode 100644 index 0000000000..323441b6da --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/manifests.ts @@ -0,0 +1,13 @@ +import { UmbImagingRepository } from './imaging.repository.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_IMAGING_REPOSITORY_ALIAS = 'Umb.Repository.Imaging'; + +const repository: ManifestRepository = { + type: 'repository', + alias: UMB_IMAGING_REPOSITORY_ALIAS, + name: 'Imaging Repository', + api: UmbImagingRepository, +}; + +export const manifests: Array = [repository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts new file mode 100644 index 0000000000..cc3b637a97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts @@ -0,0 +1,8 @@ +import type { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; + +export interface UmbImagingModel { + uniques: Array; + height?: number; + width?: number; + mode?: ImageCropModeModel; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts index 460f7acc8d..22d8b9f67f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/manifests.ts @@ -7,6 +7,7 @@ import { manifests as debugManifests } from './debug/manifests.js'; import { manifests as entityActionManifests } from './entity-action/manifests.js'; import { manifests as extensionManifests } from './extension-registry/manifests.js'; import { manifests as iconRegistryManifests } from './icon-registry/manifests.js'; +import { manifests as imagingManifests } from './imaging/manifests.js'; import { manifests as localizationManifests } from './localization/manifests.js'; import { manifests as modalManifests } from './modal/common/manifests.js'; import { manifests as propertyActionManifests } from './property-action/manifests.js'; @@ -24,6 +25,7 @@ export const manifests: Array = [ ...authManifests, ...extensionManifests, ...iconRegistryManifests, + ...imagingManifests, ...cultureManifests, ...localizationManifests, ...themeManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts index bcf2f7ffe2..5a9078f6ea 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts @@ -1,13 +1,39 @@ +import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging'; import type { UmbMediaCollectionFilterModel, UmbMediaCollectionItemModel } from './types.js'; import { UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS } from './views/index.js'; +import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; export class UmbMediaCollectionContext extends UmbDefaultCollectionContext< UmbMediaCollectionItemModel, UmbMediaCollectionFilterModel > { + #imagingRepository: UmbImagingRepository; + + #thumbnailItems = new UmbArrayState([], (x) => x); + public readonly thumbnailItems = this.#thumbnailItems.asObservable(); + constructor(host: UmbControllerHost) { super(host, UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS); + this.#imagingRepository = new UmbImagingRepository(host); + + this.observe(this.items, async (items) => { + if (!items?.length) return; + + const { data } = await this.#imagingRepository.requestResizedItems({ + uniques: items.map((m) => m.unique), + width: 250, + mode: ImageCropModeModel.MIN, + }); + + this.#thumbnailItems.setValue( + items.map((item) => { + const thumbnail = data?.find((m) => m.unique === item.unique)?.url; + return { ...item, url: thumbnail }; + }), + ); + }); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts index 729e57f8b2..d12a162972 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts @@ -20,10 +20,10 @@ export interface UmbMediaCollectionItemModel { updateDate: Date; updater?: string | null; values: Array<{ alias: string; value: string }>; + url?: string; } export interface UmbEditableMediaCollectionItemModel { item: UmbMediaCollectionItemModel; editPath: string; } - diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts index 43201b8839..d8e8f2d220 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts @@ -26,7 +26,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { constructor() { super(); this.consumeContext(UMB_COLLECTION_CONTEXT, (collectionContext) => { - this.#collectionContext = collectionContext; + this.#collectionContext = collectionContext as UmbMediaCollectionContext; this.#observeCollectionContext(); }); @@ -51,7 +51,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { this.observe(this.#collectionContext.loading, (loading) => (this._loading = loading), '_observeLoading'); - this.observe(this.#collectionContext.items, (items) => (this._items = items), '_observeItems'); + this.observe(this.#collectionContext.thumbnailItems, (items) => (this._items = items), '_observeItems'); this.observe( this.#collectionContext.selection.selection, @@ -128,6 +128,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { @deselected=${() => this.#onDeselect(item)} class="media-item" file-ext="${item.icon}"> + ${item.url ? html`${item.name}` : html``} @@ -151,9 +152,12 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { #media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - grid-template-rows: repeat(auto-fill, 200px); + grid-auto-rows: 200px; gap: var(--uui-size-space-5); } + umb-icon { + font-size: var(--uui-size-24); + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts index 86d2451247..559c9f62df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts @@ -253,7 +253,6 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { box-sizing: border-box; height: auto; width: 100%; - padding: var(--uui-size-space-3) var(--uui-size-space-6); } .container { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/components/media-picker-folder-path.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/components/media-picker-folder-path.element.ts index cb03f97e42..838c7b5f5f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/components/media-picker-folder-path.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/components/media-picker-folder-path.element.ts @@ -2,24 +2,23 @@ import type { UmbMediaPathModel } from '../types.js'; import type { UmbMediaDetailModel } from '../../../types.js'; import { UmbMediaDetailRepository } from '../../../repository/index.js'; import { UmbMediaTreeRepository } from '../../../tree/index.js'; -import { UMB_MEDIA_ROOT_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_MEDIA_ENTITY_TYPE, UMB_MEDIA_ROOT_ENTITY_TYPE } from '../../../entity.js'; import { css, html, customElement, state, repeat, property } from '@umbraco-cms/backoffice/external/lit'; import type { UUIInputElement, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { UmbId } from '@umbraco-cms/backoffice/id'; import { getUmbracoFolderUnique } from '@umbraco-cms/backoffice/media-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; -// TODO: get root from tree repository -const root = { name: 'Media', unique: null, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE }; +const root: UmbMediaPathModel = { name: 'Media', unique: null, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE }; @customElement('umb-media-picker-folder-path') export class UmbMediaPickerFolderPathElement extends UmbLitElement { #mediaTreeRepository = new UmbMediaTreeRepository(this); // used to get file structure #mediaDetailRepository = new UmbMediaDetailRepository(this); // used to create folders - @property({ type: Object, attribute: false }) - public set currentMedia(value: UmbEntityModel | undefined) { + @property({ attribute: false }) + public set currentMedia(value: UmbMediaPathModel) { if (value !== this._currentMedia) { this._currentMedia = value; this.#loadPath(); @@ -31,7 +30,7 @@ export class UmbMediaPickerFolderPathElement extends UmbLitElement { } @state() - private _currentMedia: UmbEntityModel | undefined; + private _currentMedia: UmbMediaPathModel = root; @state() private _paths: Array = [root]; @@ -45,32 +44,30 @@ export class UmbMediaPickerFolderPathElement extends UmbLitElement { } async #loadPath() { - const unique = this._currentMedia?.unique; - const entityType = this._currentMedia?.entityType; + const unique = this._currentMedia.unique; - if (unique && entityType) { - const { data } = await this.#mediaTreeRepository.requestTreeItemAncestors({ - treeItem: { - unique, - entityType, - }, - }); + const items = unique + ? ( + await this.#mediaTreeRepository.requestTreeItemAncestors({ + treeItem: { unique, entityType: UMB_MEDIA_ENTITY_TYPE }, + }) + ).data + : undefined; - if (data) { - this._paths = [ - root, - ...data.map((item) => ({ name: item.name, unique: item.unique, entityType: item.entityType })), - ]; - return; - } + if (items) { + this._paths = [ + root, + ...items.map((item) => ({ name: item.name, unique: item.unique, entityType: item.entityType })), + ]; + return; } - this._paths = [root]; } - #goToFolder(entity: UmbEntityModel) { + #goToFolder(entity: UmbMediaPathModel) { this._paths = [...this._paths].slice(0, this._paths.findIndex((path) => path.unique === entity.unique) + 1); this.currentMedia = entity; + this.dispatchEvent(new UmbChangeEvent()); } #focusFolderInput() { @@ -84,6 +81,7 @@ export class UmbMediaPickerFolderPathElement extends UmbLitElement { async #addFolder(e: UUIInputEvent) { e.stopPropagation(); + const newName = e.target.value as string; this._typingNewFolder = false; if (!newName) return; @@ -118,7 +116,8 @@ export class UmbMediaPickerFolderPathElement extends UmbLitElement { const entityType = data.entityType; this._paths = [...this._paths, { name, unique, entityType }]; - this.currentMedia = { unique, entityType }; + this.currentMedia = { name, unique, entityType }; + this.dispatchEvent(new UmbChangeEvent()); } render() { @@ -130,8 +129,8 @@ export class UmbMediaPickerFolderPathElement extends UmbLitElement { html` this.#goToFolder({ unique: path.unique, entityType: path.entityType })}> this.#goToFolder(path)}>/`, )}${this._typingNewFolder ? html` { #mediaTreeRepository = new UmbMediaTreeRepository(this); // used to get file structure #mediaUrlRepository = new UmbMediaUrlRepository(this); // used to get urls - #mediaItemRepository = new UmbMediaItemRepository(this); // used to search & get media type of current path + #mediaItemRepository = new UmbMediaItemRepository(this); // used to search + #imagingRepository = new UmbImagingRepository(this); // used to get image renditions #mediaItemsCurrentFolder: Array = []; @@ -27,7 +31,8 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement { super.connectedCallback(); @@ -35,7 +40,7 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement): Promise> { if (!items.length) return []; - const { data } = await this.#mediaUrlRepository.requestItems(items.map((item) => item.unique)); + const { data } = await this.#imagingRepository.requestResizedItems({ + uniques: items.map((item) => item.unique), + width: 250, + mode: ImageCropModeModel.MIN, + }); return items.map((item): UmbMediaCardItemModel => { const url = data?.find((media) => media.unique === item.unique)?.url; - const extension = url?.split('.').pop(); - //TODO Eventually we will get a renderable img from the server. Use this for the url. [LI] - return { name: item.name, unique: item.unique, url, extension, entityType: item.entityType }; + + return { name: item.name, unique: item.unique, url, icon: item.mediaType.icon, entityType: item.entityType }; }); } #onOpen(item: UmbMediaCardItemModel) { this._currentMediaEntity = { + name: item.name, unique: item.unique, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE, }; @@ -189,9 +198,10 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement this.#onSelected(item)} @deselected=${() => this.#onDeselected(item)} ?selected=${this.value?.selection?.find((value) => value === item.unique)} - selectable - file-ext=${ifDefined(item.extension)}> - ${item.url ? html`${ifDefined(item.name)}` : ''} + selectable> + ${item.url + ? html`${ifDefined(item.name)}` + : html``} `; } @@ -199,7 +209,7 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement`; } @@ -227,10 +237,23 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement'); + background-size: 10px 10px; + background-repeat: repeat; + } + + #actions { + max-width: 100%; + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts index 434bd4c12a..768968bff8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts @@ -6,7 +6,7 @@ export interface UmbMediaCardItemModel { unique: string; entityType: UmbMediaEntityType; url?: string; - extension?: string; + icon?: string; } export interface UmbMediaPathModel extends UmbEntityModel { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/index.ts index 30dfbb63e1..cc92e27b5f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/index.ts @@ -2,4 +2,5 @@ export { UmbMediaDetailRepository, UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from './d export { UmbMediaItemRepository, UMB_MEDIA_ITEM_REPOSITORY_ALIAS } from './item/index.js'; export { UmbMediaUrlRepository, UMB_MEDIA_URL_REPOSITORY_ALIAS } from './url/index.js'; +export type { UmbMediaUrlModel } from './url/types.js'; export type { UmbMediaItemModel } from './item/types.js'; diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 316fbbe6d5..86aa97925d 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -66,6 +66,7 @@ DON'T EDIT THIS FILE DIRECTLY. It is generated by /devops/tsconfig/index.js "@umbraco-cms/backoffice/extension-registry": ["./src/packages/core/extension-registry/index.ts"], "@umbraco-cms/backoffice/icon": ["./src/packages/core/icon-registry/index.ts"], "@umbraco-cms/backoffice/id": ["./src/packages/core/id/index.ts"], + "@umbraco-cms/backoffice/imaging": ["./src/packages/core/imaging/index.ts"], "@umbraco-cms/backoffice/language": ["./src/packages/language/index.ts"], "@umbraco-cms/backoffice/lit-element": ["./src/packages/core/lit-element/index.ts"], "@umbraco-cms/backoffice/localization": ["./src/packages/core/localization/index.ts"], From f4a52b612cb3a31102655c4a190f6821d0d59091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 21:39:38 +0200 Subject: [PATCH 03/11] apending css assets --- .../assets/css/umbraco-blockgridlayout.css | 46 +++++++++++++++++++ .../staticwebapp.config.json | 15 +++--- 2 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout.css diff --git a/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout.css b/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout.css new file mode 100644 index 0000000000..8a4f567cac --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout.css @@ -0,0 +1,46 @@ +.umb-block-grid__layout-container { + position: relative; + display: grid; + grid-template-columns: repeat(var(--umb-block-grid--grid-columns, 1), minmax(0, 1fr)); + grid-auto-flow: row; + grid-auto-rows: minmax(50px, min-content); + + column-gap: var(--umb-block-grid--column-gap, 0); + row-gap: var(--umb-block-grid--row-gap, 0); +} +.umb-block-grid__layout-item { + position: relative; + /* For small devices we scale columnSpan by three, to make everything bigger than 1/3 take full width: */ + grid-column-end: span min(calc(var(--umb-block-grid--item-column-span, 1) * 3), var(--umb-block-grid--grid-columns)); + grid-row: span var(--umb-block-grid--item-row-span, 1); +} + + +.umb-block-grid__area-container, .umb-block-grid__block--view::part(area-container) { + position: relative; + display: grid; + grid-template-columns: repeat(var(--umb-block-grid--area-grid-columns, var(--umb-block-grid--grid-columns, 1)), minmax(0, 1fr)); + grid-auto-flow: row; + grid-auto-rows: minmax(50px, min-content); + + column-gap: var(--umb-block-grid--areas-column-gap, 0); + row-gap: var(--umb-block-grid--areas-row-gap, 0); +} +.umb-block-grid__area { + position: relative; + height: 100%; + display: flex; + flex-direction: column; + /* For small devices we scale columnSpan by three, to make everything bigger than 1/3 take full width: */ + grid-column-end: span min(calc(var(--umb-block-grid--area-column-span, 1) * 3), var(--umb-block-grid--area-grid-columns)); + grid-row: span var(--umb-block-grid--area-row-span, 1); +} + +@media (min-width:1024px) { + .umb-block-grid__layout-item { + grid-column-end: span min(var(--umb-block-grid--item-column-span, 1), var(--umb-block-grid--grid-columns)); + } + .umb-block-grid__area { + grid-column-end: span min(var(--umb-block-grid--area-column-span, 1), var(--umb-block-grid--area-grid-columns)); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/staticwebapp.config.json b/src/Umbraco.Web.UI.Client/staticwebapp.config.json index d08bfb5cc1..4ff06b6140 100644 --- a/src/Umbraco.Web.UI.Client/staticwebapp.config.json +++ b/src/Umbraco.Web.UI.Client/staticwebapp.config.json @@ -1,10 +1,7 @@ { - "navigationFallback": { - "rewrite": "/index.html", - "exclude": [ - "*.{jpg,jpeg,gif,png,svg}", - "/assets/*" - ] - }, - "trailingSlash": "never" -} \ No newline at end of file + "navigationFallback": { + "rewrite": "/index.html", + "exclude": ["*.{jpg,jpeg,gif,png,svg,css}", "/assets/*"] + }, + "trailingSlash": "never" +} From 7e8832c805dc2a8164d06d9e605ce34254004201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 21:39:45 +0200 Subject: [PATCH 04/11] flexbox version --- .../css/umbraco-blockgridlayout-flexbox.css | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout-flexbox.css diff --git a/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout-flexbox.css b/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout-flexbox.css new file mode 100644 index 0000000000..3f921c0470 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/assets/css/umbraco-blockgridlayout-flexbox.css @@ -0,0 +1,35 @@ +/** Example of how a grid layout stylehseet could be done with Flex box: */ + +.umb-block-grid__layout-container { + position: relative; + display: flex; + flex-wrap: wrap; + gap: var(--umb-block-grid--row-gap, 0) var(--umb-block-grid--column-gap, 0); +} +.umb-block-grid__layout-item { + position: relative; + --umb-block-grid__layout-item-calc: calc(var(--umb-block-grid--item-column-span) / var(--umb-block-grid--grid-columns)); + width: calc(var(--umb-block-grid__layout-item-calc) * 100% - (1 - var(--umb-block-grid__layout-item-calc)) * var(--umb-block-grid--column-gap, 0px)); +} + + +.umb-block-grid__area-container, .umb-block-grid__block--view::part(area-container) { + position: relative; + display: flex; + flex-wrap: wrap; + width: 100%; + gap: var(--umb-block-grid--areas-row-gap, 0) var(--umb-block-grid--areas-column-gap, 0); +} +.umb-block-grid__area { + position: relative; + height: 100%; + display: flex; + flex-direction: column; + --umb-block-grid__area-calc: calc(var(--umb-block-grid--area-column-span) / var(--umb-block-grid--area-grid-columns, 1)); + width: calc(var(--umb-block-grid__area-calc) * 100% - (1 - var(--umb-block-grid__area-calc)) * var(--umb-block-grid--areas-column-gap, 0px)); +} + + +.umb-block-grid__actions { + clear: both; +} From e1d60b065f20dc43890c63e47c8dd94bdd053581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 21:39:50 +0200 Subject: [PATCH 05/11] correct link --- .../property-editor-ui-block-grid-layout-stylesheet.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts index 9cd3218e1c..0b3351a30e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts @@ -44,7 +44,7 @@ export class UmbPropertyEditorUIBlockGridLayoutStylesheetElement .min=${0} .max=${1}>
- Link to default layout stylesheet + Link to default layout stylesheet `; } From 9399b9d91c91a9eab53673b93d35318496fb01e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 22:01:22 +0200 Subject: [PATCH 06/11] ability to put weight on property editor configuration properties, to sort properties and mix schema and ui props --- .../block-grid-editor/Umbraco.BlockGrid.ts | 1 + .../block-grid-editor/manifests.ts | 1 + .../models/property-editor.model.ts | 1 + .../workspace/data-type-workspace.context.ts | 16 +++++++++++++--- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/Umbraco.BlockGrid.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/Umbraco.BlockGrid.ts index b6d7ac4518..4c9e5eb5df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/Umbraco.BlockGrid.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/Umbraco.BlockGrid.ts @@ -19,6 +19,7 @@ export const manifest: ManifestPropertyEditorSchema = { label: 'Amount', propertyEditorUiAlias: 'Umb.PropertyEditorUi.NumberRange', config: [{ alias: 'validationRange', value: { min: 0, max: Infinity } }], + weight: 100, }, ], defaultData: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts index 26879650f8..5802ce70d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts @@ -20,6 +20,7 @@ export const manifests: Array = [ alias: 'blockGroups', label: '', propertyEditorUiAlias: 'Umb.PropertyEditorUi.BlockTypeGroupConfiguration', + weight: 1, }, { alias: 'useLiveEditing', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/property-editor.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/property-editor.model.ts index 9dd8113023..4d88b28827 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/property-editor.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/property-editor.model.ts @@ -51,6 +51,7 @@ export interface PropertyEditorSettingsProperty { alias: string; propertyEditorUiAlias: string; config?: UmbPropertyEditorConfig; + weight?: number; } export interface PropertyEditorSettingsDefaultData { diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.context.ts index 0808e07aff..d95b3b83cf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/workspace/data-type-workspace.context.ts @@ -58,7 +58,9 @@ export class UmbDataTypeWorkspaceContext readonly propertyEditorUiAlias = this.#currentData.asObservablePart((data) => data?.editorUiAlias); readonly propertyEditorSchemaAlias = this.#currentData.asObservablePart((data) => data?.editorAlias); - #properties = new UmbArrayState([], (x) => x.alias); + #properties = new UmbArrayState([], (x) => x.alias).sortBy( + (a, b) => (a.weight || 0) - (b.weight || 0), + ); readonly properties = this.#properties.asObservable(); #defaults = new UmbArrayState([], (entry) => entry.alias); @@ -164,7 +166,11 @@ export class UmbDataTypeWorkspaceContext return this.observe( umbExtensionsRegistry.byTypeAndAlias('propertyEditorSchema', propertyEditorSchemaAlias), (manifest) => { - this.#propertyEditorSchemaSettingsProperties = manifest?.meta.settings?.properties || []; + // Maps properties to have a weight, so they can be sorted + this.#propertyEditorSchemaSettingsProperties = (manifest?.meta.settings?.properties ?? []).map((x, i) => ({ + ...x, + weight: x.weight ?? i, + })); this.#propertyEditorSchemaSettingsDefaultData = manifest?.meta.settings?.defaultData || []; this.#propertyEditorSchemaConfigDefaultUIAlias = manifest?.meta.defaultPropertyEditorUiAlias || null; }, @@ -180,7 +186,11 @@ export class UmbDataTypeWorkspaceContext this.#propertyEditorUiName.setValue(manifest?.name || null); this.#propertyEditorUISettingsSchemaAlias = manifest?.meta.propertyEditorSchemaAlias; - this.#propertyEditorUISettingsProperties = manifest?.meta.settings?.properties || []; + // Maps properties to have a weight, so they can be sorted, notice UI properties have a +1000 weight compared to schema properties. + this.#propertyEditorUISettingsProperties = (manifest?.meta.settings?.properties ?? []).map((x, i) => ({ + ...x, + weight: x.weight ?? 1000 + i, + })); this.#propertyEditorUISettingsDefaultData = manifest?.meta.settings?.defaultData || []; }, 'editorUi', From e7cd4fb42e316aa001c21f4399e9d1b99e2cb410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 22:28:24 +0200 Subject: [PATCH 07/11] get name for dialog --- .../input-block-type/input-block-type.element.ts | 12 +++++++++--- .../src/packages/core/store/store-base.ts | 2 +- .../item/document-type-item-store.context-token.ts | 6 ++++++ .../repository/item/document-type-item.repository.ts | 2 +- .../repository/item/document-type-item.store.ts | 6 +----- .../document-types/repository/item/index.ts | 3 ++- 6 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item-store.context-token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts index ef77263298..94bdbaa328 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts @@ -7,7 +7,10 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbPropertyDatasetContext } from '@umbraco-cms/backoffice/property'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import { UmbDeleteEvent } from '@umbraco-cms/backoffice/event'; -import { UMB_DOCUMENT_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/document-type'; +import { + UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT, + UMB_DOCUMENT_TYPE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/document-type'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; /** TODO: Look into sending a "change" event when there is a change, rather than create, delete, and change event. Make sure it doesn't break move for RTE/List/Grid. [LI] */ @@ -123,10 +126,13 @@ export class UmbInputBlockTypeElement< } async #onRequestDelete(item: BlockType) { + const store = await this.getContext(UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT); + const contentType = store.getItems([item.contentElementTypeKey]); await umbConfirmModal(this, { color: 'danger', - headline: `Remove [TODO: Get name]?`, - content: 'Are you sure you want to remove this block type?', + headline: `Remove ${contentType[0]?.name}?`, + // TODO: Translations: [NL] + content: 'Are you sure you want to remove this Block Type Configuration?', confirmLabel: 'Remove', }); this.deleteItem(item.contentElementTypeKey); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts index d333c1f4a2..1d51ad902a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/store/store-base.ts @@ -74,7 +74,7 @@ export class UmbStoreBase extends UmbContextBase imple * @returns {Array} * @memberof UmbStoreBase */ - getItems(uniques: Array) { + getItems(uniques: Array): Array { return this._data.getValue().filter((item) => uniques.includes(this._data.getUniqueMethod(item) as string)); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item-store.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item-store.context-token.ts new file mode 100644 index 0000000000..8a07283038 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item-store.context-token.ts @@ -0,0 +1,6 @@ +import type { UmbDocumentTypeItemStore } from './document-type-item.store.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT = new UmbContextToken( + 'UmbDocumentTypeItemStore', +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.repository.ts index c8a5d0fa7e..80362b89ee 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.repository.ts @@ -1,6 +1,6 @@ import type { UmbDocumentTypeItemModel } from './types.js'; import { UmbDocumentTypeItemServerDataSource } from './document-type-item.server.data-source.js'; -import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT } from './document-type-item.store.js'; +import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT } from './document-type-item-store.context-token.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbItemRepositoryBase } from '@umbraco-cms/backoffice/repository'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.store.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.store.ts index 7c9bae5794..3362035543 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.store.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.store.ts @@ -1,5 +1,5 @@ import type { UmbDocumentTypeItemModel } from './types.js'; -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UMB_DOCUMENT_TYPE_ITEM_STORE_CONTEXT } from './document-type-item-store.context-token.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store'; @@ -20,7 +20,3 @@ export class UmbDocumentTypeItemStore extends UmbItemStoreBase( - 'UmbDocumentTypeItemStore', -); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/index.ts index 2ff626ece5..635759aa63 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/index.ts @@ -1,3 +1,4 @@ -export { UmbDocumentTypeItemRepository } from './document-type-item.repository.js'; export { UMB_DOCUMENT_TYPE_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_ITEM_STORE_ALIAS } from './manifests.js'; +export { UmbDocumentTypeItemRepository } from './document-type-item.repository.js'; +export * from './document-type-item-store.context-token.js'; export * from './types.js'; From c91b57b3228d7264e68803606814aa991656ed23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 22:32:50 +0200 Subject: [PATCH 08/11] binding thumbnail --- .../block-type-card/block-type-card.element.ts | 13 +++++++++---- .../input-block-type/input-block-type.element.ts | 1 + .../src/packages/block/block-type/types.ts | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/block-type-card/block-type-card.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/block-type-card/block-type-card.element.ts index da664eabd4..9ede814398 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/block-type-card/block-type-card.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/block-type-card/block-type-card.element.ts @@ -18,6 +18,9 @@ export class UmbBlockTypeCardElement extends UmbLitElement { @property({ type: String, attribute: false }) href?: string; + @property({ type: String, attribute: false }) + iconFile?: string; + @property({ type: String, attribute: false }) iconColor?: string; @@ -41,7 +44,7 @@ export class UmbBlockTypeCardElement extends UmbLitElement { private _elementTypeKey?: string | undefined; @state() - _fallbackName?: string; + _name?: string; @state() _fallbackIcon?: string | null; @@ -53,7 +56,7 @@ export class UmbBlockTypeCardElement extends UmbLitElement { const item = items[0]; if (item) { this._fallbackIcon = item.icon; - this._fallbackName = item.name; + this._name = item.name; } }); } @@ -63,9 +66,11 @@ export class UmbBlockTypeCardElement extends UmbLitElement { return html` - + ${this.iconFile + ? html`` + : html``} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts index 94bdbaa328..521dcc51b0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-type/components/input-block-type/input-block-type.element.ts @@ -149,6 +149,7 @@ export class UmbInputBlockTypeElement< Date: Wed, 15 May 2024 22:54:40 +0200 Subject: [PATCH 09/11] placeholder configuration property for number property editor --- .../block-grid-editor/manifests.ts | 7 +++- ...-grid-type-workspace-view-areas.element.ts | 41 +++++++++++-------- .../property-editors/number/manifests.ts | 9 +++- .../property-editor-ui-number.element.ts | 7 +++- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts index 26879650f8..84fef84c2a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts @@ -42,9 +42,12 @@ export const manifests: Array = [ { alias: 'gridColumns', label: 'Grid Columns', - description: 'Set the number of columns for the layout. (defaults to 12)', + description: 'Set the number of columns for the layout.', propertyEditorUiAlias: 'Umb.PropertyEditorUi.Integer', - config: [{ alias: 'min', value: 0 }], + config: [ + { alias: 'min', value: 0 }, + { alias: 'placeholder', value: '12' }, + ], }, { alias: 'layoutStylesheet', diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-areas.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-areas.element.ts index e2b39bb072..025fd3e564 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-areas.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-areas.element.ts @@ -1,5 +1,5 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; @@ -8,6 +8,9 @@ import { UMB_DATA_TYPE_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/data-ty @customElement('umb-block-grid-type-workspace-view-areas') export class UmbBlockGridTypeWorkspaceViewAreasElement extends UmbLitElement implements UmbWorkspaceViewElement { // + @state() + _areaColumnsConfigurationObject?: UmbPropertyEditorConfig; + @state() _areaConfigConfigurationObject?: UmbPropertyEditorConfig; @@ -18,7 +21,8 @@ export class UmbBlockGridTypeWorkspaceViewAreasElement extends UmbLitElement imp this.observe( await context.propertyValueByAlias('gridColumns'), (value) => { - const dataTypeGridColumns = value ? parseInt(value, 10) : undefined; + const dataTypeGridColumns = value ? parseInt(value, 10) : 12; + this._areaColumnsConfigurationObject = [{ alias: 'placeholder', value: dataTypeGridColumns }]; this._areaConfigConfigurationObject = [{ alias: 'defaultAreaGridColumns', value: dataTypeGridColumns }]; }, 'observeGridColumns', @@ -27,21 +31,24 @@ export class UmbBlockGridTypeWorkspaceViewAreasElement extends UmbLitElement imp } render() { - return html` - - - > - - `; + return this._areaConfigConfigurationObject + ? html` + + + > + + ` + : nothing; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/manifests.ts index e64c47d910..a93dbdbdc3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/manifests.ts @@ -14,7 +14,14 @@ export const manifests: Array = [ icon: 'icon-autofill', group: 'common', settings: { - properties: [], + properties: [ + { + alias: 'placeholder', + label: 'Placeholder text', + description: 'Enter the text to be displayed when the value is empty', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox', + }, + ], defaultData: [ { alias: 'step', diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/property-editor-ui-number.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/property-editor-ui-number.element.ts index f4317acc81..e95cd74ca5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/property-editor-ui-number.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number/property-editor-ui-number.element.ts @@ -18,11 +18,15 @@ export class UmbPropertyEditorUINumberElement extends UmbLitElement implements U @state() private _step?: number; + @state() + private _placeholder?: string; + public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; this._min = this.#parseInt(config.getValueByAlias('min')); this._max = this.#parseInt(config.getValueByAlias('max')); this._step = this.#parseInt(config.getValueByAlias('step')); + this._placeholder = config.getValueByAlias('placeholder'); } #parseInt(input: unknown): number | undefined { @@ -42,7 +46,8 @@ export class UmbPropertyEditorUINumberElement extends UmbLitElement implements U min=${ifDefined(this._min)} max=${ifDefined(this._max)} step=${ifDefined(this._step)} - .value=${this.value ?? 0} + placeholder=${ifDefined(this._placeholder)} + .value=${this.value ?? (this._placeholder ? undefined : 0)} @input=${this.#onInput}>
`; From d7519cc15be91407d877ac256db9869930107d5d Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Thu, 16 May 2024 09:25:05 +0200 Subject: [PATCH 10/11] parameters optional --- .../core/imaging/imaging.repository.ts | 16 ++---------- .../core/imaging/imaging.server.data.ts | 4 +-- .../packages/core/imaging/imaging.store.ts | 26 ------------------- .../src/packages/core/imaging/types.ts | 1 - .../collection/media-collection.context.ts | 7 +---- .../media-picker-modal.element.ts | 8 +----- 6 files changed, 6 insertions(+), 56 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts index aae7b477f0..a675e2ff5e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.repository.ts @@ -5,17 +5,11 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; export class UmbImagingRepository extends UmbControllerBase implements UmbApi { - //protected _init: Promise; - //protected _itemStore?: UmbImagingStore; #itemSource: UmbImagingServerDataSource; constructor(host: UmbControllerHost) { super(host); this.#itemSource = new UmbImagingServerDataSource(host); - - /*this._init = this.consumeContext(UMB_IMAGING_STORE_CONTEXT, (instance) => { - this._itemStore = instance as UmbImagingStore; - }).asPromise();*/ } /** @@ -24,17 +18,11 @@ export class UmbImagingRepository extends UmbControllerBase implements UmbApi { * @return {*} * @memberof UmbImagingRepository */ - async requestResizedItems({ uniques, height, width, mode }: UmbImagingModel) { + async requestResizedItems(uniques: Array, imagingModel?: UmbImagingModel) { if (!uniques.length) throw new Error('Uniques are missing'); - //await this._init; - const { data, error: _error } = await this.#itemSource.getItems({ uniques, height, width, mode }); + const { data, error: _error } = await this.#itemSource.getItems(uniques, imagingModel); const error: any = _error; - /*if (data) { - this._itemStore!.appendItems(data); - } - return { data, error, asObservable: () => this._itemStore!.items(uniques) };*/ - return { data, error }; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts index ab297cff99..e64b32c34d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.server.data.ts @@ -27,12 +27,12 @@ export class UmbImagingServerDataSource { * @param {string} unique * @memberof UmbImagingServerDataSource */ - async getItems({ uniques, width, height, mode }: UmbImagingModel) { + async getItems(uniques: Array, imagingModel?: UmbImagingModel) { if (!uniques.length) throw new Error('Uniques are missing'); const { data, error } = await tryExecuteAndNotify( this.#host, - ImagingService.getImagingResizeUrls({ id: uniques, width, height, mode }), + ImagingService.getImagingResizeUrls({ id: uniques, ...imagingModel }), ); if (data) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts deleted file mode 100644 index acbb9b5f6e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/imaging.store.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbItemStoreBase } from '@umbraco-cms/backoffice/store'; -import type { UmbMediaUrlModel } from '@umbraco-cms/backoffice/media'; - -/** - * @export - * @class UmbImagingStore - * @extends {UmbStoreBase} - * @description - Data Store for Imaging Items - */ - -export class UmbImagingStore extends UmbItemStoreBase { - /** - * Creates an instance of UmbImagingStore. - * @param {UmbControllerHost} host - * @memberof UmbImagingStore - */ - constructor(host: UmbControllerHost) { - super(host, UMB_IMAGING_STORE_CONTEXT.toString()); - } -} - -export default UmbImagingStore; - -export const UMB_IMAGING_STORE_CONTEXT = new UmbContextToken('UmbImagingStore'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts index cc3b637a97..41df2f5b95 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/imaging/types.ts @@ -1,7 +1,6 @@ import type { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; export interface UmbImagingModel { - uniques: Array; height?: number; width?: number; mode?: ImageCropModeModel; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts index 5a9078f6ea..ee33b64eea 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/media-collection.context.ts @@ -4,7 +4,6 @@ import { UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS } from './views/index.js'; import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; export class UmbMediaCollectionContext extends UmbDefaultCollectionContext< UmbMediaCollectionItemModel, @@ -22,11 +21,7 @@ export class UmbMediaCollectionContext extends UmbDefaultCollectionContext< this.observe(this.items, async (items) => { if (!items?.length) return; - const { data } = await this.#imagingRepository.requestResizedItems({ - uniques: items.map((m) => m.unique), - width: 250, - mode: ImageCropModeModel.MIN, - }); + const { data } = await this.#imagingRepository.requestResizedItems(items.map((m) => m.unique)); this.#thumbnailItems.setValue( items.map((item) => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts index e8e8949e45..c76bd46ae8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts @@ -8,7 +8,6 @@ import type { UmbMediaPickerModalData, UmbMediaPickerModalValue } from './media- import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { css, html, customElement, state, repeat, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; -import { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; const root: UmbMediaPathModel = { name: 'Media', unique: null, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE }; @@ -64,15 +63,10 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement): Promise> { if (!items.length) return []; - const { data } = await this.#imagingRepository.requestResizedItems({ - uniques: items.map((item) => item.unique), - width: 250, - mode: ImageCropModeModel.MIN, - }); + const { data } = await this.#imagingRepository.requestResizedItems(items.map((item) => item.unique)); return items.map((item): UmbMediaCardItemModel => { const url = data?.find((media) => media.unique === item.unique)?.url; - return { name: item.name, unique: item.unique, url, icon: item.mediaType.icon, entityType: item.entityType }; }); } From 035971e835d3e82ccde112629839e6619cf74771 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 16 May 2024 09:52:55 +0200 Subject: [PATCH 11/11] pass correct data --- .../user-workspace-access/user-workspace-access.element.ts | 7 +++++-- .../user-workspace-assign-access.element.ts | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts index 7b9ad681c5..d303ea8569 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-access/user-workspace-access.element.ts @@ -40,12 +40,15 @@ export class UmbUserWorkspaceAccessElement extends UmbLitElement { #renderDocumentStartNodes() { return html` Content `; + .uniques=${this._user?.documentStartNodeUniques.map((reference) => reference.unique) || + []}>`; } #renderMediaStartNodes() { return html` Media - `; + reference.unique) || + []}>`; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts index 3ff486de9e..7a39ff8589 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/workspace/components/user-workspace-assign-access/user-workspace-assign-access.element.ts @@ -130,7 +130,7 @@ export class UmbUserWorkspaceAssignAccessElement extends UmbLitElement { description="${this.localize.term('user_groupsHelp')}"> reference.unique)} @change=${this.#onUserGroupsChange}> `; } @@ -152,7 +152,7 @@ export class UmbUserWorkspaceAssignAccessElement extends UmbLitElement { ? html` reference.unique)} @change=${this.#onDocumentStartNodeChange}> ` : nothing} @@ -177,7 +177,7 @@ export class UmbUserWorkspaceAssignAccessElement extends UmbLitElement { ? html` reference.unique)} @change=${this.#onMediaStartNodeChange}> ` : nothing}