d7d5baa41a
- Extract use-config-profiles hook for state management - Extract ConfigProfileListSidebar, ConfigProfileEditorPanel, ConfigProfilesMobileView - Slim ConfigProfilesPage from 1,611 to 170 lines Quality gates: tsc --noEmit passes, npm run build passes
171 lines
4.2 KiB
TypeScript
171 lines
4.2 KiB
TypeScript
import { useState } from "react";
|
|
import { ErrorState, LoadingState } from "../components/data-states";
|
|
import { useMobileViewport } from "../hooks/use-mobile-viewport";
|
|
import { useConfigProfiles } from "../hooks/use-config-profiles";
|
|
import { ConfigProfileListSidebar } from "../components/features/config-profiles/ConfigProfileListSidebar";
|
|
import { ConfigProfileEditorPanel } from "../components/features/config-profiles/ConfigProfileEditorPanel";
|
|
import { ConfigProfilesMobileView } from "../components/features/config-profiles/ConfigProfilesMobileView";
|
|
|
|
type MobileView = "list" | "detail" | "edit";
|
|
|
|
export const ConfigProfilesPage = () => {
|
|
const isMobile = useMobileViewport();
|
|
const [mobileView, setMobileView] = useState<MobileView>("list");
|
|
const {
|
|
status,
|
|
profiles,
|
|
projects,
|
|
toolTypes,
|
|
selectedProfile,
|
|
selectedProfileId,
|
|
isCreating,
|
|
saveStatus,
|
|
error,
|
|
previewData,
|
|
previewingId,
|
|
formData,
|
|
includedProfileIds,
|
|
dragOverIndex,
|
|
loadData,
|
|
handleSelectProfile,
|
|
handleCreateNew,
|
|
handleSubmit,
|
|
handleDelete,
|
|
handlePreview,
|
|
updateFormField,
|
|
addEnvVar,
|
|
updateEnvVar,
|
|
removeEnvVar,
|
|
addFile,
|
|
updateFile,
|
|
removeFile,
|
|
addMount,
|
|
updateMount,
|
|
removeMount,
|
|
addMountFile,
|
|
updateMountFile,
|
|
removeMountFile,
|
|
getIncludedProfile,
|
|
getScopeLabel,
|
|
availableProfilesForInclude,
|
|
addInclude,
|
|
removeInclude,
|
|
handleDragStart,
|
|
handleDragOver,
|
|
handleDragLeave,
|
|
handleDrop,
|
|
setPreviewData,
|
|
setFormData,
|
|
setSaveStatus,
|
|
setIncludedProfileIds,
|
|
populateForm,
|
|
} = useConfigProfiles();
|
|
|
|
if (status === "loading") {
|
|
return (
|
|
<div className="container">
|
|
<LoadingState message="Loading Config Profiles..." />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (status === "error") {
|
|
return (
|
|
<div className="container">
|
|
<ErrorState message="Failed to load Config Profiles." onRetry={loadData} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (isMobile) {
|
|
return (
|
|
<ConfigProfilesMobileView
|
|
profiles={profiles}
|
|
selectedProfile={selectedProfile}
|
|
mobileView={mobileView}
|
|
isCreating={isCreating}
|
|
formData={formData}
|
|
saveStatus={saveStatus}
|
|
onViewChange={setMobileView}
|
|
onSelect={handleSelectProfile}
|
|
onCreate={handleCreateNew}
|
|
onDelete={handleDelete}
|
|
onFormChange={updateFormField}
|
|
onSubmit={handleSubmit}
|
|
getScopeLabel={getScopeLabel}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className="container"
|
|
style={{ display: "flex", height: "calc(100vh - 4rem)", gap: 0, padding: 0 }}
|
|
>
|
|
<ConfigProfileListSidebar
|
|
profiles={profiles}
|
|
selectedProfileId={selectedProfileId}
|
|
onSelect={handleSelectProfile}
|
|
onCreate={handleCreateNew}
|
|
onDelete={handleDelete}
|
|
/>
|
|
<ConfigProfileEditorPanel
|
|
isCreating={isCreating}
|
|
selectedProfile={selectedProfile}
|
|
formData={formData}
|
|
includedProfileIds={includedProfileIds}
|
|
dragOverIndex={dragOverIndex}
|
|
error={error}
|
|
saveStatus={saveStatus}
|
|
previewData={previewData}
|
|
previewingId={previewingId}
|
|
projects={projects}
|
|
toolTypes={toolTypes}
|
|
availableProfiles={availableProfilesForInclude()}
|
|
getIncludedProfile={getIncludedProfile}
|
|
getScopeLabel={getScopeLabel}
|
|
onFormChange={updateFormField}
|
|
onSubmit={handleSubmit}
|
|
onReset={() => {
|
|
if (isCreating) {
|
|
setFormData({
|
|
name: "",
|
|
description: "",
|
|
env_vars: {},
|
|
runtime_hints: {},
|
|
mounts: [],
|
|
git_mounts: [],
|
|
files: {},
|
|
is_default: false,
|
|
});
|
|
setIncludedProfileIds([]);
|
|
setSaveStatus("idle");
|
|
} else if (selectedProfile) {
|
|
populateForm(selectedProfile);
|
|
}
|
|
}}
|
|
onPreview={() => selectedProfile && handlePreview(selectedProfile.id)}
|
|
onAddInclude={addInclude}
|
|
onRemoveInclude={removeInclude}
|
|
onDragStart={handleDragStart}
|
|
onDragOver={handleDragOver}
|
|
onDragLeave={handleDragLeave}
|
|
onDrop={handleDrop}
|
|
onAddEnvVar={addEnvVar}
|
|
onUpdateEnvVar={updateEnvVar}
|
|
onRemoveEnvVar={removeEnvVar}
|
|
onAddFile={addFile}
|
|
onUpdateFile={updateFile}
|
|
onRemoveFile={removeFile}
|
|
onAddMount={addMount}
|
|
onUpdateMount={updateMount}
|
|
onRemoveMount={removeMount}
|
|
onAddMountFile={addMountFile}
|
|
onUpdateMountFile={updateMountFile}
|
|
onRemoveMountFile={removeMountFile}
|
|
onClosePreview={() => setPreviewData(null)}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|