ccc62d9324
* feat(github): configurable quick-action presets and PR branch checkout - Add workspace-scoped action presets (icon, label, hint, prompt template) for PRs and Issues, editable from GitHub settings with reset-to-defaults. - When starting a task from a PR, check out the PR head branch directly in the worktree instead of branching off main. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(github): extract action-preset service to keep service.go under line limit Splits the preset CRUD methods out of the oversized service.go and applies prettier formatting to three frontend files flagged by CI. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(github): address review feedback on action presets - Prevent infinite refetch loop when fetching presets fails by tracking attempted workspaces in a ref instead of re-entering the effect on every loading-state change. - Drop unused savePR/saveIssue helpers from the hook; only save() is consumed. - Reorder the init spread in updateGitHubActionPresets/resetGitHubActionPresets so callers can't accidentally overwrite method/body. - Tighten the GitHubActionPreset.icon type with string & {} so known icon keys keep autocomplete. - Sharpen the eye-icon test to assert the exact IconEye mapping. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(github): address second round of review feedback - Seed preset editor drafts from current store state via lazy initializers so a warm mount shows the user's saved customisations instead of silently reverting to defaults when Save is clicked. - Guard Reset button with its own in-flight state to prevent double-firing. - Stop freezing resolved defaults into the stored row on a partial update; persist only what the store has for the untouched kind so future default improvements still reach those workspaces. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * refactor(github): tighten quick-actions editor UI Replace the stacked PR/Issue editors and multi-line preset cards with a tabbed layout and single-line rows. Each row shows icon · label · hint inline; an "Edit prompt" toggle reveals the template textarea only when needed. Drops the redundant section headings, up/down reorder buttons, and verbose template helper label (hint moved into the textarea placeholder). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(github): widen icon select trigger so the icon is visible The icon select trigger had a fixed 40px width which the SelectTrigger's built-in chevron, padding, and icon gap all competed for, clipping the icon out of view. Drop the width override so the trigger sizes to its content. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useCallback, useRef } from "react";
|
|
import {
|
|
fetchGitHubActionPresets,
|
|
updateGitHubActionPresets,
|
|
resetGitHubActionPresets,
|
|
} from "@/lib/api/domains/github-api";
|
|
import { useAppStore } from "@/components/state-provider";
|
|
import type { UpdateGitHubActionPresetsRequest } from "@/lib/types/github";
|
|
|
|
export function useGitHubActionPresets(workspaceId: string | null) {
|
|
const presets = useAppStore((state) =>
|
|
workspaceId ? (state.actionPresets.byWorkspaceId[workspaceId] ?? null) : null,
|
|
);
|
|
const loading = useAppStore((state) =>
|
|
workspaceId ? Boolean(state.actionPresets.loading[workspaceId]) : false,
|
|
);
|
|
const setPresets = useAppStore((state) => state.setActionPresets);
|
|
const setLoading = useAppStore((state) => state.setActionPresetsLoading);
|
|
// Tracks which workspaces we've already attempted a fetch for so a
|
|
// network failure does not cause the effect to re-fire indefinitely.
|
|
const attemptedRef = useRef<Set<string>>(new Set());
|
|
|
|
useEffect(() => {
|
|
if (!workspaceId) return;
|
|
if (presets || attemptedRef.current.has(workspaceId)) return;
|
|
attemptedRef.current.add(workspaceId);
|
|
setLoading(workspaceId, true);
|
|
fetchGitHubActionPresets(workspaceId, { cache: "no-store" })
|
|
.then((response) => {
|
|
if (response) setPresets(workspaceId, response);
|
|
})
|
|
.catch(() => {
|
|
// Leave presets unset on failure; consumers fall back to defaults.
|
|
})
|
|
.finally(() => {
|
|
setLoading(workspaceId, false);
|
|
});
|
|
}, [workspaceId, presets, setPresets, setLoading]);
|
|
|
|
const save = useCallback(
|
|
async (payload: Omit<UpdateGitHubActionPresetsRequest, "workspace_id">) => {
|
|
if (!workspaceId) return null;
|
|
const response = await updateGitHubActionPresets({ workspace_id: workspaceId, ...payload });
|
|
if (response) setPresets(workspaceId, response);
|
|
return response;
|
|
},
|
|
[workspaceId, setPresets],
|
|
);
|
|
|
|
const reset = useCallback(async () => {
|
|
if (!workspaceId) return null;
|
|
const response = await resetGitHubActionPresets(workspaceId);
|
|
if (response) setPresets(workspaceId, response);
|
|
return response;
|
|
}, [workspaceId, setPresets]);
|
|
|
|
return {
|
|
presets,
|
|
loading,
|
|
save,
|
|
reset,
|
|
};
|
|
}
|