Merge branch 'main' into feature/log-viewer
This commit is contained in:
@@ -3,3 +3,4 @@ VITE_UMBRACO_USE_MSW=on # on = turns on MSW, off = disables all mock handlers
|
||||
VITE_UMBRACO_API_URL=http://localhost:11000
|
||||
VITE_UMBRACO_INSTALL_STATUS=running # running or must-install or must-upgrade
|
||||
VITE_MSW_QUIET=off # on = turns off MSW console logs, off = turns on MSW console logs
|
||||
VITE_UMBRACO_EXTENSION_MOCKS=off # on = turns on extension mocks, off = turns off extension mocks
|
||||
|
||||
@@ -50,7 +50,7 @@ The frontend has an API formatter that takes the OpenAPI schema file and convert
|
||||
|
||||
### Example: Published Cache Status Dashboard
|
||||
|
||||

|
||||

|
||||
|
||||
### Boilerplate (example using Lit)
|
||||
|
||||
@@ -155,7 +155,7 @@ Let’s go through each of these properties…
|
||||
|
||||
Running the app with `npm run dev`, you will quickly notice the API requests turn into 404 errors. In order to hit the API, we need to add a mock handler to define the endpoints which our dashboard will call. In the case of the Published Cache Status section, we have a number of calls to work through. Let’s start by looking at the call to retrieve the current status of the cache:
|
||||
|
||||

|
||||

|
||||
|
||||
From the existing functionality, we can see that this is a string message that is received as part of a `GET` request from the server.
|
||||
|
||||
@@ -184,7 +184,7 @@ It returns a `200 OK` response and a string value with the current “status”
|
||||
|
||||
An example `POST` is similar. Let’s take the “Refresh status” button as an example:
|
||||
|
||||

|
||||

