Add project creation wizard (step 7)
New project flow: native directory picker, project name (auto-filled from folder name), project type selector (Auto-detect plus common CMS/framework types), optional docroot, and a "start after creating" checkbox. Runs ddev config with cwd = the chosen directory (streamed through the existing commandRunner), then reuses the existing useStartProject() mutation for the start step rather than inventing multi-phase operation semantics — ddev config registers the project by name, so a plain `ddev start <name>` works identically to starting any other project afterward. Scoped down from the original app's wizard: skipped scaffolding a fresh CMS codebase (composer create-project / wp core download / etc.) since each framework needs different install commands — this covers project registration + config + start, with ddev's own --auto/--project-type detection handling "auto-detect for existing folders" for free (no custom detection heuristics needed). Verified end-to-end against the real scratch environment: called the create.configure IPC directly (the picker itself opens a native OS dialog CDP can't drive, same constraint as import/export in step 4) with a real target directory, confirmed the generated .ddev/config.yaml has the correct name/type/docroot, confirmed the new project appears in the sidebar via the existing polling within one refresh cycle, and verified the modal's form guards (Create disabled until a directory is chosen) and all type-selector options render correctly. Cleaned up via `ddev delete`.
This commit is contained in:
@@ -7,6 +7,7 @@ import { registerTerminalIpc } from './ipc/terminal'
|
||||
import { registerDatabaseIpc } from './ipc/database'
|
||||
import { registerAddonsIpc } from './ipc/addons'
|
||||
import { registerLogsIpc } from './ipc/logs'
|
||||
import { registerCreateIpc } from './ipc/create'
|
||||
import { killAllRunningCommands } from './commandRunner'
|
||||
|
||||
function createWindow(): void {
|
||||
@@ -61,6 +62,7 @@ app.whenReady().then(() => {
|
||||
registerDatabaseIpc()
|
||||
registerAddonsIpc()
|
||||
registerLogsIpc()
|
||||
registerCreateIpc()
|
||||
|
||||
createWindow()
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { dialog, ipcMain } from 'electron'
|
||||
import { runStreamed } from '../commandRunner'
|
||||
|
||||
export function registerCreateIpc(): void {
|
||||
ipcMain.handle('create:pickDirectory', async () => {
|
||||
const result = await dialog.showOpenDialog({
|
||||
properties: ['openDirectory', 'createDirectory']
|
||||
})
|
||||
return result.canceled ? null : result.filePaths[0]
|
||||
})
|
||||
|
||||
ipcMain.handle(
|
||||
'create:configure',
|
||||
(
|
||||
event,
|
||||
operationId: string,
|
||||
directory: string,
|
||||
projectName: string,
|
||||
projectType: string,
|
||||
docroot: string
|
||||
) => {
|
||||
const args = ['config', `--project-name=${projectName}`, '--auto']
|
||||
if (projectType) args.push(`--project-type=${projectType}`)
|
||||
if (docroot.trim()) args.push(`--docroot=${docroot.trim()}`)
|
||||
return runStreamed(operationId, args, event.sender, { cwd: directory })
|
||||
}
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user