diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts index 0d1532cf44..26cb637132 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/index.ts @@ -284,6 +284,7 @@ export type { PagedProblemDetailsModel } from './models/PagedProblemDetailsModel export type { PagedRedirectUrlResponseModel } from './models/PagedRedirectUrlResponseModel'; export type { PagedRelationItemResponseModel } from './models/PagedRelationItemResponseModel'; export type { PagedRelationResponseModel } from './models/PagedRelationResponseModel'; +export type { PagedRelationTypeTreeItemResponseModel } from './models/PagedRelationTypeTreeItemResponseModel'; export type { PagedSavedLogSearchResponseModel } from './models/PagedSavedLogSearchResponseModel'; export type { PagedSearcherResponseModel } from './models/PagedSearcherResponseModel'; export type { PagedSearchResultResponseModel } from './models/PagedSearchResultResponseModel'; @@ -291,6 +292,7 @@ export type { PagedTagResponseModel } from './models/PagedTagResponseModel'; export type { PagedTelemetryResponseModel } from './models/PagedTelemetryResponseModel'; export type { PagedUserGroupResponseModel } from './models/PagedUserGroupResponseModel'; export type { PagedUserResponseModel } from './models/PagedUserResponseModel'; +export type { PagedWebhookResponseModel } from './models/PagedWebhookResponseModel'; export type { PartialViewFolderResponseModel } from './models/PartialViewFolderResponseModel'; export type { PartialViewItemResponseModel } from './models/PartialViewItemResponseModel'; export type { PartialViewResponseModel } from './models/PartialViewResponseModel'; @@ -320,6 +322,7 @@ export type { RelationResponseModel } from './models/RelationResponseModel'; export type { RelationTypeBaseModel } from './models/RelationTypeBaseModel'; export type { RelationTypeItemResponseModel } from './models/RelationTypeItemResponseModel'; export type { RelationTypeResponseModel } from './models/RelationTypeResponseModel'; +export type { RelationTypeTreeItemResponseModel } from './models/RelationTypeTreeItemResponseModel'; export type { RenamePartialViewRequestModel } from './models/RenamePartialViewRequestModel'; export type { RenameScriptRequestModel } from './models/RenameScriptRequestModel'; export type { RenameStylesheetRequestModel } from './models/RenameStylesheetRequestModel'; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ContentTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ContentTreeItemResponseModel.ts index b2e1c8d529..bb5f9c106d 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ContentTreeItemResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/ContentTreeItemResponseModel.ts @@ -6,7 +6,6 @@ import type { ReferenceByIdModel } from './ReferenceByIdModel'; export type ContentTreeItemResponseModel = { - type: string; hasChildren: boolean; parent?: ReferenceByIdModel | null; noAccess: boolean; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedNamedEntityTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedNamedEntityTreeItemResponseModel.ts index 8af4c598e0..c42a7ab504 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedNamedEntityTreeItemResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedNamedEntityTreeItemResponseModel.ts @@ -9,9 +9,10 @@ import type { DocumentTypeTreeItemResponseModel } from './DocumentTypeTreeItemRe import type { FolderTreeItemResponseModel } from './FolderTreeItemResponseModel'; import type { MediaTypeTreeItemResponseModel } from './MediaTypeTreeItemResponseModel'; import type { NamedEntityTreeItemResponseModel } from './NamedEntityTreeItemResponseModel'; +import type { RelationTypeTreeItemResponseModel } from './RelationTypeTreeItemResponseModel'; export type PagedNamedEntityTreeItemResponseModel = { total: number; - items: Array<(NamedEntityTreeItemResponseModel | DataTypeTreeItemResponseModel | DocumentBlueprintTreeItemResponseModel | DocumentTypeTreeItemResponseModel | FolderTreeItemResponseModel | MediaTypeTreeItemResponseModel)>; + items: Array<(NamedEntityTreeItemResponseModel | DataTypeTreeItemResponseModel | DocumentBlueprintTreeItemResponseModel | DocumentTypeTreeItemResponseModel | FolderTreeItemResponseModel | MediaTypeTreeItemResponseModel | RelationTypeTreeItemResponseModel)>; }; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedRelationTypeTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedRelationTypeTreeItemResponseModel.ts new file mode 100644 index 0000000000..7790bc4b16 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedRelationTypeTreeItemResponseModel.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationTypeTreeItemResponseModel } from './RelationTypeTreeItemResponseModel'; + +export type PagedRelationTypeTreeItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedWebhookResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedWebhookResponseModel.ts new file mode 100644 index 0000000000..1efc883d28 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/PagedWebhookResponseModel.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { WebhookResponseModel } from './WebhookResponseModel'; + +export type PagedWebhookResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeItemResponseModel.ts index f156f0987d..1f9bcdfe1e 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeItemResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeItemResponseModel.ts @@ -5,5 +5,7 @@ import type { NamedItemResponseModelBaseModel } from './NamedItemResponseModelBaseModel'; -export type RelationTypeItemResponseModel = NamedItemResponseModelBaseModel; +export type RelationTypeItemResponseModel = (NamedItemResponseModelBaseModel & { + isDeletable: boolean; +}); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeResponseModel.ts index 990febe8b7..b20537c5d0 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeResponseModel.ts @@ -9,7 +9,7 @@ export type RelationTypeResponseModel = (RelationTypeBaseModel & { id: string; alias?: string | null; path: string; - isSystemRelationType: boolean; + isDeletable: boolean; parentObjectTypeName?: string | null; childObjectTypeName?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeTreeItemResponseModel.ts new file mode 100644 index 0000000000..c1c4ce7465 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/RelationTypeTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { NamedEntityTreeItemResponseModel } from './NamedEntityTreeItemResponseModel'; + +export type RelationTypeTreeItemResponseModel = (NamedEntityTreeItemResponseModel & { + isDeletable: boolean; +}); + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TreeItemPresentationModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TreeItemPresentationModel.ts index b6e40540ce..3f84670b27 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TreeItemPresentationModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TreeItemPresentationModel.ts @@ -4,7 +4,6 @@ /* eslint-disable */ export type TreeItemPresentationModel = { - type: string; hasChildren: boolean; }; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/RelationTypeResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/RelationTypeResource.ts index bcbb7f7c50..a3f6109d3a 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/RelationTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/RelationTypeResource.ts @@ -3,7 +3,7 @@ /* tslint:disable */ /* eslint-disable */ import type { CreateRelationTypeRequestModel } from '../models/CreateRelationTypeRequestModel'; -import type { PagedNamedEntityTreeItemResponseModel } from '../models/PagedNamedEntityTreeItemResponseModel'; +import type { PagedRelationTypeTreeItemResponseModel } from '../models/PagedRelationTypeTreeItemResponseModel'; import type { RelationTypeItemResponseModel } from '../models/RelationTypeItemResponseModel'; import type { RelationTypeResponseModel } from '../models/RelationTypeResponseModel'; import type { UpdateRelationTypeRequestModel } from '../models/UpdateRelationTypeRequestModel'; @@ -130,7 +130,7 @@ export class RelationTypeResource { } /** - * @returns PagedNamedEntityTreeItemResponseModel Success + * @returns PagedRelationTypeTreeItemResponseModel Success * @throws ApiError */ public static getTreeRelationTypeRoot({ @@ -139,7 +139,7 @@ export class RelationTypeResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/relation-type/root', diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts index bbe951c01d..4e7f80c31f 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts @@ -3,6 +3,7 @@ /* tslint:disable */ /* eslint-disable */ import type { CreateWebhookRequestModel } from '../models/CreateWebhookRequestModel'; +import type { PagedWebhookResponseModel } from '../models/PagedWebhookResponseModel'; import type { UpdateWebhookRequestModel } from '../models/UpdateWebhookRequestModel'; import type { WebhookItemResponseModel } from '../models/WebhookItemResponseModel'; import type { WebhookResponseModel } from '../models/WebhookResponseModel'; @@ -13,6 +14,30 @@ import { request as __request } from '../core/request'; export class WebhookResource { + /** + * @returns PagedWebhookResponseModel Success + * @throws ApiError + */ + public static getWebhook({ + skip, + take = 100, + }: { + skip?: number, + take?: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/webhook', + query: { + 'skip': skip, + 'take': take, + }, + errors: { + 401: `The resource is protected and requires an authentication token`, + }, + }); + } + /** * @returns string Created * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/assign-to-frozen-object.function.ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/assign-to-frozen-object.function.ts new file mode 100644 index 0000000000..f0f2665bbb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/assign-to-frozen-object.function.ts @@ -0,0 +1,3 @@ +export function assignToFrozenObject(target: T, source: Partial): T { + return Object.assign(Object.create(Object.getPrototypeOf(target)), target, source); +} diff --git a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/index.ts b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/index.ts index 0c77207194..f207030636 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/index.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/observable-api/utils/index.ts @@ -1,4 +1,5 @@ export * from './append-to-frozen-array.function.js'; +export * from './assign-to-frozen-object.function.js'; export * from './create-observable-part.function.js'; export * from './deep-freeze.function.js'; export * from './default-memoization.function.js'; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts index 52f12c19dc..492fd72563 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts @@ -4,9 +4,7 @@ import type { DataTypeTreeItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockDataTypeModelHack = DataTypeResponseModel & DataTypeTreeItemResponseModel & DataTypeItemResponseModel; - -export interface UmbMockDataTypeModel extends Omit {} +export type UmbMockDataTypeModel = DataTypeResponseModel & DataTypeTreeItemResponseModel & DataTypeItemResponseModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.data.ts index b135a1b516..3f68fa97f5 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.data.ts @@ -5,13 +5,11 @@ import type { NamedEntityTreeItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockDictionaryModelHack = DictionaryItemResponseModel & +export type UmbMockDictionaryModel = DictionaryItemResponseModel & NamedEntityTreeItemResponseModel & DictionaryItemItemResponseModel & DictionaryOverviewResponseModel; -export interface UmbMockDictionaryModel extends Omit {} - export const data: Array = [ { name: 'Hello', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.db.ts index 191f854604..bc8977c9ab 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/dictionary/dictionary.db.ts @@ -38,7 +38,7 @@ export class UmbDictionaryMockDB extends UmbEntityMockDbBase => { +const treeItemMapper = (model: UmbMockDictionaryModel): NamedEntityTreeItemResponseModel => { return { name: model.name, id: model.id, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts index 182e04ef9c..22a13f84ce 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts @@ -5,12 +5,10 @@ import type { DocumentTypeTreeItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockDocumentTypeModelHack = DocumentTypeResponseModel & +export type UmbMockDocumentTypeModel = DocumentTypeResponseModel & DocumentTypeTreeItemResponseModel & DocumentTypeItemResponseModel; -export interface UmbMockDocumentTypeModel extends Omit {} - export const data: Array = [ { allowedTemplates: [], diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.db.ts index 47428a85b5..24a362a1cb 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.db.ts @@ -122,9 +122,7 @@ const documentTypeDetailMapper = (item: UmbMockDocumentTypeModel): DocumentTypeR }; }; -const documentTypeTreeItemMapper = ( - item: UmbMockDocumentTypeModel, -): Omit => { +const documentTypeTreeItemMapper = (item: UmbMockDocumentTypeModel): DocumentTypeTreeItemResponseModel => { return { name: item.name, hasChildren: item.hasChildren, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts index cf47af845a..1c0a6b60a2 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts @@ -5,9 +5,7 @@ import type { } from '@umbraco-cms/backoffice/external/backend-api'; import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockDocumentTypeModelHack = DocumentResponseModel & DocumentTreeItemResponseModel & DocumentItemResponseModel; - -export interface UmbMockDocumentModel extends Omit {} +export type UmbMockDocumentModel = DocumentResponseModel & DocumentTreeItemResponseModel & DocumentItemResponseModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.db.ts index 76e2dfaafd..fdd0e3f23e 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.db.ts @@ -41,7 +41,7 @@ export class UmbDocumentMockDB extends UmbEntityMockDbBase } } -const treeItemMapper = (model: UmbMockDocumentModel): Omit => { +const treeItemMapper = (model: UmbMockDocumentModel): DocumentTreeItemResponseModel => { const documentType = umbDocumentTypeMockDb.read(model.documentType.id); if (!documentType) throw new Error(`Document type with id ${model.documentType.id} not found`); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/log-viewer.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/log-viewer.data.ts index 33f66fb115..fa179f05e7 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/log-viewer.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/log-viewer.data.ts @@ -14,7 +14,7 @@ class UmbLogViewerSearchesData extends UmbMockDBBase { - return this.data.slice(skip, take); + return this.data.slice(skip, take + skip); } getByName(name: string) { @@ -29,7 +29,7 @@ class UmbLogViewerTemplatesData extends UmbMockDBBase // skip can be number or null getTemplates(skip = 0, take = this.data.length): Array { - return this.data.slice(skip, take); + return this.data.slice(skip, take + skip); } } diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.data.ts index a7d235712b..aeba10c756 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.data.ts @@ -4,9 +4,9 @@ import type { MediaTypeTreeItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockMediaTypeModelHack = MediaTypeResponseModel & MediaTypeTreeItemResponseModel & MediaTypeItemResponseModel; - -export interface UmbMockMediaTypeModel extends Omit {} +export type UmbMockMediaTypeModel = MediaTypeResponseModel & + MediaTypeTreeItemResponseModel & + MediaTypeItemResponseModel; export const data: Array = [ { @@ -91,9 +91,7 @@ export const data: Array = [ variesByCulture: false, variesBySegment: false, isElement: false, - allowedMediaTypes: [ - { mediaType: { id: 'media-type-1-id' }, sortOrder: 0 }, - ], + allowedMediaTypes: [{ mediaType: { id: 'media-type-1-id' }, sortOrder: 0 }], compositions: [], isFolder: false, hasChildren: false, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.db.ts index 630e0d7e7c..874a4e4374 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/media-type/media-type.db.ts @@ -110,7 +110,7 @@ const mediaTypeDetailMapper = (item: UmbMockMediaTypeModel): MediaTypeResponseMo }; }; -const mediaTypeTreeItemMapper = (item: UmbMockMediaTypeModel): Omit => { +const mediaTypeTreeItemMapper = (item: UmbMockMediaTypeModel): MediaTypeTreeItemResponseModel => { return { name: item.name, hasChildren: item.hasChildren, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.data.ts index 211c9aa3f2..012ab54620 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.data.ts @@ -4,9 +4,7 @@ import type { MediaTreeItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockMediaModelHack = MediaResponseModel & MediaTreeItemResponseModel & MediaItemResponseModel; - -export interface UmbMockMediaModel extends Omit {} +export type UmbMockMediaModel = MediaResponseModel & MediaTreeItemResponseModel & MediaItemResponseModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.db.ts index a87acd02d9..e0a6337152 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/media/media.db.ts @@ -28,7 +28,7 @@ export class UmbMediaMockDB extends UmbEntityMockDbBase { } } -const treeItemMapper = (model: UmbMockMediaModel): Omit => { +const treeItemMapper = (model: UmbMockMediaModel): MediaTreeItemResponseModel => { const mediaType = umbMediaTypeMockDb.read(model.mediaType.id); if (!mediaType) throw new Error(`Media type with id ${model.mediaType.id} not found`); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/partial-view/partial-view.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/partial-view/partial-view.data.ts index 86efd983d6..0fa1bf78c7 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/partial-view/partial-view.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/partial-view/partial-view.data.ts @@ -5,12 +5,10 @@ import type { PartialViewSnippetResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockPartialViewModelHack = PartialViewResponseModel & +export type UmbMockPartialViewModel = PartialViewResponseModel & FileSystemTreeItemPresentationModel & PartialViewItemResponseModel; -export interface UmbMockPartialViewModel extends Omit {} - export const data: Array = [ { name: 'blockgrid', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/relations/relation-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/relations/relation-type.data.ts index ae17352881..081b6e1f9c 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/relations/relation-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/relations/relation-type.data.ts @@ -12,7 +12,7 @@ export const data: Array = [ alias: 'relateDocumentOnCopy', name: 'Relate Document On Copy', path: '', - isSystemRelationType: true, + isDeletable: true, isBidirectional: false, isDependency: false, parentObjectType: 'Document', @@ -25,7 +25,7 @@ export const data: Array = [ alias: 'relateParentDocumentOnDelete', name: 'Relate Parent Document On Delete', path: '', - isSystemRelationType: true, + isDeletable: true, isBidirectional: false, isDependency: false, parentObjectType: 'Document', @@ -38,7 +38,7 @@ export const data: Array = [ alias: 'relateParentMediaFolderOnDelete', name: 'Relate Parent Media Folder On Delete', path: '', - isSystemRelationType: true, + isDeletable: true, isBidirectional: false, isDependency: false, parentObjectType: 'Document', @@ -51,7 +51,7 @@ export const data: Array = [ alias: 'relatedMedia', name: 'Related Media', path: '', - isSystemRelationType: true, + isDeletable: true, isBidirectional: false, isDependency: false, parentObjectType: 'Document', @@ -64,7 +64,7 @@ export const data: Array = [ alias: 'relatedDocument', name: 'Related Document', path: '', - isSystemRelationType: true, + isDeletable: true, isBidirectional: false, isDependency: false, parentObjectType: 'Document', @@ -79,7 +79,6 @@ export const treeData: Array = [ id: 'e0d39ff5-71d8-453f-b682-9d8d31ee5e06', parent: null, name: 'Relate Document On Copy', - type: 'relation-type', hasChildren: false, }, { @@ -87,28 +86,24 @@ export const treeData: Array = [ parent: null, name: 'Relate Parent Document On Delete', - type: 'relation-type', hasChildren: false, }, { id: '6f9b800c-762c-42d4-85d9-bf40a77d689e', parent: null, name: 'Relate Parent Media Folder On Delete', - type: 'relation-type', hasChildren: false, }, { id: 'd421727d-43de-4205-b4c6-037404f309ad', parent: null, name: 'Related Media', - type: 'relation-type', hasChildren: false, }, { id: 'e9a0a28e-2d5b-4229-ac00-66f2df230513', parent: null, name: 'Related Document', - type: 'relation-type', hasChildren: false, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/script/script.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/script/script.data.ts index a71cfe367d..24b7fb53e0 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/script/script.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/script/script.data.ts @@ -4,9 +4,7 @@ import type { ScriptResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockScriptModelHack = ScriptResponseModel & FileSystemTreeItemPresentationModel & ScriptItemResponseModel; - -export interface UmbMockScriptModel extends Omit {} +export type UmbMockScriptModel = ScriptResponseModel & FileSystemTreeItemPresentationModel & ScriptItemResponseModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/static-file/static-file.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/static-file/static-file.data.ts index 052cdaca11..b0eb91d277 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/static-file/static-file.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/static-file/static-file.data.ts @@ -3,8 +3,7 @@ import type { StaticFileItemResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockStaticFileModelHack = StaticFileItemResponseModel & FileSystemTreeItemPresentationModel; -export interface UmbMockStaticFileModel extends Omit {} +export type UmbMockStaticFileModel = StaticFileItemResponseModel & FileSystemTreeItemPresentationModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/stylesheet/stylesheet.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/stylesheet/stylesheet.data.ts index 2ce1bcde20..1145bb66e9 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/stylesheet/stylesheet.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/stylesheet/stylesheet.data.ts @@ -4,12 +4,10 @@ import type { StylesheetResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockStylesheetModelHack = StylesheetResponseModel & +export type UmbMockStylesheetModel = StylesheetResponseModel & FileSystemTreeItemPresentationModel & StylesheetItemResponseModel; -export interface UmbMockStylesheetModel extends Omit {} - export const data: Array = [ { name: 'Stylesheet File 1.css', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/template/template.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/template/template.data.ts index fd6988429a..4aadfd758e 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/template/template.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/template/template.data.ts @@ -7,9 +7,7 @@ import type { } from '@umbraco-cms/backoffice/external/backend-api'; import { TemplateQueryPropertyTypeModel, OperatorModel } from '@umbraco-cms/backoffice/external/backend-api'; -type UmbMockTemplateModelHack = TemplateResponseModel & NamedEntityTreeItemResponseModel & TemplateItemResponseModel; - -export interface UmbMockTemplateModel extends Omit {} +export type UmbMockTemplateModel = TemplateResponseModel & NamedEntityTreeItemResponseModel & TemplateItemResponseModel; export const data: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/utils.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/utils.ts index 54e1eee8ff..f3a9ac812e 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/utils.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/utils.ts @@ -7,7 +7,6 @@ import type { export const createEntityTreeItem = (item: any): NamedEntityTreeItemResponseModel => { return { name: item.name, - type: item.type, hasChildren: item.hasChildren, id: item.id, parent: item.parent, @@ -21,7 +20,7 @@ export const folderTreeItemMapper = (item: any): FolderTreeItemResponseModel => }; }; -export const createFileSystemTreeItem = (item: any): Omit => { +export const createFileSystemTreeItem = (item: any): FileSystemTreeItemPresentationModel => { return { path: item.path, parent: item.parent ?? null, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-folder.manager.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-folder.manager.ts index 968fe7f8e7..87eaef9361 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-folder.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-folder.manager.ts @@ -6,7 +6,7 @@ import type { UpdateFolderResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; -export class UmbMockEntityFolderManager> { +export class UmbMockEntityFolderManager { #db: UmbEntityMockDbBase; #createMockFolderMapper: (request: CreateFolderRequestModel) => MockItemType; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-recycle-bin.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-recycle-bin.ts index fb6940cc7a..2cb6918b2d 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-recycle-bin.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-recycle-bin.ts @@ -2,9 +2,7 @@ import { UmbEntityMockDbBase } from './entity-base.js'; import { UmbMockEntityTreeManager } from './entity-tree.manager.js'; import type { ContentTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; -export class UmbEntityRecycleBin< - MockType extends Omit, -> extends UmbEntityMockDbBase { +export class UmbEntityRecycleBin extends UmbEntityMockDbBase { tree; constructor(data: Array, treeItemMapper: (model: MockType) => any) { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-tree.manager.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-tree.manager.ts index 38c08ccad5..def3178707 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-tree.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/entity/entity-tree.manager.ts @@ -3,7 +3,7 @@ import type { UmbEntityMockDbBase } from './entity-base.js'; import { UmbId } from '@umbraco-cms/backoffice/id'; import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; -export class UmbMockEntityTreeManager> { +export class UmbMockEntityTreeManager { #db: UmbEntityMockDbBase; #treeItemMapper: (item: T) => any; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/file-system/file-system-tree.manager.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/file-system/file-system-tree.manager.ts index cad195d8f9..2641be20f2 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/utils/file-system/file-system-tree.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/utils/file-system/file-system-tree.manager.ts @@ -3,7 +3,7 @@ import { createFileSystemTreeItem } from '../../utils.js'; import { pagedResult } from '../paged-result.js'; import type { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/external/backend-api'; -export class UmbMockFileSystemTreeManager> { +export class UmbMockFileSystemTreeManager { #db: UmbMockDBBase; constructor(mockDb: UmbMockDBBase) { @@ -11,7 +11,7 @@ export class UmbMockFileSystemTreeManager>; + items: Array; total: number; } { const items = this.#db.getAll().filter((item) => item.parent === null); @@ -19,7 +19,7 @@ export class UmbMockFileSystemTreeManager>; + items: Array; total: number; } { const items = this.#db.getAll().filter((item) => item.parent?.path === parentPath); diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/log-viewer.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/log-viewer.handlers.ts index c1aabd575f..acf457650e 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/log-viewer.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/log-viewer.handlers.ts @@ -14,7 +14,7 @@ export const handlers = [ const items = umbLogViewerData.searches.getSavedSearches(skipNumber, takeNumber); const response = { - total: items.length, + total: umbLogViewerData.searches.total, items, }; @@ -57,7 +57,7 @@ export const handlers = [ return res(ctx.delay(), ctx.status(200), ctx.json(response)); }), //#endregion - + //#region Logs rest.get(umbracoPath('/log-viewer/level'), (req, res, ctx) => { return res(ctx.delay(), ctx.status(200), ctx.json(umbLogViewerData.logLevels)); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-view-bundle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-view-bundle.element.ts index c651449d27..70684c1c66 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-view-bundle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-view-bundle.element.ts @@ -85,7 +85,7 @@ export class UmbCollectionViewBundleElement extends UmbLitElement { } #renderItemDisplay(view: ManifestCollectionView) { - return html``; + return html``; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/default/collection-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/default/collection-default.element.ts index 929fb667ac..3bacd4e26a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/default/collection-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/default/collection-default.element.ts @@ -69,7 +69,7 @@ export class UmbCollectionDefaultElement extends UmbLitElement { } protected renderSelectionActions() { - return html``; + return html``; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/extension-with-api-slot/extension-with-api-slot.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/extension-with-api-slot/extension-with-api-slot.element.ts index 40248f67a3..1cd00a2c24 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/extension-with-api-slot/extension-with-api-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/extension-with-api-slot/extension-with-api-slot.element.ts @@ -161,6 +161,7 @@ export class UmbExtensionWithApiSlotElement extends UmbLitElement { undefined, // We can leave the alias to undefined, as we destroy this our selfs. this.defaultElement, ); + this.#extensionsController.apiProperties = this.#apiProps; this.#extensionsController.elementProperties = this.#elProps; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts index 464a42f7e0..9e28e70b4e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts @@ -26,7 +26,7 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement icon.name.includes(e.target.value)); + this._iconListFiltered = this._iconList.filter((icon) => + icon.name.toLowerCase().includes(e.target.value.toLowerCase()), + ); } else { this._iconListFiltered = this._iconList; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/selection-manager/selection.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/selection-manager/selection.manager.ts index 099c3d744e..6bfb64d0b9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/selection-manager/selection.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/selection-manager/selection.manager.ts @@ -9,7 +9,7 @@ import { UmbArrayState, UmbBooleanState } from '@umbraco-cms/backoffice/observab * @class UmbSelectionManager */ export class UmbSelectionManager extends UmbControllerBase { - #selectable = new UmbBooleanState(false); + #selectable = new UmbBooleanState(true); public readonly selectable = this.#selectable.asObservable(); #selection = new UmbArrayState(>[], (x) => x); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts index abc2c4a7af..a414f3f365 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts @@ -111,7 +111,7 @@ export class UmbCreateDocumentCollectionActionElement extends UmbLitElement { const label = this.manifest?.meta.label ?? this.localize.term('general_create'); return html` - + ${label} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts index 139d393fd6..37fe554b42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts @@ -10,6 +10,5 @@ export class UmbDocumentCollectionContext extends UmbDefaultCollectionContext< constructor(host: UmbControllerHost) { super(host, UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS); - this.selection.setSelectable(true); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts index 47042ffd2d..9364d5ab58 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.repository.ts @@ -1,12 +1,15 @@ import type { UmbDocumentCollectionFilterModel } from '../types.js'; import { UmbDocumentCollectionServerDataSource } from './document-collection.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import type { UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -export class UmbDocumentCollectionRepository implements UmbCollectionRepository { +export class UmbDocumentCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository { #collectionSource: UmbDocumentCollectionServerDataSource; constructor(host: UmbControllerHost) { + super(host); + this.#collectionSource = new UmbDocumentCollectionServerDataSource(host); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts index d2709afa67..8ddf18a51e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts @@ -17,13 +17,9 @@ export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataS throw new Error('Unique ID is required to fetch a collection.'); } - if (!query.dataTypeId) { - throw new Error('Data type ID is required to fetch a collection.'); - } - const params = { id: query.unique, - dataTypeId: query.dataTypeId, + dataTypeId: query.dataTypeId ?? '', orderBy: query.orderBy ?? 'updateDate', orderCulture: query.orderCulture ?? 'en-US', orderDirection: query.orderDirection === 'asc' ? DirectionModel.ASCENDING : DirectionModel.DESCENDING, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index 70a08a5ae7..d66f93d783 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -1,11 +1,11 @@ import { getPropertyValueByAlias } from '../index.js'; import type { UmbCollectionColumnConfiguration } from '../../../../../core/collection/types.js'; -import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../../types.js'; +import type { UmbDocumentCollectionItemModel } from '../../types.js'; +import type { UmbDocumentCollectionContext } from '../../document-collection.context.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_DEFAULT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; -import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, @@ -62,7 +62,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { @state() private _skip: number = 0; - #collectionContext?: UmbDefaultCollectionContext; + #collectionContext?: UmbDocumentCollectionContext; constructor() { super(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-root-picker/input-document-root-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-root-picker/input-document-root-picker.element.ts index 7c635c2a29..d8b2b46b98 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-root-picker/input-document-root-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-root-picker/input-document-root-picker.element.ts @@ -87,7 +87,9 @@ export class UmbInputDocumentRootPickerElement extends FormControlMixin(UmbLitEl }); #openDynamicRootOriginPicker() { - this.#openModal = this.#modalContext?.open(this, UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL, {}); + this.#openModal = this.#modalContext?.open(this, UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL, { + data: { items: this._originManifests }, + }); this.#openModal?.onSubmit().then((data: UmbTreePickerDynamicRoot) => { const existingData = { ...this.data }; existingData.originKey = undefined; @@ -98,7 +100,9 @@ export class UmbInputDocumentRootPickerElement extends FormControlMixin(UmbLitEl } #openDynamicRootQueryStepPicker() { - this.#openModal = this.#modalContext?.open(this, UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL, {}); + this.#openModal = this.#modalContext?.open(this, UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL, { + data: { items: this._queryStepManifests }, + }); this.#openModal?.onSubmit().then((step) => { if (this.data) { const querySteps = [...(this.data.querySteps ?? []), step]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/collection/document-workspace-view-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/collection/document-workspace-view-collection.element.ts index 758a11482d..47f4fff704 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/collection/document-workspace-view-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/collection/document-workspace-view-collection.element.ts @@ -2,7 +2,7 @@ import type { UmbCollectionBulkActionPermissions, UmbCollectionConfiguration, } from '../../../../../core/collection/types.js'; -import { customElement, html, state } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; @@ -58,7 +58,6 @@ export class UmbDocumentWorkspaceViewCollectionElement extends UmbLitElement imp const config = new UmbPropertyEditorConfigCollection(dataType.values); return { unique: this._documentUnique, - dataTypeId: dataType.unique, allowedEntityBulkActions: config?.getValueByAlias('bulkActionPermissions'), orderBy: config?.getValueByAlias('orderBy') ?? 'updateDate', orderDirection: config?.getValueByAlias('orderDirection') ?? 'asc', @@ -69,7 +68,7 @@ export class UmbDocumentWorkspaceViewCollectionElement extends UmbLitElement imp } render() { - if (!this._config?.unique || !this._config?.dataTypeId) return html``; + if (!this._config?.unique) return nothing; return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-origin-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-origin-picker-modal.element.ts index 156a2dcc6d..c641283f66 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-origin-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-origin-picker-modal.element.ts @@ -1,12 +1,12 @@ import { UmbDocumentPickerContext } from '../../documents/documents/components/input-document/input-document.context.js'; +import type { UmbDynamicRootOriginModalData } from './index.js'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { css, html, customElement, state, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import type { ManifestDynamicRootOrigin } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbTreePickerDynamicRoot } from '@umbraco-cms/backoffice/components'; @customElement('umb-dynamic-root-origin-picker-modal') -export class UmbDynamicRootOriginPickerModalModalElement extends UmbModalBaseElement { +export class UmbDynamicRootOriginPickerModalModalElement extends UmbModalBaseElement { @state() private _origins: Array = []; @@ -16,10 +16,14 @@ export class UmbDynamicRootOriginPickerModalModalElement extends UmbModalBaseEle super(); this.#documentPickerContext.max = 1; + } - this.observe(umbExtensionsRegistry.byType('dynamicRootOrigin'), (origins: Array) => { - this._origins = origins; - }); + connectedCallback() { + super.connectedCallback(); + + if (this.data) { + this._origins = this.data.items; + } } #choose(item: ManifestDynamicRootOrigin) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-query-step-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-query-step-picker-modal.element.ts index f322d47a7a..9eee8c8d58 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-query-step-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/dynamic-root-query-step-picker-modal.element.ts @@ -1,28 +1,25 @@ import { UmbDocumentTypePickerContext } from '../../documents/document-types/components/input-document-type/input-document-type.context.js'; +import type { UmbDynamicRootQueryStepModalData } from './index.js'; import { UmbId } from '@umbraco-cms/backoffice/id'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, state, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbTreePickerDynamicRootQueryStep } from '@umbraco-cms/backoffice/components'; import type { ManifestDynamicRootQueryStep } from '@umbraco-cms/backoffice/extension-registry'; @customElement('umb-dynamic-root-query-step-picker-modal') -export class UmbDynamicRootQueryStepPickerModalModalElement extends UmbModalBaseElement { +export class UmbDynamicRootQueryStepPickerModalModalElement extends UmbModalBaseElement { @state() private _querySteps: Array = []; #documentTypePickerContext = new UmbDocumentTypePickerContext(this); - constructor() { - super(); + connectedCallback() { + super.connectedCallback(); - this.observe( - umbExtensionsRegistry.byType('dynamicRootQueryStep'), - (querySteps: Array) => { - this._querySteps = querySteps; - }, - ); + if (this.data) { + this._querySteps = this.data.items; + } } #choose(item: ManifestDynamicRootQueryStep) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/index.ts b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/index.ts index 1a7a4d6fdc..3fcf6dc3f7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/index.ts @@ -2,16 +2,31 @@ import { UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL_ALIAS, UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL_ALIAS, } from './manifests.js'; +import type { + ManifestDynamicRootOrigin, + ManifestDynamicRootQueryStep, +} from '@umbraco-cms/backoffice/extension-registry'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; -export const UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL = new UmbModalToken(UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL_ALIAS, { - modal: { - type: 'sidebar', - size: 'small', - }, -}); +export interface UmbDynamicRootOriginModalData { + items: Array; +} -export const UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL = new UmbModalToken( +export interface UmbDynamicRootQueryStepModalData { + items: Array; +} + +export const UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL = new UmbModalToken( + UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL_ALIAS, + { + modal: { + type: 'sidebar', + size: 'small', + }, + }, +); + +export const UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL = new UmbModalToken( UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL_ALIAS, { modal: { diff --git a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/manifests.ts index 97a63c351d..a04fc0ec86 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dynamic-root/modals/manifests.ts @@ -12,13 +12,13 @@ const modals: Array = [ type: 'modal', alias: UMB_DYNAMIC_ROOT_ORIGIN_PICKER_MODAL_ALIAS, name: 'Choose an origin', - js: () => import('./dynamic-root-origin-picker-modal.element.js'), + element: () => import('./dynamic-root-origin-picker-modal.element.js'), }, { type: 'modal', alias: UMB_DYNAMIC_ROOT_QUERY_STEP_PICKER_MODAL_ALIAS, name: 'Append step to query', - js: () => import('./dynamic-root-query-step-picker-modal.element.js'), + element: () => import('./dynamic-root-query-step-picker-modal.element.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer.context.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer.context.ts index 6dbbe79933..c5f467d934 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer.context.ts @@ -67,7 +67,7 @@ export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements U }; #savedSearches = new UmbObjectState(undefined); - savedSearches = this.#savedSearches.asObservablePart((data) => data?.items); + savedSearches = this.#savedSearches.asObservablePart((data) => data); #logCount = new UmbObjectState(null); logCount = this.#logCount.asObservable(); @@ -168,8 +168,8 @@ export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements U return this.#dateRange.getValue(); } - async getSavedSearches() { - const { data } = await this.#repository.getSavedSearches({ skip: 0, take: 100 }); + async getSavedSearches({ skip = 0, take = 999 }: { skip?: number; take?: number } = {}) { + const { data } = await this.#repository.getSavedSearches({ skip, take }); if (data) { this.#savedSearches.setValue(data); } else { diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer/logviewer-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer/logviewer-workspace.element.ts index c0aed6bc80..aea79e21e9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer/logviewer-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer/logviewer-workspace.element.ts @@ -33,7 +33,11 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement { } render() { - return html` `; + return html` + + `; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts index 21c65ce697..24dc5c6022 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts @@ -4,7 +4,6 @@ import { html, nothing, customElement, property, state } from '@umbraco-cms/back import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { LoggerResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; -//TODO: implement the saved searches pagination when the API total bug is fixed @customElement('umb-log-viewer-log-level-overview') export class UmbLogViewerLogLevelOverviewElement extends UmbLitElement { #logViewerContext?: UmbLogViewerWorkspaceContext; diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts index 56e67450cd..9edcbc0b0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts @@ -1,25 +1,31 @@ import type { UmbLogViewerWorkspaceContext } from '../../../logviewer.context.js'; import { UMB_APP_LOG_VIEWER_CONTEXT } from '../../../logviewer.context.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { - PagedLogTemplateResponseModel, + LogTemplateResponseModel, SavedLogSearchResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; -//TODO: fix pagination bug when API is fixed @customElement('umb-log-viewer-message-templates-overview') export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { + #itemsPerPage = 10; + #currentPage = 1; + @state() - private _messageTemplates: PagedLogTemplateResponseModel | null = null; + private _total = 0; + + @state() + private _messageTemplates: Array = []; #logViewerContext?: UmbLogViewerWorkspaceContext; constructor() { super(); this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT, (instance) => { this.#logViewerContext = instance; - this.#logViewerContext?.getMessageTemplates(0, 10); + this.#logViewerContext?.getMessageTemplates(0, this.#itemsPerPage); this.#observeStuff(); }); } @@ -27,13 +33,19 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { #observeStuff() { if (!this.#logViewerContext) return; this.observe(this.#logViewerContext.messageTemplates, (templates) => { - this._messageTemplates = templates ?? null; + this._messageTemplates = templates?.items ?? []; + this._total = templates?.total ?? 0; }); } #getMessageTemplates() { - const take = this._messageTemplates?.items?.length ?? 0; - this.#logViewerContext?.getMessageTemplates(0, take + 10); + const skip = this.#currentPage * this.#itemsPerPage - this.#itemsPerPage; + this.#logViewerContext?.getMessageTemplates(skip, this.#itemsPerPage); + } + + #onChangePage(event: UUIPaginationEvent) { + this.#currentPage = event.target.current; + this.#getMessageTemplates(); } #renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => { @@ -54,11 +66,11 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { render() { return html` -

Total Unique Message types: ${this._messageTemplates?.total}

+

Total Unique Message types: ${this._total}

${this._messageTemplates - ? this._messageTemplates.items.map( + ? this._messageTemplates.map( (template) => html` @@ -70,17 +82,15 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { `, - ) + ) : ''} - - - Show more - + ${this._total > this.#itemsPerPage + ? html`` + : nothing}
`; } @@ -88,6 +98,10 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { static styles = [ UmbTextStyles, css` + uui-pagination { + margin-top: var(--uui-size-layout-1); + } + #show-more-templates-btn { margin-top: var(--uui-size-space-5); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts index 517a46d848..c77d0f5e21 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts @@ -1,23 +1,29 @@ import type { UmbLogViewerWorkspaceContext } from '../../../logviewer.context.js'; import { UMB_APP_LOG_VIEWER_CONTEXT } from '../../../logviewer.context.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; -//TODO: implement the saved searches pagination when the API total bug is fixed @customElement('umb-log-viewer-saved-searches-overview') export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement { + #itemsPerPage = 999; + #currentPage = 1; + @state() private _savedSearches: SavedLogSearchResponseModel[] = []; + @state() + private _total = 0; + #logViewerContext?: UmbLogViewerWorkspaceContext; constructor() { super(); this.consumeContext(UMB_APP_LOG_VIEWER_CONTEXT, (instance) => { this.#logViewerContext = instance; - this.#logViewerContext?.getSavedSearches(); + this.#logViewerContext?.getSavedSearches({ skip: 0, take: this.#itemsPerPage }); this.#observeStuff(); }); } @@ -25,10 +31,21 @@ export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement { #observeStuff() { if (!this.#logViewerContext) return; this.observe(this.#logViewerContext.savedSearches, (savedSearches) => { - this._savedSearches = savedSearches ?? []; + this._savedSearches = savedSearches?.items ?? []; + this._total = savedSearches?.total ?? 0; }); } + #getSavedSearches() { + const skip = this.#currentPage * this.#itemsPerPage - this.#itemsPerPage; + this.#logViewerContext?.getSavedSearches({ skip, take: this.#itemsPerPage }); + } + + #onChangePage(event: UUIPaginationEvent) { + this.#currentPage = event.target.current; + this.#getSavedSearches(); + } + #renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => { return html`
  • ${this.#renderSearchItem({ name: 'All logs', query: '' })} ${this._savedSearches.map(this.#renderSearchItem)} + ${this._total > this.#itemsPerPage + ? html`` + : nothing} `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts index ec98da6550..88a8fa48a1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts @@ -89,12 +89,12 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement { .properties=${log.properties ?? []} .exception=${log.exception ?? ''} .messageTemplate=${log.messageTemplate ?? ''}>`, - )}` + )}` : html` Sorry, we cannot find what you are looking for. - `}`; + `}`; } render() { @@ -124,6 +124,10 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement { static styles = [ css` + uui-pagination { + display: block; + margin-bottom: var(--uui-size-layout-1); + } uui-box { --uui-box-default-padding: 0; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts index aeaa9df8f1..d07c85ef72 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts @@ -71,7 +71,7 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { #observeStuff() { if (!this.#logViewerContext) return; this.observe(this.#logViewerContext.savedSearches, (savedSearches) => { - this._savedSearches = savedSearches ?? []; + this._savedSearches = savedSearches?.items ?? []; this._isQuerySaved = this._savedSearches.some((search) => search.query === this._inputQuery); }); @@ -156,13 +156,13 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { ${this._showLoader ? html`
    -
    ` + ` : ''} ${this._inputQuery ? html`${!this._isQuerySaved ? html`` + >` : ''}` diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts index 9443eb507a..7ca2dd25cd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts @@ -57,6 +57,10 @@ export class UmbLogViewerSearchViewElement extends UmbLitElement { static styles = [ UmbTextStyles, css` + :host { + margin-bottom: var(--uui-size-space-2); + } + uui-box { --uui-box-default-padding: 0; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/detail/media-type-detail.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/detail/media-type-detail.server.data-source.ts index 9837b7d73c..28c704c689 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/detail/media-type-detail.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/detail/media-type-detail.server.data-source.ts @@ -42,7 +42,7 @@ export class UmbMediaTypeServerDataSource implements UmbDetailDataSource - ` + @click=${this.#onAddGroup}>` : ''} `; } 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 3b4d29afac..bcf2f7ffe2 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 @@ -9,7 +9,5 @@ export class UmbMediaCollectionContext extends UmbDefaultCollectionContext< > { constructor(host: UmbControllerHost) { super(host, UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS); - - this.selection.setSelectable(true); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.repository.ts index f5be70970c..ffb21ff449 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.repository.ts @@ -1,12 +1,15 @@ import type { UmbMediaCollectionFilterModel } from '../types.js'; import { UmbMediaCollectionServerDataSource } from './media-collection.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import type { UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -export class UmbMediaCollectionRepository implements UmbCollectionRepository { +export class UmbMediaCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository { #collectionSource: UmbMediaCollectionServerDataSource; constructor(host: UmbControllerHost) { + super(host); + this.#collectionSource = new UmbMediaCollectionServerDataSource(host); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/input-image-cropper.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/input-image-cropper.element.ts index f4bc06e0a8..902f1f082a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/input-image-cropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/input-image-cropper.element.ts @@ -1,14 +1,17 @@ import type { UmbImageCropperPropertyEditorValue } from './types.js'; +import type { UmbInputImageCropperFieldElement } from './image-cropper-field.element.js'; import { html, customElement, property, query, state } from '@umbraco-cms/backoffice/external/lit'; -import './image-cropper.element.js'; -import './image-cropper-focus-setter.element.js'; -import './image-cropper-preview.element.js'; -import './image-cropper-field.element.js'; import type { UUIFileDropzoneElement, UUIFileDropzoneEvent } from '@umbraco-cms/backoffice/external/uui'; import { UmbId } from '@umbraco-cms/backoffice/id'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { type TemporaryFileQueueItem, UmbTemporaryFileManager } from '@umbraco-cms/backoffice/temporary-file'; +import { UmbTemporaryFileManager } from '@umbraco-cms/backoffice/temporary-file'; +import { assignToFrozenObject } from '@umbraco-cms/backoffice/observable-api'; + +import './image-cropper.element.js'; +import './image-cropper-focus-setter.element.js'; +import './image-cropper-preview.element.js'; +import './image-cropper-field.element.js'; @customElement('umb-input-image-cropper') export class UmbInputImageCropperElement extends UmbLitElement { @@ -22,6 +25,9 @@ export class UmbInputImageCropperElement extends UmbLitElement { focalPoint: { left: 0.5, top: 0.5 }, }; + @property({ attribute: false }) + crops: UmbImageCropperPropertyEditorValue['crops'] = []; + @state() file?: File; @@ -33,18 +39,11 @@ export class UmbInputImageCropperElement extends UmbLitElement { constructor() { super(); this.#manager = new UmbTemporaryFileManager(this); - - // this.observe(this.#manager.isReady, (value) => (this.error = !value)); - this.observe(this.#manager.queue, this.#onQueueUpdate); } - #onQueueUpdate = (value: TemporaryFileQueueItem[]) => { - if (value.length) { - // this.file = value[0].file; - // this.fileUnique = value[0].unique; - // this.value.src = value[0].unique; - } - }; + protected firstUpdated(): void { + this.#mergeCrops(); + } #onUpload(e: UUIFileDropzoneEvent) { const file = e.detail.files[0]; @@ -53,7 +52,8 @@ export class UmbInputImageCropperElement extends UmbLitElement { this.file = file; this.fileUnique = unique; - this.value.src = unique; + + this.value = assignToFrozenObject(this.value, { src: unique }); this.#manager?.uploadOne(unique, file, 'waiting'); @@ -66,7 +66,7 @@ export class UmbInputImageCropperElement extends UmbLitElement { } #onRemove = () => { - this.value = { ...this.value, src: '' }; + this.value = assignToFrozenObject(this.value, { src: '' }); if (!this.fileUnique) return; this.#manager?.removeOne(this.fileUnique); this.fileUnique = undefined; @@ -75,6 +75,24 @@ export class UmbInputImageCropperElement extends UmbLitElement { this.dispatchEvent(new UmbChangeEvent()); }; + #mergeCrops() { + // Replace crops from the value with the crops from the config while keeping the coordinates from the value if they exist. + const filteredCrops = this.crops.map((crop) => { + const cropFromValue = this.value.crops.find((valueCrop) => valueCrop.alias === crop.alias); + const result = { + ...crop, + coordinates: cropFromValue?.coordinates ?? undefined, + }; + + return result; + }); + + this.value = { + ...this.value, + crops: filteredCrops, + }; + } + render() { if (this.value.src || this.file) { return this.#renderImageCropper(); @@ -91,9 +109,16 @@ export class UmbInputImageCropperElement extends UmbLitElement { `; } - #onChange(e: any) { - this.value = e.target.value; + #onChange(e: CustomEvent) { + const value = (e.target as UmbInputImageCropperFieldElement).value; + if (!value) { + this.value = { src: '', crops: [], focalPoint: { left: 0.5, top: 0.5 } }; + this.dispatchEvent(new UmbChangeEvent()); + return; + } + + this.value = value; this.dispatchEvent(new UmbChangeEvent()); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.context.ts index 44e59a35cf..4d8ba6ece6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.context.ts @@ -1,4 +1,5 @@ import type { UmbMediaItemModel } from '../../repository/item/types.js'; +import { UMB_MEDIA_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js'; import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_MEDIA_TREE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; @@ -7,6 +8,6 @@ export class UmbMediaPickerContext extends UmbPickerInputContext = { getUniqueOfElement: (element) => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-cropper/property-editor-ui-image-cropper.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-cropper/property-editor-ui-image-cropper.element.ts index 90b5cbb01e..6f04f15b06 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-cropper/property-editor-ui-image-cropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-cropper/property-editor-ui-image-cropper.element.ts @@ -1,8 +1,12 @@ -import type { UmbImageCropperPropertyEditorValue } from '../../components/index.js'; -import { html, customElement, property, nothing } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbImageCropperPropertyEditorValue, UmbInputImageCropperElement } from '../../components/index.js'; +import { html, customElement, property, nothing, state } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import '../../components/input-image-cropper/input-image-cropper.element.js'; +import { + UmbPropertyValueChangeEvent, + type UmbPropertyEditorConfigCollection, +} from '@umbraco-cms/backoffice/property-editor'; /** * @element umb-property-editor-ui-image-cropper @@ -16,6 +20,9 @@ export class UmbPropertyEditorUIImageCropperElement extends UmbLitElement implem focalPoint: { left: 0.5, top: 0.5 }, }; + @state() + crops: UmbImageCropperPropertyEditorValue['crops'] = []; + updated(changedProperties: Map) { super.updated(changedProperties); if (changedProperties.has('value')) { @@ -29,31 +36,23 @@ export class UmbPropertyEditorUIImageCropperElement extends UmbLitElement implem } } - // #crops = []; - - // @property({ attribute: false }) - // public set config(config: UmbPropertyEditorConfigCollection | undefined) { - // this.#crops = config?.getValueByAlias('crops') ?? []; - - // if (!this.value) { - // //TODO: How should we combine the crops from the value with the configuration? - // this.value = { - // crops: this.#crops, - // focalPoint: { left: 0.5, top: 0.5 }, - // src: 'https://picsum.photos/seed/picsum/1920/1080', - // }; - // } - // } + @property({ attribute: false }) + public set config(config: UmbPropertyEditorConfigCollection | undefined) { + this.crops = config?.getValueByAlias('crops') ?? []; + } #onChange(e: Event) { - this.value = (e.target as any).value; - this.dispatchEvent(new CustomEvent('property-value-change')); + this.value = (e.target as UmbInputImageCropperElement).value; + this.dispatchEvent(new UmbPropertyValueChangeEvent()); } render() { if (!this.value) return nothing; - return html``; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts index 7eddcc7572..54a8835b52 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts @@ -1 +1,9 @@ export * from './property-editor-ui-media-picker.element.js'; + +export type UmbMediaPickerPropertyValue = { + key: string; + mediaKey: string; + mediaTypeAlias: string; + focalPoint: { left: number; top: number } | null; + crops: Array<{ alias: string; width: number; height: number }>; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts index 2443efbfa6..54ccf9af0f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts @@ -1,5 +1,6 @@ import type { UmbInputMediaElement } from '../../components/input-media/input-media.element.js'; import '../../components/input-media/input-media.element.js'; +import type { UmbMediaPickerPropertyValue } from './index.js'; import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbPropertyValueChangeEvent, @@ -7,14 +8,23 @@ import { } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbId } from '@umbraco-cms/backoffice/id'; /** * @element umb-property-editor-ui-media-picker */ @customElement('umb-property-editor-ui-media-picker') export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement { - @property() - public value?: string; + @property({ attribute: false }) + public set value(value: Array) { + this.#value = value; + this._items = this.value ? this.value.map((x) => x.mediaKey) : []; + } + //TODO: Add support for document specific crops. The server side already supports this. + + public get value() { + return this.#value; + } @property({ attribute: false }) public set config(config: UmbPropertyEditorConfigCollection | undefined) { @@ -30,21 +40,39 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme return undefined; } + @state() + _items: Array = []; + @state() private _limitMin: number = 0; @state() private _limitMax: number = Infinity; - private _onChange(event: CustomEvent) { - this.value = (event.target as UmbInputMediaElement).selectedIds.join(','); + #value: Array = []; + + #onChange(event: CustomEvent) { + const selectedIds = (event.target as UmbInputMediaElement).selectedIds; + + const result = selectedIds.map((mediaKey) => { + return { + key: UmbId.new(), + mediaKey, + mediaTypeAlias: '', + focalPoint: null, + crops: [], + }; + }); + + this.value = result; + this._items = this.value ? this.value.map((x) => x.mediaKey) : []; this.dispatchEvent(new UmbPropertyValueChangeEvent()); } render() { return html` Add diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/collection/media-workspace-view-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/collection/media-workspace-view-collection.element.ts index 70a18ba74e..a8d12c291f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/collection/media-workspace-view-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/collection/media-workspace-view-collection.element.ts @@ -1,4 +1,4 @@ -import { customElement, html, state } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; @@ -58,7 +58,6 @@ export class UmbMediaWorkspaceViewCollectionElement extends UmbLitElement implem const config = new UmbPropertyEditorConfigCollection(dataType.values); return { unique: this._mediaUnique, - dataTypeId: dataType.unique, allowedEntityBulkActions: config?.getValueByAlias('bulkActionPermissions'), orderBy: config?.getValueByAlias('orderBy') ?? 'updateDate', orderDirection: config?.getValueByAlias('orderDirection') ?? 'asc', @@ -69,7 +68,7 @@ export class UmbMediaWorkspaceViewCollectionElement extends UmbLitElement implem } render() { - if (!this._config?.unique || !this._config?.dataTypeId) return html``; + if (!this._config?.unique) return nothing; return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/repository/sources/relation-type.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/repository/sources/relation-type.server.data.ts index decdbf2cf3..88bfe5c358 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/repository/sources/relation-type.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relation-types/repository/sources/relation-type.server.data.ts @@ -78,7 +78,7 @@ export class UmbRelationTypeServerDataSource { isBidirectional: false, isDependency: false, path: '', - isSystemRelationType: false, + isDeletable: false, }; return { data };