|
||||
|
||||
From our existing functionality we can see that this makes a `POST`call to the server to prompt a reload of the published cache. So we would add a new endpoint to the mock handler that would look like:
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ export type { OkResultModel } from './models/OkResultModel';
|
||||
export { OperatorModel } from './models/OperatorModel';
|
||||
export type { OutOfDateStatusModel } from './models/OutOfDateStatusModel';
|
||||
export { OutOfDateTypeModel } from './models/OutOfDateTypeModel';
|
||||
export type { PackageMigrationStatusModel } from './models/PackageMigrationStatusModel';
|
||||
export type { PagedContentTreeItemModel } from './models/PagedContentTreeItemModel';
|
||||
export type { PagedCultureModel } from './models/PagedCultureModel';
|
||||
export type { PagedDictionaryOverviewModel } from './models/PagedDictionaryOverviewModel';
|
||||
@@ -100,6 +101,7 @@ export type { PagedLanguageModel } from './models/PagedLanguageModel';
|
||||
export type { PagedLoggerModel } from './models/PagedLoggerModel';
|
||||
export type { PagedLogMessageModel } from './models/PagedLogMessageModel';
|
||||
export type { PagedLogTemplateModel } from './models/PagedLogTemplateModel';
|
||||
export type { PagedPackageMigrationStatusModel } from './models/PagedPackageMigrationStatusModel';
|
||||
export type { PagedRecycleBinItemModel } from './models/PagedRecycleBinItemModel';
|
||||
export type { PagedRedirectUrlModel } from './models/PagedRedirectUrlModel';
|
||||
export type { PagedRelationItemModel } from './models/PagedRelationItemModel';
|
||||
@@ -172,6 +174,7 @@ export { MediaTypeResource } from './services/MediaTypeResource';
|
||||
export { MemberGroupResource } from './services/MemberGroupResource';
|
||||
export { MemberTypeResource } from './services/MemberTypeResource';
|
||||
export { ModelsBuilderResource } from './services/ModelsBuilderResource';
|
||||
export { PackageResource } from './services/PackageResource';
|
||||
export { PartialViewResource } from './services/PartialViewResource';
|
||||
export { ProfilingResource } from './services/ProfilingResource';
|
||||
export { PublishedCacheResource } from './services/PublishedCacheResource';
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { PackageModelBaseModel } from './PackageModelBaseModel';
|
||||
|
||||
export type PackageCreateModel = PackageModelBaseModel;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { PackageModelBaseModel } from './PackageModelBaseModel';
|
||||
|
||||
export type PackageDefinitionModel = (PackageModelBaseModel & {
|
||||
key?: string;
|
||||
packagePath?: string;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type PackageMigrationStatusModel = {
|
||||
packageName?: string;
|
||||
hasPendingMigrations?: boolean;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type PackageModelBaseModel = {
|
||||
name?: string;
|
||||
contentNodeId?: string | null;
|
||||
contentLoadChildNodes?: boolean;
|
||||
mediaKeys?: Array<string>;
|
||||
mediaLoadChildNodes?: boolean;
|
||||
documentTypes?: Array<string>;
|
||||
mediaTypes?: Array<string>;
|
||||
dataTypes?: Array<string>;
|
||||
templates?: Array<string>;
|
||||
partialViews?: Array<string>;
|
||||
stylesheets?: Array<string>;
|
||||
scripts?: Array<string>;
|
||||
languages?: Array<string>;
|
||||
dictionaryItems?: Array<string>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { PackageModelBaseModel } from './PackageModelBaseModel';
|
||||
|
||||
export type PackageUpdateModel = (PackageModelBaseModel & {
|
||||
packagePath?: string;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { PackageDefinitionModel } from './PackageDefinitionModel';
|
||||
|
||||
export type PagedPackageDefinitionModel = {
|
||||
total: number;
|
||||
items: Array<PackageDefinitionModel>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { PackageMigrationStatusModel } from './PackageMigrationStatusModel';
|
||||
|
||||
export type PagedPackageMigrationStatusModel = {
|
||||
total: number;
|
||||
items: Array<PackageMigrationStatusModel>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { PackageCreateModel } from '../models/PackageCreateModel';
|
||||
import type { PackageDefinitionModel } from '../models/PackageDefinitionModel';
|
||||
import type { PackageUpdateModel } from '../models/PackageUpdateModel';
|
||||
import type { PagedPackageDefinitionModel } from '../models/PagedPackageDefinitionModel';
|
||||
import type { PagedPackageMigrationStatusModel } from '../models/PagedPackageMigrationStatusModel';
|
||||
|
||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||
import { OpenAPI } from '../core/OpenAPI';
|
||||
import { request as __request } from '../core/request';
|
||||
|
||||
export class PackageResource {
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static postPackageByNameRunMigration({
|
||||
name,
|
||||
}: {
|
||||
name: string,
|
||||
}): CancelablePromise<any> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/umbraco/management/api/v1/package/{name}/run-migration',
|
||||
path: {
|
||||
'name': name,
|
||||
},
|
||||
errors: {
|
||||
404: `Not Found`,
|
||||
409: `Conflict`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns PagedPackageDefinitionModel Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getPackageCreated({
|
||||
skip,
|
||||
take = 100,
|
||||
}: {
|
||||
skip?: number,
|
||||
take?: number,
|
||||
}): CancelablePromise<PagedPackageDefinitionModel> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/package/created',
|
||||
query: {
|
||||
'skip': skip,
|
||||
'take': take,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns string Created
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static postPackageCreated({
|
||||
requestBody,
|
||||
}: {
|
||||
requestBody?: PackageCreateModel,
|
||||
}): CancelablePromise<string> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'POST',
|
||||
url: '/umbraco/management/api/v1/package/created',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
responseHeader: 'Location',
|
||||
errors: {
|
||||
400: `Bad Request`,
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getPackageCreatedByKey({
|
||||
key,
|
||||
}: {
|
||||
key: string,
|
||||
}): CancelablePromise<PackageDefinitionModel> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/package/created/{key}',
|
||||
path: {
|
||||
'key': key,
|
||||
},
|
||||
errors: {
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static deletePackageCreatedByKey({
|
||||
key,
|
||||
}: {
|
||||
key: string,
|
||||
}): CancelablePromise<any> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'DELETE',
|
||||
url: '/umbraco/management/api/v1/package/created/{key}',
|
||||
path: {
|
||||
'key': key,
|
||||
},
|
||||
errors: {
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns any Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static putPackageCreatedByKey({
|
||||
key,
|
||||
requestBody,
|
||||
}: {
|
||||
key: string,
|
||||
requestBody?: PackageUpdateModel,
|
||||
}): CancelablePromise<any> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'PUT',
|
||||
url: '/umbraco/management/api/v1/package/created/{key}',
|
||||
path: {
|
||||
'key': key,
|
||||
},
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns binary Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getPackageCreatedByKeyDownload({
|
||||
key,
|
||||
}: {
|
||||
key: string,
|
||||
}): CancelablePromise<Blob> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/package/created/{key}/download',
|
||||
path: {
|
||||
'key': key,
|
||||
},
|
||||
errors: {
|
||||
404: `Not Found`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns PagedPackageMigrationStatusModel Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static getPackageMigrationStatus({
|
||||
skip,
|
||||
take = 100,
|
||||
}: {
|
||||
skip?: number,
|
||||
take?: number,
|
||||
}): CancelablePromise<PagedPackageMigrationStatusModel> {
|
||||
return __request(OpenAPI, {
|
||||
method: 'GET',
|
||||
url: '/umbraco/management/api/v1/package/migration-status',
|
||||
query: {
|
||||
'skip': skip,
|
||||
'take': take,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,8 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/extensions-api';
|
||||
import { UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
|
||||
export interface UmbAction<RepositoryType> {
|
||||
export interface UmbAction<RepositoryType = unknown> {
|
||||
host: UmbControllerHostInterface;
|
||||
repository: RepositoryType;
|
||||
execute(): Promise<void>;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbEntityActionBase } from '..';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbCopyEntityAction<T extends { copy(): Promise<void> }> extends UmbEntityActionBase<T> {
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbEntityActionBase } from '..';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './copy/copy.action';
|
||||
export * from './delete/delete.action';
|
||||
export * from './move/move.action';
|
||||
export * from './sort-children-of/sort-children-of.action';
|
||||
export * from './trash/trash.action';
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbEntityActionBase } from '..';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbMoveEntityAction<T extends { move(): Promise<void> }> extends UmbEntityActionBase<T> {
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbEntityActionBase } from '..';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbSortChildrenOfEntityAction<
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbEntityActionBase } from '..';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbAction, UmbActionBase } from '../action';
|
||||
import { UmbAction, UmbActionBase } from './action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export interface UmbEntityAction<RepositoryType> extends UmbAction<RepositoryType> {
|
||||
@@ -0,0 +1,20 @@
|
||||
import { UmbAction, UmbActionBase } from './action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export interface UmbEntityBulkAction<RepositoryType = unknown> extends UmbAction<RepositoryType> {
|
||||
selection: Array<string>;
|
||||
setSelection(selection: Array<string>): void;
|
||||
}
|
||||
|
||||
export class UmbEntityBulkActionBase<RepositoryType = unknown> extends UmbActionBase<RepositoryType> {
|
||||
selection: Array<string>;
|
||||
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.selection = selection;
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.selection = selection;
|
||||
}
|
||||
}
|
||||
4
src/Umbraco.Web.UI.Client/libs/entity-action/index.ts
Normal file
4
src/Umbraco.Web.UI.Client/libs/entity-action/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './action';
|
||||
export * from './entity-action';
|
||||
export * from './entity-bulk-action';
|
||||
export * from './actions';
|
||||
@@ -0,0 +1,4 @@
|
||||
import config from '../../utils/rollup.config.js';
|
||||
export default {
|
||||
...config,
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ManifestJSType } from './load-extension.function';
|
||||
import type { ManifestBase } from '@umbraco-cms/extensions-registry';
|
||||
|
||||
export function isManifestJSType(manifest: ManifestBase): manifest is ManifestJSType {
|
||||
export function isManifestJSType(manifest: ManifestBase | unknown): manifest is ManifestJSType {
|
||||
return (manifest as ManifestJSType).js !== undefined;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { ManifestElement } from './models';
|
||||
|
||||
export interface ManifestMenuItem extends ManifestElement {
|
||||
type: 'menuItem';
|
||||
meta: MetaMenuItem;
|
||||
}
|
||||
|
||||
export interface MetaMenuItem {
|
||||
label: string;
|
||||
icon: string;
|
||||
menus: Array<string>;
|
||||
entityType?: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { ManifestElement } from './models';
|
||||
|
||||
export interface ManifestMenu extends ManifestElement {
|
||||
type: 'menu';
|
||||
}
|
||||
@@ -11,8 +11,9 @@ import type { ManifestPropertyAction } from './property-action.models';
|
||||
import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './property-editor.models';
|
||||
import type { ManifestSection } from './section.models';
|
||||
import type { ManifestSectionView } from './section-view.models';
|
||||
import type { ManifestSidebarMenu } from './sidebar-menu.models';
|
||||
import type { ManifestSidebarMenuItem } from './sidebar-menu-item.models';
|
||||
import type { ManifestSectionSidebarApp, ManifestMenuSectionSidebarApp } from './section-sidebar-app.models';
|
||||
import type { ManifestMenu } from './menu.models';
|
||||
import type { ManifestMenuItem } from './menu-item.models';
|
||||
import type { ManifestTheme } from './theme.models';
|
||||
import type { ManifestTree } from './tree.models';
|
||||
import type { ManifestTreeItemAction } from './tree-item-action.models';
|
||||
@@ -37,8 +38,9 @@ export * from './property-action.models';
|
||||
export * from './property-editor.models';
|
||||
export * from './section-view.models';
|
||||
export * from './section.models';
|
||||
export * from './sidebar-menu.models';
|
||||
export * from './sidebar-menu-item.models';
|
||||
export * from './section-sidebar-app.models';
|
||||
export * from './menu.models';
|
||||
export * from './menu-item.models';
|
||||
export * from './theme.models';
|
||||
export * from './tree-item-action.models';
|
||||
export * from './tree.models';
|
||||
@@ -66,9 +68,11 @@ export type ManifestTypes =
|
||||
| ManifestPropertyEditorUI
|
||||
| ManifestRepository
|
||||
| ManifestSection
|
||||
| ManifestSectionSidebarApp
|
||||
| ManifestSectionView
|
||||
| ManifestSidebarMenu
|
||||
| ManifestSidebarMenuItem
|
||||
| ManifestMenuSectionSidebarApp
|
||||
| ManifestMenu
|
||||
| ManifestMenuItem
|
||||
| ManifestTheme
|
||||
| ManifestTree
|
||||
| ManifestTreeItemAction
|
||||
@@ -76,7 +80,8 @@ export type ManifestTypes =
|
||||
| ManifestWorkspace
|
||||
| ManifestWorkspaceAction
|
||||
| ManifestWorkspaceView
|
||||
| ManifestWorkspaceViewCollection;
|
||||
| ManifestWorkspaceViewCollection
|
||||
| ManifestBase;
|
||||
|
||||
export type ManifestStandardTypes = ManifestTypes['type'];
|
||||
|
||||
@@ -112,7 +117,7 @@ export interface ManifestElement extends ManifestWithLoader<object | HTMLElement
|
||||
js?: string;
|
||||
elementName?: string;
|
||||
//loader?: () => Promise<object | HTMLElement>;
|
||||
meta?: any;
|
||||
meta?: unknown;
|
||||
}
|
||||
|
||||
export interface ManifestWithView extends ManifestElement {
|
||||
@@ -131,11 +136,11 @@ export interface ManifestElementWithElementName extends ManifestElement {
|
||||
|
||||
export interface ManifestCustom extends ManifestBase {
|
||||
type: 'custom';
|
||||
meta?: any;
|
||||
meta?: unknown;
|
||||
}
|
||||
|
||||
export interface ManifestWithMeta extends ManifestBase {
|
||||
meta: any;
|
||||
meta: unknown;
|
||||
}
|
||||
|
||||
export interface ManifestEntrypoint extends ManifestBase {
|
||||
|
||||
@@ -6,5 +6,5 @@ export interface ManifestPackageView extends ManifestElement {
|
||||
}
|
||||
|
||||
export interface MetaPackageView {
|
||||
packageAlias: string;
|
||||
packageName: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { ManifestElement } from './models';
|
||||
|
||||
export interface ManifestSectionSidebarApp extends ManifestElement {
|
||||
type: 'sectionSidebarApp';
|
||||
meta: MetaSectionSidebarApp;
|
||||
}
|
||||
|
||||
export interface MetaSectionSidebarApp {
|
||||
sections: Array<string>;
|
||||
}
|
||||
|
||||
// TODO: this is a temp solution until we implement kinds
|
||||
export interface ManifestMenuSectionSidebarApp extends ManifestElement {
|
||||
type: 'menuSectionSidebarApp';
|
||||
meta: MetaMenuSectionSidebarApp;
|
||||
}
|
||||
|
||||
export interface MetaMenuSectionSidebarApp extends MetaSectionSidebarApp {
|
||||
label: string;
|
||||
menu: string;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import type { ManifestElement } from './models';
|
||||
|
||||
export interface ManifestSidebarMenuItem extends ManifestElement {
|
||||
type: 'sidebarMenuItem';
|
||||
meta: MetaSidebarMenuItem;
|
||||
}
|
||||
|
||||
export interface MetaSidebarMenuItem {
|
||||
label: string;
|
||||
icon: string;
|
||||
sidebarMenus: Array<string>;
|
||||
entityType?: string;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import type { ManifestElement } from './models';
|
||||
|
||||
export interface ManifestSidebarMenu extends ManifestElement {
|
||||
type: 'sidebarMenu';
|
||||
meta: MetaSidebarMenu;
|
||||
}
|
||||
|
||||
export interface MetaSidebarMenu {
|
||||
label: string;
|
||||
sections: Array<string>;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { InterfaceColor, InterfaceLook } from '@umbraco-ui/uui-base/lib/types/index';
|
||||
import type { ManifestElement } from './models';
|
||||
import { UmbWorkspaceAction } from '@umbraco-cms/workspace';
|
||||
import type { ClassConstructor } from '@umbraco-cms/models';
|
||||
|
||||
export interface ManifestWorkspaceAction extends ManifestElement {
|
||||
type: 'workspaceAction';
|
||||
@@ -11,6 +13,5 @@ export interface MetaWorkspaceAction {
|
||||
label?: string; //TODO: Use or implement additional label-key
|
||||
look?: InterfaceLook;
|
||||
color?: InterfaceColor;
|
||||
repositoryAlias?: string; // TODO: make mandatory when repositories are fully implemented
|
||||
api?: any; //TODO: Implement UmbEntityAction
|
||||
api: ClassConstructor<UmbWorkspaceAction>;
|
||||
}
|
||||
|
||||
@@ -151,3 +151,11 @@ export interface SwatchDetails {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type UmbPackage = {
|
||||
name?: string;
|
||||
version?: string;
|
||||
extensions?: unknown[];
|
||||
};
|
||||
|
||||
export type PagedManifestsResponse = UmbPackage[];
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import '../layouts/default';
|
||||
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import { html } from 'lit';
|
||||
|
||||
import { UmbNotificationService } from '..';
|
||||
|
||||
export default {
|
||||
title: 'API/Notifications/Overview',
|
||||
component: 'ucp-notification-layout-default',
|
||||
decorators: [
|
||||
(story) =>
|
||||
html`<umb-context-provider key="umbNotificationService" .value=${new UmbNotificationService()}>
|
||||
${story()}
|
||||
</umb-context-provider>`,
|
||||
],
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = () => html`<story-notification-default-example></story-notification-default-example>`;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.parameters = {
|
||||
docs: {
|
||||
source: {
|
||||
language: 'js',
|
||||
code: `
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
data: {
|
||||
headline: 'Headline',
|
||||
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
|
||||
}
|
||||
};
|
||||
|
||||
this._notificationService?.peek('positive', options);
|
||||
`,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,28 +1,14 @@
|
||||
import './layouts/default';
|
||||
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import { html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
|
||||
import type { UmbNotificationDefaultData } from './layouts/default';
|
||||
import { UmbNotificationDefaultData } from '../layouts/default';
|
||||
import {
|
||||
UmbNotificationColor,
|
||||
UmbNotificationOptions,
|
||||
UmbNotificationService,
|
||||
UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN,
|
||||
} from '.';
|
||||
UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN
|
||||
} from '..';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
export default {
|
||||
title: 'API/Notifications/Overview',
|
||||
component: 'ucp-notification-layout-default',
|
||||
decorators: [
|
||||
(story) =>
|
||||
html`<umb-context-provider key="umbNotificationService" .value=${new UmbNotificationService()}>
|
||||
${story()}
|
||||
</umb-context-provider>`,
|
||||
],
|
||||
} as Meta;
|
||||
|
||||
@customElement('story-notification-default-example')
|
||||
export class StoryNotificationDefaultExampleElement extends UmbLitElement {
|
||||
@@ -69,24 +55,3 @@ export class StoryNotificationDefaultExampleElement extends UmbLitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
const Template: Story = () => html`<story-notification-default-example></story-notification-default-example>`;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.parameters = {
|
||||
docs: {
|
||||
source: {
|
||||
language: 'js',
|
||||
code: `
|
||||
const options: UmbNotificationOptions<UmbNotificationDefaultData> = {
|
||||
data: {
|
||||
headline: 'Headline',
|
||||
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
|
||||
}
|
||||
};
|
||||
|
||||
this._notificationService?.peek('positive', options);
|
||||
`,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './workspace-action-base';
|
||||
export * from './save/save.action';
|
||||
@@ -1,11 +1,11 @@
|
||||
import { UmbWorkspaceAction } from '../components/workspace/workspace-action';
|
||||
import { UmbWorkspaceContextInterface } from '../components/workspace/workspace-context/workspace-context.interface';
|
||||
import { UmbWorkspaceContextInterface } from '../../../../src/backoffice/shared/components/workspace/workspace-context/workspace-context.interface';
|
||||
import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
// TODO: add interface for repo/partial repo/save-repo
|
||||
export class UmbSaveWorkspaceAction extends UmbWorkspaceAction<any, UmbWorkspaceContextInterface> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string) {
|
||||
super(host, repositoryAlias);
|
||||
export class UmbSaveWorkspaceAction extends UmbWorkspaceActionBase<UmbWorkspaceContextInterface> {
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
/* TODO: we need a solution for all actions to notify the system that is has been executed.
|
||||
@@ -26,7 +26,8 @@ export class UmbSaveWorkspaceAction extends UmbWorkspaceAction<any, UmbWorkspace
|
||||
if (!this.workspaceContext) return;
|
||||
|
||||
// TODO: preferably the actions dont talk directly with repository, but instead with its context.
|
||||
const { error } = await this.repository.create(data);
|
||||
// We just need to consider how third parties can extend the system.
|
||||
const { error } = await this.workspaceContext.repository.create(data);
|
||||
|
||||
// TODO: this is temp solution to bubble validation errors to the UI
|
||||
if (error) {
|
||||
@@ -41,6 +42,7 @@ export class UmbSaveWorkspaceAction extends UmbWorkspaceAction<any, UmbWorkspace
|
||||
}
|
||||
|
||||
#update(data: any) {
|
||||
this.repository?.save(data);
|
||||
if (!this.workspaceContext) return;
|
||||
this.workspaceContext.repository?.save(data);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
import { UmbActionBase } from '../../../action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
|
||||
export class UmbWorkspaceAction<RepositoryType, WorkspaceType> extends UmbActionBase<RepositoryType> {
|
||||
export interface UmbWorkspaceAction<T = unknown> {
|
||||
host: UmbControllerHostInterface;
|
||||
workspaceContext?: T;
|
||||
execute(): Promise<void>;
|
||||
}
|
||||
|
||||
export class UmbWorkspaceActionBase<WorkspaceType> {
|
||||
host: UmbControllerHostInterface;
|
||||
workspaceContext?: WorkspaceType;
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string) {
|
||||
super(host, repositoryAlias);
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
this.host = host;
|
||||
|
||||
new UmbContextConsumerController(this.host, 'umbWorkspaceContext', (instance: WorkspaceType) => {
|
||||
this.workspaceContext = instance;
|
||||
1
src/Umbraco.Web.UI.Client/libs/workspace/index.ts
Normal file
1
src/Umbraco.Web.UI.Client/libs/workspace/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './actions';
|
||||
@@ -0,0 +1,4 @@
|
||||
import config from '../../utils/rollup.config.js';
|
||||
export default {
|
||||
...config,
|
||||
};
|
||||
@@ -19,7 +19,7 @@ import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
import { OpenAPI, RuntimeLevelModel, ServerResource } from '@umbraco-cms/backend-api';
|
||||
import { UmbIconStore } from '@umbraco-cms/store';
|
||||
import { UmbContextDebugRequest, umbDebugContextEventType } from '@umbraco-cms/context-api';
|
||||
import { umbDebugContextEventType } from '@umbraco-cms/context-api';
|
||||
|
||||
@customElement('umb-app')
|
||||
export class UmbApp extends UmbLitElement {
|
||||
@@ -82,15 +82,14 @@ export class UmbApp extends UmbLitElement {
|
||||
this.provideContext('UMBRACOBASE', OpenAPI.BASE);
|
||||
|
||||
await this._setInitStatus();
|
||||
await this._registerExtensionManifestsFromServer();
|
||||
this._redirect();
|
||||
|
||||
// Listen for the debug event from the <umb-debug> component
|
||||
this.addEventListener(umbDebugContextEventType, (event: any) => {
|
||||
// Once we got to the outter most component <umb-app>
|
||||
// we can send the event containing all the contexts
|
||||
// we can send the event containing all the contexts
|
||||
// we have collected whilst coming up through the DOM
|
||||
// and pass it back down to the callback in
|
||||
// and pass it back down to the callback in
|
||||
// the <umb-debug> component that originally fired the event
|
||||
event.callback(event.instances);
|
||||
});
|
||||
@@ -152,13 +151,6 @@ export class UmbApp extends UmbLitElement {
|
||||
};
|
||||
}
|
||||
|
||||
private async _registerExtensionManifestsFromServer() {
|
||||
// TODO: Implement once manifest endpoint exists
|
||||
// const res = await getManifests({});
|
||||
// const { manifests } = res.data as unknown as { manifests: ManifestTypes[] };
|
||||
// manifests.forEach((manifest) => umbExtensionsRegistry.register(manifest));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<umb-router-slot id="router-slot" .routes=${this._routes}></umb-router-slot>`;
|
||||
}
|
||||
|
||||
@@ -40,9 +40,15 @@ import { UmbTemplateDetailStore } from './templating/templates/workspace/data/te
|
||||
import { UmbThemeContext } from './themes/theme.context';
|
||||
import { UmbLogSearchesStore } from './settings/logviewer/workspace/data/log-search.store';
|
||||
import { UmbLanguageStore } from './settings/languages/repository/language.store';
|
||||
import { UMB_APP_LANGUAGE_CONTEXT_TOKEN, UmbAppLanguageContext } from './settings/languages/app-language.context';
|
||||
import {
|
||||
UMB_APP_LANGUAGE_CONTEXT_TOKEN,
|
||||
UmbAppLanguageContext,
|
||||
} from './settings/languages/app-language-select/app-language.context';
|
||||
import { UmbPackageStore } from './packages/repository/package.store';
|
||||
import { UmbServerExtensionController } from './packages/repository/server-extension.controller';
|
||||
import { UmbNotificationService, UMB_NOTIFICATION_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/notification';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api';
|
||||
|
||||
import '@umbraco-cms/router';
|
||||
|
||||
@@ -115,6 +121,9 @@ export class UmbBackofficeElement extends UmbLitElement {
|
||||
this.provideContext(UMB_BACKOFFICE_CONTEXT_TOKEN, new UmbBackofficeContext());
|
||||
this.provideContext(UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, new UmbCurrentUserHistoryStore());
|
||||
new UmbThemeContext(this);
|
||||
|
||||
new UmbPackageStore(this);
|
||||
new UmbServerExtensionController(this, umbExtensionsRegistry);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
|
||||
export const manifests = [...sidebarMenuItemManifests, ...workspaceManifests];
|
||||
export const manifests = [...menuItemManifests, ...workspaceManifests];
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.DocumentBlueprints',
|
||||
name: 'Document Blueprints Menu Item',
|
||||
weight: 90,
|
||||
meta: {
|
||||
label: 'Document Blueprints',
|
||||
icon: 'umb:blueprint',
|
||||
menus: ['Umb.Menu.Settings'],
|
||||
entityType: 'document-blueprint-root',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menuItem];
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.DocumentBlueprints',
|
||||
name: 'Document Blueprints Sidebar Menu Item',
|
||||
weight: 90,
|
||||
meta: {
|
||||
label: 'Document Blueprints',
|
||||
icon: 'umb:blueprint',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Settings'],
|
||||
entityType: 'document-blueprint-root',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
@@ -1,6 +1,6 @@
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
|
||||
export const manifests = [...sidebarMenuItemManifests, ...treeManifests, ...repositoryManifests, ...workspaceManifests];
|
||||
export const manifests = [...menuItemManifests, ...treeManifests, ...repositoryManifests, ...workspaceManifests];
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.DocumentTypes',
|
||||
name: 'Document Types Menu Item',
|
||||
weight: 10,
|
||||
loader: () => import('./document-types-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Document Types',
|
||||
icon: 'umb:folder',
|
||||
menus: ['Umb.Menu.Settings'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menuItem];
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.DocumentTypes',
|
||||
name: 'Document Types Sidebar Menu Item',
|
||||
weight: 10,
|
||||
loader: () => import('./document-types-sidebar-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Document Types',
|
||||
icon: 'umb:folder',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Settings'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
@@ -7,20 +7,15 @@ import { ObjectState } from '@umbraco-cms/observable-api';
|
||||
|
||||
type EntityType = DocumentTypeModel;
|
||||
export class UmbWorkspaceDocumentTypeContext
|
||||
extends UmbWorkspaceContext
|
||||
extends UmbWorkspaceContext<UmbDocumentTypeRepository>
|
||||
implements UmbWorkspaceEntityContextInterface<EntityType | undefined>
|
||||
{
|
||||
#host: UmbControllerHostInterface;
|
||||
#repo: UmbDocumentTypeRepository;
|
||||
|
||||
#data = new ObjectState<EntityType | undefined>(undefined);
|
||||
data = this.#data.asObservable();
|
||||
name = this.#data.getObservablePart((data) => data?.name);
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
this.#host = host;
|
||||
this.#repo = new UmbDocumentTypeRepository(this.#host);
|
||||
super(host, new UmbDocumentTypeRepository(host));
|
||||
}
|
||||
|
||||
public setPropertyValue(alias: string, value: unknown) {
|
||||
@@ -49,21 +44,21 @@ export class UmbWorkspaceDocumentTypeContext
|
||||
}
|
||||
|
||||
async load(entityKey: string) {
|
||||
const { data } = await this.#repo.requestByKey(entityKey);
|
||||
const { data } = await this.repository.requestByKey(entityKey);
|
||||
if (data) {
|
||||
this.#data.next(data);
|
||||
}
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
const { data } = await this.#repo.createScaffold(parentKey);
|
||||
const { data } = await this.repository.createScaffold(parentKey);
|
||||
if (!data) return;
|
||||
this.#data.next(data);
|
||||
}
|
||||
|
||||
async save() {
|
||||
if (!this.#data.value) return;
|
||||
this.#repo.save(this.#data.value);
|
||||
this.repository.save(this.#data.value);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace';
|
||||
import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
@@ -31,12 +32,12 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
type: 'workspaceAction',
|
||||
alias: 'Umb.WorkspaceAction.DocumentType.Save',
|
||||
name: 'Save Document Type Workspace Action',
|
||||
loader: () =>
|
||||
import('../../../shared/components/workspace/workspace-action/save/workspace-action-node-save.element'),
|
||||
meta: {
|
||||
workspaces: ['Umb.Workspace.DocumentType'],
|
||||
label: 'Save',
|
||||
look: 'primary',
|
||||
color: 'positive',
|
||||
api: UmbSaveWorkspaceAction,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbCreateDocumentBlueprintEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbCreateDocumentEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentCultureAndHostnamesEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import { UmbCopyEntityAction } from '../../../shared/entity-actions/copy/copy.action';
|
||||
import { UmbMoveEntityAction } from '../../../shared/entity-actions/move/move.action';
|
||||
import { UmbTrashEntityAction } from '../../../shared/entity-actions/trash/trash.action';
|
||||
import { UmbSortChildrenOfEntityAction } from '../../../shared/entity-actions/sort-children-of/sort-children-of.action';
|
||||
import { UmbCreateDocumentEntityAction } from './create.action';
|
||||
import { UmbPublishDocumentEntityAction } from './publish.action';
|
||||
import { UmbDocumentCultureAndHostnamesEntityAction } from './culture-and-hostnames.action';
|
||||
@@ -10,6 +6,12 @@ import { UmbDocumentPublicAccessEntityAction } from './public-access.action';
|
||||
import { UmbDocumentPermissionsEntityAction } from './permissions.action';
|
||||
import { UmbUnpublishDocumentEntityAction } from './unpublish.action';
|
||||
import { UmbRollbackDocumentEntityAction } from './rollback.action';
|
||||
import {
|
||||
UmbCopyEntityAction,
|
||||
UmbMoveEntityAction,
|
||||
UmbTrashEntityAction,
|
||||
UmbSortChildrenOfEntityAction,
|
||||
} from '@umbraco-cms/entity-action';
|
||||
import { ManifestEntityAction } from '@umbraco-cms/extensions-registry';
|
||||
|
||||
const entityType = 'document';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentPublicAccessEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbPublishDocumentEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbRollbackDocumentEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentRepository } from '../repository/document.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase<UmbDocumentRepository> {
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import { UmbDocumentRepository } from '../../repository/document.repository';
|
||||
import { UmbActionBase } from '../../../../shared/action';
|
||||
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentCopyEntityBulkAction extends UmbActionBase<UmbDocumentRepository> {
|
||||
#selection: Array<string>;
|
||||
|
||||
export class UmbDocumentCopyEntityBulkAction extends UmbEntityBulkActionBase<UmbDocumentRepository> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.#selection = selection;
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.#selection = selection;
|
||||
super(host, repositoryAlias, selection);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
console.log(`execute copy for: ${this.#selection}`);
|
||||
console.log(`execute copy for: ${this.selection}`);
|
||||
await this.repository?.copy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import { UmbDocumentRepository } from '../../repository/document.repository';
|
||||
import { UmbActionBase } from '../../../../shared/action';
|
||||
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentMoveEntityBulkAction extends UmbActionBase<UmbDocumentRepository> {
|
||||
#selection: Array<string>;
|
||||
|
||||
export class UmbDocumentMoveEntityBulkAction extends UmbEntityBulkActionBase<UmbDocumentRepository> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.#selection = selection;
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.#selection = selection;
|
||||
super(host, repositoryAlias, selection);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
console.log(`execute move for: ${this.#selection}`);
|
||||
console.log(`execute move for: ${this.selection}`);
|
||||
await this.repository?.move();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { manifests as collectionManifests } from './collection/manifests';
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
@@ -8,7 +8,7 @@ import { manifests as entityBulkActionManifests } from './entity-bulk-actions/ma
|
||||
|
||||
export const manifests = [
|
||||
...collectionManifests,
|
||||
...sidebarMenuItemManifests,
|
||||
...menuItemManifests,
|
||||
...treeManifests,
|
||||
...repositoryManifests,
|
||||
...workspaceManifests,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.Documents',
|
||||
name: 'Documents Sidebar Menu Item',
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.Documents',
|
||||
name: 'Documents Menu Item',
|
||||
weight: 100,
|
||||
loader: () => import('./document-sidebar-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Documents',
|
||||
icon: 'umb:folder',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Content'],
|
||||
menus: ['Umb.Menu.Content'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
export const manifests = [menuItem];
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import { UmbWorkspaceAction } from '../../../../shared/components/workspace/workspace-action';
|
||||
import { UmbDocumentWorkspaceContext } from '../document-workspace.context';
|
||||
import { UmbDocumentRepository } from '../../repository/document.repository';
|
||||
import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceAction<
|
||||
UmbDocumentRepository,
|
||||
UmbDocumentWorkspaceContext
|
||||
> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string) {
|
||||
super(host, repositoryAlias);
|
||||
export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceActionBase<UmbDocumentWorkspaceContext> {
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
@@ -17,6 +13,6 @@ export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceAction
|
||||
const document = this.workspaceContext.getData();
|
||||
// TODO: handle errors
|
||||
if (!document) return;
|
||||
this.repository?.saveAndPreview();
|
||||
this.workspaceContext.repository?.saveAndPreview();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import { UmbWorkspaceAction } from '../../../../shared/components/workspace/workspace-action';
|
||||
import { UmbDocumentWorkspaceContext } from '../document-workspace.context';
|
||||
import { UmbDocumentRepository } from '../../repository/document.repository';
|
||||
import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbDocumentSaveAndPublishWorkspaceAction extends UmbWorkspaceAction<
|
||||
UmbDocumentRepository,
|
||||
UmbDocumentWorkspaceContext
|
||||
> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string) {
|
||||
super(host, repositoryAlias);
|
||||
export class UmbDocumentSaveAndPublishWorkspaceAction extends UmbWorkspaceActionBase<UmbDocumentWorkspaceContext> {
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
@@ -17,6 +13,6 @@ export class UmbDocumentSaveAndPublishWorkspaceAction extends UmbWorkspaceAction
|
||||
const document = this.workspaceContext.getData();
|
||||
// TODO: handle errors
|
||||
if (!document) return;
|
||||
this.repository?.saveAndPublish();
|
||||
this.workspaceContext.repository.saveAndPublish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import { UmbWorkspaceAction } from '../../../../shared/components/workspace/workspace-action';
|
||||
import { UmbDocumentRepository } from '../../repository/document.repository';
|
||||
import { UmbDocumentWorkspaceContext } from '../document-workspace.context';
|
||||
import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbSaveAndScheduleDocumentWorkspaceAction extends UmbWorkspaceAction<
|
||||
UmbDocumentRepository,
|
||||
UmbDocumentWorkspaceContext
|
||||
> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string) {
|
||||
super(host, repositoryAlias);
|
||||
export class UmbSaveAndScheduleDocumentWorkspaceAction extends UmbWorkspaceActionBase<UmbDocumentWorkspaceContext> {
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
@@ -17,6 +13,6 @@ export class UmbSaveAndScheduleDocumentWorkspaceAction extends UmbWorkspaceActio
|
||||
const document = this.workspaceContext.getData();
|
||||
// TODO: handle errors
|
||||
if (!document) return;
|
||||
this.repository?.saveAndSchedule();
|
||||
this.workspaceContext.repository.saveAndSchedule();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,9 @@ export type ActiveVariant = {
|
||||
|
||||
type EntityType = DocumentModel;
|
||||
export class UmbDocumentWorkspaceContext
|
||||
extends UmbWorkspaceContext
|
||||
extends UmbWorkspaceContext<UmbDocumentRepository>
|
||||
implements UmbWorkspaceVariableEntityContextInterface<EntityType | undefined>
|
||||
{
|
||||
#host: UmbControllerHostInterface;
|
||||
#documentRepository: UmbDocumentRepository;
|
||||
|
||||
/**
|
||||
* The document is the current stored version of the document.
|
||||
* For now lets not share this publicly as it can become confusing.
|
||||
@@ -48,18 +45,15 @@ export class UmbDocumentWorkspaceContext
|
||||
readonly structure;
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
this.#host = host;
|
||||
super(host, new UmbDocumentRepository(host));
|
||||
|
||||
this.#documentRepository = new UmbDocumentRepository(this.#host);
|
||||
this.structure = new UmbWorkspacePropertyStructureManager(this.host, new UmbDocumentTypeRepository(this.host));
|
||||
|
||||
this.structure = new UmbWorkspacePropertyStructureManager(this.#host, new UmbDocumentTypeRepository(this.#host));
|
||||
|
||||
new UmbObserverController(this._host, this.documentTypeKey, (key) => this.structure.loadType(key));
|
||||
new UmbObserverController(this.host, this.documentTypeKey, (key) => this.structure.loadType(key));
|
||||
}
|
||||
|
||||
async load(entityKey: string) {
|
||||
const { data } = await this.#documentRepository.requestByKey(entityKey);
|
||||
const { data } = await this.repository.requestByKey(entityKey);
|
||||
if (!data) return undefined;
|
||||
|
||||
this.setIsNew(false);
|
||||
@@ -69,7 +63,7 @@ export class UmbDocumentWorkspaceContext
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
const { data } = await this.#documentRepository.createScaffold(parentKey);
|
||||
const { data } = await this.repository.createScaffold(parentKey);
|
||||
if (!data) return undefined;
|
||||
|
||||
this.setIsNew(true);
|
||||
@@ -177,16 +171,16 @@ export class UmbDocumentWorkspaceContext
|
||||
async save() {
|
||||
if (!this.#draft.value) return;
|
||||
if (this.getIsNew()) {
|
||||
await this.#documentRepository.create(this.#draft.value);
|
||||
await this.repository.create(this.#draft.value);
|
||||
} else {
|
||||
await this.#documentRepository.save(this.#draft.value);
|
||||
await this.repository.save(this.#draft.value);
|
||||
}
|
||||
// If it went well, then its not new anymore?.
|
||||
this.setIsNew(false);
|
||||
}
|
||||
|
||||
async delete(key: string) {
|
||||
await this.#documentRepository.delete(key);
|
||||
await this.repository.delete(key);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { DOCUMENT_REPOSITORY_ALIAS } from '../repository/manifests';
|
||||
import { UmbSaveWorkspaceAction } from '../../../shared/workspace-actions/save.action';
|
||||
import { UmbDocumentSaveAndPublishWorkspaceAction } from './actions/save-and-publish.action';
|
||||
import { UmbDocumentSaveAndPreviewWorkspaceAction } from './actions/save-and-preview.action';
|
||||
import { UmbSaveAndScheduleDocumentWorkspaceAction } from './actions/save-and-schedule.action';
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace';
|
||||
import type {
|
||||
ManifestWorkspace,
|
||||
ManifestWorkspaceAction,
|
||||
@@ -81,7 +81,6 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
label: 'Save And Publish',
|
||||
look: 'primary',
|
||||
color: 'positive',
|
||||
repositoryAlias: DOCUMENT_REPOSITORY_ALIAS,
|
||||
api: UmbDocumentSaveAndPublishWorkspaceAction,
|
||||
},
|
||||
},
|
||||
@@ -94,7 +93,6 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
workspaces: ['Umb.Workspace.Document'],
|
||||
label: 'Save',
|
||||
look: 'secondary',
|
||||
repositoryAlias: DOCUMENT_REPOSITORY_ALIAS,
|
||||
api: UmbSaveWorkspaceAction,
|
||||
},
|
||||
},
|
||||
@@ -106,7 +104,6 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
meta: {
|
||||
workspaces: ['Umb.Workspace.Document'],
|
||||
label: 'Save And Preview',
|
||||
repositoryAlias: DOCUMENT_REPOSITORY_ALIAS,
|
||||
api: UmbDocumentSaveAndPreviewWorkspaceAction,
|
||||
},
|
||||
},
|
||||
@@ -118,7 +115,6 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
meta: {
|
||||
workspaces: ['Umb.Workspace.Document'],
|
||||
label: 'Save And Schedule',
|
||||
repositoryAlias: DOCUMENT_REPOSITORY_ALIAS,
|
||||
api: UmbSaveAndScheduleDocumentWorkspaceAction,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { manifests as dashboardManifests } from './dashboards/manifests';
|
||||
import { manifests as contentSectionManifests } from './section.manifests';
|
||||
import { manifests as contentMenuManifest } from './menu.manifests';
|
||||
import { manifests as documentBlueprintManifests } from './document-blueprints/manifests';
|
||||
import { manifests as documentTypeManifests } from './document-types/manifests';
|
||||
import { manifests as documentManifests } from './documents/manifests';
|
||||
@@ -17,6 +18,7 @@ const registerExtensions = (manifests: Array<ManifestTypes>) => {
|
||||
registerExtensions([
|
||||
...dashboardManifests,
|
||||
...contentSectionManifests,
|
||||
...contentMenuManifest,
|
||||
...documentBlueprintManifests,
|
||||
...documentTypeManifests,
|
||||
...documentManifests,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ManifestMenu } from '@umbraco-cms/extensions-registry';
|
||||
|
||||
const menu: ManifestMenu = {
|
||||
type: 'menu',
|
||||
alias: 'Umb.Menu.Content',
|
||||
name: 'Content Menu',
|
||||
meta: {
|
||||
label: 'Content',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menu];
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ManifestSection, ManifestSidebarMenu } from '@umbraco-cms/models';
|
||||
import type { ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models';
|
||||
|
||||
const sectionAlias = 'Umb.Section.Content';
|
||||
|
||||
@@ -13,15 +13,16 @@ const section: ManifestSection = {
|
||||
},
|
||||
};
|
||||
|
||||
const sidebarMenu: ManifestSidebarMenu = {
|
||||
type: 'sidebarMenu',
|
||||
const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = {
|
||||
type: 'menuSectionSidebarApp',
|
||||
alias: 'Umb.SidebarMenu.Content',
|
||||
name: 'Content Sidebar Menu',
|
||||
weight: 100,
|
||||
meta: {
|
||||
label: 'Content',
|
||||
sections: [sectionAlias],
|
||||
menu: 'Umb.Menu.Content',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [section, sidebarMenu];
|
||||
export const manifests = [section, menuSectionSidebarApp];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { manifests as mediaSectionManifests } from './section.manifests';
|
||||
import { manifests as mediaMenuManifests } from './menu.manifests';
|
||||
import { manifests as mediaManifests } from './media/manifests';
|
||||
import { manifests as mediaTypesManifests } from './media-types/manifests';
|
||||
|
||||
@@ -12,4 +13,4 @@ const registerExtensions = (manifests: Array<ManifestTypes>) => {
|
||||
});
|
||||
};
|
||||
|
||||
registerExtensions([...mediaSectionManifests, ...mediaManifests, ...mediaTypesManifests]);
|
||||
registerExtensions([...mediaSectionManifests, ...mediaMenuManifests, ...mediaManifests, ...mediaTypesManifests]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbMediaTypeRepository } from '../repository/media-type.repository';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbCreateMediaTypeEntityAction extends UmbEntityActionBase<UmbMediaTypeRepository> {
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { UmbDeleteEntityAction } from '../../../../backoffice/shared/entity-actions/delete/delete.action';
|
||||
import { UmbMoveEntityAction } from '../../../../backoffice/shared/entity-actions/move/move.action';
|
||||
import { MEDIA_TYPE_REPOSITORY_ALIAS } from '../repository/manifests';
|
||||
import { UmbCopyEntityAction } from '../../../../backoffice/shared/entity-actions/copy/copy.action';
|
||||
import { UmbCreateMediaTypeEntityAction } from './create.action';
|
||||
import UmbReloadMediaTypeEntityAction from './reload.action';
|
||||
import { UmbDeleteEntityAction, UmbMoveEntityAction, UmbCopyEntityAction } from '@umbraco-cms/entity-action';
|
||||
import type { ManifestEntityAction } from '@umbraco-cms/models';
|
||||
|
||||
const entityType = 'media-type';
|
||||
@@ -62,7 +60,7 @@ const entityActions: Array<ManifestEntityAction> = [
|
||||
api: UmbDeleteEntityAction,
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
type: 'entityAction',
|
||||
alias: 'Umb.EntityAction.MediaType.Reload',
|
||||
name: 'Reload Media Type Entity Action',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { UmbEntityActionBase } from '../../../shared/entity-actions';
|
||||
import { UmbMediaTypeRepository } from '../repository/media-type.repository';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export default class UmbReloadMediaTypeEntityAction extends UmbEntityActionBase<UmbMediaTypeRepository> {
|
||||
@@ -11,6 +11,6 @@ export default class UmbReloadMediaTypeEntityAction extends UmbEntityActionBase<
|
||||
}
|
||||
|
||||
async execute() {
|
||||
alert('refresh')
|
||||
alert('refresh');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
import { manifests as entityActionManifests } from './entity-actions/manifests';
|
||||
|
||||
export const manifests = [
|
||||
...sidebarMenuItemManifests,
|
||||
...menuItemManifests,
|
||||
...treeManifests,
|
||||
...repositoryManifests,
|
||||
...workspaceManifests,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.MediaTypes',
|
||||
name: 'Media Types Menu Item',
|
||||
weight: 20,
|
||||
loader: () => import('./media-types-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Media Types',
|
||||
icon: 'umb:folder',
|
||||
menus: ['Umb.Menu.Settings'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menuItem];
|
||||
@@ -2,8 +2,8 @@ import { html, nothing } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('umb-media-types-sidebar-menu-item')
|
||||
export class UmbMediaTypesSidebarMenuItemElement extends UmbLitElement {
|
||||
@customElement('umb-media-types-menu-item')
|
||||
export class UmbMediaTypesMenuItemElement extends UmbLitElement {
|
||||
@state()
|
||||
private _renderTree = false;
|
||||
|
||||
@@ -30,10 +30,10 @@ export class UmbMediaTypesSidebarMenuItemElement extends UmbLitElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbMediaTypesSidebarMenuItemElement;
|
||||
export default UmbMediaTypesMenuItemElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-media-types-sidebar-menu-item': UmbMediaTypesSidebarMenuItemElement;
|
||||
'umb-media-types-menu-item': UmbMediaTypesMenuItemElement;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.MediaTypes',
|
||||
name: 'Media Types Sidebar Menu Item',
|
||||
weight: 20,
|
||||
loader: () => import('./media-types-sidebar-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Media Types',
|
||||
icon: 'umb:folder',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Settings'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
@@ -7,20 +7,15 @@ import type { MediaTypeDetails } from '@umbraco-cms/models';
|
||||
|
||||
type EntityType = MediaTypeDetails;
|
||||
export class UmbWorkspaceMediaTypeContext
|
||||
extends UmbWorkspaceContext
|
||||
extends UmbWorkspaceContext<UmbMediaTypeRepository>
|
||||
implements UmbWorkspaceEntityContextInterface<EntityType | undefined>
|
||||
{
|
||||
#host: UmbControllerHostInterface;
|
||||
#repo: UmbMediaTypeRepository;
|
||||
|
||||
#data = new ObjectState<MediaTypeDetails | undefined>(undefined);
|
||||
data = this.#data.asObservable();
|
||||
name = this.#data.getObservablePart((data) => data?.name);
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
this.#host = host;
|
||||
this.#repo = new UmbMediaTypeRepository(this.#host);
|
||||
super(host, new UmbMediaTypeRepository(host));
|
||||
}
|
||||
|
||||
getData() {
|
||||
@@ -44,14 +39,14 @@ export class UmbWorkspaceMediaTypeContext
|
||||
}
|
||||
|
||||
async load(entityKey: string) {
|
||||
const { data } = await this.#repo.requestDetails(entityKey);
|
||||
const { data } = await this.repository.requestDetails(entityKey);
|
||||
if (data) {
|
||||
this.#data.next(data);
|
||||
}
|
||||
}
|
||||
|
||||
async createScaffold() {
|
||||
const { data } = await this.#repo.createScaffold();
|
||||
const { data } = await this.repository.createScaffold();
|
||||
if (!data) return;
|
||||
this.setIsNew(true);
|
||||
this.#data.next(data);
|
||||
@@ -59,7 +54,7 @@ export class UmbWorkspaceMediaTypeContext
|
||||
|
||||
async save() {
|
||||
if (!this.#data.value) return;
|
||||
await this.#repo.save(this.#data.value);
|
||||
await this.repository.save(this.#data.value);
|
||||
this.setIsNew(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbTrashEntityAction } from '../../../shared/entity-actions/trash/trash.action';
|
||||
import { UmbTrashEntityAction } from '@umbraco-cms/entity-action';
|
||||
import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models';
|
||||
|
||||
const entityActions: Array<ManifestEntityAction> = [
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import type { UmbMediaRepository } from '../../repository/media.repository';
|
||||
import { UmbActionBase } from '../../../../shared/action';
|
||||
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
|
||||
export class UmbMediaCopyEntityBulkAction extends UmbActionBase<UmbMediaRepository> {
|
||||
#selection: Array<string>;
|
||||
|
||||
export class UmbMediaCopyEntityBulkAction extends UmbEntityBulkActionBase<UmbMediaRepository> {
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.#selection = selection;
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.#selection = selection;
|
||||
super(host, repositoryAlias, selection);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
console.log(`execute copy for: ${this.#selection}`);
|
||||
console.log(`execute copy for: ${this.selection}`);
|
||||
await this.repository?.copy([], '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
import type { UmbMediaRepository } from '../../repository/media.repository';
|
||||
import { UmbActionBase } from '../../../../shared/action';
|
||||
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
|
||||
export class UmbMediaMoveEntityBulkAction extends UmbActionBase<UmbMediaRepository> {
|
||||
#selection: Array<string>;
|
||||
export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase<UmbMediaRepository> {
|
||||
#modalService?: UmbModalService;
|
||||
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.#selection = selection;
|
||||
super(host, repositoryAlias, selection);
|
||||
|
||||
new UmbContextConsumerController(host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
|
||||
this.#modalService = instance;
|
||||
});
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.#selection = selection;
|
||||
}
|
||||
|
||||
async execute() {
|
||||
// TODO: the picker should be single picker by default
|
||||
const modalHandler = this.#modalService?.mediaPicker({ selection: [], multiple: false });
|
||||
const selection = await modalHandler?.onClose();
|
||||
const destination = selection[0];
|
||||
await this.repository?.move(this.#selection, destination);
|
||||
await this.repository?.move(this.selection, destination);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,32 @@
|
||||
import { html } from 'lit';
|
||||
import type { UmbMediaRepository } from '../../repository/media.repository';
|
||||
import { UmbActionBase } from '../../../../shared/action';
|
||||
import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
|
||||
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
|
||||
import { UmbContextConsumerController } from '@umbraco-cms/context-api';
|
||||
import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
|
||||
export class UmbMediaTrashEntityBulkAction extends UmbActionBase<UmbMediaRepository> {
|
||||
#selection: Array<string>;
|
||||
export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase<UmbMediaRepository> {
|
||||
#modalService?: UmbModalService;
|
||||
|
||||
constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array<string>) {
|
||||
super(host, repositoryAlias);
|
||||
this.#selection = selection;
|
||||
super(host, repositoryAlias, selection);
|
||||
|
||||
new UmbContextConsumerController(host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => {
|
||||
this.#modalService = instance;
|
||||
});
|
||||
}
|
||||
|
||||
setSelection(selection: Array<string>) {
|
||||
this.#selection = selection;
|
||||
}
|
||||
|
||||
async execute() {
|
||||
// TODO: show error
|
||||
if (!this.#modalService || !this.repository) return;
|
||||
|
||||
// TODO: should we subscribe in cases like this?
|
||||
const { data } = await this.repository.requestTreeItems(this.#selection);
|
||||
const { data } = await this.repository.requestTreeItems(this.selection);
|
||||
|
||||
if (data) {
|
||||
// TODO: use correct markup
|
||||
const modalHandler = this.#modalService?.confirm({
|
||||
headline: `Deleting ${this.#selection.length} items`,
|
||||
headline: `Deleting ${this.selection.length} items`,
|
||||
content: html`
|
||||
This will delete the following files:
|
||||
<ul style="list-style-type: none; padding: 0; margin: 0; margin-top: var(--uui-size-space-2);">
|
||||
@@ -45,7 +39,7 @@ export class UmbMediaTrashEntityBulkAction extends UmbActionBase<UmbMediaReposit
|
||||
|
||||
const { confirmed } = await modalHandler.onClose();
|
||||
if (confirmed) {
|
||||
await this.repository?.trash(this.#selection);
|
||||
await this.repository?.trash(this.selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
import { manifests as entityActionsManifests } from './entity-actions/manifests';
|
||||
@@ -7,7 +7,7 @@ import { manifests as entityBulkActionsManifests } from './entity-bulk-actions/m
|
||||
|
||||
export const manifests = [
|
||||
...repositoryManifests,
|
||||
...sidebarMenuItemManifests,
|
||||
...menuItemManifests,
|
||||
...treeManifests,
|
||||
...workspaceManifests,
|
||||
...entityActionsManifests,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.Media',
|
||||
name: 'Media Menu Item',
|
||||
weight: 100,
|
||||
loader: () => import('./media-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Media',
|
||||
icon: 'umb:folder',
|
||||
menus: ['Umb.Menu.Media'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menuItem];
|
||||
@@ -2,17 +2,17 @@ import { html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('umb-media-sidebar-menu-item')
|
||||
export class UmbMediaSidebarMenuItemElement extends UmbLitElement {
|
||||
@customElement('umb-media-menu-item')
|
||||
export class UmbMediaMenuItemElement extends UmbLitElement {
|
||||
render() {
|
||||
return html`<umb-tree alias="Umb.Tree.Media"></umb-tree>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbMediaSidebarMenuItemElement;
|
||||
export default UmbMediaMenuItemElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-media-sidebar-menu-item': UmbMediaSidebarMenuItemElement;
|
||||
'umb-media-menu-item': UmbMediaMenuItemElement;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.Media',
|
||||
name: 'Media Sidebar Menu Item',
|
||||
weight: 100,
|
||||
loader: () => import('./media-sidebar-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Media',
|
||||
icon: 'umb:folder',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Media'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
@@ -1,3 +1,4 @@
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace';
|
||||
import type {
|
||||
ManifestWorkspace,
|
||||
ManifestWorkspaceAction,
|
||||
@@ -68,12 +69,12 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
type: 'workspaceAction',
|
||||
alias: 'Umb.WorkspaceAction.Media.Save',
|
||||
name: 'Save Media Workspace Action',
|
||||
loader: () =>
|
||||
import('src/backoffice/shared/components/workspace/workspace-action/save/workspace-action-node-save.element'),
|
||||
meta: {
|
||||
workspaces: ['Umb.Workspace.Media'],
|
||||
label: 'Save',
|
||||
look: 'primary',
|
||||
color: 'positive',
|
||||
api: UmbSaveWorkspaceAction,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -7,20 +7,15 @@ import type { MediaDetails } from '@umbraco-cms/models';
|
||||
|
||||
type EntityType = MediaDetails;
|
||||
export class UmbMediaWorkspaceContext
|
||||
extends UmbWorkspaceContext
|
||||
extends UmbWorkspaceContext<UmbMediaRepository>
|
||||
implements UmbWorkspaceEntityContextInterface<EntityType | undefined>
|
||||
{
|
||||
#host: UmbControllerHostInterface;
|
||||
#detailRepository: UmbMediaRepository;
|
||||
|
||||
#data = new ObjectState<EntityType | undefined>(undefined);
|
||||
data = this.#data.asObservable();
|
||||
name = this.#data.getObservablePart((data) => data?.name);
|
||||
|
||||
constructor(host: UmbControllerHostInterface) {
|
||||
super(host);
|
||||
this.#host = host;
|
||||
this.#detailRepository = new UmbMediaRepository(this.#host);
|
||||
super(host, new UmbMediaRepository(host));
|
||||
}
|
||||
|
||||
getData() {
|
||||
@@ -51,7 +46,7 @@ export class UmbMediaWorkspaceContext
|
||||
}
|
||||
|
||||
async load(entityKey: string) {
|
||||
const { data } = await this.#detailRepository.requestByKey(entityKey);
|
||||
const { data } = await this.repository.requestByKey(entityKey);
|
||||
if (data) {
|
||||
this.setIsNew(false);
|
||||
this.#data.next(data);
|
||||
@@ -59,7 +54,7 @@ export class UmbMediaWorkspaceContext
|
||||
}
|
||||
|
||||
async createScaffold(parentKey: string | null) {
|
||||
const { data } = await this.#detailRepository.createScaffold(parentKey);
|
||||
const { data } = await this.repository.createScaffold(parentKey);
|
||||
if (!data) return;
|
||||
this.setIsNew(true);
|
||||
this.#data.next(data);
|
||||
@@ -68,16 +63,16 @@ export class UmbMediaWorkspaceContext
|
||||
async save() {
|
||||
if (!this.#data.value) return;
|
||||
if (this.isNew) {
|
||||
await this.#detailRepository.create(this.#data.value);
|
||||
await this.repository.create(this.#data.value);
|
||||
} else {
|
||||
await this.#detailRepository.save(this.#data.value);
|
||||
await this.repository.save(this.#data.value);
|
||||
}
|
||||
// If it went well, then its not new anymore?.
|
||||
this.setIsNew(false);
|
||||
}
|
||||
|
||||
async delete(key: string) {
|
||||
await this.#detailRepository.delete(key);
|
||||
await this.repository.delete(key);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ManifestMenu } from '@umbraco-cms/extensions-registry';
|
||||
|
||||
const menu: ManifestMenu = {
|
||||
type: 'menu',
|
||||
alias: 'Umb.Menu.Media',
|
||||
name: 'Media Menu',
|
||||
meta: {
|
||||
label: 'Media',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menu];
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ManifestDashboardCollection, ManifestSection, ManifestSidebarMenu } from '@umbraco-cms/models';
|
||||
import type { ManifestDashboardCollection, ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models';
|
||||
|
||||
const sectionAlias = 'Umb.Section.Media';
|
||||
|
||||
@@ -29,15 +29,16 @@ const dashboards: Array<ManifestDashboardCollection> = [
|
||||
},
|
||||
];
|
||||
|
||||
const sidebarMenu: ManifestSidebarMenu = {
|
||||
type: 'sidebarMenu',
|
||||
alias: 'Umb.SidebarMenu.Media',
|
||||
name: 'Media Sidebar Menu',
|
||||
const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = {
|
||||
type: 'menuSectionSidebarApp',
|
||||
alias: 'Umb.SectionSidebarMenu.Media',
|
||||
name: 'Media Section Sidebar Menu',
|
||||
weight: 100,
|
||||
meta: {
|
||||
label: 'Media',
|
||||
sections: [sectionAlias],
|
||||
menu: 'Umb.Menu.Media',
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [section, sidebarMenu, ...dashboards];
|
||||
export const manifests = [section, menuSectionSidebarApp, ...dashboards];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { manifests as memberSectionManifests } from './section.manifests';
|
||||
import { manifests as menuSectionManifests } from './menu.manifests';
|
||||
import { manifests as memberGroupManifests } from './member-groups/manifests';
|
||||
import { manifests as memberTypeManifests } from './member-types/manifests';
|
||||
import { manifests as memberManifests } from './members/manifests';
|
||||
@@ -13,4 +14,10 @@ const registerExtensions = (manifests: Array<ManifestTypes>) => {
|
||||
});
|
||||
};
|
||||
|
||||
registerExtensions([...memberSectionManifests, ...memberGroupManifests, ...memberTypeManifests, ...memberManifests]);
|
||||
registerExtensions([
|
||||
...memberSectionManifests,
|
||||
...menuSectionManifests,
|
||||
...memberGroupManifests,
|
||||
...memberTypeManifests,
|
||||
...memberManifests,
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbDeleteEntityAction } from '../../../shared/entity-actions/delete/delete.action';
|
||||
import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action';
|
||||
import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models';
|
||||
|
||||
const entityActions: Array<ManifestEntityAction> = [
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { manifests as repositoryManifests } from './repository/manifests';
|
||||
import { manifests as entityActionManifests } from './entity-actions/manifests';
|
||||
import { manifests as sidebarMenuItemManifests } from './sidebar-menu-item/manifests';
|
||||
import { manifests as menuItemManifests } from './menu-item/manifests';
|
||||
import { manifests as treeManifests } from './tree/manifests';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests';
|
||||
|
||||
export const manifests = [
|
||||
...repositoryManifests,
|
||||
...entityActionManifests,
|
||||
...sidebarMenuItemManifests,
|
||||
...menuItemManifests,
|
||||
...treeManifests,
|
||||
...workspaceManifests,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { ManifestMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const menuItem: ManifestMenuItem = {
|
||||
type: 'menuItem',
|
||||
alias: 'Umb.MenuItem.MemberGroups',
|
||||
name: 'Member Groups Menu Item',
|
||||
weight: 800,
|
||||
loader: () => import('./member-groups-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Member Groups',
|
||||
icon: 'umb:folder',
|
||||
menus: ['Umb.Menu.Members'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [menuItem];
|
||||
@@ -2,8 +2,8 @@ import { html, nothing } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('umb-member-groups-sidebar-menu-item')
|
||||
export class UmbMemberGroupsSidebarMenuItemElement extends UmbLitElement {
|
||||
@customElement('umb-member-groups-menu-item')
|
||||
export class UmbMemberGroupsMenuItemElement extends UmbLitElement {
|
||||
@state()
|
||||
private _renderTree = false;
|
||||
|
||||
@@ -30,10 +30,10 @@ export class UmbMemberGroupsSidebarMenuItemElement extends UmbLitElement {
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbMemberGroupsSidebarMenuItemElement;
|
||||
export default UmbMemberGroupsMenuItemElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-member-groups-sidebar-menu-item': UmbMemberGroupsSidebarMenuItemElement;
|
||||
'umb-member-groups-menu-item': UmbMemberGroupsMenuItemElement;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { ManifestSidebarMenuItem } from '@umbraco-cms/models';
|
||||
|
||||
const sidebarMenuItem: ManifestSidebarMenuItem = {
|
||||
type: 'sidebarMenuItem',
|
||||
alias: 'Umb.SidebarMenuItem.MemberGroups',
|
||||
name: 'Member Groups Sidebar Menu Item',
|
||||
weight: 800,
|
||||
loader: () => import('./member-groups-sidebar-menu-item.element'),
|
||||
meta: {
|
||||
label: 'Member Groups',
|
||||
icon: 'umb:folder',
|
||||
sidebarMenus: ['Umb.SidebarMenu.Members'],
|
||||
},
|
||||
};
|
||||
|
||||
export const manifests = [sidebarMenuItem];
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MEMBER_GROUP_REPOSITORY_ALIAS } from '../repository/manifests';
|
||||
import { UmbSaveWorkspaceAction } from '../../../shared/workspace-actions/save.action';
|
||||
import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace';
|
||||
import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models';
|
||||
|
||||
const workspace: ManifestWorkspace = {
|
||||
@@ -38,7 +38,6 @@ const workspaceActions: Array<ManifestWorkspaceAction> = [
|
||||
label: 'Save',
|
||||
look: 'primary',
|
||||
color: 'positive',
|
||||
repositoryAlias: MEMBER_GROUP_REPOSITORY_ALIAS,
|
||||
api: UmbSaveWorkspaceAction,
|
||||
},
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user