Merge branch 'main' into feature/block-grid-editor-inline-mode
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -76,6 +76,7 @@ export type { CreateTemplateRequestModel } from './models/CreateTemplateRequestM
|
||||
export type { CreateUserGroupRequestModel } from './models/CreateUserGroupRequestModel';
|
||||
export type { CreateUserRequestModel } from './models/CreateUserRequestModel';
|
||||
export type { CreateUserResponseModel } from './models/CreateUserResponseModel';
|
||||
export type { CreateWebhookRequestModel } from './models/CreateWebhookRequestModel';
|
||||
export type { CultureAndScheduleRequestModel } from './models/CultureAndScheduleRequestModel';
|
||||
export type { CultureReponseModel } from './models/CultureReponseModel';
|
||||
export type { CurrentUserResponseModel } from './models/CurrentUserResponseModel';
|
||||
@@ -361,6 +362,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';
|
||||
@@ -399,6 +401,7 @@ export type { UpdateTemplateRequestModel } from './models/UpdateTemplateRequestM
|
||||
export type { UpdateUserGroupRequestModel } from './models/UpdateUserGroupRequestModel';
|
||||
export type { UpdateUserGroupsOnUserRequestModel } from './models/UpdateUserGroupsOnUserRequestModel';
|
||||
export type { UpdateUserRequestModel } from './models/UpdateUserRequestModel';
|
||||
export type { UpdateWebhookRequestModel } from './models/UpdateWebhookRequestModel';
|
||||
export type { UpgradeSettingsResponseModel } from './models/UpgradeSettingsResponseModel';
|
||||
export type { UserConfigurationResponseModel } from './models/UserConfigurationResponseModel';
|
||||
export type { UserGroupBaseModel } from './models/UserGroupBaseModel';
|
||||
@@ -422,6 +425,10 @@ export type { VariantModelBaseModel } from './models/VariantModelBaseModel';
|
||||
export type { VariantResponseModelBaseModel } from './models/VariantResponseModelBaseModel';
|
||||
export type { VerifyInviteUserRequestModel } from './models/VerifyInviteUserRequestModel';
|
||||
export type { VerifyResetPasswordTokenRequestModel } from './models/VerifyResetPasswordTokenRequestModel';
|
||||
export type { WebhookEventResponseModel } from './models/WebhookEventResponseModel';
|
||||
export type { WebhookItemResponseModel } from './models/WebhookItemResponseModel';
|
||||
export type { WebhookModelBaseModel } from './models/WebhookModelBaseModel';
|
||||
export type { WebhookResponseModel } from './models/WebhookResponseModel';
|
||||
|
||||
export { AuditLogResource } from './services/AuditLogResource';
|
||||
export { CultureResource } from './services/CultureResource';
|
||||
@@ -468,3 +475,4 @@ export { TrackedReferenceResource } from './services/TrackedReferenceResource';
|
||||
export { UpgradeResource } from './services/UpgradeResource';
|
||||
export { UserResource } from './services/UserResource';
|
||||
export { UserGroupResource } from './services/UserGroupResource';
|
||||
export { WebhookResource } from './services/WebhookResource';
|
||||
|
||||
@@ -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<MediaTypeSortModel>;
|
||||
compositions: Array<MediaTypeCompositionModel>;
|
||||
collection?: ReferenceByIdModel | null;
|
||||
});
|
||||
|
||||
|
||||
12
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateWebhookRequestModel.ts
vendored
Normal file
12
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/CreateWebhookRequestModel.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { WebhookModelBaseModel } from './WebhookModelBaseModel';
|
||||
|
||||
export type CreateWebhookRequestModel = (WebhookModelBaseModel & {
|
||||
id?: string | null;
|
||||
events: Array<string>;
|
||||
});
|
||||
|
||||
@@ -10,5 +10,6 @@ export type DataTypeResponseModel = (DataTypeModelBaseModel & {
|
||||
id: string;
|
||||
parent?: ReferenceByIdModel | null;
|
||||
isDeletable: boolean;
|
||||
canIgnoreStartNodes: boolean;
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type TemporaryFileConfigurationResponseModel = {
|
||||
imageFileTypes: Array<string>;
|
||||
disallowedUploadedFilesExtensions: Array<string>;
|
||||
allowedUploadedFileExtensions: Array<string>;
|
||||
maxFileSize?: number | null;
|
||||
};
|
||||
|
||||
11
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/UpdateWebhookRequestModel.ts
vendored
Normal file
11
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/UpdateWebhookRequestModel.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { WebhookModelBaseModel } from './WebhookModelBaseModel';
|
||||
|
||||
export type UpdateWebhookRequestModel = (WebhookModelBaseModel & {
|
||||
events: Array<string>;
|
||||
});
|
||||
|
||||
11
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookEventResponseModel.ts
vendored
Normal file
11
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookEventResponseModel.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type WebhookEventResponseModel = {
|
||||
eventName: string;
|
||||
eventType: string;
|
||||
alias: string;
|
||||
};
|
||||
|
||||
13
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookItemResponseModel.ts
vendored
Normal file
13
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookItemResponseModel.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type WebhookItemResponseModel = {
|
||||
enabled: boolean;
|
||||
name: string;
|
||||
events: string;
|
||||
url: string;
|
||||
types: string;
|
||||
};
|
||||
|
||||
12
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookModelBaseModel.ts
vendored
Normal file
12
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookModelBaseModel.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type WebhookModelBaseModel = {
|
||||
enabled: boolean;
|
||||
url: string;
|
||||
contentTypeKeys: Array<string>;
|
||||
headers: Record<string, string>;
|
||||
};
|
||||
|
||||
13
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookResponseModel.ts
vendored
Normal file
13
src/Umbraco.Web.UI.Client/src/external/backend-api/src/models/WebhookResponseModel.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { WebhookEventResponseModel } from './WebhookEventResponseModel';
|
||||
import type { WebhookModelBaseModel } from './WebhookModelBaseModel';
|
||||
|
||||
export type WebhookResponseModel = (WebhookModelBaseModel & {
|
||||
id: string;
|
||||
events: Array<WebhookEventResponseModel>;
|
||||
});
|
||||
|
||||
@@ -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';
|
||||
@@ -225,7 +227,7 @@ export class DocumentResource {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @returns void
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static putDocumentByIdDomains({
|
||||
@@ -234,7 +236,7 @@ export class DocumentResource {
|
||||
}: {
|
||||
id: string,
|
||||
requestBody?: UpdateDomainsRequestModel,
|
||||
}): CancelablePromise<any> {
|
||||
}): CancelablePromise<void> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'PUT',
|
||||
url: '/umbraco/management/api/v1/document/{id}/domains',
|
||||
@@ -244,7 +246,10 @@ export class DocumentResource {
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `Bad Request`,
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
404: `Not Found`,
|
||||
409: `Conflict`,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -683,6 +688,58 @@ export class DocumentResource {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getRecycleBinDocumentByIdOriginalParent({
|
||||
id,
|
||||
}: {
|
||||
id: string,
|
||||
}): CancelablePromise<ReferenceByIdModel> {
|
||||
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<any> {
|
||||
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
|
||||
|
||||
@@ -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<ReferenceByIdModel> {
|
||||
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<any> {
|
||||
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
|
||||
|
||||
@@ -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<any> {
|
||||
public static getTemporaryFileConfiguration(): CancelablePromise<TemporaryFileConfigurationResponseModel> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/temporary-file/configuration',
|
||||
|
||||
132
src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts
vendored
Normal file
132
src/Umbraco.Web.UI.Client/src/external/backend-api/src/services/WebhookResource.ts
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/* generated using openapi-typescript-codegen -- do no edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { CreateWebhookRequestModel } from '../models/CreateWebhookRequestModel';
|
||||
import type { UpdateWebhookRequestModel } from '../models/UpdateWebhookRequestModel';
|
||||
import type { WebhookItemResponseModel } from '../models/WebhookItemResponseModel';
|
||||
import type { WebhookResponseModel } from '../models/WebhookResponseModel';
|
||||
|
||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||
import { OpenAPI } from '../core/OpenAPI';
|
||||
import { request as __request } from '../core/request';
|
||||
|
||||
export class WebhookResource {
|
||||
|
||||
/**
|
||||
* @returns string Created
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static postWebhook({
|
||||
requestBody,
|
||||
}: {
|
||||
requestBody?: CreateWebhookRequestModel,
|
||||
}): CancelablePromise<string> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/umbraco/management/api/v1/webhook',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
responseHeader: 'Umb-Generated-Resource',
|
||||
errors: {
|
||||
400: `Bad Request`,
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getWebhookById({
|
||||
id,
|
||||
}: {
|
||||
id: string,
|
||||
}): CancelablePromise<WebhookResponseModel> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/webhook/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static putWebhookById({
|
||||
id,
|
||||
requestBody,
|
||||
}: {
|
||||
id: string,
|
||||
requestBody?: UpdateWebhookRequestModel,
|
||||
}): CancelablePromise<any> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'PUT',
|
||||
url: '/umbraco/management/api/v1/webhook/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
400: `Bad Request`,
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static deleteWebhookById({
|
||||
id,
|
||||
}: {
|
||||
id: string,
|
||||
}): CancelablePromise<any> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'DELETE',
|
||||
url: '/umbraco/management/api/v1/webhook/{id}',
|
||||
path: {
|
||||
'id': id,
|
||||
},
|
||||
errors: {
|
||||
400: `Bad Request`,
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getWebhookItem({
|
||||
ids,
|
||||
}: {
|
||||
ids?: Array<string>,
|
||||
}): CancelablePromise<Array<WebhookItemResponseModel>> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/webhook/item',
|
||||
query: {
|
||||
'ids': ids,
|
||||
},
|
||||
errors: {
|
||||
401: `The resource is protected and requires an authentication token`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
editorAlias: '',
|
||||
values: [],
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
},
|
||||
{
|
||||
name: 'Folder 2',
|
||||
@@ -28,6 +29,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
editorAlias: '',
|
||||
values: [],
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
},
|
||||
{
|
||||
id: '0cc0eba1-9960-42c9-bf9b-60e150b429ae',
|
||||
@@ -39,6 +41,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
},
|
||||
{
|
||||
name: 'Text',
|
||||
@@ -49,6 +52,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'maxChars',
|
||||
@@ -65,6 +69,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -76,6 +81,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -87,6 +93,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'useLabel',
|
||||
@@ -144,6 +151,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'validationLimit',
|
||||
@@ -160,6 +168,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
//showPalette
|
||||
@@ -198,6 +207,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'overlaySize',
|
||||
@@ -230,6 +240,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'startNode',
|
||||
@@ -278,6 +289,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'format',
|
||||
@@ -301,6 +313,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'format',
|
||||
@@ -321,6 +334,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'format',
|
||||
@@ -341,6 +355,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'inputMode',
|
||||
@@ -357,6 +372,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'minNumber',
|
||||
@@ -377,6 +393,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'multiple',
|
||||
@@ -401,6 +418,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'enableRange',
|
||||
@@ -437,6 +455,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'default',
|
||||
@@ -465,6 +484,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'group',
|
||||
@@ -485,6 +505,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -496,6 +517,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'items',
|
||||
@@ -516,6 +538,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'items',
|
||||
@@ -536,6 +559,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'blocks',
|
||||
@@ -600,6 +624,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -611,6 +636,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'crops',
|
||||
@@ -643,6 +669,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'fileExtensions',
|
||||
@@ -663,6 +690,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'blockGroups',
|
||||
@@ -781,8 +809,9 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: false,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{ alias: 'pageSize', value: 2 },
|
||||
{ alias: 'pageSize', value: 25 },
|
||||
{ alias: 'orderDirection', value: 'desc' },
|
||||
{
|
||||
alias: 'includeProperties',
|
||||
@@ -816,6 +845,51 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
{ 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',
|
||||
@@ -825,6 +899,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -836,6 +911,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'hideLabel',
|
||||
@@ -915,6 +991,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -926,6 +1003,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -937,6 +1015,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [
|
||||
{
|
||||
alias: 'step',
|
||||
@@ -953,6 +1032,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -964,6 +1044,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -975,6 +1056,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -986,6 +1068,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
@@ -997,6 +1080,7 @@ export const data: Array<UmbMockDataTypeModel> = [
|
||||
hasChildren: false,
|
||||
isFolder: false,
|
||||
isDeletable: true,
|
||||
canIgnoreStartNodes: false,
|
||||
values: [],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -57,6 +57,26 @@ export const data: Array<UmbMockMediaTypeModel> = [
|
||||
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<UmbMockMediaTypeModel> = [
|
||||
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' },
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ export const data: Array<UmbMockMediaModel> = [
|
||||
mediaType: {
|
||||
id: 'media-type-1-id',
|
||||
icon: 'icon-bug',
|
||||
collection: { id: 'dt-collectionView' },
|
||||
},
|
||||
values: [],
|
||||
variants: [
|
||||
@@ -97,6 +98,7 @@ export const data: Array<UmbMockMediaModel> = [
|
||||
mediaType: {
|
||||
id: 'media-type-1-id',
|
||||
icon: 'icon-bug',
|
||||
collection: { id: 'dt-collectionView' },
|
||||
},
|
||||
values: [],
|
||||
variants: [
|
||||
|
||||
@@ -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<RepositoryType> 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) => {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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<RepositoryType>
|
||||
* @extends {UmbAction<RepositoryType>}
|
||||
* @template RepositoryType
|
||||
*/
|
||||
export interface UmbEntityAction<RepositoryType> extends UmbAction<RepositoryType> {
|
||||
/**
|
||||
* The unique identifier of the entity.
|
||||
* @type {string}
|
||||
*/
|
||||
unique: string;
|
||||
|
||||
/**
|
||||
* The href location, the action will act as a link.
|
||||
* @returns {Promise<string | null | undefined>}
|
||||
*/
|
||||
getHref(): Promise<string | null | undefined>;
|
||||
|
||||
/**
|
||||
* The `execute` method, the action will act as a button.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
execute(): Promise<void>;
|
||||
}
|
||||
|
||||
export class UmbEntityActionBase<RepositoryType> extends UmbActionBase<RepositoryType> {
|
||||
/**
|
||||
* Base class for an entity action.
|
||||
* @export
|
||||
* @abstract
|
||||
* @class UmbEntityActionBase<RepositoryType>
|
||||
* @extends {UmbActionBase<RepositoryType>}
|
||||
* @implements {UmbEntityAction<RepositoryType>}
|
||||
* @template RepositoryType
|
||||
*/
|
||||
export abstract class UmbEntityActionBase<RepositoryType>
|
||||
extends UmbActionBase<RepositoryType>
|
||||
implements UmbEntityAction<RepositoryType>
|
||||
{
|
||||
entityType: string;
|
||||
unique: string;
|
||||
repositoryAlias: string;
|
||||
|
||||
constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string, entityType: string) {
|
||||
/**
|
||||
* Creates an instance of UmbEntityActionBase<RepositoryType>.
|
||||
* @param {UmbControllerHost} host
|
||||
* @param {string} repositoryAlias
|
||||
* @param {string} unique
|
||||
* @param {string} entityType
|
||||
* @memberof UmbEntityActionBase<RepositoryType>
|
||||
*/
|
||||
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<string | null | undefined> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* By specifying the `execute` method, the action will act as a button.
|
||||
* @abstract
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public execute(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controlle
|
||||
export interface UmbEntityBulkAction<RepositoryType = unknown> extends UmbAction<RepositoryType> {
|
||||
selection: Array<string>;
|
||||
setSelection(selection: Array<string>): void;
|
||||
execute(): Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class UmbEntityBulkActionBase<RepositoryType = unknown>
|
||||
|
||||
@@ -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<Option> = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_DEFAULT_COLLECTION_CONTEXT, (collectionContext) => {
|
||||
this.#collectionContext = collectionContext;
|
||||
});
|
||||
|
||||
this.observe(umbExtensionsRegistry.extensions, (extensions) => {
|
||||
const types = [...new Set(extensions.map((x) => x.type))];
|
||||
const options = types.sort().map((x) => ({ name: this.#camelCaseToWords(x), value: x }));
|
||||
this.#options = [{ name: 'All', value: '' }, ...options];
|
||||
});
|
||||
}
|
||||
|
||||
// credit: https://stackoverflow.com/a/7225450/12787 [LK]
|
||||
#camelCaseToWords(input: string) {
|
||||
const result = input.replace(/([A-Z])/g, ' $1');
|
||||
return result.charAt(0).toUpperCase() + result.slice(1);
|
||||
}
|
||||
|
||||
#onChange(event: UUISelectEvent) {
|
||||
const extensionType = event.target.value;
|
||||
console.log('onChange', extensionType);
|
||||
this.#collectionContext?.setFilter({ type: extensionType });
|
||||
}
|
||||
|
||||
#onSearch(event: InputEvent) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const query = target.value || '';
|
||||
clearTimeout(this.#inputTimer);
|
||||
this.#inputTimer = setTimeout(() => this.#collectionContext?.setFilter({ query }), this.#inputTimerAmount);
|
||||
}
|
||||
|
||||
protected renderToolbar() {
|
||||
return html`
|
||||
<div id="toolbar" slot="header">
|
||||
<uui-input @input=${this.#onSearch} label="Search" placeholder="Search..." id="input-search"></uui-input>
|
||||
<uui-select
|
||||
label="Select type..."
|
||||
placeholder="Select type..."
|
||||
.options=${this.#options}
|
||||
@change=${this.#onChange}></uui-select>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#toolbar {
|
||||
display: flex;
|
||||
gap: var(--uui-size-space-5);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: var(--uui-size-space-4);
|
||||
padding-right: var(--uui-size-space-6);
|
||||
width: 100%;
|
||||
}
|
||||
uui-input {
|
||||
width: 100%;
|
||||
}
|
||||
uui-select {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbExtensionCollectionElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-extension-collection': UmbExtensionCollectionElement;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ const collectionManifest: ManifestCollection = {
|
||||
kind: 'default',
|
||||
alias: UMB_EXTENSION_COLLECTION_ALIAS,
|
||||
name: 'Extension Collection',
|
||||
element: () => import('./extension-collection.element.js'),
|
||||
meta: {
|
||||
repositoryAlias: UMB_EXTENSION_COLLECTION_REPOSITORY_ALIAS,
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbCollectionRepository } from '@umbraco-cms/backoffice/collection';
|
||||
|
||||
export interface UmbExtensionCollectionFilter {
|
||||
query?: string;
|
||||
skip: number;
|
||||
take: number;
|
||||
type?: ManifestTypes['type'];
|
||||
@@ -17,9 +18,20 @@ export class UmbExtensionCollectionRepository extends UmbRepositoryBase implemen
|
||||
|
||||
async requestCollection(filter: UmbExtensionCollectionFilter) {
|
||||
let extensions = umbExtensionsRegistry.getAllExtensions();
|
||||
|
||||
if (filter.query) {
|
||||
const query = filter.query.toLowerCase();
|
||||
extensions = extensions.filter(
|
||||
(x) => x.name.toLowerCase().includes(query) || x.alias.toLowerCase().includes(query),
|
||||
);
|
||||
}
|
||||
|
||||
if (filter.type) {
|
||||
extensions = extensions.filter((x) => x.type === filter.type);
|
||||
}
|
||||
|
||||
extensions.sort((a, b) => a.type.localeCompare(b.type) || a.alias.localeCompare(b.alias));
|
||||
|
||||
const total = extensions.length;
|
||||
const items = extensions.slice(filter.skip, filter.skip + filter.take);
|
||||
const data = { items, total };
|
||||
|
||||
@@ -20,6 +20,6 @@ export interface NumberRangeValueType {
|
||||
max?: number;
|
||||
}
|
||||
|
||||
export interface UmbReferenceById {
|
||||
id: string;
|
||||
export interface UmbReferenceByUnique {
|
||||
unique: string;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@ import type {
|
||||
import type { UmbPropertyEditorConfigCollection } from '../../config/index.js';
|
||||
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UMB_DOCUMENT_COLLECTION_ALIAS } from '@umbraco-cms/backoffice/document';
|
||||
import { UMB_MEDIA_COLLECTION_ALIAS } from '@umbraco-cms/backoffice/media';
|
||||
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/document';
|
||||
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
|
||||
import type { UmbDocumentWorkspaceContext } from '@umbraco-cms/backoffice/document';
|
||||
import type { UmbMediaWorkspaceContext } from '@umbraco-cms/backoffice/media';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-collection-view
|
||||
@@ -18,6 +21,9 @@ export class UmbPropertyEditorUICollectionViewElement extends UmbLitElement impl
|
||||
@property()
|
||||
value?: string;
|
||||
|
||||
@state()
|
||||
private _collectionAlias: string = UMB_DOCUMENT_COLLECTION_ALIAS;
|
||||
|
||||
@state()
|
||||
private _config?: UmbCollectionConfiguration;
|
||||
|
||||
@@ -31,17 +37,25 @@ export class UmbPropertyEditorUICollectionViewElement extends UmbLitElement impl
|
||||
|
||||
// Gets the Data Type ID for the current property.
|
||||
this.consumeContext(UMB_PROPERTY_CONTEXT, (propertyContext) => {
|
||||
// TODO: [LK:2024-02-01] Replace `UMB_DOCUMENT_WORKSPACE_CONTEXT`
|
||||
// with an abstracted context that supports both document and media workspaces.
|
||||
this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspaceContext) => {
|
||||
this.observe(workspaceContext.unique, (unique) => {
|
||||
this.consumeContext(UMB_WORKSPACE_CONTEXT, (workspaceContext) => {
|
||||
// TODO: [LK:2024-02-22] We need a solution that will allow the Collection property-editor
|
||||
// to work in any workspace (that supports `unique` and `structure.getPropertyStructureByAlias`).
|
||||
const entityType = workspaceContext.getEntityType();
|
||||
const contentWorkspaceContext =
|
||||
entityType === 'media'
|
||||
? (workspaceContext as UmbMediaWorkspaceContext)
|
||||
: (workspaceContext as UmbDocumentWorkspaceContext);
|
||||
|
||||
this._collectionAlias = entityType === 'media' ? UMB_MEDIA_COLLECTION_ALIAS : UMB_DOCUMENT_COLLECTION_ALIAS;
|
||||
|
||||
this.observe(contentWorkspaceContext.unique, (unique) => {
|
||||
if (this._config) {
|
||||
this._config.unique = unique;
|
||||
}
|
||||
});
|
||||
this.observe(propertyContext.alias, async (propertyAlias) => {
|
||||
if (propertyAlias) {
|
||||
const property = await workspaceContext.structure.getPropertyStructureByAlias(propertyAlias);
|
||||
const property = await contentWorkspaceContext.structure.getPropertyStructureByAlias(propertyAlias);
|
||||
if (property && this._config) {
|
||||
this._config.dataTypeId = property.dataType.unique;
|
||||
this.requestUpdate('_config');
|
||||
@@ -67,7 +81,7 @@ export class UmbPropertyEditorUICollectionViewElement extends UmbLitElement impl
|
||||
|
||||
render() {
|
||||
if (!this._config?.unique || !this._config?.dataTypeId) return html`<uui-loader></uui-loader>`;
|
||||
return html`<umb-collection alias="Umb.Collection.Document" .config=${this._config}></umb-collection>`;
|
||||
return html`<umb-collection .alias=${this._collectionAlias} .config=${this._config}></umb-collection>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ export class UmbDocumentWorkspaceHasCollectionCondition extends UmbBaseControlle
|
||||
|
||||
this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (context) => {
|
||||
this.observe(
|
||||
context.contentTypeHasCollection,
|
||||
(hasCollection) => {
|
||||
this.permitted = hasCollection ?? false;
|
||||
context.contentTypeCollection,
|
||||
(collection) => {
|
||||
this.permitted = !!collection?.unique;
|
||||
this.#onChange();
|
||||
},
|
||||
'observeCollection',
|
||||
|
||||
@@ -43,6 +43,7 @@ export class UmbDocumentServerDataSource implements UmbDetailDataSource<UmbDocum
|
||||
template: null,
|
||||
documentType: {
|
||||
unique: '',
|
||||
collection: null,
|
||||
},
|
||||
isTrashed: false,
|
||||
values: [],
|
||||
@@ -113,7 +114,7 @@ export class UmbDocumentServerDataSource implements UmbDetailDataSource<UmbDocum
|
||||
template: data.template ? { unique: data.template.id } : null,
|
||||
documentType: {
|
||||
unique: data.documentType.id,
|
||||
collection: data.documentType.collection ?? undefined,
|
||||
collection: data.documentType.collection ? { unique: data.documentType.collection.id } : null,
|
||||
},
|
||||
isTrashed: data.isTrashed,
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ const mapper = (item: DocumentItemResponseModel): UmbDocumentItemModel => {
|
||||
documentType: {
|
||||
unique: item.documentType.id,
|
||||
icon: item.documentType.icon,
|
||||
collection: item.documentType.collection ?? undefined,
|
||||
collection: item.documentType.collection ? { unique: item.documentType.collection.id } : null,
|
||||
},
|
||||
variants: item.variants.map((variant) => {
|
||||
return {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
|
||||
export interface UmbDocumentItemModel {
|
||||
name: string; // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
|
||||
@@ -9,7 +9,7 @@ export interface UmbDocumentItemModel {
|
||||
documentType: {
|
||||
unique: string;
|
||||
icon: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
variants: Array<UmbDocumentItemVariantModel>;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ const mapper = (item: DocumentTreeItemResponseModel): UmbDocumentTreeItemModel =
|
||||
documentType: {
|
||||
unique: item.documentType.id,
|
||||
icon: item.documentType.icon,
|
||||
collection: item.documentType.collection ?? undefined,
|
||||
collection: item.documentType.collection ? { unique: item.documentType.collection.id } : null,
|
||||
},
|
||||
variants: item.variants.map((variant) => {
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { UmbDocumentEntityType, UmbDocumentRootEntityType } from '../entity.js';
|
||||
import type { UmbUniqueTreeItemModel, UmbUniqueTreeRootModel } from '@umbraco-cms/backoffice/tree';
|
||||
import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
|
||||
export interface UmbDocumentTreeItemModel extends UmbUniqueTreeItemModel {
|
||||
entityType: UmbDocumentEntityType;
|
||||
@@ -11,7 +11,7 @@ export interface UmbDocumentTreeItemModel extends UmbUniqueTreeItemModel {
|
||||
documentType: {
|
||||
unique: string;
|
||||
icon: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
variants: Array<UmbDocumentTreeItemVariantModel>;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { UmbDocumentEntityType } from './entity.js';
|
||||
import type { UmbVariantModel } from '@umbraco-cms/backoffice/variant';
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
import { DocumentVariantStateModel as UmbDocumentVariantState } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
export { UmbDocumentVariantState };
|
||||
|
||||
export interface UmbDocumentDetailModel {
|
||||
documentType: {
|
||||
unique: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
entityType: UmbDocumentEntityType;
|
||||
isTrashed: boolean;
|
||||
|
||||
@@ -39,7 +39,7 @@ export class UmbDocumentWorkspaceContext
|
||||
readonly unique = this.#currentData.asObservablePart((data) => data?.unique);
|
||||
|
||||
readonly contentTypeUnique = this.#currentData.asObservablePart((data) => data?.documentType.unique);
|
||||
readonly contentTypeHasCollection = this.#currentData.asObservablePart((data) => !!data?.documentType.collection);
|
||||
readonly contentTypeCollection = this.#currentData.asObservablePart((data) => data?.documentType.collection);
|
||||
|
||||
readonly variants = this.#currentData.asObservablePart((data) => data?.variants || []);
|
||||
readonly urls = this.#currentData.asObservablePart((data) => data?.urls || []);
|
||||
@@ -79,6 +79,7 @@ export class UmbDocumentWorkspaceContext
|
||||
this.#getDataPromise = this.repository.createScaffold(parentUnique, {
|
||||
documentType: {
|
||||
unique: documentTypeUnique,
|
||||
collection: null,
|
||||
},
|
||||
});
|
||||
const { data } = await this.#getDataPromise;
|
||||
|
||||
@@ -33,10 +33,9 @@ export class UmbDocumentWorkspaceViewCollectionElement extends UmbLitElement imp
|
||||
this.observe(
|
||||
workspaceContext.structure.ownerContentType(),
|
||||
async (documentType) => {
|
||||
if (!documentType) return;
|
||||
if (!documentType || !documentType.collection) return;
|
||||
|
||||
// TODO: [LK] Temp hard-coded. Once the API is ready, wire up the data-type ID from the content-type.
|
||||
const dataTypeUnique = 'c0808dd3-8133-4e4b-8ce8-e2bea84a96a4'; // documentType.collection.dataTypeId;
|
||||
const dataTypeUnique = documentType.collection.unique;
|
||||
|
||||
if (dataTypeUnique) {
|
||||
await this.#dataTypeDetailRepository.requestByUnique(dataTypeUnique);
|
||||
|
||||
@@ -10,6 +10,13 @@ export class UmbMediaCollectionRepository implements UmbCollectionRepository {
|
||||
this.#collectionSource = new UmbMediaCollectionServerDataSource(host);
|
||||
}
|
||||
|
||||
async getDefaultConfiguration() {
|
||||
return {
|
||||
// TODO: The default Collection data-type ID (for the Media ListView) will come from the server soon. [LK]
|
||||
defaultDataTypeId: '3a0156c4-3b8c-4803-bdc1-6871faa83fff',
|
||||
};
|
||||
}
|
||||
|
||||
async requestCollection(query: UmbMediaCollectionFilterModel) {
|
||||
return this.#collectionSource.getCollection(query);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ export class UmbMediaCollectionServerDataSource implements UmbCollectionDataSour
|
||||
}
|
||||
|
||||
async getCollection(query: UmbMediaCollectionFilterModel) {
|
||||
// if (!query.dataTypeId) {
|
||||
// throw new Error('Data type 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 ?? '',
|
||||
|
||||
@@ -51,6 +51,9 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
|
||||
@state()
|
||||
private _selection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _skip: number = 0;
|
||||
|
||||
#collectionContext?: UmbDefaultCollectionContext<UmbMediaCollectionItemModel, UmbMediaCollectionFilterModel>;
|
||||
|
||||
constructor() {
|
||||
@@ -89,6 +92,14 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
|
||||
},
|
||||
'umbCollectionSelectionObserver',
|
||||
);
|
||||
|
||||
this.observe(
|
||||
this.#collectionContext.pagination.skip,
|
||||
(skip) => {
|
||||
this._skip = skip;
|
||||
},
|
||||
'umbCollectionSkipObserver',
|
||||
);
|
||||
}
|
||||
|
||||
#createTableHeadings() {
|
||||
@@ -113,14 +124,16 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
|
||||
this.#createTableHeadings();
|
||||
}
|
||||
|
||||
this._tableItems = items.map((item) => {
|
||||
this._tableItems = items.map((item, rowIndex) => {
|
||||
if (!item.unique) throw new Error('Item id is missing.');
|
||||
|
||||
const sortOrder = this._skip + rowIndex;
|
||||
|
||||
const data =
|
||||
this._tableColumns?.map((column) => {
|
||||
return {
|
||||
columnAlias: column.alias,
|
||||
value: column.elementName ? item : this.#getPropertyValueByAlias(item, column.alias),
|
||||
value: column.elementName ? item : this.#getPropertyValueByAlias(sortOrder, item, column.alias),
|
||||
};
|
||||
}) ?? [];
|
||||
|
||||
@@ -132,7 +145,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
#getPropertyValueByAlias(item: UmbMediaCollectionItemModel, alias: string) {
|
||||
#getPropertyValueByAlias(sortOrder: number, item: UmbMediaCollectionItemModel, alias: string) {
|
||||
switch (alias) {
|
||||
case 'createDate':
|
||||
return item.createDate.toLocaleString();
|
||||
@@ -140,6 +153,8 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement {
|
||||
return item.name;
|
||||
case 'owner':
|
||||
return item.creator;
|
||||
case 'sortOrder':
|
||||
return sortOrder;
|
||||
case 'updateDate':
|
||||
return item.updateDate.toLocaleString();
|
||||
default:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION } from './media-workspace-has-collection.condition.js';
|
||||
@@ -0,0 +1,3 @@
|
||||
import { manifest as mediaWorkspaceHasCollectionCondition } from './media-workspace-has-collection.condition.js';
|
||||
|
||||
export const manifests = [mediaWorkspaceHasCollectionCondition];
|
||||
@@ -0,0 +1,44 @@
|
||||
import { UMB_MEDIA_WORKSPACE_CONTEXT } from '../workspace/media-workspace.context-token.js';
|
||||
import { UmbBaseController } from '@umbraco-cms/backoffice/class-api';
|
||||
import type {
|
||||
ManifestCondition,
|
||||
UmbConditionConfigBase,
|
||||
UmbConditionControllerArguments,
|
||||
UmbExtensionCondition,
|
||||
} from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbMediaWorkspaceHasCollectionCondition extends UmbBaseController implements UmbExtensionCondition {
|
||||
config: MediaWorkspaceHasCollectionConditionConfig;
|
||||
permitted = false;
|
||||
#onChange: () => void;
|
||||
|
||||
constructor(args: UmbConditionControllerArguments<MediaWorkspaceHasCollectionConditionConfig>) {
|
||||
super(args.host);
|
||||
this.config = args.config;
|
||||
this.#onChange = args.onChange;
|
||||
|
||||
this.consumeContext(UMB_MEDIA_WORKSPACE_CONTEXT, (context) => {
|
||||
this.observe(
|
||||
context.contentTypeCollection,
|
||||
(collection) => {
|
||||
this.permitted = !!collection?.unique;
|
||||
this.#onChange();
|
||||
},
|
||||
'observeCollection',
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export type MediaWorkspaceHasCollectionConditionConfig = UmbConditionConfigBase<
|
||||
typeof UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION
|
||||
>;
|
||||
|
||||
export const UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION = 'Umb.Condition.MediaWorkspaceHasCollection';
|
||||
|
||||
export const manifest: ManifestCondition = {
|
||||
type: 'condition',
|
||||
name: 'Media Workspace Has Collection Condition',
|
||||
alias: UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION,
|
||||
api: UmbMediaWorkspaceHasCollectionCondition,
|
||||
};
|
||||
@@ -7,6 +7,7 @@ export * from './tracked-reference/index.js';
|
||||
export * from './user-permissions/index.js';
|
||||
export * from './utils/index.js';
|
||||
export * from './workspace/index.js';
|
||||
export * from './conditions/index.js';
|
||||
|
||||
export { UMB_MEDIA_TREE_ALIAS } from './tree/index.js';
|
||||
export { UMB_MEDIA_COLLECTION_ALIAS } from './collection/index.js';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { manifests as collectionManifests } from './collection/manifests.js';
|
||||
import { manifests as conditionManifests } from './conditions/manifests.js';
|
||||
import { manifests as entityActionsManifests } from './entity-actions/manifests.js';
|
||||
import { manifests as entityBulkActionsManifests } from './entity-bulk-actions/manifests.js';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests.js';
|
||||
@@ -11,6 +12,7 @@ import { manifests as workspaceManifests } from './workspace/manifests.js';
|
||||
|
||||
export const manifests = [
|
||||
...collectionManifests,
|
||||
...conditionManifests,
|
||||
...entityActionsManifests,
|
||||
...entityBulkActionsManifests,
|
||||
...menuItemManifests,
|
||||
|
||||
@@ -40,6 +40,7 @@ export class UmbMediaServerDataSource implements UmbDetailDataSource<UmbMediaDet
|
||||
urls: [],
|
||||
mediaType: {
|
||||
unique: mediaType.unique,
|
||||
collection: mediaType.collection || null,
|
||||
},
|
||||
isTrashed: false,
|
||||
values: [],
|
||||
@@ -89,7 +90,10 @@ export class UmbMediaServerDataSource implements UmbDetailDataSource<UmbMediaDet
|
||||
};
|
||||
}),
|
||||
urls: data.urls,
|
||||
mediaType: { unique: data.mediaType.id },
|
||||
mediaType: {
|
||||
unique: data.mediaType.id,
|
||||
collection: data.mediaType.collection ? { unique: data.mediaType.collection.id } : null,
|
||||
},
|
||||
isTrashed: data.isTrashed,
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ const mapper = (item: MediaItemResponseModel): UmbMediaItemModel => {
|
||||
mediaType: {
|
||||
unique: item.mediaType.id,
|
||||
icon: item.mediaType.icon,
|
||||
collection: item.mediaType.collection ?? undefined,
|
||||
collection: item.mediaType.collection ? { unique: item.mediaType.collection.id } : null,
|
||||
},
|
||||
variants: item.variants.map((variant) => {
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
|
||||
export interface UmbMediaItemModel {
|
||||
unique: string;
|
||||
@@ -6,7 +6,7 @@ export interface UmbMediaItemModel {
|
||||
mediaType: {
|
||||
unique: string;
|
||||
icon: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
variants: Array<UmbMediaItemVariantModel>;
|
||||
name: string; // TODO: get correct variant name
|
||||
|
||||
@@ -1,48 +1,80 @@
|
||||
import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js';
|
||||
import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbMediaCollectionRepository } from '../collection/repository/index.js';
|
||||
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbCollectionElement } from '@umbraco-cms/backoffice/collection';
|
||||
import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type';
|
||||
import type {
|
||||
UmbCollectionBulkActionPermissions,
|
||||
UmbCollectionConfiguration,
|
||||
} from '@umbraco-cms/backoffice/collection';
|
||||
import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type';
|
||||
import type { UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
|
||||
|
||||
@customElement('umb-media-section-view')
|
||||
export class UmbMediaSectionViewElement extends UmbLitElement {
|
||||
#routes: UmbRoute[] = [
|
||||
{
|
||||
path: 'collection',
|
||||
component: () => {
|
||||
#dataTypeDetailRepository = new UmbDataTypeDetailRepository(this);
|
||||
#mediaCollectionRepository = new UmbMediaCollectionRepository(this);
|
||||
|
||||
// TODO: [LK] Work-in-progress. Need to get the data-type configuration for the Media Collection.
|
||||
const config = {
|
||||
unique: '',
|
||||
dataTypeId: '', //'3a0156c4-3b8c-4803-bdc1-6871faa83fff', //'dt-collectionView',
|
||||
allowedEntityBulkActions: {
|
||||
allowBulkCopy: true,
|
||||
allowBulkDelete: true,
|
||||
allowBulkMove: true,
|
||||
allowBulkPublish: false,
|
||||
allowBulkUnpublish: false,
|
||||
@state()
|
||||
private _routes?: UmbRoute[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.#defineRoutes();
|
||||
}
|
||||
|
||||
async #defineRoutes() {
|
||||
const config = await this.#mediaCollectionRepository.getDefaultConfiguration();
|
||||
|
||||
await this.#dataTypeDetailRepository.requestByUnique(config.defaultDataTypeId);
|
||||
|
||||
this.observe(
|
||||
await this.#dataTypeDetailRepository.byUnique(config.defaultDataTypeId),
|
||||
(dataType) => {
|
||||
if (!dataType) return;
|
||||
|
||||
const dataTypeConfig = this.#mapDataTypeConfigToCollectionConfig(dataType);
|
||||
|
||||
this._routes = [
|
||||
{
|
||||
path: 'collection',
|
||||
component: () => {
|
||||
const element = new UmbCollectionElement();
|
||||
element.alias = UMB_MEDIA_COLLECTION_ALIAS;
|
||||
element.config = dataTypeConfig;
|
||||
return element;
|
||||
},
|
||||
},
|
||||
orderBy: 'updateDate',
|
||||
orderDirection: 'asc',
|
||||
pageSize: 50,
|
||||
useInfiniteEditor: false,
|
||||
userDefinedProperties: undefined,
|
||||
};
|
||||
|
||||
const element = new UmbCollectionElement();
|
||||
element.alias = UMB_MEDIA_COLLECTION_ALIAS;
|
||||
element.config = config;
|
||||
return element;
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'collection',
|
||||
},
|
||||
];
|
||||
'_observeConfigDataType',
|
||||
);
|
||||
}
|
||||
|
||||
#mapDataTypeConfigToCollectionConfig(dataType: UmbDataTypeDetailModel): UmbCollectionConfiguration {
|
||||
const config = new UmbPropertyEditorConfigCollection(dataType.values);
|
||||
return {
|
||||
unique: '',
|
||||
dataTypeId: dataType.unique,
|
||||
allowedEntityBulkActions: config?.getValueByAlias<UmbCollectionBulkActionPermissions>('bulkActionPermissions'),
|
||||
orderBy: config?.getValueByAlias('orderBy') ?? 'updateDate',
|
||||
orderDirection: config?.getValueByAlias('orderDirection') ?? 'asc',
|
||||
pageSize: Number(config?.getValueByAlias('pageSize')) ?? 50,
|
||||
useInfiniteEditor: config?.getValueByAlias('useInfiniteEditor') ?? false,
|
||||
userDefinedProperties: config?.getValueByAlias('includeProperties'),
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<umb-router-slot id="router-slot" .routes=${this.#routes}></umb-router-slot>`;
|
||||
if (!this._routes) return;
|
||||
return html`<umb-router-slot id="router-slot" .routes=${this._routes}></umb-router-slot>`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
|
||||
@@ -54,7 +54,7 @@ const mapper = (item: MediaTreeItemResponseModel): UmbMediaTreeItemModel => {
|
||||
mediaType: {
|
||||
unique: item.mediaType.id,
|
||||
icon: item.mediaType.icon,
|
||||
collection: item.mediaType.collection ?? undefined,
|
||||
collection: item.mediaType.collection ? { unique: item.mediaType.collection.id } : null,
|
||||
},
|
||||
name: item.variants[0]?.name, // TODO: this is not correct. We need to get it from the variants. This is a temp solution.
|
||||
variants: item.variants.map((variant) => {
|
||||
|
||||
@@ -42,7 +42,7 @@ export class UmbMediaTreeStore extends UmbUniqueTreeStore {
|
||||
hasChildren: false,
|
||||
variants: item.variants,
|
||||
isTrashed: item.isTrashed,
|
||||
mediaType: { unique: item.mediaType.unique, icon: '' },
|
||||
mediaType: { unique: item.mediaType.unique, icon: '', collection: null },
|
||||
noAccess: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { UmbMediaEntityType, UmbMediaRootEntityType } from '../entity.js';
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbUniqueTreeItemModel, UmbUniqueTreeRootModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export interface UmbMediaTreeItemModel extends UmbUniqueTreeItemModel {
|
||||
@@ -9,7 +9,7 @@ export interface UmbMediaTreeItemModel extends UmbUniqueTreeItemModel {
|
||||
mediaType: {
|
||||
unique: string;
|
||||
icon: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
variants: Array<UmbMediaTreeItemVariantModel>;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import type { UmbMediaEntityType } from './entity.js';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbVariantModel } from '@umbraco-cms/backoffice/variant';
|
||||
import type { MediaUrlInfoModel, MediaValueModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
|
||||
export interface UmbMediaDetailModel {
|
||||
mediaType: { unique: string };
|
||||
mediaType: {
|
||||
unique: string;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
entityType: UmbMediaEntityType;
|
||||
isTrashed: boolean;
|
||||
unique: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js';
|
||||
import { UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION } from '../conditions/media-workspace-has-collection.condition.js';
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
|
||||
import type {
|
||||
ManifestWorkspace,
|
||||
@@ -18,24 +18,23 @@ const workspace: ManifestWorkspace = {
|
||||
};
|
||||
|
||||
const workspaceViews: Array<ManifestWorkspaceView> = [
|
||||
// {
|
||||
// type: 'workspaceView',
|
||||
// alias: 'Umb.WorkspaceView.Media.Collection',
|
||||
// name: 'Media Workspace Collection View',
|
||||
// element: () => import('./views/collection/media-collection-workspace-view.element.js'),
|
||||
// weight: 300,
|
||||
// meta: {
|
||||
// label: 'Media',
|
||||
// pathname: 'collection',
|
||||
// icon: 'icon-grid',
|
||||
// },
|
||||
// conditions: [
|
||||
// {
|
||||
// alias: 'Umb.Condition.WorkspaceAlias',
|
||||
// match: workspace.alias,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
type: 'workspaceView',
|
||||
alias: 'Umb.WorkspaceView.Media.Collection',
|
||||
name: 'Media Workspace Collection View',
|
||||
element: () => import('./views/collection/media-workspace-view-collection.element.js'),
|
||||
weight: 300,
|
||||
meta: {
|
||||
label: 'Collection',
|
||||
pathname: 'collection',
|
||||
icon: 'icon-grid',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
alias: UMB_MEDIA_WORKSPACE_HAS_COLLECTION_CONDITION,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'workspaceView',
|
||||
alias: 'Umb.WorkspaceView.Media.Edit',
|
||||
|
||||
@@ -32,6 +32,7 @@ export class UmbMediaWorkspaceContext
|
||||
|
||||
readonly unique = this.#currentData.asObservablePart((data) => data?.unique);
|
||||
readonly contentTypeUnique = this.#currentData.asObservablePart((data) => data?.mediaType.unique);
|
||||
readonly contentTypeCollection = this.#currentData.asObservablePart((data) => data?.mediaType.collection);
|
||||
|
||||
readonly variants = this.#currentData.asObservablePart((data) => data?.variants || []);
|
||||
readonly urls = this.#currentData.asObservablePart((data) => data?.urls || []);
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { customElement, html, 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';
|
||||
import { UMB_MEDIA_COLLECTION_ALIAS, UMB_MEDIA_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/media';
|
||||
import type {
|
||||
UmbCollectionBulkActionPermissions,
|
||||
UmbCollectionConfiguration,
|
||||
} from '@umbraco-cms/backoffice/collection';
|
||||
import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type';
|
||||
import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
@customElement('umb-media-workspace-view-collection')
|
||||
export class UmbMediaWorkspaceViewCollectionElement extends UmbLitElement implements UmbWorkspaceViewElement {
|
||||
@state()
|
||||
private _config?: UmbCollectionConfiguration;
|
||||
|
||||
@state()
|
||||
private _mediaUnique?: string;
|
||||
|
||||
#dataTypeDetailRepository = new UmbDataTypeDetailRepository(this);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#observeConfig();
|
||||
}
|
||||
|
||||
async #observeConfig() {
|
||||
this.consumeContext(UMB_MEDIA_WORKSPACE_CONTEXT, (workspaceContext) => {
|
||||
this.observe(workspaceContext.unique, (unique) => {
|
||||
this._mediaUnique = unique;
|
||||
});
|
||||
this.observe(
|
||||
workspaceContext.structure.ownerContentType(),
|
||||
async (mediaType) => {
|
||||
if (!mediaType || !mediaType.collection) return;
|
||||
|
||||
const dataTypeUnique = mediaType.collection.unique;
|
||||
|
||||
if (dataTypeUnique) {
|
||||
await this.#dataTypeDetailRepository.requestByUnique(dataTypeUnique);
|
||||
this.observe(
|
||||
await this.#dataTypeDetailRepository.byUnique(dataTypeUnique),
|
||||
(dataType) => {
|
||||
if (!dataType) return;
|
||||
this._config = this.#mapDataTypeConfigToCollectionConfig(dataType);
|
||||
},
|
||||
'_observeConfigDataType',
|
||||
);
|
||||
}
|
||||
},
|
||||
'_observeConfigMediaType',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#mapDataTypeConfigToCollectionConfig(dataType: UmbDataTypeDetailModel): UmbCollectionConfiguration {
|
||||
const config = new UmbPropertyEditorConfigCollection(dataType.values);
|
||||
return {
|
||||
unique: this._mediaUnique,
|
||||
dataTypeId: dataType.unique,
|
||||
allowedEntityBulkActions: config?.getValueByAlias<UmbCollectionBulkActionPermissions>('bulkActionPermissions'),
|
||||
orderBy: config?.getValueByAlias('orderBy') ?? 'updateDate',
|
||||
orderDirection: config?.getValueByAlias('orderDirection') ?? 'asc',
|
||||
pageSize: Number(config?.getValueByAlias('pageSize')) ?? 50,
|
||||
useInfiniteEditor: config?.getValueByAlias('useInfiniteEditor') ?? false,
|
||||
userDefinedProperties: config?.getValueByAlias('includeProperties'),
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this._config?.unique || !this._config?.dataTypeId) return html`<uui-loader></uui-loader>`;
|
||||
return html`<umb-collection .alias=${UMB_MEDIA_COLLECTION_ALIAS} .config=${this._config}></umb-collection>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbMediaWorkspaceViewCollectionElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-media-workspace-view-collection': UmbMediaWorkspaceViewCollectionElement;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ const mapper = (item: MemberItemResponseModel): UmbMemberItemModel => {
|
||||
memberType: {
|
||||
unique: item.memberType.id,
|
||||
icon: item.memberType.icon,
|
||||
collection: item.memberType.collection ?? undefined,
|
||||
collection: item.memberType.collection ? { unique: item.memberType.collection.id } : null,
|
||||
},
|
||||
variants: item.variants.map((variant) => {
|
||||
return {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { UmbReferenceById } from '@umbraco-cms/backoffice/models';
|
||||
import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models';
|
||||
|
||||
export interface UmbMemberItemModel {
|
||||
unique: string;
|
||||
memberType: {
|
||||
unique: string;
|
||||
icon: string;
|
||||
collection?: UmbReferenceById;
|
||||
collection: UmbReferenceByUnique | null;
|
||||
};
|
||||
variants: Array<UmbMemberVariantItemModel>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user