Skip to content

Commit

Permalink
Delete page on file system when deleted in UI (#1913)
Browse files Browse the repository at this point in the history
  • Loading branch information
Janpot authored Apr 20, 2023
1 parent 9df3b90 commit d2e0767
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 12 deletions.
5 changes: 4 additions & 1 deletion packages/toolpad-app/pages/api/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getVersionInfo } from '../../src/server/versionInfo';
import { hasOwnProperty } from '../../src/utils/collections';
import { errorFrom, serializeError } from '../../src/utils/errors';
import logger from '../../src/server/logs/logger';
import { createComponent, openCodeComponentEditor } from '../../src/server/localMode';
import { createComponent, deletePage, openCodeComponentEditor } from '../../src/server/localMode';
import { getDomFingerprint, loadDom, saveDom } from '../../src/server/liveProject';

export interface Method<P extends any[] = any[], R = any> {
Expand Down Expand Up @@ -134,6 +134,9 @@ const rpcServer = {
createComponent: createMethod<typeof createComponent>(({ params }) => {
return createComponent(...params);
}),
deletePage: createMethod<typeof deletePage>(({ params }) => {
return deletePage(...params);
}),
},
} as const;

Expand Down
29 changes: 22 additions & 7 deletions packages/toolpad-app/src/server/localMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ function getPagesFolder(root: string): string {
return path.join(toolpadFolder, './pages');
}

function getPageFolder(root: string, name: string): string {
const pagesFolder = getPagesFolder(root);
const pageFolder = path.resolve(pagesFolder, name);
return pageFolder;
}

function getPageFile(root: string, name: string): string {
const pageFolder = getPageFolder(root, name);
const pageFileName = path.resolve(pageFolder, 'page.yml');
return pageFileName;
}

function getComponentFilePath(componentsFolder: string, componentName: string): string {
return path.join(componentsFolder, `${componentName}.tsx`);
}
Expand Down Expand Up @@ -224,6 +236,12 @@ export async function createComponent(name: string) {
await writeFileRecursive(filePath, content, { encoding: 'utf-8' });
}

export async function deletePage(name: string) {
const root = getUserProjectRoot();
const pageFolder = getPageFolder(root, name);
await fs.rm(pageFolder, { force: true, recursive: true });
}

class Lock {
pending: Promise<any> | null = null;

Expand Down Expand Up @@ -861,11 +879,10 @@ function extractPagesFromDom(dom: appDom.AppDom): ExtractedPages {
return { pages, dom };
}

async function writePagesToFiles(pagesFolder: string, pages: PagesContent) {
async function writePagesToFiles(root: string, pages: PagesContent) {
await Promise.all(
Object.entries(pages).map(async ([name, page]) => {
const pageFolder = path.resolve(pagesFolder, name);
const pageFileName = path.resolve(pageFolder, 'page.yml');
const pageFileName = getPageFile(root, name);
await updateYamlFile(pageFileName, page);
}),
);
Expand Down Expand Up @@ -920,9 +937,8 @@ function extractThemeContentFromDom(dom: appDom.AppDom): Theme | null {

async function writeDomToDisk(dom: appDom.AppDom): Promise<void> {
const root = getUserProjectRoot();
const pagesFolder = getPagesFolder(root);
const { pages: pagesContent } = extractPagesFromDom(dom);
await Promise.all([writePagesToFiles(pagesFolder, pagesContent)]);
await Promise.all([writePagesToFiles(root, pagesContent)]);
}

export async function openCodeEditor(file: string): Promise<void> {
Expand Down Expand Up @@ -981,8 +997,7 @@ async function writeProjectFolder(
folder: ToolpadProjectFolder,
writeComponents: boolean = false,
): Promise<void> {
const pagesFolder = getPagesFolder(root);
await writePagesToFiles(pagesFolder, folder.pages);
await writePagesToFiles(root, folder.pages);
await writeThemeFile(root, folder.theme);
if (writeComponents) {
const componentsFolder = getComponentsFolder(root);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import CreatePageNodeDialog from './CreatePageNodeDialog';
import useLocalStorageState from '../../../utils/useLocalStorageState';
import NodeMenu from '../NodeMenu';
import { DomView } from '../../../utils/domView';
import client from '../../../api';

const HierarchyExplorerRoot = styled('div')({
overflow: 'auto',
Expand Down Expand Up @@ -187,16 +188,19 @@ export default function HierarchyExplorer({ className }: HierarchyExplorerProps)
}, []);
const handleCreatepageDialogClose = React.useCallback(() => setCreatePageDialogOpen(0), []);

const handleDeleteNode = React.useCallback(
(nodeId: NodeId) => {
const handleDeletePage = React.useCallback(
async (nodeId: NodeId) => {
const deletedNode = appDom.getNode(dom, nodeId);

let domViewAfterDelete: DomView | undefined;
if (nodeId === activeNode) {
const deletedNode = appDom.getNode(dom, nodeId);
const siblings = appDom.getSiblings(dom, deletedNode);
const firstSiblingOfType = siblings.find((sibling) => sibling.type === deletedNode.type);
domViewAfterDelete = firstSiblingOfType && getNodeEditorDomView(firstSiblingOfType);
}

await client.mutation.deletePage(deletedNode.name);

appStateApi.update(
(draft) => appDom.removeNode(draft, nodeId),
domViewAfterDelete || { kind: 'page' },
Expand Down Expand Up @@ -265,7 +269,7 @@ export default function HierarchyExplorer({ className }: HierarchyExplorerProps)
aria-level={2}
labelText={page.name}
onDuplicateNode={handleDuplicateNode}
onDeleteNode={handleDeleteNode}
onDeleteNode={handleDeletePage}
onSettingsNode={handlePageSettingsNode}
/>
))}
Expand Down
34 changes: 34 additions & 0 deletions test/integration/editor/new.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import path from 'path';
import { test, expect } from '../../playwright/localTest';
import { ToolpadEditor } from '../../models/ToolpadEditor';
import { fileExists, folderExists } from '../../../packages/toolpad-app/src/utils/fs';

test.use({
localAppConfig: {
Expand Down Expand Up @@ -43,3 +45,35 @@ test('can create new component', async ({ page }) => {
await editorModel.createPage('somePage');
await editorModel.createComponent('someComponent');
});

test('can create/delete page', async ({ page, localApp }) => {
const editorModel = new ToolpadEditor(page);

await editorModel.goto();

await editorModel.createPage('somePage');

const pageMenuItem = editorModel.hierarchyItem('pages', 'somePage');
const pageFolder = path.resolve(localApp.dir, './toolpad/pages/somePage');
const pageFile = path.resolve(pageFolder, './page.yml');

await expect(pageMenuItem).toBeVisible();

await expect.poll(async () => folderExists(pageFolder)).toBe(true);
await expect.poll(async () => fileExists(pageFile)).toBe(true);

await pageMenuItem.hover();

await pageMenuItem.getByRole('button', { name: 'Open hierarchy menu' }).click();

await page.getByRole('menuitem', { name: 'Delete' }).click();

await page
.getByRole('dialog', { name: 'Confirm' })
.getByRole('button', { name: 'Delete' })
.click();

await expect(pageMenuItem).toBeHidden();

await expect.poll(async () => folderExists(pageFolder)).toBe(false);
});

0 comments on commit d2e0767

Please sign in to comment.