23fc0a6b82
- Update MobileEditView to render Save and optional Delete in a sticky bottom action bar; header now shows Cancel + title only. - Make ConfigProfilesMobileView open edit view on profile tap. - Make ToolWorkshopMobileView open edit view on tool type tap. - Wire delete into MobileEditView for existing profiles and tool types. - Stay on edit view after saving an existing item; create flow returns to list as before. - Update ToolWorkshopPage cancel to return to list. - Add mobile-edit-actions and mobile-edit-delete CSS. Quality gates: npm run typecheck, npm run lint, npm test -- --run (87 passed) Refs: openspec/changes/mobile-edit-default-bottom-actions
119 lines
3.1 KiB
TypeScript
119 lines
3.1 KiB
TypeScript
import { ErrorState, LoadingState } from "../components/data-states";
|
|
import { useMobileViewport } from "../hooks/use-mobile-viewport";
|
|
import { useToolWorkshop } from "../hooks/use-tool-workshop";
|
|
import { ToolTypeListSidebar } from "../components/features/tool-workshop/ToolTypeListSidebar";
|
|
import { ToolTypeEditorPanel } from "../components/features/tool-workshop/ToolTypeEditorPanel";
|
|
import { ToolWorkshopMobileView } from "../components/features/tool-workshop/ToolWorkshopMobileView";
|
|
import type { MobileView } from "../components/features/tool-workshop/ToolWorkshopMobileView";
|
|
import { useState } from "react";
|
|
|
|
export const ToolWorkshopPage = () => {
|
|
const isMobile = useMobileViewport();
|
|
const [mobileView, setMobileView] = useState<MobileView>("list");
|
|
const {
|
|
status,
|
|
toolTypes,
|
|
baseDefinitions,
|
|
selectedToolType,
|
|
selectedToolTypeId,
|
|
isCreating,
|
|
toolTypeForm,
|
|
manifestData,
|
|
manifestDefinitionId,
|
|
toolTypeError,
|
|
toolTypeDirty,
|
|
loadData,
|
|
handleSelectToolType,
|
|
handleCreateNew,
|
|
handleToolTypeSubmit,
|
|
handleDeleteToolType,
|
|
handleFormChange,
|
|
handleReset,
|
|
setManifestData,
|
|
setToolTypeDirty,
|
|
} = useToolWorkshop();
|
|
|
|
if (status === "loading") {
|
|
return (
|
|
<div className="container">
|
|
<LoadingState message="Loading Tool Workshop..." />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (status === "error") {
|
|
return (
|
|
<div className="container">
|
|
<ErrorState message="Failed to load Tool Workshop." onRetry={loadData} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (isMobile) {
|
|
return (
|
|
<ToolWorkshopMobileView
|
|
toolTypes={toolTypes}
|
|
selectedToolType={selectedToolType}
|
|
mobileView={mobileView}
|
|
isCreating={isCreating}
|
|
toolTypeForm={toolTypeForm}
|
|
manifestData={manifestData}
|
|
manifestDefinitionId={manifestDefinitionId}
|
|
baseDefinitions={baseDefinitions}
|
|
toolTypeError={toolTypeError}
|
|
toolTypeDirty={toolTypeDirty}
|
|
onViewChange={setMobileView}
|
|
onSelect={handleSelectToolType}
|
|
onCreate={handleCreateNew}
|
|
onDelete={handleDeleteToolType}
|
|
onFormChange={handleFormChange}
|
|
onManifestChange={(m) => {
|
|
setManifestData(m);
|
|
setToolTypeDirty(true);
|
|
}}
|
|
onSubmit={handleToolTypeSubmit}
|
|
onCancel={() => {
|
|
if (toolTypeDirty) {
|
|
if (!window.confirm("You have unsaved changes. Discard them?")) {
|
|
return;
|
|
}
|
|
}
|
|
setMobileView("list");
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className="container"
|
|
style={{ display: "flex", height: "calc(100vh - 4rem)", gap: 0, padding: 0 }}
|
|
>
|
|
<ToolTypeListSidebar
|
|
toolTypes={toolTypes}
|
|
selectedToolTypeId={selectedToolTypeId}
|
|
onSelect={handleSelectToolType}
|
|
onCreate={handleCreateNew}
|
|
onDelete={handleDeleteToolType}
|
|
/>
|
|
<ToolTypeEditorPanel
|
|
isCreating={isCreating}
|
|
selectedToolType={selectedToolType}
|
|
form={toolTypeForm}
|
|
manifestData={manifestData}
|
|
manifestDefinitionId={manifestDefinitionId}
|
|
baseDefinitions={baseDefinitions}
|
|
toolTypeError={toolTypeError}
|
|
toolTypeDirty={toolTypeDirty}
|
|
onFormChange={handleFormChange}
|
|
onManifestChange={(m) => {
|
|
setManifestData(m);
|
|
setToolTypeDirty(true);
|
|
}}
|
|
onSubmit={handleToolTypeSubmit}
|
|
onReset={handleReset}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|