diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index e8e232ac2d..9a9654021c 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -127,6 +127,7 @@ "example": "node ./devops/example-runner/index.js", "format:fix": "npm run format -- --write", "format": "prettier 'src/**/*.ts' -- check", + "generate:api-local": "openapi --input ../Umbraco.Cms.Api.Management/OpenApi.json --output src/external/backend-api/src --postfixServices Resource --useOptions", "generate:api-dev": "openapi --input http://localhost:11000/umbraco/swagger/management/swagger.json --output src/external/backend-api/src --postfixServices Resource --useOptions", "generate:api": "openapi --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v14/dev/src/Umbraco.Cms.Api.Management/OpenApi.json --output src/external/backend-api/src --postfixServices Resource --useOptions", "generate:icons": "node ./devops/icons/index.js", 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 16a1bd5bf9..5571e4b3eb 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 @@ -361,6 +361,7 @@ export type { TemplateQueryResultItemPresentationModel } from './models/Template export type { TemplateQueryResultResponseModel } from './models/TemplateQueryResultResponseModel'; export type { TemplateQuerySettingsResponseModel } from './models/TemplateQuerySettingsResponseModel'; export type { TemplateResponseModel } from './models/TemplateResponseModel'; +export type { TemporaryFileConfigurationResponseModel } from './models/TemporaryFileConfigurationResponseModel'; export type { TemporaryFileResponseModel } from './models/TemporaryFileResponseModel'; export type { TourStatusModel } from './models/TourStatusModel'; export type { TreeItemPresentationModel } from './models/TreeItemPresentationModel'; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateMediaTypeRequestModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateMediaTypeRequestModel.ts index e143edb901..9db4ac7433 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateMediaTypeRequestModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateMediaTypeRequestModel.ts @@ -6,9 +6,11 @@ import type { CreateContentTypeForMediaTypeRequestModel } from './CreateContentTypeForMediaTypeRequestModel'; import type { MediaTypeCompositionModel } from './MediaTypeCompositionModel'; import type { MediaTypeSortModel } from './MediaTypeSortModel'; +import type { ReferenceByIdModel } from './ReferenceByIdModel'; export type CreateMediaTypeRequestModel = (CreateContentTypeForMediaTypeRequestModel & { allowedMediaTypes: Array; compositions: Array; + collection?: ReferenceByIdModel | null; }); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/DataTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/DataTypeResponseModel.ts index afd9143aef..4be982e714 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/DataTypeResponseModel.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/DataTypeResponseModel.ts @@ -10,5 +10,6 @@ export type DataTypeResponseModel = (DataTypeModelBaseModel & { id: string; parent?: ReferenceByIdModel | null; isDeletable: boolean; + canIgnoreStartNodes: boolean; }); diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TemporaryFileConfigurationResponseModel.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TemporaryFileConfigurationResponseModel.ts new file mode 100644 index 0000000000..e9c57080fd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/TemporaryFileConfigurationResponseModel.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type TemporaryFileConfigurationResponseModel = { + imageFileTypes: Array; + disallowedUploadedFilesExtensions: Array; + allowedUploadedFileExtensions: Array; + maxFileSize?: number | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts index 1453062de2..70fc1eff70 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/DocumentResource.ts @@ -11,12 +11,14 @@ import type { DocumentNotificationResponseModel } from '../models/DocumentNotifi import type { DocumentResponseModel } from '../models/DocumentResponseModel'; import type { DomainsResponseModel } from '../models/DomainsResponseModel'; import type { MoveDocumentRequestModel } from '../models/MoveDocumentRequestModel'; +import type { MoveMediaRequestModel } from '../models/MoveMediaRequestModel'; import type { PagedDocumentCollectionResponseModel } from '../models/PagedDocumentCollectionResponseModel'; import type { PagedDocumentRecycleBinItemResponseModel } from '../models/PagedDocumentRecycleBinItemResponseModel'; import type { PagedDocumentTreeItemResponseModel } from '../models/PagedDocumentTreeItemResponseModel'; import type { PublicAccessRequestModel } from '../models/PublicAccessRequestModel'; import type { PublishDocumentRequestModel } from '../models/PublishDocumentRequestModel'; import type { PublishDocumentWithDescendantsRequestModel } from '../models/PublishDocumentWithDescendantsRequestModel'; +import type { ReferenceByIdModel } from '../models/ReferenceByIdModel'; import type { SortingRequestModel } from '../models/SortingRequestModel'; import type { UnpublishDocumentRequestModel } from '../models/UnpublishDocumentRequestModel'; import type { UpdateDocumentNotificationsRequestModel } from '../models/UpdateDocumentNotificationsRequestModel'; @@ -683,6 +685,58 @@ export class DocumentResource { }); } + /** + * @returns any Success + * @throws ApiError + */ + public static getRecycleBinDocumentByIdOriginalParent({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/recycle-bin/document/{id}/original-parent', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 401: `The resource is protected and requires an authentication token`, + 403: `The authenticated user do not have access to this resource`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putRecycleBinDocumentByIdRestore({ + id, + requestBody, + }: { + id: string, + requestBody?: MoveMediaRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/recycle-bin/document/{id}/restore', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + 401: `The resource is protected and requires an authentication token`, + 403: `The authenticated user do not have access to this resource`, + 404: `Not Found`, + }, + }); + } + /** * @returns PagedDocumentRecycleBinItemResponseModel Success * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MediaResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MediaResource.ts index bbfb4abc63..d85c17a566 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MediaResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/MediaResource.ts @@ -11,6 +11,7 @@ import type { MoveMediaRequestModel } from '../models/MoveMediaRequestModel'; import type { PagedMediaCollectionResponseModel } from '../models/PagedMediaCollectionResponseModel'; import type { PagedMediaRecycleBinItemResponseModel } from '../models/PagedMediaRecycleBinItemResponseModel'; import type { PagedMediaTreeItemResponseModel } from '../models/PagedMediaTreeItemResponseModel'; +import type { ReferenceByIdModel } from '../models/ReferenceByIdModel'; import type { SortingRequestModel } from '../models/SortingRequestModel'; import type { UpdateMediaRequestModel } from '../models/UpdateMediaRequestModel'; @@ -360,6 +361,58 @@ export class MediaResource { }); } + /** + * @returns any Success + * @throws ApiError + */ + public static getRecycleBinMediaByIdOriginalParent({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/recycle-bin/media/{id}/original-parent', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 401: `The resource is protected and requires an authentication token`, + 403: `The authenticated user do not have access to this resource`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putRecycleBinMediaByIdRestore({ + id, + requestBody, + }: { + id: string, + requestBody?: MoveMediaRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/recycle-bin/media/{id}/restore', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + 401: `The resource is protected and requires an authentication token`, + 403: `The authenticated user do not have access to this resource`, + 404: `Not Found`, + }, + }); + } + /** * @returns PagedMediaRecycleBinItemResponseModel Success * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/TemporaryFileResource.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/TemporaryFileResource.ts index 848076b99a..c78ba660da 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/TemporaryFileResource.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/TemporaryFileResource.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { TemporaryFileConfigurationResponseModel } from '../models/TemporaryFileConfigurationResponseModel'; import type { TemporaryFileResponseModel } from '../models/TemporaryFileResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; @@ -85,7 +86,7 @@ export class TemporaryFileResource { * @returns any Success * @throws ApiError */ - public static getTemporaryFileConfiguration(): CancelablePromise { + public static getTemporaryFileConfiguration(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/temporary-file/configuration', 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 2b4f4af2b3..b05cea02f5 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 @@ -18,6 +18,7 @@ export const data: Array = [ editorAlias: '', values: [], isDeletable: true, + canIgnoreStartNodes: false, }, { name: 'Folder 2', @@ -28,6 +29,7 @@ export const data: Array = [ editorAlias: '', values: [], isDeletable: true, + canIgnoreStartNodes: false, }, { id: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', @@ -39,6 +41,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, }, { name: 'Text', @@ -49,6 +52,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'maxChars', @@ -65,6 +69,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -76,6 +81,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -87,6 +93,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'useLabel', @@ -144,6 +151,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'validationLimit', @@ -160,6 +168,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { //showPalette @@ -198,6 +207,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'overlaySize', @@ -230,6 +240,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'startNode', @@ -278,6 +289,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'format', @@ -301,6 +313,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'format', @@ -321,6 +334,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'format', @@ -341,6 +355,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'inputMode', @@ -357,6 +372,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'minNumber', @@ -377,6 +393,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'multiple', @@ -401,6 +418,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'enableRange', @@ -437,6 +455,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'default', @@ -465,6 +484,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'group', @@ -485,6 +505,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -496,6 +517,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'items', @@ -516,6 +538,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'items', @@ -536,6 +559,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'blocks', @@ -600,6 +624,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -611,6 +636,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'crops', @@ -643,6 +669,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'fileExtensions', @@ -663,6 +690,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'blockGroups', @@ -780,8 +808,9 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: false, + canIgnoreStartNodes: false, values: [ - { alias: 'pageSize', value: 2 }, + { alias: 'pageSize', value: 25 }, { alias: 'orderDirection', value: 'desc' }, { alias: 'includeProperties', @@ -815,6 +844,51 @@ export const data: Array = [ { alias: 'useInfiniteEditor', value: true }, ], }, + { + name: 'Collection View - Media', + id: '3a0156c4-3b8c-4803-bdc1-6871faa83fff', + parent: null, + editorAlias: 'Umbraco.ListView', + editorUiAlias: 'Umb.PropertyEditorUi.CollectionView', + hasChildren: false, + isFolder: false, + isDeletable: false, + canIgnoreStartNodes: false, + values: [ + { alias: 'pageSize', value: 2 }, + { alias: 'orderDirection', value: 'desc' }, + { + alias: 'includeProperties', + value: [ + { alias: 'sortOrder', header: 'Sort order', isSystem: true, nameTemplate: '' }, + { alias: 'updateDate', header: 'Last edited', isSystem: true }, + { alias: 'owner', header: 'Created by', isSystem: true }, + ], + }, + { alias: 'orderBy', value: 'updateDate' }, + { + alias: 'bulkActionPermissions', + value: { + allowBulkPublish: false, + allowBulkUnpublish: false, + allowBulkCopy: true, + allowBulkMove: true, + allowBulkDelete: true, + }, + }, + { + alias: 'layouts', + value: [ + { icon: 'icon-grid', isSystem: true, name: 'Grid', path: '', selected: true }, + { icon: 'icon-list', isSystem: true, name: 'Table', path: '', selected: true }, + ], + }, + { alias: 'icon', value: 'icon-layers' }, + { alias: 'tabName', value: 'Items' }, + { alias: 'showContentFirst', value: false }, + { alias: 'useInfiniteEditor', value: true }, + ], + }, { name: 'Icon Picker', id: 'dt-iconPicker', @@ -824,6 +898,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -835,6 +910,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'hideLabel', @@ -914,6 +990,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -925,6 +1002,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -936,6 +1014,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [ { alias: 'step', @@ -952,6 +1031,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -963,6 +1043,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -974,6 +1055,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -985,6 +1067,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, { @@ -996,6 +1079,7 @@ export const data: Array = [ hasChildren: false, isFolder: false, isDeletable: true, + canIgnoreStartNodes: false, values: [], }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.db.ts index ea4a7251d7..b1b0423c9c 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.db.ts @@ -34,6 +34,7 @@ const createFolderMockMapper = (request: CreateFolderRequestModel): UmbMockDataT hasChildren: false, editorAlias: '', isDeletable: true, + canIgnoreStartNodes: false, values: [], }; }; @@ -49,6 +50,7 @@ const createDetailMockMapper = (request: CreateDataTypeRequestModel): UmbMockDat isFolder: false, hasChildren: false, isDeletable: true, + canIgnoreStartNodes: false, }; }; @@ -61,6 +63,7 @@ const detailResponseMapper = (item: UmbMockDataTypeModel): DataTypeResponseModel editorUiAlias: item.editorUiAlias, values: item.values, isDeletable: item.isDeletable, + canIgnoreStartNodes: item.canIgnoreStartNodes, }; }; 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 8535971a82..a7d235712b 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 @@ -57,6 +57,26 @@ export const data: Array = [ labelOnTop: false, }, }, + { + id: '7', + container: { id: 'c3cd2f12-b7c4-4206-8d8b-27c061589f75' }, + alias: 'listView', + name: 'List View', + description: '', + dataType: { id: 'dt-collectionView' }, + variesByCulture: false, + variesBySegment: false, + sortOrder: 2, + validation: { + mandatory: false, + mandatoryMessage: null, + regEx: null, + regExMessage: null, + }, + appearance: { + labelOnTop: false, + }, + }, ], containers: [ { @@ -71,9 +91,12 @@ export const data: Array = [ variesByCulture: false, variesBySegment: false, isElement: false, - allowedMediaTypes: [], + allowedMediaTypes: [ + { mediaType: { id: 'media-type-1-id' }, sortOrder: 0 }, + ], compositions: [], isFolder: false, hasChildren: false, + collection: { id: 'dt-collectionView' }, }, ]; 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 e6c08f434a..33d25fcfaa 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 @@ -65,6 +65,7 @@ const createMockMediaTypeFolderMapper = (request: CreateFolderRequestModel): Umb compositions: [], isFolder: true, hasChildren: false, + collection: null, }; }; @@ -86,6 +87,7 @@ const createMockMediaTypeMapper = (request: CreateMediaTypeRequestModel): UmbMoc parent: request.folder ? { id: request.folder.id } : null, isFolder: false, hasChildren: false, + collection: null, }; }; @@ -104,6 +106,7 @@ const mediaTypeDetailMapper = (item: UmbMockMediaTypeModel): MediaTypeResponseMo isElement: item.isElement, allowedMediaTypes: item.allowedMediaTypes, compositions: item.compositions, + collection: item.collection, }; }; 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 02173732f6..211c9aa3f2 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 @@ -74,6 +74,7 @@ export const data: Array = [ mediaType: { id: 'media-type-1-id', icon: 'icon-bug', + collection: { id: 'dt-collectionView' }, }, values: [], variants: [ @@ -97,6 +98,7 @@ export const data: Array = [ mediaType: { id: 'media-type-1-id', icon: 'icon-bug', + collection: { id: 'dt-collectionView' }, }, values: [], variants: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/action/repository-action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/action/repository-action.ts index 37875ffaef..ebcb378547 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/action/repository-action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/action/repository-action.ts @@ -1,4 +1,4 @@ -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbBaseController } from '@umbraco-cms/backoffice/class-api'; import { type UmbApi, UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; @@ -6,7 +6,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr export class UmbActionBase extends UmbBaseController implements UmbApi { repository?: RepositoryType; - constructor(host: UmbControllerHostElement, repositoryAlias: string) { + constructor(host: UmbControllerHost, repositoryAlias: string) { super(host); new UmbExtensionApiInitializer(this, umbExtensionsRegistry, repositoryAlias, [this._host], (permitted, ctrl) => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/index.ts index 265dfa9afc..93c0d2aceb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/index.ts @@ -14,3 +14,4 @@ export { UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION } from './collection-bu export { UmbCollectionActionElement, UmbCollectionActionBase } from './action/index.js'; export type { UmbCollectionDataSource, UmbCollectionRepository } from './repository/index.js'; +export type { UmbCollectionBulkActionPermissions, UmbCollectionConfiguration } from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.ts index 8b2e890e32..b3001ee0a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.ts @@ -1,20 +1,82 @@ -import type { UmbAction} from '../action/index.js'; +import type { UmbAction } from '../action/index.js'; import { UmbActionBase } from '../action/index.js'; -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +/** + * Interface for an entity action. + * @export + * @interface UmbEntityAction + * @extends {UmbAction} + * @template RepositoryType + */ export interface UmbEntityAction extends UmbAction { + /** + * The unique identifier of the entity. + * @type {string} + */ unique: string; + + /** + * The href location, the action will act as a link. + * @returns {Promise} + */ + getHref(): Promise; + + /** + * The `execute` method, the action will act as a button. + * @returns {Promise} + */ + execute(): Promise; } -export class UmbEntityActionBase extends UmbActionBase { +/** + * Base class for an entity action. + * @export + * @abstract + * @class UmbEntityActionBase + * @extends {UmbActionBase} + * @implements {UmbEntityAction} + * @template RepositoryType + */ +export abstract class UmbEntityActionBase + extends UmbActionBase + implements UmbEntityAction +{ entityType: string; unique: string; repositoryAlias: string; - constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string, entityType: string) { + /** + * Creates an instance of UmbEntityActionBase. + * @param {UmbControllerHost} host + * @param {string} repositoryAlias + * @param {string} unique + * @param {string} entityType + * @memberof UmbEntityActionBase + */ + constructor(host: UmbControllerHost, repositoryAlias: string, unique: string, entityType: string) { super(host, repositoryAlias); this.entityType = entityType; this.unique = unique; this.repositoryAlias = repositoryAlias; } + + /** + * By specifying the href, the action will act as a link. + * The `execute` method will not be called. + * @abstract + * @returns {string | null | undefined} + */ + public getHref(): Promise { + return Promise.resolve(undefined); + } + + /** + * By specifying the `execute` method, the action will act as a button. + * @abstract + * @returns {Promise} + */ + public execute(): Promise { + return Promise.resolve(); + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.ts index 20b2250b1c..dbd9e0c67a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.ts @@ -5,6 +5,7 @@ import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controlle export interface UmbEntityBulkAction extends UmbAction { selection: Array; setSelection(selection: Array): void; + execute(): Promise; } export abstract class UmbEntityBulkActionBase diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/collection/extension-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/collection/extension-collection.element.ts new file mode 100644 index 0000000000..5fc7239181 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/collection/extension-collection.element.ts @@ -0,0 +1,89 @@ +import { umbExtensionsRegistry } from '../registry.js'; +import { html, customElement, css } from '@umbraco-cms/backoffice/external/lit'; +import { UMB_DEFAULT_COLLECTION_CONTEXT, UmbCollectionDefaultElement } from '@umbraco-cms/backoffice/collection'; +import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; +import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; + +@customElement('umb-extension-collection') +export class UmbExtensionCollectionElement extends UmbCollectionDefaultElement { + #collectionContext?: UmbDefaultCollectionContext; + + #inputTimer?: NodeJS.Timeout; + #inputTimerAmount = 500; + + #options: Array