feat: refresh shared Git config mounts live

- Use profile-scoped canonical Git clone sources with locked refreshes
- Mount shared Git configuration read-only and isolate profile content
- Add API and desktop/mobile actions for live Git mount refresh

Quality gates: frontend build and backend py_compile passed.
Skipped: backend pytest/Ruff unavailable; Docker/manual checks not approved.
This commit is contained in:
Developer
2026-07-21 14:37:42 +00:00
parent 3c25fffd49
commit 886c863260
11 changed files with 254 additions and 81 deletions
@@ -23,6 +23,7 @@ interface Props {
onSubmit: (e?: React.FormEvent) => void;
onReset: () => void;
onPreview: () => void;
onRefreshGitMounts: () => void;
onAddInclude: (id: string) => void;
onRemoveInclude: (index: number) => void;
onDragStart: (e: React.DragEvent, index: number) => void;
@@ -63,6 +64,7 @@ export const ConfigProfileEditorPanel = ({
onSubmit,
onReset,
onPreview,
onRefreshGitMounts,
onAddInclude,
onRemoveInclude,
onDragStart,
@@ -114,6 +116,9 @@ export const ConfigProfileEditorPanel = ({
</div>
{!isCreating && selectedProfile && (
<div className="row row-sm">
<button className="btn btn-secondary" onClick={onRefreshGitMounts}>
<Icon name="refresh" size="sm" /> Refresh Git mounts
</button>
<button className="btn btn-secondary" onClick={onPreview} disabled={previewingId === selectedProfile.id}>
{previewingId === selectedProfile.id ? (
<><Icon name="loading" size="sm" /> Previewing...</>
@@ -64,6 +64,7 @@ interface Props {
) => void;
onRemoveMountFile: (mountIndex: number, path: string) => void;
onPreview: (id: string) => void;
onRefreshGitMounts: (id: string) => void;
onClosePreview: () => void;
}
@@ -104,6 +105,7 @@ export const ConfigProfilesMobileView = ({
onUpdateMountFile,
onRemoveMountFile,
onPreview,
onRefreshGitMounts,
onClosePreview,
}: Props) => {
const [isSaving, setIsSaving] = useState(false);
@@ -363,6 +365,13 @@ export const ConfigProfilesMobileView = ({
onDelete={handleDeleteClick}
>
<div className="mobile-detail-actions-extra">
<button
type="button"
className="secondary-button"
onClick={() => onRefreshGitMounts(selectedProfile.id)}
>
<Icon name="refresh" size="sm" /> Refresh Git mounts
</button>
<button
type="button"
className="secondary-button"