feat(admin): E2E CRUD/i18n polish, IFT smoke workflow, fix edit payload wiping id. Refs EventHub/EventHubFrontAdmin#33 #37 #38 #39
This commit is contained in:
@@ -118,8 +118,8 @@ const CalendarListPage: React.FC = () => {
|
||||
const original = originalCalendarRef.current;
|
||||
const cleanedValues: Record<string, unknown> = {};
|
||||
|
||||
const allKeys = new Set([...Object.keys(values), ...Object.keys(original)]);
|
||||
allKeys.forEach((key) => {
|
||||
// Only form fields — do not null-out entity keys absent from the form (e.g. id, owner_id).
|
||||
Object.keys(values).forEach((key) => {
|
||||
const newVal = (values as Record<string, unknown>)[key];
|
||||
if (newVal === '' || newVal === undefined || newVal === null) {
|
||||
const origVal = (original as unknown as Record<string, unknown>)[key];
|
||||
@@ -146,19 +146,18 @@ const CalendarListPage: React.FC = () => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (editingCalendar && editModal.open) {
|
||||
originalCalendarRef.current = editingCalendar;
|
||||
const clean = (val: unknown) => (val === '-' || val === 'undefined' ? '' : val);
|
||||
editForm.reset({
|
||||
title: clean(editingCalendar.title) as string,
|
||||
description: clean(editingCalendar.description) as string,
|
||||
type: clean(editingCalendar.type) as string,
|
||||
status: clean(editingCalendar.status) as string,
|
||||
category: clean(editingCalendar.category) as string,
|
||||
reason: clean(editingCalendar.reason) as string,
|
||||
});
|
||||
}
|
||||
}, [editingCalendar, editModal.open, editForm]);
|
||||
if (!editModal.open || loadingCalendar || !editingCalendar) return;
|
||||
originalCalendarRef.current = editingCalendar;
|
||||
const clean = (val: unknown) => (val === '-' || val === 'undefined' ? '' : val);
|
||||
editForm.reset({
|
||||
title: clean(editingCalendar.title) as string,
|
||||
description: clean(editingCalendar.description) as string,
|
||||
type: clean(editingCalendar.type) as string,
|
||||
status: clean(editingCalendar.status) as string,
|
||||
category: clean(editingCalendar.category) as string,
|
||||
reason: clean(editingCalendar.reason) as string,
|
||||
});
|
||||
}, [editingCalendar, editModal.open, loadingCalendar, editForm]);
|
||||
|
||||
const handleDelete = (id: string) => setDeleteConfirm({ open: true, calendarId: id });
|
||||
|
||||
@@ -399,7 +398,7 @@ const CalendarListPage: React.FC = () => {
|
||||
</ExploreListShell>
|
||||
|
||||
<Dialog open={editModal.open} onOpenChange={(open) => !open && setEditModal({ open: false, calendarId: null })}>
|
||||
<DialogContent className="max-w-lg">
|
||||
<DialogContent className="max-w-lg" data-testid="dialog-edit-calendar">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('calendars.editTitle')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -424,7 +423,7 @@ const CalendarListPage: React.FC = () => {
|
||||
name="type"
|
||||
control={editForm.control}
|
||||
render={({ field }) => (
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
<Select value={field.value || undefined} onValueChange={field.onChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('common.selectType')} />
|
||||
</SelectTrigger>
|
||||
@@ -443,7 +442,7 @@ const CalendarListPage: React.FC = () => {
|
||||
control={editForm.control}
|
||||
rules={{ required: true }}
|
||||
render={({ field }) => (
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
<Select value={field.value || undefined} onValueChange={field.onChange}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t('common.selectStatus')} />
|
||||
</SelectTrigger>
|
||||
@@ -470,7 +469,12 @@ const CalendarListPage: React.FC = () => {
|
||||
<Button variant="outline" onClick={() => setEditModal({ open: false, calendarId: null })}>
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button type="submit" form="edit-calendar-form" disabled={editHasErrors || updateCalendar.isPending}>
|
||||
<Button
|
||||
type="submit"
|
||||
form="edit-calendar-form"
|
||||
data-testid="btn-save"
|
||||
disabled={editHasErrors || updateCalendar.isPending}
|
||||
>
|
||||
{t('common.save')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
@@ -478,7 +482,7 @@ const CalendarListPage: React.FC = () => {
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={deleteConfirm.open} onOpenChange={(open) => !open && setDeleteConfirm({ open: false, calendarId: null })}>
|
||||
<DialogContent>
|
||||
<DialogContent data-testid="dialog-delete-calendar">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('calendars.deleteTitle')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -487,7 +491,12 @@ const CalendarListPage: React.FC = () => {
|
||||
<Button variant="outline" onClick={() => setDeleteConfirm({ open: false, calendarId: null })}>
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
<Button variant="destructive" onClick={confirmDelete} disabled={deleteCalendar.isPending}>
|
||||
<Button
|
||||
variant="destructive"
|
||||
data-testid="btn-delete-confirm"
|
||||
onClick={confirmDelete}
|
||||
disabled={deleteCalendar.isPending}
|
||||
>
|
||||
{t('common.delete')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
|
||||
Reference in New Issue
Block a user