feat: redesign mobile Config Profiles detail, preview, and edit pages

- Rewrite ConfigProfilesMobileView to match desktop functionality:
  full detail view with all fields, preview action showing resolved
  profile, and edit view with project/tool selects, includes,
  environment variables, runtime hints, files, mounts with nested
  files, and git mounts.
- Update useConfigProfiles.handleSubmit to return boolean success.
- Update ConfigProfilesPage to pass required state and callbacks.
- Add mobile-specific CSS for config profile forms, includes,
  mount/file cards, and preview panels.
- Allow MobileDetailView to render extra children.

Quality gates: npm run typecheck, npm run lint, npm test -- --run (87 passed)

Refs: openspec/changes/mobile-config-profiles-ui
This commit is contained in:
Developer
2026-06-13 22:04:17 +00:00
parent 35f0a3ea2e
commit 98d4393387
29 changed files with 1135 additions and 337 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ dir: .
Trust boundary: index routes, map orients, source decides.
## role
Infrastructure and deployment configuration for a self-hosted project management and git repository platform with OAuth2 authentication.
A self-hosted, containerized project management and Git repository platform with OAuth2 SSO integration, designed for deployment via Docker Compose with or without Traefik reverse proxy.
## parent
-
## children
+2 -2
View File
@@ -18,7 +18,7 @@ index: ./.pi-map.index.md
Trust boundary: index routes, map orients, source decides.
## role
Infrastructure and deployment configuration for a self-hosted project management and git repository platform with OAuth2 authentication.
Infrastructure and deployment configuration for a self-hosted project management and git repository platform with multi-service Docker orchestration.
## files
- .env.example | Provides a template of environment variables for configuring a Headquarter application with PostgreSQL, Redis, Authentik SSO, and Docker/Traefik deployment
- .gitignore | Specifies files and directories for Git to ignore across a multi-language project with Python, Node, and custom tooling | dep: Git
@@ -31,7 +31,7 @@ Infrastructure and deployment configuration for a self-hosted project management
- progress.md | Tracks completed and remaining tasks for a backend-frontend code refactoring project organized in 7 phases
- swap-pane | Empty file with no functionality
## arch
Containerized microservices architecture using Docker Compose with PostgreSQL/Redis data layer, Traefik reverse proxy for TLS/ingress, and environment-driven configuration across frontend/backend services.
Docker Compose-based microservices with PostgreSQL/Redis backend, Traefik reverse proxy, OAuth2 SSO integration, and environment-driven configuration management.
## tags
docker, redis, git, application, postgresql, compose, traefik, project
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps
## role
Contains the main deployable application entry points and top-level configurations for the project.
Contains the main deployable application entry points and executable configurations for the project.
## parent
index: ./.pi-map.index.md
map: ./.pi-map.md
+2 -2
View File
@@ -4,10 +4,10 @@ dir: apps
index: apps/.pi-map.index.md
## role
Contains the main deployable application entry points and top-level configurations for the project.
Contains the main application entry points and executable modules for the project.
## files
## arch
Monorepo-style app separation with distinct application boundaries, likely sharing common libraries/modules while maintaining independent deployment artifacts.
Modular application structure with separate deployable units, typically following framework-specific conventions (e.g., Next.js, React, or other app-based architectures).
## tags
-
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web
## role
Frontend web application for a React-based developer workspace with code editing, terminal, and routing capabilities.
Frontend web application for a React-based "headquarter" project providing code editing, terminal, and routing capabilities via Vite/TypeScript.
## parent
index: apps/.pi-map.index.md
map: apps/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/web
index: apps/web/.pi-map.index.md
## role
Frontend web application for a React-based developer workspace with code editing, terminal, and routing capabilities.
Frontend web application for a React-based "headquarter" project providing code editing, terminal, and routing capabilities via Vite/TypeScript.
## files
- .env.example | Template file defining example environment variables for frontend API and application URL configuration
- .eslintrc.cjs | Configures ESLint for a TypeScript browser project with modern ECMAScript module support | dep: @typescript-eslint/parser, @typescript-eslint/eslint-plugin, eslint
@@ -16,7 +16,7 @@ Frontend web application for a React-based developer workspace with code editing
- tsconfig.json | TypeScript configuration file for a React project using Vite with modern ES2020 target and bundler module resolution | dep: typescript, react, vite
- vite.config.ts | Configures Vite build tool for a React project with custom dev server port and Vitest test settings. | dep: vite, @vitejs/plugin-react
## arch
Modern Vite-based SPA with TypeScript, nginx reverse proxy serving, multi-stage Docker containerization, and client-side routing.
Modern SPA architecture using Vite bundler with React, TypeScript, nginx static serving, multi-stage Docker containerization, and client-side routing with optimized asset caching.
## tags
react, eslint, vite, typescript, dom, application, nginx, web
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web/src
## role
Entry point and core infrastructure for a React web application handling authentication, routing, and domain type definitions.
Provides the core web application entry point, routing infrastructure, and shared domain type definitions for a React-based frontend.
## parent
index: apps/web/.pi-map.index.md
map: apps/web/.pi-map.md
+2 -2
View File
@@ -4,13 +4,13 @@ dir: apps/web/src
index: apps/web/src/.pi-map.index.md
## role
Entry point and core infrastructure for a React web application handling authentication, routing, and domain type definitions.
Frontend web application entry point and core infrastructure for a React-based collaborative development platform.
## files
- main.tsx | Bootstraps a React application with routing, authentication, and session management providers. | dep: react, react-dom/client, react-router-dom, ./router, ./state/auth, ./state/sessions, ./styles/tokens.css, ./styles/global.css, ./styles/utilities.css, ./styles/syntax-highlight.css, ./styles/pages/git-history.css, ./styles/pages/projects.css, ./styles/pages/sessions.css, ./styles/pages/ssh-keys.css, ./styles/pages/workspace-detail.css, ./styles/pages/workspaces.css, react-dom
- router.tsx | Defines the React Router configuration for a web application with protected routes, nested layouts, and redirects. | exp: AppRouter | dep: react-router-dom, ./components/app-shell, ./components/protected-route, ./pages/DashboardPage, ./pages/PlaceholderPage, ./pages/ProfilePage, ./pages/ProjectsPage, ./pages/GitRepositoriesPage, ./pages/GitHistoryPage, ./pages/ProjectSettingsPage, ./pages/SettingsPage, ./pages/TerminalPage, ./pages/ToolWorkshopPage, ./pages/SshKeysPage, ./pages/ConfigProfilesPage, ./pages/SessionsPage, ./pages/WorkspacesPage, ./pages/WorkspaceDetailPage
- types.ts | Defines TypeScript type definitions for user sessions, projects, repositories, and workspaces in an application. | exp: SessionUser, SessionPayload, Project, WorkspaceSummary, RepositorySummary, ProjectWithRepos
## arch
Provider pattern wrapping React Router with nested route layouts, protected route guards, and centralized TypeScript type definitions for session-based auth and workspace/project domain models.
Modular React SPA with provider-pattern state management, nested routing with authentication guards, and centralized TypeScript domain modeling for multi-tenant workspace/project hierarchy.
## tags
pages, styles, css, router, react, session, dom, project
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web/src/components
## role
Provides reusable, accessible UI primitives and layout components for a React web application, including shell layout, data states, icons, code display, routing guards, and toast notifications.
Provides reusable, accessible UI primitives and layout components for a React web application, including shell structure, data visualization states, iconography, code editing/display, authentication guards, and toast notifications.
## parent
index: apps/web/src/.pi-map.index.md
map: apps/web/src/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/web/src/components
index: apps/web/src/components/.pi-map.index.md
## role
Provides reusable, accessible UI components and utilities for rendering the application shell, data states, icons, code display, notifications, and route protection in a React web application.
Provides reusable UI components, layout primitives, and auth guards for the web application's React-based frontend.
## files
- app-shell.tsx | Renders the main application shell layout with navigation, header, session management, and mobile-responsive behavior for a React Router-based SPA. | exp: AppShell | dep: react-router-dom, ../api/sessions, ../hooks/use-theme, ../state/auth, ../state/sessions, ../hooks/use-mobile-viewport, ../state/events, ../state/toast, ../state/notifications, ./features/notification/event-toast-bridge, ./features/notification/notification-center, ./icon, ./features/mobile/mobile-nav, ./features/tool/start-tool-fab, ../utils/icons
- code-editor.tsx | A React component that renders a syntax-highlighted code editor with line numbers using react-simple-code-editor. | exp: CodeEditor | dep: react, react-simple-code-editor, ../utils/language
@@ -17,7 +17,7 @@ Provides reusable, accessible UI components and utilities for rendering the appl
- toast-rules.test.ts | Unit tests for mapping instance events to toast notification categories and severities | dep: vitest, ./toast-rules, ../types/events
- toast-rules.ts | Maps instance events to toast notifications with deduplication logic to prevent spam | exp: func:mapEventToCategory(event: InstanceEventPayload) → string, call:event.event.startsWith, func:mapEventToSeverity(event: InstanceEventPayload) → "info" | "warning" | "error" | "success", func:handleEventToast(event: InstanceEventPayload) → void, call:shouldShowToast, call:toast.info, call:toast.success, call:toast.warning, call:toast.error, func:clearToastDedup() → void, call:lastToastTime.clear | dep: ../state/toast, ../types/events, toast state module, InstanceEventPayload type
## arch
Component-based React architecture with functional components, composition patterns, separation of concerns (presentation vs logic), and test coverage for critical utilities; integrates third-party libraries (Phosphor icons, react-simple-code-editor) and React Router for SPA navigation.
Component-based React architecture with functional components, composition patterns, separation of concerns (presentation, auth, feedback), and test colocation.
## tags
toast, icon, react, state, code, loading, event, editor
## symbols
@@ -2,7 +2,7 @@
dir: apps/web/src/components/features
## role
Reusable UI feature components that compose domain-specific functionality for the web application
Reusable UI feature components for the web application that compose domain-specific user interface elements.
## parent
index: apps/web/src/components/.pi-map.index.md
map: apps/web/src/components/.pi-map.md
+2 -2
View File
@@ -4,10 +4,10 @@ dir: apps/web/src/components/features
index: apps/web/src/components/features/.pi-map.index.md
## role
Contains reusable React components that implement specific user-facing features and functionality across the web application.
Reusable UI feature components for the web application that compose domain-specific user interface elements.
## files
## arch
Feature-based component organization with domain-specific UI building blocks following React composition patterns, likely co-located with related hooks, utilities, or sub-components for each feature area.
Modular feature-based component organization with domain-specific grouping, likely following atomic design or container/presentational patterns with shared component composition.
## tags
-
## symbols
@@ -2,7 +2,7 @@
dir: apps/web/src/components/features/config-profiles
## role
Provides a complete UI subsystem for managing configuration profiles with desktop and mobile views, supporting CRUD operations, profile relationships, and advanced configuration options.
Provides a complete UI subsystem for managing container configuration profiles across desktop and mobile form factors.
## parent
index: apps/web/src/components/features/.pi-map.index.md
map: apps/web/src/components/features/.pi-map.md
@@ -4,15 +4,15 @@ dir: apps/web/src/components/features/config-profiles
index: apps/web/src/components/features/config-profiles/.pi-map.index.md
## role
Provides a complete UI subsystem for managing configuration profiles with desktop and mobile views, supporting CRUD operations, profile relationships, and advanced configuration options.
Provides a complete UI subsystem for managing container configuration profiles across desktop and mobile form factors.
## files
- ConfigProfileEditorPanel.tsx | React component that renders a form-based editor panel for creating and editing configuration profiles with support for includes, environment variables, runtime hints, files, and mounts. | exp: ConfigProfileEditorPanel | dep: ../../icon, ../git/git-mount-editor, ../../../api/config-profiles, ../../../types, ../../../api/tool-types, React, Icon, GitMountEditor, ConfigProfile, CreateConfigProfileRequest, ResolvedProfile, ProjectWithRepos, ToolType
- ConfigProfileListSidebar.tsx | Renders a sidebar component for listing, selecting, creating, and deleting configuration profiles with visual indicators for default status, scope, and includes. | exp: ConfigProfileListSidebar | dep: ../../icon, ../../../api/config-profiles, Icon, ConfigProfile
- ConfigProfilesMobileView.tsx | Renders a mobile-responsive CRUD interface for managing configuration profiles with list, detail, and edit views. | exp: ConfigProfilesMobileView | dep: ../mobile/mobile-list-view, ../mobile/mobile-detail-view, ../mobile/mobile-edit-view, ../mobile/mobile-fab, ../../icon, ../../../api/config-profiles, MobileListView, MobileDetailView, MobileEditView, MobileFAB, Icon, ConfigProfile, CreateConfigProfileRequest
- ConfigProfilesMobileView.tsx | Renders a mobile-optimized view for managing configuration profiles with list, detail, edit, and preview states. | exp: ConfigProfilesMobileView | dep: react, ../mobile/mobile-list-view, ../mobile/mobile-detail-view, ../mobile/mobile-edit-view, ../mobile/mobile-fab, ../git/git-mount-editor, ../../icon, ../../../api/config-profiles, ../../../types, ../../../api/tool-types, mobile-list-view, mobile-detail-view, mobile-edit-view, mobile-fab, git-mount-editor, icon, config-profiles API types, project types, tool-types API
## arch
Compound component architecture with panel/sidebar split for desktop, dedicated mobile view with state-driven routing, shared state management across list/editor views, and form-based configuration with nested array/object handling for includes, env vars, files, and mounts.
Compound component architecture with state-driven mobile adaptation, separating list navigation from editing concerns with explicit responsive breakpoint handling.
## tags
config, mobile, profiles, profile, view, editor, icon, list
mobile, config, view, profiles, editor, profile, list, icon
## symbols
- ConfigProfileEditorPanel
- ConfigProfileListSidebar
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
dir: apps/web/src/components/features/mobile
## role
Provides mobile-optimized UI components for core application features including navigation, data views, forms, modals, and specialized terminal interfaces.
Provides a complete set of mobile-optimized UI components for building responsive mobile interfaces including navigation, lists, detail/edit views, action sheets, and specialized terminal wrappers.
## parent
index: apps/web/src/components/features/.pi-map.index.md
map: apps/web/src/components/features/.pi-map.md
@@ -4,22 +4,22 @@ dir: apps/web/src/components/features/mobile
index: apps/web/src/components/features/mobile/.pi-map.index.md
## role
Provides mobile-optimized UI components for core application features including navigation, data views, forms, modals, and specialized terminal interfaces.
Provides a complete set of mobile-optimized UI components for building responsive mobile interfaces including navigation, lists, detail/edit views, action sheets, and specialized terminal wrappers.
## files
- mobile-action-sheet.tsx | Renders a mobile-optimized action sheet modal with title, configurable action buttons, and cancel option. | exp: MobileActionSheetItem, func:MobileActionSheet({ isOpen, onClose, title, actions, }: MobileActionSheetProps), call:useRef, call:useEffect, call:onClose, call:document.addEventListener, call:document.removeEventListener, call:e.stopPropagation, call:actions.map, call:action.onClick | dep: react, ../../icon, icon
- mobile-detail-view.tsx | A React component that renders a mobile-optimized detail view with a header (back button, title, edit/delete actions) and a field list supporting multiple value types (text, code, JSON, boolean). | exp: MobileDetailView | dep: ../../icon, react
- mobile-detail-view.tsx | A React component that renders a mobile-optimized detail view with a header, back/edit/delete actions, and a configurable list of typed fields. | exp: MobileDetailView | dep: ../../icon, React
- mobile-edit-view.tsx | A React component that renders a mobile-optimized form for editing data with configurable field types and save/cancel actions. | exp: MobileEditView | dep: react
- mobile-fab.tsx | Renders a floating action button component for mobile with an add icon and configurable click handler and label. | exp: MobileFAB | dep: ../../icon, react, icon
- mobile-list-view.tsx | Renders a mobile-optimized list view with optional search, empty state, and customizable item rendering | exp: MobileListView | dep: react, ../../icon, ../../../utils/icons, icon
- mobile-nav.tsx | Renders a mobile navigation bar with grouped items that open bottom sheets and standard items that use React Router links, including active state indicators and session count badges. | exp: MobileNav | dep: react, react-router-dom, ../../icon, ../tool/tools-bottom-sheet, ./spaces-bottom-sheet, ../../../utils/icons
- mobile-nav.tsx | Renders a mobile navigation bar with grouped items that trigger bottom sheets and standard links with active state highlighting | exp: MobileNav | dep: react, react-router-dom, ../../icon, ../tool/tools-bottom-sheet, ./spaces-bottom-sheet, ../../../utils/icons
- mobile-page-header.tsx | Renders a mobile-only page header with optional back navigation and custom actions. | exp: func:MobilePageHeader({ title, showBack = true, actions }: MobilePageHeaderProps), call:useNavigate, call:useMobileViewport, call:navigate | dep: react-router-dom, ../../../hooks/use-mobile-viewport, ../../icon, use-mobile-viewport hook, Icon component
- mobile-terminal-header.tsx | Renders a mobile-responsive header for a terminal interface with navigation, title, connection status, font size controls, and close actions. | exp: MobileTerminalHeader | dep: react, ../../icon, icon
- mobile-terminal-wrapper.tsx | Wraps a terminal component with mobile-specific UI including auto-hiding header, virtual keyboard handling, and special keys interface. | exp: MobileTerminalWrapper | dep: react, ../terminal/terminal, ./mobile-terminal-header, ../terminal/special-keys-strip, ../terminal/special-keys-panel, ../../../hooks/use-mobile-viewport, ../../../hooks/use-virtual-keyboard, ../../../hooks/use-auto-hide, ../../../hooks/use-special-keys
- spaces-bottom-sheet.tsx | Renders a mobile bottom sheet navigation menu for switching between "Projects" and "Workspaces" spaces with active state highlighting. | exp: SpacesBottomSheet | dep: react-router-dom, ../../icon, icon
## arch
Compositional React component library with feature-specific mobile adaptations, using bottom sheets/action sheets for mobile-native UX patterns, and wrapper components that inject mobile-specific behaviors (auto-hiding headers, virtual keyboard handling) into existing features.
Feature-based component library using compound mobile patterns (bottom sheets, FABs, auto-hiding headers) with typed configurable props and progressive enhancement for touch/keyboard interactions.
## tags
mobile, terminal, sheet, react, icon, view, header, renders
mobile, terminal, sheet, icon, view, react, header, renders
## symbols
- MobileActionSheet
- MobilePageHeader
@@ -13,6 +13,7 @@ interface MobileDetailViewProps {
onEdit: () => void;
onDelete: () => void;
onBack: () => void;
children?: React.ReactNode;
}
export const MobileDetailView: React.FC<MobileDetailViewProps> = ({
@@ -22,6 +23,7 @@ export const MobileDetailView: React.FC<MobileDetailViewProps> = ({
onEdit,
onDelete,
onBack,
children,
}) => {
const renderValue = (field: Field) => {
if (field.value === null || field.value === undefined) {
@@ -90,6 +92,7 @@ export const MobileDetailView: React.FC<MobileDetailViewProps> = ({
</div>
))}
</div>
{children}
</div>
);
};
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web/src/hooks
## role
Provides a collection of reusable React custom hooks that encapsulate domain-specific business logic, API interactions, and UI state management for the web application.
Provides reusable React custom hooks that encapsulate stateful logic, side effects, and API interactions for the web application's UI components, covering data fetching, terminal management, workspace operations, notifications, and mobile-specific behaviors.
## parent
index: apps/web/src/.pi-map.index.md
map: apps/web/src/.pi-map.md
+3 -3
View File
@@ -4,11 +4,11 @@ dir: apps/web/src/hooks
index: apps/web/src/hooks/.pi-map.index.md
## role
Provides a collection of reusable React custom hooks that encapsulate domain-specific business logic, API interactions, and UI state management for the web application.
Provides reusable React custom hooks that encapsulate stateful logic, side effects, and API interactions for the web application's UI components, covering data fetching, terminal management, workspace operations, notifications, and mobile-specific behaviors.
## files
- use-async-data.ts | A custom React hook that manages asynchronous data fetching with loading, error, and ready states, plus a manual reload capability. | exp: func:useAsyncData(fetcher: () => Promise<T>, deps: React.DependencyList) → UseAsyncDataResult<T>, call:useState, call:useCallback, call:setStatus, call:setError, call:fetcher, call:setData, call:load, call:useEffect | dep: react
- use-auto-hide.ts | A React custom hook that automatically hides an element after a specified timeout and provides manual controls for showing, hiding, and toggling visibility. | exp: func:useAutoHide(options: AutoHideOptions), call:useState, call:useRef, call:Date.now, call:useCallback, call:setIsVisible, call:clearTimeout, call:setTimeout, call:hide, call:show, call:useEffect | dep: react
- use-config-profiles.ts | A React custom hook that manages config profile CRUD operations, form state, profile inclusion with cycle detection, and drag-and-drop reordering. | exp: useConfigProfiles | dep: react, ../utils/errors, ../api/config-profiles, ../api/projects, ../api/tool-types, ../types
- use-config-profiles.ts | A React custom hook that manages CRUD operations, form state, drag-and-drop ordering, and cyclic dependency prevention for configuration profiles. | exp: useConfigProfiles | dep: react, ../utils/errors, ../api/config-profiles, ../api/projects, ../api/tool-types, ../types
- use-events.test.ts | Tests a React hook that manages Server-Sent Events (SSE) connections with automatic reconnection, backoff, and error handling | dep: vitest, @testing-library/react, ./use-events, ../api/events, use-events hook
- use-events.ts | React hook that manages a Server-Sent Events connection with automatic exponential backoff reconnection, lifecycle event handling, and authentication redirect on 401 errors. | exp: UseEventsReturn, func:useEvents() → UseEventsReturn, call:useState, call:useRef, call:useCallback, call:clearTimeout, call:createEventSource, call:setConnected, call:setError, call:setReconnectCount, call:JSON.parse, call:setEvents, call:es.addEventListener, call:es.close, call:Math.min, call:Math.pow, call:Math.random, call:setTimeout, call:probeEventStreamStatus, call:window.location.assign, call:connect, call:useEffect, call:esRef.current.close | dep: react, ../api/events, ../types/events
- use-git-repo.ts | A custom React hook that centralizes all git repository operations (branch management, status tracking, commit history, and git actions) into a reusable interface for components. | exp: GitStatus, UseGitRepoResult, func:useGitRepo(projectId: string | undefined, repoId: string | undefined) → UseGitRepoResult, call:useState, call:useCallback, call:setLoading, call:setError, call:fn, call:extractError, call:withLoading, call:listRepositoryBranches, call:setBranches, call:data.branches.map, call:setDefaultBranch, call:getRepositoryStatus, call:setStatus, call:getRepositoryHistory, call:setHistory, call:getCommitDetail, call:setCommitDetail, call:commitChanges, call:refreshStatus, call:pushRepository, call:pullRepository, call:fetchRepository, call:checkoutBranch, call:refreshBranches, call:createBranch, call:deleteBranch, call:mergeBranches, call:refreshHistory, call:useEffect, raise:err | dep: react, ../api/git-repositories
@@ -31,7 +31,7 @@ Provides a collection of reusable React custom hooks that encapsulate domain-spe
- use-workspace-instances.ts | Custom React hook for managing workspace instances with CRUD operations, loading states, and error handling. | exp: UseWorkspaceInstancesResult, func:useWorkspaceInstances(workspaceId: string) → UseWorkspaceInstancesResult, call:useState, call:useCallback, call:setLoading, call:setError, call:listWorkspaceInstances, call:setInstances, call:createWorkspaceInstance, call:refresh, call:useEffect | dep: react, ../api/workspace-instances, ../api/sessions
- use-workspaces.ts | Custom React hook that fetches and manages workspace data with loading and error states. | exp: UseWorkspacesResult, func:useWorkspaces(projectId: string, repoId: string) → UseWorkspacesResult, call:useState, call:useCallback, call:setLoading, call:setError, call:listWorkspaces, call:listAllWorkspaces, call:setWorkspaces, call:useEffect, call:refresh | dep: react, ../api/workspaces, ../types/workspace
## arch
Follows a feature-based composition pattern where each hook is a self-contained unit managing specific concerns (data fetching, CRUD operations, lifecycle management, UI behaviors) using React primitives (useState, useEffect, useCallback) with consistent patterns for loading/error states, optimistic updates, and cleanup; hooks are granular and single-responsibility, often wrapping TanStack Query or direct API calls, with some hooks providing imperative controls and others integrating with browser APIs (SSE, viewport, keyboard, theme).
Follows a custom hook composition pattern where each hook encapsulates a single domain concern (data fetching, CRUD operations, UI state, device detection), often combining useState/useEffect/useCallback with SWR-style async data management, and layering higher-level hooks (use-terminal-page) from lower-level ones (use-mobile-viewport, use-virtual-keyboard).
## tags
call:set, call:use, workspace, react, state, terminal, api, callback
## symbols
+4 -2
View File
@@ -193,7 +193,7 @@ export const useConfigProfiles = () => {
setDragOverIndex(null);
};
const handleSubmit = async (e?: React.FormEvent) => {
const handleSubmit = async (e?: React.FormEvent): Promise<boolean> => {
e?.preventDefault();
setError(null);
setSaveStatus("saving");
@@ -201,7 +201,7 @@ export const useConfigProfiles = () => {
if (!formData.name?.trim()) {
setError("Name is required");
setSaveStatus("error");
return;
return false;
}
try {
@@ -224,9 +224,11 @@ export const useConfigProfiles = () => {
const refreshed = (await listConfigProfiles()).find((p) => p.id === selectedProfile.id);
if (refreshed) populateForm(refreshed);
}
return true;
} catch (err) {
setError(extractErrorMessage(err));
setSaveStatus("error");
return false;
}
};
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web/src/pages
## role
Contains top-level page components that serve as route endpoints for the web application, each managing a distinct functional domain of the developer workspace platform.
Contains top-level page components that render the main application screens for workspace management, project administration, Git operations, user settings, and terminal sessions.
## parent
index: apps/web/src/.pi-map.index.md
map: apps/web/src/.pi-map.md
+4 -4
View File
@@ -4,9 +4,9 @@ dir: apps/web/src/pages
index: apps/web/src/pages/.pi-map.index.md
## role
Contains top-level page components that serve as route endpoints for the web application, each managing a distinct functional domain of the developer workspace platform.
Contains top-level page components that render the main application screens for workspace management, project administration, Git operations, user settings, and terminal sessions.
## files
- ConfigProfilesPage.tsx | Renders a responsive configuration profiles management page with sidebar list and editor panel for desktop, and a dedicated mobile view for creating, editing, and managing config profiles. | exp: ConfigProfilesPage | dep: react, ../components/data-states, ../hooks/use-mobile-viewport, ../hooks/use-config-profiles, ../components/features/config-profiles/ConfigProfileListSidebar, ../components/features/config-profiles/ConfigProfileEditorPanel, ../components/features/config-profiles/ConfigProfilesMobileView
- ConfigProfilesPage.tsx | Renders a configuration profiles management page with responsive desktop/mobile layouts for creating, editing, previewing, and organizing config profiles. | exp: ConfigProfilesPage | dep: react, ../components/data-states, ../hooks/use-mobile-viewport, ../hooks/use-config-profiles, ../components/features/config-profiles/ConfigProfileListSidebar, ../components/features/config-profiles/ConfigProfileEditorPanel, ../components/features/config-profiles/ConfigProfilesMobileView, use-mobile-viewport, use-config-profiles, data-states, ConfigProfileListSidebar, ConfigProfileEditorPanel, ConfigProfilesMobileView
- DashboardPage.test.tsx | Unit tests for the DashboardPage component verifying overview loading and error retry behavior | dep: @testing-library/jest-dom/vitest, @testing-library/react, react-router-dom, vitest, ./DashboardPage, ../state/sessions, DashboardPage, SessionsProvider
- DashboardPage.tsx | Renders a dashboard homepage that displays workspace overview, active/recent sessions, summary statistics, and polling health checks for running instances. | exp: HomePage | dep: react, react-router-dom, ../api/dashboard, ../api/sessions, ../components/data-states, ../components/features/session/session-list, ../hooks/use-instance-actions, ../state/sessions
- GitHistoryPage.tsx | Renders a Git commit history page with branch selection, commit list with graph visualization, and a detail panel showing commit metadata, stats, and diffs. | exp: GitHistoryPage | dep: react, react-router-dom, ../api/git-repositories, ../components/data-states, ../components/icon, ../hooks/use-async-data
@@ -25,9 +25,9 @@ Contains top-level page components that serve as route endpoints for the web app
- WorkspaceDetailPage.tsx | Renders a workspace detail page with tab-based navigation for files, git, tools, and settings panels, with mobile-responsive layout. | exp: func:WorkspaceDetailPage(), call:useParams, call:useState, call:useMobileViewport, call:useWorkspaces, call:workspaces.find | dep: react, react-router-dom, ../hooks/use-workspaces, ../hooks/use-mobile-viewport, ../components/features/workspace/workspace-detail-header, ../components/features/workspace/workspace-tab-bar, ../components/features/workspace/workspace-file-panel, ../components/features/workspace/workspace-git-panel, ../components/features/workspace/workspace-tools-panel, ../components/features/workspace/workspace-settings-panel, use-workspaces, use-mobile-viewport, workspace-detail-header, workspace-tab-bar, workspace-file-panel, workspace-git-panel, workspace-tools-panel, workspace-settings-panel
- WorkspacesPage.tsx | Renders a responsive workspaces management page with mobile and desktop views supporting listing, creating, viewing details, syncing, deleting, and starting tools for workspaces. | exp: func:WorkspacesPage(), call:useMobileViewport, call:useState, call:useWorkspaces, call:useWorkspaceActions, call:actions.delete, call:actions.sync, call:setMobileView, call:refresh, call:setStartWorkspace, call:handleDelete, call:setSelectedWorkspace, call:workspaces.map, call:e.stopPropagation, call:setShowCreate | dep: react, ../components/icon, ../hooks/use-mobile-viewport, ../hooks/use-workspaces, ../hooks/use-workspace-actions, ../components/features/workspace/workspace-card, ../components/features/workspace/workspace-create-form, ../components/features/mobile/mobile-detail-view, ../components/features/mobile/mobile-fab, ../components/features/tool/tool-starter, ../types/workspace
## arch
Follows a page-based routing architecture with responsive mobile/desktop split layouts, heavy use of tabbed navigation and sidebar+editor panel patterns, polling-based real-time data updates, and CRUD-heavy container components with embedded API logic.
Follows a page-based routing architecture with responsive mobile/desktop view splitting, tabbed navigation patterns, polling-based health checks, and CRUD operations backed by API hooks, with co-located test files.
## tags
page, components, workspace, features, react, mobile, hooks, settings
page, components, workspace, features, mobile, react, hooks, settings
## symbols
- WorkspaceDetailPage
- WorkspacesPage
+25 -1
View File
@@ -6,7 +6,7 @@ import { ConfigProfileListSidebar } from "../components/features/config-profiles
import { ConfigProfileEditorPanel } from "../components/features/config-profiles/ConfigProfileEditorPanel";
import { ConfigProfilesMobileView } from "../components/features/config-profiles/ConfigProfilesMobileView";
type MobileView = "list" | "detail" | "edit";
type MobileView = "list" | "detail" | "edit" | "preview";
export const ConfigProfilesPage = () => {
const isMobile = useMobileViewport();
@@ -100,11 +100,18 @@ export const ConfigProfilesPage = () => {
return (
<ConfigProfilesMobileView
profiles={profiles}
projects={projects}
toolTypes={toolTypes}
selectedProfile={selectedProfile}
mobileView={mobileView}
isCreating={isCreating}
formData={formData}
includedProfileIds={includedProfileIds}
availableProfiles={availableProfilesForInclude()}
previewData={previewData}
previewingId={previewingId}
saveStatus={saveStatus}
error={error}
onViewChange={setMobileView}
onSelect={handleSelectProfile}
onCreate={handleCreateNew}
@@ -112,6 +119,23 @@ export const ConfigProfilesPage = () => {
onFormChange={updateFormField}
onSubmit={handleSubmit}
getScopeLabel={getScopeLabel}
getIncludedProfile={getIncludedProfile}
onAddInclude={addInclude}
onRemoveInclude={removeInclude}
onAddEnvVar={addEnvVar}
onUpdateEnvVar={updateEnvVar}
onRemoveEnvVar={removeEnvVar}
onAddFile={addFile}
onUpdateFile={updateFile}
onRemoveFile={removeFile}
onAddMount={addMount}
onUpdateMount={updateMount}
onRemoveMount={removeMount}
onAddMountFile={addMountFile}
onUpdateMountFile={updateMountFile}
onRemoveMountFile={removeMountFile}
onPreview={handlePreview}
onClosePreview={() => setPreviewData(null)}
/>
);
}
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/web/src/styles
## role
Provides the complete visual design system and styling foundation for the web application, encompassing global styles, theme tokens, syntax highlighting, and utility classes.
Houses the complete CSS styling system for the web application, providing design tokens, global styles, component-specific styles, syntax highlighting themes, and responsive utility classes.
## parent
index: apps/web/src/.pi-map.index.md
map: apps/web/src/.pi-map.md
+4 -4
View File
@@ -4,16 +4,16 @@ dir: apps/web/src/styles
index: apps/web/src/styles/.pi-map.index.md
## role
Provides the complete visual design system and styling foundation for the web application, encompassing global styles, theme tokens, syntax highlighting, and utility classes.
Houses the complete CSS styling system for the web application, providing design tokens, global styles, component-specific styles, syntax highlighting themes, and responsive utility classes.
## files
- global.css | Defines global CSS styles for a web application shell layout, navigation, cards, forms, dialogs, settings pages, and responsive design patterns. | dep: CSS custom properties (CSS variables: --border, --panel, --brand, --muted, --ink, --bg, --danger, --success, --warning, --font-size-xs, --font-size-sm, --space-2, --space-3, --space-4, --space-5)
- syntax-highlight.css | Stylesheet for a syntax highlighting component with toolbar, line numbers, code display, and Prism.js theme integration | dep: Prism.js
- tokens.css | Defines a comprehensive CSS design token system with light/dark themes, spacing scales, breakpoints, and fluid typography for a web application.
- utilities.css | Provides responsive CSS utility classes and component-specific styles for a web application featuring terminals, dialogs, tables, forms, and navigation. | dep: CSS custom properties (variables), xterm.js (terminal integration)
- utilities.css | Provides responsive CSS utility classes and component-specific styles for a web application featuring terminals, session management, dialogs, tables, and forms with mobile-first responsive design. | dep: CSS custom properties (variables like --space-*, --border, --bg, --brand, --muted, --success, --danger, --text-xs, --text-sm), xterm.js (terminal library)
## arch
CSS custom properties-based design token architecture with theme-aware variables, modular separation of concerns across global/base/syntax/utility layers, and responsive breakpoint system with fluid typography scaling.
Token-based CSS architecture using CSS custom properties for light/dark theming, mobile-first responsive design with breakpoint scaling, and modular separation of concerns across tokens, globals, utilities, and component-specific stylesheets.
## tags
space, global, css, web, application, syntax, defines, styles
space, global, css, web, application, responsive, design, syntax
## symbols
-
## workflows
+229
View File
@@ -2452,6 +2452,235 @@ a.nav-item,
width: 100% !important;
}
/* Mobile config profile form extras */
.mobile-form-group p {
margin: 0;
}
.mobile-form-row {
display: flex;
align-items: center;
}
.mobile-form-section {
padding: var(--space-3);
background: var(--panel);
border-radius: 8px;
border: 1px solid var(--border);
margin-bottom: var(--space-2);
}
.mobile-form-section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-3);
}
.mobile-form-section-header h4 {
margin: 0;
font-size: 1rem;
}
.mobile-add-button {
width: 100%;
justify-content: center;
margin-top: var(--space-2);
}
.mobile-form-success {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-3);
background: var(--success-light);
color: var(--success);
border-radius: 10px;
font-size: 0.875rem;
margin: var(--space-2) 0;
}
.mobile-list-plain {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.mobile-list-plain li {
padding: var(--space-2);
background: var(--bg);
border-radius: 6px;
font-size: 0.875rem;
}
/* Mobile detail extra actions */
.mobile-detail-actions-extra {
padding: var(--space-3);
padding-top: 0;
margin-top: calc(var(--space-2) * -1);
}
.mobile-detail-actions-extra .secondary-button {
width: 100%;
justify-content: center;
}
/* Mobile includes */
.mobile-includes-list {
display: flex;
flex-direction: column;
gap: var(--space-2);
margin-bottom: var(--space-3);
}
.mobile-include-item {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-3);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
}
.mobile-include-name {
flex: 1;
font-weight: 500;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mobile-include-scope {
font-size: 0.75rem;
padding: 0.125rem 0.5rem;
background: var(--bg);
color: var(--muted);
border-radius: 999px;
text-transform: uppercase;
letter-spacing: 0.025em;
}
/* Mobile key/value rows */
.mobile-key-value-row {
display: flex;
gap: var(--space-2);
align-items: center;
margin-bottom: var(--space-2);
}
.mobile-key-value-row .mobile-form-input {
flex: 1;
}
/* Mobile file and mount cards */
.mobile-file-card,
.mobile-mount-card {
padding: var(--space-3);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
margin-bottom: var(--space-2);
}
.mobile-file-header,
.mobile-mount-header {
display: flex;
gap: var(--space-2);
align-items: center;
margin-bottom: var(--space-2);
}
.mobile-file-header .mobile-form-input,
.mobile-mount-header .mobile-form-input {
flex: 1;
}
.mobile-mount-files {
padding-left: var(--space-3);
border-left: 2px solid var(--border);
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.mobile-mount-file-row {
display: flex;
gap: var(--space-2);
align-items: flex-start;
}
.mobile-mount-file-row .mobile-form-input,
.mobile-mount-file-row .mobile-form-textarea {
flex: 1;
}
/* Mobile preview */
.mobile-preview-code {
background: var(--code-bg, #1e1e1e);
color: var(--code-fg, #d4d4d4);
padding: var(--space-3);
border-radius: 8px;
overflow-x: auto;
font-size: 0.8125rem;
font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco,
Consolas, monospace;
margin: var(--space-2) 0 0 0;
}
.mobile-preview-item {
padding: var(--space-3);
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
margin-bottom: var(--space-2);
font-size: 0.875rem;
}
.mobile-preview-item strong {
display: block;
margin-bottom: var(--space-2);
word-break: break-all;
}
.mobile-preview-mapping {
font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco,
Consolas, monospace;
font-size: 0.8125rem;
color: var(--muted);
margin-top: var(--space-1);
}
/* Mobile git mount editor overrides */
.mobile-form-section .git-mount-editor .card {
padding: var(--space-3);
margin-bottom: var(--space-2);
}
.mobile-form-section .git-mount-editor .form-row {
flex-direction: column;
align-items: stretch;
gap: var(--space-2);
}
.mobile-form-section .git-mount-editor input,
.mobile-form-section .git-mount-editor select,
.mobile-form-section .git-mount-editor textarea {
width: 100%;
}
.mobile-form-section .git-mount-editor .form-actions {
flex-direction: row;
}
.mobile-form-section .git-mount-editor button {
min-height: 44px;
}
/* Ensure minimum touch targets on mobile */
button,
a,
@@ -0,0 +1,34 @@
# Mobile Config Profiles UI Rework
## Goal
Redesign the mobile **Config Profiles** detail ("preview") and edit pages to match the full desktop functionality, following the same mobile UX pattern used for the Tool Workshop.
## Scope
- Rewrite `ConfigProfilesMobileView` so the detail view displays all profile fields and supports resolving/previewing the profile.
- Rewrite the mobile edit view to expose every field available on the desktop editor:
- name, description, project, tool type, default flag
- includes with add/remove/reorder
- environment variables
- runtime hints
- files
- mounts with nested files
- git mounts
- Update `ConfigProfilesPage` to pass the required state and callbacks.
- Update `useConfigProfiles` so `handleSubmit` returns success status for cleaner mobile navigation.
- Add mobile-specific CSS for config profile forms.
## Acceptance Criteria
- On viewports narrower than 768 px, the Config Profiles page renders a mobile-friendly list/detail/edit flow.
- The mobile detail view shows all profile fields and offers a Preview action that displays the resolved profile.
- The mobile edit view supports all desktop fields, including includes, runtime hints, files, mounts, nested mount files, and git mounts.
- All existing desktop functionality remains intact.
- `npm run typecheck` and `npm run lint` pass in `apps/web`.
## Out of Scope
- Backend API changes.
- Changes to other pages.
- New features beyond existing desktop capabilities.
@@ -0,0 +1,10 @@
# Tasks: Mobile Config Profiles UI Rework
- [x] Inspect existing ConfigProfilesMobileView, desktop editor, hook, and page.
- [x] Update `useConfigProfiles.handleSubmit` to return boolean success.
- [x] Rewrite `ConfigProfilesMobileView` detail view with full field display and preview action.
- [x] Rewrite `ConfigProfilesMobileView` edit view with all desktop fields (includes, env vars, runtime hints, files, mounts, git mounts).
- [x] Update `ConfigProfilesPage` to pass required props to mobile view.
- [x] Add responsive CSS for config profile mobile forms.
- [x] Run `npm run typecheck` and `npm run lint` in `apps/web` and fix issues.
- [x] Update project maps for changed files.