diff --git a/src/App.tsx b/src/App.tsx index 0f10251..81c2ccf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -112,19 +112,19 @@ export default function App() { } /> } /> - } /> + } /> } /> } /> } /> - } /> + } /> } /> - } /> + } /> } /> {/* Legacy routes for backward compatibility */} } /> - } /> - } /> - } /> + } /> + } /> + } /> } /> } /> } /> diff --git a/src/components/CreateTaskModal.tsx b/src/components/CreateTaskModal.tsx index 4b21e76..5d70866 100644 --- a/src/components/CreateTaskModal.tsx +++ b/src/components/CreateTaskModal.tsx @@ -18,8 +18,8 @@ type Props = { onClose: () => void onCreated?: (task: Task) => void | Promise onSaved?: (task: Task) => void | Promise - initialProjectId?: number - initialMilestoneId?: number + initialProjectCode?: string + initialMilestoneCode?: string lockProject?: boolean lockMilestone?: boolean task?: Task | null @@ -28,8 +28,8 @@ type Props = { type FormState = { title: string description: string - project_id: number - milestone_id: number + project_code: string + milestone_code: string task_type: string task_subtype: string priority: string @@ -37,11 +37,11 @@ type FormState = { reporter_id: number } -const makeInitialForm = (projectId = 0, milestoneId = 0): FormState => ({ +const makeInitialForm = (projectCode = '', milestoneCode = ''): FormState => ({ title: '', description: '', - project_id: projectId, - milestone_id: milestoneId, + project_code: projectCode, + milestone_code: milestoneCode, task_type: 'issue', // P7.1: default changed from 'task' to 'issue' task_subtype: '', priority: 'medium', @@ -54,8 +54,8 @@ export default function CreateTaskModal({ onClose, onCreated, onSaved, - initialProjectId, - initialMilestoneId, + initialProjectCode, + initialMilestoneCode, lockProject = false, lockMilestone = false, task, @@ -63,7 +63,7 @@ export default function CreateTaskModal({ const [projects, setProjects] = useState([]) const [milestones, setMilestones] = useState([]) const [saving, setSaving] = useState(false) - const [form, setForm] = useState(makeInitialForm(initialProjectId, initialMilestoneId)) + const [form, setForm] = useState(makeInitialForm(initialProjectCode, initialMilestoneCode)) const isEdit = Boolean(task) const currentType = useMemo( @@ -72,18 +72,18 @@ export default function CreateTaskModal({ ) const subtypes = currentType.subtypes || [] - const loadMilestones = async (projectId: number, preferredMilestoneId?: number) => { - if (!projectId) { + const loadMilestones = async (projectCode: string, preferredMilestoneCode?: string) => { + if (!projectCode) { setMilestones([]) - setForm((f) => ({ ...f, milestone_id: 0 })) + setForm((f) => ({ ...f, milestone_code: '' })) return } - const { data } = await api.get(`/milestones?project_id=${projectId}`) + const { data } = await api.get(`/milestones?project_code=${projectCode}`) setMilestones(data) - const hasPreferred = preferredMilestoneId && data.some((m) => m.id === preferredMilestoneId) - const nextMilestoneId = hasPreferred ? preferredMilestoneId! : (data[0]?.id || 0) - setForm((f) => ({ ...f, milestone_id: nextMilestoneId })) + const hasPreferred = preferredMilestoneCode && data.some((m) => m.milestone_code === preferredMilestoneCode) + const nextMilestoneCode = hasPreferred ? preferredMilestoneCode! : (data[0]?.milestone_code || '') + setForm((f) => ({ ...f, milestone_code: nextMilestoneCode })) } useEffect(() => { @@ -93,30 +93,30 @@ export default function CreateTaskModal({ const { data } = await api.get('/projects') setProjects(data) - const chosenProjectId = task?.project_id || initialProjectId || data[0]?.id || 0 - const chosenMilestoneId = task?.milestone_id || initialMilestoneId || 0 + const chosenProjectCode = task?.project_code || initialProjectCode || data[0]?.project_code || '' + const chosenMilestoneCode = task?.milestone_code || initialMilestoneCode || '' setForm(task ? { title: task.title, description: task.description || '', - project_id: task.project_id, - milestone_id: task.milestone_id || 0, + project_code: task.project_code || '', + milestone_code: task.milestone_code || '', task_type: task.task_type, task_subtype: task.task_subtype || '', priority: task.priority, tags: task.tags || '', reporter_id: task.reporter_id, - } : makeInitialForm(chosenProjectId, chosenMilestoneId)) + } : makeInitialForm(chosenProjectCode, chosenMilestoneCode)) - await loadMilestones(chosenProjectId, chosenMilestoneId) + await loadMilestones(chosenProjectCode, chosenMilestoneCode) } init().catch(console.error) - }, [isOpen, initialProjectId, initialMilestoneId, task]) + }, [isOpen, initialProjectCode, initialMilestoneCode, task]) - const handleProjectChange = async (projectId: number) => { - setForm((f) => ({ ...f, project_id: projectId, milestone_id: 0 })) - await loadMilestones(projectId) + const handleProjectChange = async (projectCode: string) => { + setForm((f) => ({ ...f, project_code: projectCode, milestone_code: '' })) + await loadMilestones(projectCode) } const handleTypeChange = (taskType: string) => { @@ -125,7 +125,7 @@ export default function CreateTaskModal({ const submit = async (e: React.FormEvent) => { e.preventDefault() - if (!form.milestone_id) { + if (!form.milestone_code) { alert('Please select a milestone') return } @@ -136,7 +136,7 @@ export default function CreateTaskModal({ setSaving(true) try { const { data } = isEdit - ? await api.patch(`/tasks/${task!.id}`, payload) + ? await api.patch(`/tasks/${task!.task_code}`, payload) : await api.post('/tasks', payload) await onCreated?.(data) await onSaved?.(data) @@ -181,12 +181,12 @@ export default function CreateTaskModal({ Project @@ -195,13 +195,13 @@ export default function CreateTaskModal({ Milestone diff --git a/src/components/MilestoneFormModal.tsx b/src/components/MilestoneFormModal.tsx index 7147dc1..8180959 100644 --- a/src/components/MilestoneFormModal.tsx +++ b/src/components/MilestoneFormModal.tsx @@ -7,14 +7,14 @@ type Props = { onClose: () => void onSaved?: (milestone: Milestone) => void | Promise milestone?: Milestone | null - initialProjectId?: number + initialProjectCode?: string lockProject?: boolean } type FormState = { title: string description: string - project_id: number + project_code: string status: string due_date: string planned_release_date: string @@ -23,7 +23,7 @@ type FormState = { const emptyForm: FormState = { title: '', description: '', - project_id: 0, + project_code: '', status: 'open', due_date: '', planned_release_date: '', @@ -31,7 +31,7 @@ const emptyForm: FormState = { const toDateInput = (value?: string | null) => (value ? String(value).slice(0, 10) : '') -export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone, initialProjectId, lockProject = false }: Props) { +export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone, initialProjectCode, lockProject = false }: Props) { const [projects, setProjects] = useState([]) const [saving, setSaving] = useState(false) const [form, setForm] = useState(emptyForm) @@ -42,11 +42,11 @@ export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone const init = async () => { const { data } = await api.get('/projects') setProjects(data) - const defaultProjectId = milestone?.project_id || initialProjectId || data[0]?.id || 0 + const defaultProjectCode = milestone?.project_code || initialProjectCode || data[0]?.project_code || '' setForm({ title: milestone?.title || '', description: milestone?.description || '', - project_id: defaultProjectId, + project_code: defaultProjectCode, status: milestone?.status || 'open', due_date: toDateInput(milestone?.due_date), planned_release_date: toDateInput(milestone?.planned_release_date), @@ -54,7 +54,7 @@ export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone } init().catch(console.error) - }, [isOpen, milestone, initialProjectId]) + }, [isOpen, milestone, initialProjectCode]) const submit = async (e: React.FormEvent) => { e.preventDefault() @@ -63,13 +63,13 @@ export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone const payload = { title: form.title, description: form.description || null, - project_id: form.project_id, + project_code: form.project_code, status: form.status, due_date: form.due_date || null, planned_release_date: form.planned_release_date || null, } if (milestone) { - const { data } = await api.patch(`/milestones/${milestone.id}`, payload) + const { data } = await api.patch(`/milestones/${milestone.milestone_code}`, payload) await onSaved?.(data) } else { const { data } = await api.post('/milestones', payload) @@ -116,8 +116,8 @@ export default function MilestoneFormModal({ isOpen, onClose, onSaved, milestone
diff --git a/src/pages/CreateTaskPage.tsx b/src/pages/CreateTaskPage.tsx index 374d955..dd07085 100644 --- a/src/pages/CreateTaskPage.tsx +++ b/src/pages/CreateTaskPage.tsx @@ -19,7 +19,7 @@ export default function CreateTaskPage() { const [projects, setProjects] = useState([]) const [milestones, setMilestones] = useState([]) const [form, setForm] = useState({ - title: '', description: '', project_id: 0, milestone_id: 0, task_type: 'issue', // P7.1: default changed from 'task' to 'issue' + title: '', description: '', project_code: '', milestone_code: '', task_type: 'issue', // P7.1: default changed from 'task' to 'issue' task_subtype: '', priority: 'medium', tags: '', reporter_id: 1, }) @@ -27,21 +27,21 @@ export default function CreateTaskPage() { api.get('/projects').then(({ data }) => { setProjects(data) if (data.length) { - setForm((f) => ({ ...f, project_id: data[0].id })) + setForm((f) => ({ ...f, project_code: data[0].project_code || '' })) // Load milestones for the first project - api.get(`/milestones?project_id=${data[0].id}`).then(({ data: ms }) => { + api.get(`/milestones?project_code=${data[0].project_code}`).then(({ data: ms }) => { setMilestones(ms) - if (ms.length) setForm((f) => ({ ...f, milestone_id: ms[0].id })) + if (ms.length) setForm((f) => ({ ...f, milestone_code: ms[0].milestone_code || '' })) }) } }) }, []) - const handleProjectChange = (projectId: number) => { - setForm(f => ({ ...f, project_id: projectId, milestone_id: 0 })) - api.get(`/milestones?project_id=${projectId}`).then(({ data: ms }) => { + const handleProjectChange = (projectCode: string) => { + setForm(f => ({ ...f, project_code: projectCode, milestone_code: '' })) + api.get(`/milestones?project_code=${projectCode}`).then(({ data: ms }) => { setMilestones(ms) - if (ms.length) setForm((f) => ({ ...f, milestone_id: ms[0].id })) + if (ms.length) setForm((f) => ({ ...f, milestone_code: ms[0].milestone_code || '' })) }) } @@ -54,7 +54,7 @@ export default function CreateTaskPage() { const submit = async (e: React.FormEvent) => { e.preventDefault() - if (!form.milestone_id) { + if (!form.milestone_code) { alert('Please select a milestone') return } @@ -71,14 +71,14 @@ export default function CreateTaskPage() {