-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: content edit #664
base: main
Are you sure you want to change the base?
fix: content edit #664
Changes from 4 commits
83424d8
02c50d7
8112b80
9e02967
044ce6e
fe13e43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,14 +1,15 @@ | ||||||||||||||||
/* | ||||||||||||||||
* Copyright © 2024 Hexastack. All rights reserved. | ||||||||||||||||
* Copyright © 2025 Hexastack. All rights reserved. | ||||||||||||||||
* | ||||||||||||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: | ||||||||||||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. | ||||||||||||||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). | ||||||||||||||||
*/ | ||||||||||||||||
|
||||||||||||||||
import { Dialog, DialogActions, DialogContent } from "@mui/material"; | ||||||||||||||||
import AddIcon from "@mui/icons-material/Add"; | ||||||||||||||||
import { Button, Dialog, DialogActions, DialogContent } from "@mui/material"; | ||||||||||||||||
import { FC, useEffect } from "react"; | ||||||||||||||||
import { useForm } from "react-hook-form"; | ||||||||||||||||
import { useFieldArray, useForm } from "react-hook-form"; | ||||||||||||||||
|
||||||||||||||||
import DialogButtons from "@/app-components/buttons/DialogButtons"; | ||||||||||||||||
import { DialogTitle } from "@/app-components/dialogs/DialogTitle"; | ||||||||||||||||
|
@@ -21,10 +22,10 @@ import { DialogControlProps } from "@/hooks/useDialog"; | |||||||||||||||
import { useToast } from "@/hooks/useToast"; | ||||||||||||||||
import { useTranslate } from "@/hooks/useTranslate"; | ||||||||||||||||
import { EntityType } from "@/services/types"; | ||||||||||||||||
import { | ||||||||||||||||
IContentType, | ||||||||||||||||
IContentTypeAttributes, | ||||||||||||||||
} from "@/types/content-type.types"; | ||||||||||||||||
import { ContentFieldType, IContentType } from "@/types/content-type.types"; | ||||||||||||||||
|
||||||||||||||||
import { FieldInput } from "./components/FieldInput"; | ||||||||||||||||
import { FIELDS_FORM_DEFAULT_VALUES, READ_ONLY_FIELDS } from "./constants"; | ||||||||||||||||
|
||||||||||||||||
export type ContentTypeDialogProps = DialogControlProps<IContentType>; | ||||||||||||||||
export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({ | ||||||||||||||||
|
@@ -37,27 +38,48 @@ export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({ | |||||||||||||||
const { | ||||||||||||||||
handleSubmit, | ||||||||||||||||
register, | ||||||||||||||||
control, | ||||||||||||||||
reset, | ||||||||||||||||
setValue, | ||||||||||||||||
formState: { errors }, | ||||||||||||||||
} = useForm<IContentTypeAttributes>({ | ||||||||||||||||
defaultValues: { name: data?.name || "" }, | ||||||||||||||||
} = useForm<Partial<IContentType>>({ | ||||||||||||||||
defaultValues: { | ||||||||||||||||
name: data?.name || "", | ||||||||||||||||
fields: data?.fields || FIELDS_FORM_DEFAULT_VALUES, | ||||||||||||||||
}, | ||||||||||||||||
}); | ||||||||||||||||
const { append, fields, remove } = useFieldArray({ | ||||||||||||||||
name: "fields", | ||||||||||||||||
control, | ||||||||||||||||
}); | ||||||||||||||||
const CloseAndReset = () => { | ||||||||||||||||
closeDialog(); | ||||||||||||||||
reset(); | ||||||||||||||||
}; | ||||||||||||||||
const { mutateAsync: createContentType } = useCreate( | ||||||||||||||||
EntityType.CONTENT_TYPE, | ||||||||||||||||
{ | ||||||||||||||||
onError: (error) => { | ||||||||||||||||
toast.error(error); | ||||||||||||||||
}, | ||||||||||||||||
onSuccess: () => { | ||||||||||||||||
closeDialog(); | ||||||||||||||||
toast.success(t("message.success_save")); | ||||||||||||||||
}, | ||||||||||||||||
|
||||||||||||||||
useEffect(() => { | ||||||||||||||||
if (open) reset(); | ||||||||||||||||
}, [open, reset]); | ||||||||||||||||
|
||||||||||||||||
useEffect(() => { | ||||||||||||||||
if (data) { | ||||||||||||||||
reset({ | ||||||||||||||||
name: data.name, | ||||||||||||||||
}); | ||||||||||||||||
} else { | ||||||||||||||||
reset(); | ||||||||||||||||
} | ||||||||||||||||
}, [data, reset]); | ||||||||||||||||
|
||||||||||||||||
const { mutate: createContentType } = useCreate(EntityType.CONTENT_TYPE, { | ||||||||||||||||
onError: (error) => { | ||||||||||||||||
toast.error(error); | ||||||||||||||||
}, | ||||||||||||||||
); | ||||||||||||||||
onSuccess: () => { | ||||||||||||||||
closeDialog(); | ||||||||||||||||
toast.success(t("message.success_save")); | ||||||||||||||||
}, | ||||||||||||||||
}); | ||||||||||||||||
const { mutateAsync: updateContentType } = useUpdate( | ||||||||||||||||
EntityType.CONTENT_TYPE, | ||||||||||||||||
{ | ||||||||||||||||
|
@@ -70,36 +92,14 @@ export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({ | |||||||||||||||
}, | ||||||||||||||||
}, | ||||||||||||||||
); | ||||||||||||||||
const validationRules = { | ||||||||||||||||
name: { | ||||||||||||||||
required: t("message.name_is_required"), | ||||||||||||||||
}, | ||||||||||||||||
}; | ||||||||||||||||
const onSubmitForm = async (params: IContentTypeAttributes) => { | ||||||||||||||||
const onSubmitForm = async (params) => { | ||||||||||||||||
if (data) { | ||||||||||||||||
updateContentType({ | ||||||||||||||||
id: data.id, | ||||||||||||||||
params, | ||||||||||||||||
}); | ||||||||||||||||
updateContentType({ id: data.id, params }); | ||||||||||||||||
} else { | ||||||||||||||||
createContentType(params); | ||||||||||||||||
createContentType({ ...params, name: params.name || "" }); | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The content type "name" attribute should not be empty. In which case are getting it empty? |
||||||||||||||||
} | ||||||||||||||||
}; | ||||||||||||||||
|
||||||||||||||||
marrouchi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
useEffect(() => { | ||||||||||||||||
if (open) reset(); | ||||||||||||||||
}, [open, reset]); | ||||||||||||||||
|
||||||||||||||||
useEffect(() => { | ||||||||||||||||
if (data) { | ||||||||||||||||
reset({ | ||||||||||||||||
name: data.name, | ||||||||||||||||
}); | ||||||||||||||||
} else { | ||||||||||||||||
reset(); | ||||||||||||||||
} | ||||||||||||||||
}, [data, reset]); | ||||||||||||||||
|
||||||||||||||||
return ( | ||||||||||||||||
<Dialog open={open} fullWidth onClose={CloseAndReset}> | ||||||||||||||||
<form onSubmit={handleSubmit(onSubmitForm)}> | ||||||||||||||||
|
@@ -112,12 +112,41 @@ export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({ | |||||||||||||||
<Input | ||||||||||||||||
label={t("label.name")} | ||||||||||||||||
error={!!errors.name} | ||||||||||||||||
{...register("name", validationRules.name)} | ||||||||||||||||
helperText={errors.name ? errors.name.message : null} | ||||||||||||||||
{...register("name", { | ||||||||||||||||
required: t("message.name_is_required"), | ||||||||||||||||
})} | ||||||||||||||||
Comment on lines
+114
to
+116
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @IkbelTalebHssan, i have noticed that the input helperText attribute is accidentally removed
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thank you @yassinedorbozgithub for the review 🙏 |
||||||||||||||||
required | ||||||||||||||||
autoFocus | ||||||||||||||||
/> | ||||||||||||||||
</ContentItem> | ||||||||||||||||
|
||||||||||||||||
{fields.map((f, index) => ( | ||||||||||||||||
<ContentItem | ||||||||||||||||
key={f.id} | ||||||||||||||||
display="flex" | ||||||||||||||||
justifyContent="space-between" | ||||||||||||||||
gap={2} | ||||||||||||||||
> | ||||||||||||||||
<FieldInput | ||||||||||||||||
setValue={setValue} | ||||||||||||||||
control={control} | ||||||||||||||||
remove={remove} | ||||||||||||||||
index={index} | ||||||||||||||||
disabled={READ_ONLY_FIELDS.includes(f.label as any)} | ||||||||||||||||
/> | ||||||||||||||||
</ContentItem> | ||||||||||||||||
))} | ||||||||||||||||
<ContentItem> | ||||||||||||||||
<Button | ||||||||||||||||
startIcon={<AddIcon />} | ||||||||||||||||
variant="contained" | ||||||||||||||||
onClick={() => | ||||||||||||||||
append({ label: "", name: "", type: ContentFieldType.TEXT }) | ||||||||||||||||
} | ||||||||||||||||
> | ||||||||||||||||
{t("button.add")} | ||||||||||||||||
</Button> | ||||||||||||||||
</ContentItem> | ||||||||||||||||
</ContentContainer> | ||||||||||||||||
</DialogContent> | ||||||||||||||||
<DialogActions> | ||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a general rule, useEffect() should be place at the end, before the "return"