diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/entity-actions/manifests.ts index 9cb3417fe5..6a3ab0749c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/entity-actions/manifests.ts @@ -8,7 +8,6 @@ import { UMB_PARTIAL_VIEW_REPOSITORY_ALIAS } from '../repository/index.js'; import { UmbCreateFromSnippetPartialViewAction } from './create/create-from-snippet.action.js'; import { UmbCreateEmptyPartialViewAction } from './create/create-empty.action.js'; import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; -import { UmbCreateFolderEntityAction, UmbDeleteFolderEntityAction } from '@umbraco-cms/backoffice/tree'; import { ManifestEntityAction } from '@umbraco-cms/backoffice/extension-registry'; //Actions for partial view files @@ -27,8 +26,6 @@ const partialViewActions: Array = [ }, ]; -//TODO: add create folder action when the generic folder action is implemented -//Actions for directories const partialViewFolderActions: Array = [ { type: 'entityAction', @@ -54,30 +51,6 @@ const partialViewFolderActions: Array = [ entityTypes: [UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE, UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE], }, }, - { - type: 'entityAction', - alias: 'Umb.EntityAction.PartialViewFolder.DeleteFolder', - name: 'Delete Partial View Folder', - api: UmbDeleteFolderEntityAction, - meta: { - icon: 'icon-trash', - label: 'Delete folder...', - repositoryAlias: UMB_PARTIAL_VIEW_REPOSITORY_ALIAS, - entityTypes: [UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE], - }, - }, - { - type: 'entityAction', - alias: 'Umb.EntityAction.PartialViewFolder.CreateFolder', - name: 'Create Partial View folder', - api: UmbCreateFolderEntityAction, - meta: { - icon: 'icon-add', - label: 'Create folder...', - repositoryAlias: UMB_PARTIAL_VIEW_REPOSITORY_ALIAS, - entityTypes: [UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE, UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE], - }, - }, ]; const createFromSnippetActionModal = { diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/repository/sources/partial-view-folder.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/repository/sources/partial-view-folder.server.data-source.ts deleted file mode 100644 index bff507fc9c..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/repository/sources/partial-view-folder.server.data-source.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { CreateFolderRequestModel, PartialViewResource } from '@umbraco-cms/backoffice/backend-api'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbFolderDataSource } from '@umbraco-cms/backoffice/tree'; -import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; - -export class UmbPartialViewFolderServerDataSource implements UmbFolderDataSource { - #host: UmbControllerHost; - - constructor(host: UmbControllerHost) { - this.#host = host; - } - - createScaffold(): any { - throw new Error('Method not implemented.'); - } - - read(unique: string) { - return tryExecuteAndNotify(this.#host, PartialViewResource.getPartialViewFolder({ path: unique })); - } - - create(requestBody: CreateFolderRequestModel) { - return tryExecuteAndNotify(this.#host, PartialViewResource.postPartialViewFolder({ requestBody })); - } - - update(): any { - throw new Error('Method not implemented.'); - } - - delete(path: string) { - return tryExecuteAndNotify(this.#host, PartialViewResource.deletePartialViewFolder({ path })); - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/index.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/index.ts new file mode 100644 index 0000000000..561cd27103 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/index.ts @@ -0,0 +1,6 @@ +export { UmbPartialViewFolderRepository } from './partial-view-folder.repository.js'; +export { + UMB_PARTIAL_VIEW_FOLDER_REPOSITORY_ALIAS, + UMB_DELETE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS, + UMB_CREATE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS, +} from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/manifests.ts new file mode 100644 index 0000000000..4614377bb3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/manifests.ts @@ -0,0 +1,45 @@ +import { UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE, UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE } from '../../entity.js'; +import { UmbPartialViewFolderRepository } from './partial-view-folder.repository.js'; +import { UmbCreateFolderEntityAction, UmbDeleteFolderEntityAction } from '@umbraco-cms/backoffice/tree'; +import type { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_PARTIAL_VIEW_FOLDER_REPOSITORY_ALIAS = 'Umb.Repository.PartialView.Folder'; + +const folderRepository: ManifestRepository = { + type: 'repository', + alias: UMB_PARTIAL_VIEW_FOLDER_REPOSITORY_ALIAS, + name: 'Partial View Folder Repository', + api: UmbPartialViewFolderRepository, +}; + +export const UMB_DELETE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS = 'Umb.EntityAction.PartialView.Folder.Delete'; +export const UMB_CREATE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS = 'Umb.EntityAction.PartialView.Folder.Create'; + +const entityActions = [ + { + type: 'entityAction', + alias: UMB_CREATE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS, + name: 'Create Partial View folder Entity Action', + api: UmbCreateFolderEntityAction, + meta: { + icon: 'icon-add', + label: 'Create folder...', + repositoryAlias: UMB_PARTIAL_VIEW_FOLDER_REPOSITORY_ALIAS, + entityTypes: [UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE, UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE], + }, + }, + { + type: 'entityAction', + alias: UMB_DELETE_PARTIAL_VIEW_FOLDER_ENTITY_ACTION_ALIAS, + name: 'Delete Partial View folder Entity Action', + api: UmbDeleteFolderEntityAction, + meta: { + icon: 'icon-trash', + label: 'Delete folder...', + repositoryAlias: UMB_PARTIAL_VIEW_FOLDER_REPOSITORY_ALIAS, + entityTypes: [UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE], + }, + }, +]; + +export const manifests = [folderRepository, ...entityActions]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.repository.ts new file mode 100644 index 0000000000..fbed404302 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.repository.ts @@ -0,0 +1,29 @@ +import { UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE } from '../../entity.js'; +import { UmbPartialViewTreeItemModel } from '../types.js'; +import { UMB_PARTIAL_VIEW_TREE_STORE_CONTEXT } from '../partial-view-tree.store.js'; +import { UmbPartialViewFolderServerDataSource } from './partial-view-folder.server.data-source.js'; +import { UmbFolderModel, UmbFolderRepositoryBase } from '@umbraco-cms/backoffice/tree'; +import { type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbPartialViewFolderRepository extends UmbFolderRepositoryBase { + constructor(host: UmbControllerHost) { + super( + host, + UmbPartialViewFolderServerDataSource, + UMB_PARTIAL_VIEW_TREE_STORE_CONTEXT, + folderToPartialViewTreeItemFolder, + ); + } +} + +const folderToPartialViewTreeItemFolder = (folder: UmbFolderModel): UmbPartialViewTreeItemModel => { + return { + unique: folder.unique, + parentUnique: folder.parentUnique, + name: folder.name, + entityType: UMB_PARTIAL_VIEW_FOLDER_ENTITY_TYPE, + isFolder: true, + isContainer: false, + hasChildren: false, + }; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.server.data-source.ts new file mode 100644 index 0000000000..7aa6e20e9d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/folder/partial-view-folder.server.data-source.ts @@ -0,0 +1,111 @@ +import { UmbServerPathUniqueSerializer } from '../../../utils/index.js'; +import { UmbCreateFolderModel, UmbFolderDataSource, UmbUpdateFolderModel } from '@umbraco-cms/backoffice/tree'; +import { CreatePartialViewFolderRequestModel, PartialViewResource } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for Partial View folders that fetches data from the server + * @export + * @class UmbPartialViewFolderServerDataSource + * @implements {RepositoryDetailDataSource} + */ +export class UmbPartialViewFolderServerDataSource implements UmbFolderDataSource { + #host: UmbControllerHost; + #serverPathUniqueSerializer = new UmbServerPathUniqueSerializer(); + + /** + * Creates an instance of UmbPartialViewFolderServerDataSource. + * @param {UmbControllerHost} host + * @memberof UmbPartialViewFolderServerDataSource + */ + constructor(host: UmbControllerHost) { + this.#host = host; + } + + /** + * Fetches a Partial View folder from the server + * @param {string} unique + * @return {UmbDataSourceResponse} + * @memberof UmbPartialViewFolderServerDataSource + */ + async read(unique: string) { + if (!unique) throw new Error('Unique is missing'); + + const path = this.#serverPathUniqueSerializer.toServerPath(unique); + + const { data, error } = await tryExecuteAndNotify( + this.#host, + PartialViewResource.getPartialViewFolderByPath({ + path, + }), + ); + + if (data) { + const mappedData = { + unique: this.#serverPathUniqueSerializer.toUnique(data.path), + parentUnique: data.parent ? this.#serverPathUniqueSerializer.toUnique(data.parent.path) : null, + name: data.name, + }; + + return { data: mappedData }; + } + + return { error }; + } + + /** + * Creates a Partial View folder on the server + * @param {UmbCreateFolderModel} args + * @return {UmbDataSourceResponse} + * @memberof UmbPartialViewFolderServerDataSource + */ + async create(args: UmbCreateFolderModel) { + if (args.parentUnique === undefined) throw new Error('Parent unique is missing'); + if (!args.name) throw new Error('Name is missing'); + + const parentPath = new UmbServerPathUniqueSerializer().toServerPath(args.parentUnique); + + const requestBody: CreatePartialViewFolderRequestModel = { + parentPath, + name: args.name, + }; + + const { data, error } = await tryExecuteAndNotify( + this.#host, + PartialViewResource.postPartialViewFolder({ + requestBody, + }), + ); + + if (data) { + const newPath = this.#serverPathUniqueSerializer.toUnique(data); + return this.read(newPath); + } + + return { error }; + } + + /** + * Deletes a Partial View folder on the server + * @param {string} unique + * @return {UmbDataSourceErrorResponse} + * @memberof UmbPartialViewServerDataSource + */ + async delete(unique: string) { + if (!unique) throw new Error('Unique is missing'); + + const path = this.#serverPathUniqueSerializer.toServerPath(unique); + + return tryExecuteAndNotify( + this.#host, + PartialViewResource.deletePartialViewFolderByPath({ + path, + }), + ); + } + + async update(args: UmbUpdateFolderModel): Promise { + throw new Error('Updating is not supported'); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/manifests.ts index 2d4ea700d0..9b5cdb189f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/manifests.ts @@ -1,6 +1,7 @@ import { UMB_PARTIAL_VIEW_ENTITY_TYPE, UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE } from '../entity.js'; import { UmbPartialViewTreeRepository } from './partial-view-tree.repository.js'; import { UmbPartialViewTreeStore } from './partial-view-tree.store.js'; +import { manifests as folderManifests } from './folder/manifests.js'; import type { ManifestRepository, ManifestTree, @@ -45,4 +46,4 @@ const treeItem: ManifestTreeItem = { }, }; -export const manifests = [treeRepository, treeStore, tree, treeItem]; +export const manifests = [treeRepository, treeStore, tree, treeItem, ...folderManifests];