From e601618abdba6fcb0dc7517025f271ef230f4aa2 Mon Sep 17 00:00:00 2001 From: yassinedorbozgithub Date: Sat, 25 Jan 2025 14:30:09 +0100 Subject: [PATCH] fix: update modals logic --- frontend/public/locales/en/translation.json | 1 + frontend/public/locales/fr/translation.json | 1 + .../attachment/AttachmentThumbnail.tsx | 7 +-- .../attachment/AttachmentUploader.tsx | 6 ++- .../app-components/dialogs/DeleteDialog.tsx | 36 +++++++++------ .../src/app-components/dialogs/MoveDialog.tsx | 6 ++- frontend/src/components/Menu/index.tsx | 9 ++-- .../components/categories/CategoryDialog.tsx | 19 ++++---- frontend/src/components/categories/index.tsx | 18 ++++---- .../content-types/ContentTypeDialog.tsx | 21 +++++---- .../EditContentTypeFieldsDialog.tsx | 19 ++++---- .../src/components/content-types/index.tsx | 7 +-- .../src/components/contents/ContentDialog.tsx | 5 +-- .../contents/ContentImportDialog.tsx | 11 +++-- frontend/src/components/contents/index.tsx | 9 ++-- .../context-vars/ContextVarDialog.tsx | 29 ++++++------ .../src/components/context-vars/index.tsx | 17 +++---- .../src/components/labels/LabelDialog.tsx | 27 ++++++------ frontend/src/components/labels/index.tsx | 7 +-- .../components/languages/LanguageDialog.tsx | 27 ++++++------ frontend/src/components/languages/index.tsx | 7 +-- .../src/components/nlp/NlpEntityDialog.tsx | 31 ++++++------- .../src/components/nlp/NlpSampleDialog.tsx | 11 ++--- .../src/components/nlp/NlpValueDialog.tsx | 44 +++++++++++-------- .../components/nlp/components/NlpEntity.tsx | 16 ++++--- .../components/nlp/components/NlpSample.tsx | 15 ++++--- .../components/nlp/components/NlpValues.tsx | 18 ++++---- .../components/roles/PermissionsDialog.tsx | 30 ++++++------- frontend/src/components/roles/RoleDialog.tsx | 17 +++---- frontend/src/components/roles/index.tsx | 7 +-- .../subscribers/EditSubscriberDialog.tsx | 17 +++---- .../translations/EditTranslationDialog.tsx | 15 ++++--- .../src/components/translations/index.tsx | 7 +-- .../src/components/users/EditUserDialog.tsx | 19 ++++---- .../components/visual-editor/BlockDialog.tsx | 5 ++- .../components/visual-editor/v2/Diagrams.tsx | 31 +++++++------ frontend/src/hooks/useDialog.tsx | 35 ++++++++++----- 37 files changed, 334 insertions(+), 273 deletions(-) diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index dd9bad2a..a65a18bc 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -44,6 +44,7 @@ "account_disabled": "Your account has been either disabled or is pending confirmation.", "success_invitation_sent": "Invitation to join has been successfully sent.", "item_delete_confirm": "Are you sure you want to delete this item?", + "items_delete_confirm": "Are you sure you want to delete those {{0}} selected items?", "item_delete_success": "Item has been deleted successfully", "success_save": "Changes has been saved!", "no_result_found": "No result found", diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json index 7ce2c0dd..53b421dc 100644 --- a/frontend/public/locales/fr/translation.json +++ b/frontend/public/locales/fr/translation.json @@ -44,6 +44,7 @@ "account_disabled": "Votre compte a été désactivé ou est en attente de confirmation.", "success_invitation_sent": "L'invitation a été envoyée avec succès.", "item_delete_confirm": "Êtes-vous sûr de bien vouloir supprimer cet élément?", + "items_delete_confirm": "Êtes-vous sûr de bien vouloir supprimer ces {{0}} éléments sélectionnés?", "item_delete_success": "L'élément a été supprimé avec succès", "success_save": "Les modifications ont été enregistrées!", "no_result_found": "Aucun résultat trouvé", diff --git a/frontend/src/app-components/attachment/AttachmentThumbnail.tsx b/frontend/src/app-components/attachment/AttachmentThumbnail.tsx index 8ce6e53b..31bb996b 100644 --- a/frontend/src/app-components/attachment/AttachmentThumbnail.tsx +++ b/frontend/src/app-components/attachment/AttachmentThumbnail.tsx @@ -1,11 +1,12 @@ /* - * 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 CancelOutlinedIcon from "@mui/icons-material/CancelOutlined"; import DeleteOutlineOutlinedIcon from "@mui/icons-material/DeleteOutlineOutlined"; import FileOpenIcon from "@mui/icons-material/FileOpen"; @@ -84,7 +85,7 @@ const AttachmentThumbnail: FC = ({ }); const { toast } = useToast(); const { t } = useTranslate(); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); if (!attachment) { return t("message.attachment_not_found") + id; @@ -141,7 +142,7 @@ const AttachmentThumbnail: FC = ({ variant="contained" startIcon={} onClick={(e) => { - deleteDialogCtl.openDialog([attachment.id]); + deleteDialogCtl.openDialog(attachment.id); e.preventDefault(); e.stopPropagation(); }} diff --git a/frontend/src/app-components/attachment/AttachmentUploader.tsx b/frontend/src/app-components/attachment/AttachmentUploader.tsx index d90ed38e..2aef713d 100644 --- a/frontend/src/app-components/attachment/AttachmentUploader.tsx +++ b/frontend/src/app-components/attachment/AttachmentUploader.tsx @@ -94,7 +94,7 @@ const AttachmentUploader: FC = ({ onUploadComplete && onUploadComplete(); }, }); - const libraryDialogCtl = useDialog(false); + const libraryDialogCtl = useDialog(false); const stopDefaults = (e: DragEvent) => { e.stopPropagation(); e.preventDefault(); @@ -140,7 +140,9 @@ const AttachmentUploader: FC = ({ { + if (!Array.isArray(data)) onChange?.(data); + }} accept={accept} /> diff --git a/frontend/src/app-components/dialogs/DeleteDialog.tsx b/frontend/src/app-components/dialogs/DeleteDialog.tsx index 9d9c1248..5ab5fdfd 100644 --- a/frontend/src/app-components/dialogs/DeleteDialog.tsx +++ b/frontend/src/app-components/dialogs/DeleteDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 ErrorIcon from "@mui/icons-material/Error"; import { Button, @@ -24,10 +25,11 @@ import { useTranslate } from "@/hooks/useTranslate"; import { EntityType } from "@/services/types"; import { IEntityMapTypes } from "@/types/base.types"; -export type DeleteDialogProps = DialogControl; -export const DeleteDialog = ({ +export type DeleteDialogProps = DialogControl; +export const DeleteDialog = ({ open, closeDialog: closeFunction, + datum, data: ids, callback, entity = EntityType.ATTACHMENT, @@ -40,6 +42,9 @@ export const DeleteDialog = ({ onDeleteSuccess?: (data?: unknown) => void; }) => { const { t } = useTranslate(); + const getItemsFromData = (data: unknown) => (Array.isArray(data) ? data : []); + const hasMultipleItems = (data: unknown): boolean => + getItemsFromData(data).length > 1; const onSuccess = (data: unknown) => { setData?.(undefined); onDeleteSuccess(data); @@ -62,7 +67,16 @@ export const DeleteDialog = ({ - {t("message.item_delete_confirm")} + + {t( + `${ + hasMultipleItems(ids) + ? "message.items_delete_confirm" + : "message.item_delete_confirm" + }`, + { "0": getItemsFromData(ids).length.toString() }, + )} + @@ -73,16 +87,10 @@ export const DeleteDialog = ({ onClick={async () => { if (callback) { callback(ids); - } else { - if (!Array.isArray(ids)) { - throw new Error("IDs need to be an Array"); - } else if (ids.length === 0) { - throw new Error("IDs cannot be empty"); - } else if (ids.length === 1) { - await deleteOne(ids[0]); - } else if (ids.length > 1) { - await deleteMany(ids); - } + } else if (Array.isArray(ids)) { + await deleteMany(ids); + } else if (datum) { + await deleteOne(datum); } }} autoFocus diff --git a/frontend/src/app-components/dialogs/MoveDialog.tsx b/frontend/src/app-components/dialogs/MoveDialog.tsx index ea92aa42..37de74ae 100644 --- a/frontend/src/app-components/dialogs/MoveDialog.tsx +++ b/frontend/src/app-components/dialogs/MoveDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { Button, Dialog, @@ -22,7 +23,8 @@ import { DialogControl } from "@/hooks/useDialog"; import { useTranslate } from "@/hooks/useTranslate"; import { ICategory } from "@/types/category.types"; -export interface MoveDialogProps extends DialogControl { +export interface MoveDialogProps + extends Omit, "callback"> { categories: ICategory[]; callback?: (newCategoryId?: string) => Promise; openDialog: (data?: string) => void; diff --git a/frontend/src/components/Menu/index.tsx b/frontend/src/components/Menu/index.tsx index bab6d447..c8877528 100644 --- a/frontend/src/components/Menu/index.tsx +++ b/frontend/src/components/Menu/index.tsx @@ -1,15 +1,16 @@ /* - * 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 { faBars } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; -import { Grid, Paper, Button, Box, debounce } from "@mui/material"; -import React, { useRef, useState } from "react"; +import { Box, Button, debounce, Grid, Paper } from "@mui/material"; +import { useRef, useState } from "react"; import { DeleteDialog } from "@/app-components/dialogs/DeleteDialog"; import { NoDataOverlay } from "@/app-components/tables/NoDataOverlay"; @@ -165,7 +166,7 @@ export const Menu = () => { open={deleteDialogOpened} openDialog={() => setDeleteDialogOpened(true)} closeDialog={() => setDeleteDialogOpened(false)} - callback={() => { + callback={async () => { if (deleteRowId) { deleteMenu(deleteRowId); } diff --git a/frontend/src/components/categories/CategoryDialog.tsx b/frontend/src/components/categories/CategoryDialog.tsx index 8a2b69ec..bbf63963 100644 --- a/frontend/src/components/categories/CategoryDialog.tsx +++ b/frontend/src/components/categories/CategoryDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { FC, useEffect } from "react"; import { useForm } from "react-hook-form"; @@ -27,7 +28,7 @@ export type CategoryDialogProps = DialogControlProps; export const CategoryDialog: FC = ({ open, - data, + datum: category, closeDialog, ...rest }) => { @@ -57,7 +58,7 @@ export const CategoryDialog: FC = ({ formState: { errors }, handleSubmit, } = useForm({ - defaultValues: { label: data?.label || "" }, + defaultValues: { label: category?.label || "" }, }); const validationRules = { label: { @@ -65,8 +66,8 @@ export const CategoryDialog: FC = ({ }, }; const onSubmitForm = async (params: ICategoryAttributes) => { - if (data) { - updateCategory({ id: data.id, params }); + if (category) { + updateCategory({ id: category.id, params }); } else { createCategory(params); } @@ -77,20 +78,20 @@ export const CategoryDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (category) { reset({ - label: data.label, + label: category.label, }); } else { reset(); } - }, [data, reset]); + }, [category, reset]); return (
- {data ? t("title.edit_category") : t("title.new_category")} + {category ? t("title.edit_category") : t("title.new_category")} diff --git a/frontend/src/components/categories/index.tsx b/frontend/src/components/categories/index.tsx index 176b9cb1..7a0c2528 100644 --- a/frontend/src/components/categories/index.tsx +++ b/frontend/src/components/categories/index.tsx @@ -1,16 +1,17 @@ /* - * 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 AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import FolderIcon from "@mui/icons-material/Folder"; import { Button, Grid, Paper } from "@mui/material"; -import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { DeleteDialog } from "@/app-components/dialogs/DeleteDialog"; import { FilterTextfield } from "@/app-components/inputs/FilterTextfield"; @@ -40,7 +41,7 @@ export const Categories = () => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const hasPermission = useHasPermission(); const { onSearch, searchPayload } = useSearch({ $iLike: ["label"], @@ -61,7 +62,7 @@ export const Categories = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], @@ -101,8 +102,6 @@ export const Categories = () => { }, actionColumns, ]; - const handleSelectionChange = (selection: GridRowSelectionModel) => - deleteDialogCtl.setData?.(selection as string[]); return ( @@ -150,7 +149,7 @@ export const Categories = () => { variant="contained" color="error" onClick={() => deleteDialogCtl.openDialog()} - disabled={!deleteDialogCtl.data?.length} + disabled={!deleteDialogCtl.data?.length || deleteDialogCtl.open} > {t("button.delete")} @@ -165,7 +164,10 @@ export const Categories = () => { columns={columns} {...dataGridProps} checkboxSelection - onRowSelectionModelChange={handleSelectionChange} + rowSelectionModel={deleteDialogCtl.data || []} + onRowSelectionModelChange={(rowSelectionModel) => + deleteDialogCtl.setData?.(rowSelectionModel as string[]) + } /> diff --git a/frontend/src/components/content-types/ContentTypeDialog.tsx b/frontend/src/components/content-types/ContentTypeDialog.tsx index ebe33bb7..7f6cf6df 100644 --- a/frontend/src/components/content-types/ContentTypeDialog.tsx +++ b/frontend/src/components/content-types/ContentTypeDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { FC, useEffect } from "react"; import { useForm } from "react-hook-form"; @@ -29,7 +30,7 @@ import { export type ContentTypeDialogProps = DialogControlProps; export const ContentTypeDialog: FC = ({ open, - data, + datum: contentType, closeDialog, }) => { const { toast } = useToast(); @@ -40,7 +41,7 @@ export const ContentTypeDialog: FC = ({ reset, formState: { errors }, } = useForm({ - defaultValues: { name: data?.name || "" }, + defaultValues: { name: contentType?.name || "" }, }); const CloseAndReset = () => { closeDialog(); @@ -76,9 +77,9 @@ export const ContentTypeDialog: FC = ({ }, }; const onSubmitForm = async (params: IContentTypeAttributes) => { - if (data) { + if (contentType) { updateContentType({ - id: data.id, + id: contentType.id, params, }); } else { @@ -91,20 +92,22 @@ export const ContentTypeDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (contentType) { reset({ - name: data.name, + name: contentType.name, }); } else { reset(); } - }, [data, reset]); + }, [contentType, reset]); return ( - {data ? t("title.edit_content_type") : t("title.new_content_type")} + {contentType + ? t("title.edit_content_type") + : t("title.new_content_type")} diff --git a/frontend/src/components/content-types/EditContentTypeFieldsDialog.tsx b/frontend/src/components/content-types/EditContentTypeFieldsDialog.tsx index a2437e75..dd692040 100644 --- a/frontend/src/components/content-types/EditContentTypeFieldsDialog.tsx +++ b/frontend/src/components/content-types/EditContentTypeFieldsDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 AddIcon from "@mui/icons-material/Add"; import { Button, @@ -20,9 +21,9 @@ import { useFieldArray, useForm } from "react-hook-form"; import DialogButtons from "@/app-components/buttons/DialogButtons"; import { - DialogTitle, ContentContainer, ContentItem, + DialogTitle, } from "@/app-components/dialogs"; import { Input } from "@/app-components/inputs/Input"; import { useGet } from "@/hooks/crud/useGet"; @@ -39,9 +40,9 @@ import { FIELDS_FORM_DEFAULT_VALUES, READ_ONLY_FIELDS } from "./constants"; export type EditContentTypeDialogFieldsProps = DialogControlProps; export const EditContentTypeFieldsDialog = ({ - data: contentType, - closeDialog, open, + datum: contentType, + closeDialog, }: EditContentTypeDialogFieldsProps) => { const { t } = useTranslate(); const { isLoading, data, refetch } = useGet(contentType?.id || "", { @@ -113,10 +114,6 @@ export const EditContentTypeFieldsDialog = ({ } }, [data, reset]); - function handleClose() { - closeDialog(); - } - const { mutateAsync: updateContentType } = useUpdate( EntityType.CONTENT_TYPE, { @@ -135,9 +132,9 @@ export const EditContentTypeFieldsDialog = ({ fullWidth maxWidth="xl" sx={{ width: "fit-content", mx: "auto", minWidth: "600px" }} - onClose={handleClose} + onClose={closeDialog} > - + {t("title.manage_fields")} diff --git a/frontend/src/components/content-types/index.tsx b/frontend/src/components/content-types/index.tsx index d2e0cc38..8233fa8e 100644 --- a/frontend/src/components/content-types/index.tsx +++ b/frontend/src/components/content-types/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { faAlignLeft } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import { Button, Grid, Paper } from "@mui/material"; @@ -41,7 +42,7 @@ export const ContentTypes = () => { // Dialog Controls const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); // data fetching const { onSearch, searchPayload } = useSearch({ $iLike: ["name"], @@ -67,7 +68,7 @@ export const ContentTypes = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], diff --git a/frontend/src/components/contents/ContentDialog.tsx b/frontend/src/components/contents/ContentDialog.tsx index 164e69aa..435e23b0 100644 --- a/frontend/src/components/contents/ContentDialog.tsx +++ b/frontend/src/components/contents/ContentDialog.tsx @@ -6,7 +6,6 @@ * 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 LinkIcon from "@mui/icons-material/Link"; import { Dialog, @@ -146,11 +145,11 @@ export type ContentDialogProps = DialogControlProps<{ }>; export const ContentDialog: FC = ({ open, - data, + datum, closeDialog, ...rest }) => { - const { content, contentType } = data || { + const { content, contentType } = datum || { content: undefined, contentType: undefined, }; diff --git a/frontend/src/components/contents/ContentImportDialog.tsx b/frontend/src/components/contents/ContentImportDialog.tsx index ddf613bb..17b79b4b 100644 --- a/frontend/src/components/contents/ContentImportDialog.tsx +++ b/frontend/src/components/contents/ContentImportDialog.tsx @@ -6,7 +6,6 @@ * 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 CloseIcon from "@mui/icons-material/Close"; import { Button, Dialog, DialogActions, DialogContent } from "@mui/material"; import { FC, useState } from "react"; @@ -29,7 +28,7 @@ export type ContentImportDialogProps = DialogControlProps<{ export const ContentImportDialog: FC = ({ open, - data, + datum, closeDialog, ...rest }) => { @@ -38,10 +37,10 @@ export const ContentImportDialog: FC = ({ const { toast } = useToast(); const { apiClient } = useApiClient(); const { refetch, isFetching } = useQuery( - ["importContent", data?.contentType?.id, attachmentId], + ["importContent", datum?.contentType?.id, attachmentId], async () => { - if (data?.contentType?.id && attachmentId) { - await apiClient.importContent(data.contentType.id, attachmentId); + if (datum?.contentType?.id && attachmentId) { + await apiClient.importContent(datum.contentType.id, attachmentId); } }, { @@ -63,7 +62,7 @@ export const ContentImportDialog: FC = ({ setAttachmentId(null); }; const handleImportClick = () => { - if (attachmentId && data?.contentType?.id) { + if (attachmentId && datum?.contentType?.id) { refetch(); } }; diff --git a/frontend/src/components/contents/index.tsx b/frontend/src/components/contents/index.tsx index 54ffc8d8..d1e2cf2c 100644 --- a/frontend/src/components/contents/index.tsx +++ b/frontend/src/components/contents/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { faAlignLeft } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; @@ -53,7 +54,7 @@ export const Contents = () => { content?: IContent; contentType?: IContentType; }>(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); // data fetching const { onSearch, searchPayload } = useSearch({ $eq: [{ entity: String(query.id) }], @@ -95,7 +96,7 @@ export const Contents = () => { }, { label: ActionColumnLabel.Delete, - action: (content) => deleteDialogCtl.openDialog([content.id]), + action: (content) => deleteDialogCtl.openDialog(content.id), requires: [PermissionAction.DELETE], }, ], @@ -156,7 +157,7 @@ export const Contents = () => { { + callback={async () => { refetch(); }} /> diff --git a/frontend/src/components/context-vars/ContextVarDialog.tsx b/frontend/src/components/context-vars/ContextVarDialog.tsx index b894eae1..c6d13c5f 100644 --- a/frontend/src/components/context-vars/ContextVarDialog.tsx +++ b/frontend/src/components/context-vars/ContextVarDialog.tsx @@ -1,11 +1,12 @@ /* - * 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, @@ -34,7 +35,7 @@ import { slugify } from "@/utils/string"; export type ContextVarDialogProps = DialogControlProps; export const ContextVarDialog: FC = ({ open, - data, + datum: contextVar, closeDialog, ...rest }) => { @@ -67,9 +68,9 @@ export const ContextVarDialog: FC = ({ control, } = useForm({ defaultValues: { - name: data?.name || "", - label: data?.label || "", - permanent: data?.permanent || false, + name: contextVar?.name || "", + label: contextVar?.label || "", + permanent: contextVar?.permanent || false, }, }); const validationRules = { @@ -84,8 +85,8 @@ export const ContextVarDialog: FC = ({ }, }; const onSubmitForm = async (params: IContextVarAttributes) => { - if (data) { - updateContextVar({ id: data.id, params }); + if (contextVar) { + updateContextVar({ id: contextVar.id, params }); } else { createContextVar(params); } @@ -96,22 +97,24 @@ export const ContextVarDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (contextVar) { reset({ - label: data.label, - name: data.name, - permanent: data.permanent, + label: contextVar.label, + name: contextVar.name, + permanent: contextVar.permanent, }); } else { reset(); } - }, [data, reset]); + }, [contextVar, reset]); return ( - {data ? t("title.edit_context_var") : t("title.new_context_var")} + {contextVar + ? t("title.edit_context_var") + : t("title.new_context_var")} diff --git a/frontend/src/components/context-vars/index.tsx b/frontend/src/components/context-vars/index.tsx index 506d6a81..78767e72 100644 --- a/frontend/src/components/context-vars/index.tsx +++ b/frontend/src/components/context-vars/index.tsx @@ -1,16 +1,17 @@ /* - * 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 { faAsterisk } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import { Button, Grid, Paper, Switch } from "@mui/material"; -import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { DeleteDialog } from "@/app-components/dialogs/DeleteDialog"; import { FilterTextfield } from "@/app-components/inputs/FilterTextfield"; @@ -40,7 +41,7 @@ export const ContextVars = () => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const hasPermission = useHasPermission(); const { onSearch, searchPayload } = useSearch({ $iLike: ["label"], @@ -69,7 +70,7 @@ export const ContextVars = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], @@ -133,14 +134,11 @@ export const ContextVars = () => { }, actionColumns, ]; - const handleSelectionChange = (selection: GridRowSelectionModel) => - deleteDialogCtl.setData?.(selection as string[]); return ( - { columns={columns} {...dataGridProps} checkboxSelection - onRowSelectionModelChange={handleSelectionChange} + rowSelectionModel={deleteDialogCtl.data || []} + onRowSelectionModelChange={(rowSelectionModel) => + deleteDialogCtl.setData?.(rowSelectionModel as string[]) + } /> diff --git a/frontend/src/components/labels/LabelDialog.tsx b/frontend/src/components/labels/LabelDialog.tsx index 3c9b50a5..c02e4d39 100644 --- a/frontend/src/components/labels/LabelDialog.tsx +++ b/frontend/src/components/labels/LabelDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { FC, useEffect } from "react"; import { useForm } from "react-hook-form"; @@ -27,7 +28,7 @@ import { slugify } from "@/utils/string"; export type LabelDialogProps = DialogControlProps; export const LabelDialog: FC = ({ open, - data, + datum: label, closeDialog, ...rest }) => { @@ -59,9 +60,9 @@ export const LabelDialog: FC = ({ handleSubmit, } = useForm({ defaultValues: { - name: data?.name || "", - title: data?.title || "", - description: data?.description || "", + name: label?.name || "", + title: label?.title || "", + description: label?.description || "", }, }); const validationRules = { @@ -72,8 +73,8 @@ export const LabelDialog: FC = ({ description: {}, }; const onSubmitForm = async (params: ILabelAttributes) => { - if (data) { - updateLabel({ id: data.id, params }); + if (label) { + updateLabel({ id: label.id, params }); } else { createLabel(params); } @@ -84,22 +85,22 @@ export const LabelDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (label) { reset({ - name: data.name, - title: data.title, - description: data.description, + name: label.name, + title: label.title, + description: label.description, }); } else { reset(); } - }, [data, reset]); + }, [label, reset]); return ( - {data ? t("title.edit_label") : t("title.new_label")} + {label ? t("title.edit_label") : t("title.new_label")} diff --git a/frontend/src/components/labels/index.tsx b/frontend/src/components/labels/index.tsx index 9c7e6977..806ceaa8 100644 --- a/frontend/src/components/labels/index.tsx +++ b/frontend/src/components/labels/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { faTags } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import { Button, Grid, Paper } from "@mui/material"; @@ -38,7 +39,7 @@ export const Labels = () => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const hasPermission = useHasPermission(); const { onSearch, searchPayload } = useSearch({ $or: ["name", "title"], @@ -59,7 +60,7 @@ export const Labels = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], diff --git a/frontend/src/components/languages/LanguageDialog.tsx b/frontend/src/components/languages/LanguageDialog.tsx index 14012bc9..6f6c47e1 100644 --- a/frontend/src/components/languages/LanguageDialog.tsx +++ b/frontend/src/components/languages/LanguageDialog.tsx @@ -1,11 +1,12 @@ /* - * 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, @@ -32,7 +33,7 @@ import { ILanguage, ILanguageAttributes } from "@/types/language.types"; export type LanguageDialogProps = DialogControlProps; export const LanguageDialog: FC = ({ open, - data, + datum: language, closeDialog, ...rest }) => { @@ -64,9 +65,9 @@ export const LanguageDialog: FC = ({ control, } = useForm({ defaultValues: { - title: data?.title || "", - code: data?.code || "", - isRTL: data?.isRTL || false, + title: language?.title || "", + code: language?.code || "", + isRTL: language?.isRTL || false, }, }); const validationRules = { @@ -78,8 +79,8 @@ export const LanguageDialog: FC = ({ }, }; const onSubmitForm = async (params: ILanguageAttributes) => { - if (data) { - updateLanguage({ id: data.id, params }); + if (language) { + updateLanguage({ id: language.id, params }); } else { createLanguage(params); } @@ -90,22 +91,22 @@ export const LanguageDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (language) { reset({ - title: data.title, - code: data.code, - isRTL: data.isRTL, + title: language.title, + code: language.code, + isRTL: language.isRTL, }); } else { reset(); } - }, [data, reset]); + }, [language, reset]); return ( - {data ? t("title.edit_label") : t("title.new_label")} + {language ? t("title.edit_label") : t("title.new_label")} diff --git a/frontend/src/components/languages/index.tsx b/frontend/src/components/languages/index.tsx index 6a7b28f9..2e664133 100644 --- a/frontend/src/components/languages/index.tsx +++ b/frontend/src/components/languages/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { Flag } from "@mui/icons-material"; import AddIcon from "@mui/icons-material/Add"; import { Button, Grid, Paper, Switch } from "@mui/material"; @@ -41,7 +42,7 @@ export const Languages = () => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const queryClient = useQueryClient(); const hasPermission = useHasPermission(); const { onSearch, searchPayload } = useSearch({ @@ -82,7 +83,7 @@ export const Languages = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], isDisabled: (row) => row.isDefault, }, diff --git a/frontend/src/components/nlp/NlpEntityDialog.tsx b/frontend/src/components/nlp/NlpEntityDialog.tsx index f330588a..98d533cb 100644 --- a/frontend/src/components/nlp/NlpEntityDialog.tsx +++ b/frontend/src/components/nlp/NlpEntityDialog.tsx @@ -1,20 +1,21 @@ /* - * 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, FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, - DialogContent, - DialogActions, } from "@mui/material"; import { FC, useEffect } from "react"; import { useForm } from "react-hook-form"; @@ -39,8 +40,8 @@ import { export type NlpEntityDialogProps = DialogControlProps; export const NlpEntityDialog: FC = ({ open, + datum: nlpEntity, closeDialog, - data, ...rest }) => { const { t } = useTranslate(); @@ -70,9 +71,9 @@ export const NlpEntityDialog: FC = ({ handleSubmit, } = useForm({ defaultValues: { - name: data?.name || "", - doc: data?.doc || "", - lookups: data?.lookups || ["keywords"], + name: nlpEntity?.name || "", + doc: nlpEntity?.doc || "", + lookups: nlpEntity?.lookups || ["keywords"], }, }); const validationRules = { @@ -83,8 +84,8 @@ export const NlpEntityDialog: FC = ({ isChecked: {}, }; const onSubmitForm = async (params: INlpEntityAttributes) => { - if (data) { - updateNlpEntity({ id: data.id, params }); + if (nlpEntity) { + updateNlpEntity({ id: nlpEntity.id, params }); } else { createNlpEntity(params); } @@ -95,25 +96,25 @@ export const NlpEntityDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (nlpEntity) { reset({ - name: data.name, - doc: data.doc, + name: nlpEntity.name, + doc: nlpEntity.doc, }); } else { reset(); } - }, [data, reset]); + }, [nlpEntity, reset]); return ( - {data ? t("title.edit_nlp_entity") : t("title.new_nlp_entity")} + {nlpEntity ? t("title.edit_nlp_entity") : t("title.new_nlp_entity")} - {!data ? ( + {!nlpEntity ? ( {t("label.lookup_strategies")} diff --git a/frontend/src/components/nlp/NlpSampleDialog.tsx b/frontend/src/components/nlp/NlpSampleDialog.tsx index 3a14ce11..e1ebe6b3 100644 --- a/frontend/src/components/nlp/NlpSampleDialog.tsx +++ b/frontend/src/components/nlp/NlpSampleDialog.tsx @@ -1,11 +1,12 @@ /* - * 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, DialogContent } from "@mui/material"; import { FC } from "react"; @@ -26,7 +27,7 @@ import NlpDatasetSample from "./components/NlpTrainForm"; export type NlpSampleDialogProps = DialogControlProps; export const NlpSampleDialog: FC = ({ open, - data: sample, + datum: nlpSample, closeDialog, ...rest }) => { @@ -44,10 +45,10 @@ export const NlpSampleDialog: FC = ({ }, }); const onSubmitForm = (form: INlpSampleFormAttributes) => { - if (sample?.id) { + if (nlpSample?.id) { updateSample( { - id: sample.id, + id: nlpSample.id, params: { text: form.text, type: form.type, @@ -70,7 +71,7 @@ export const NlpSampleDialog: FC = ({ {t("title.edit_nlp_sample")} - + ); diff --git a/frontend/src/components/nlp/NlpValueDialog.tsx b/frontend/src/components/nlp/NlpValueDialog.tsx index c62f0e61..5074628c 100644 --- a/frontend/src/components/nlp/NlpValueDialog.tsx +++ b/frontend/src/components/nlp/NlpValueDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { useRouter } from "next/router"; import { FC, useEffect } from "react"; @@ -36,44 +37,47 @@ export type NlpValueDialogProps = DialogControlProps & { export const NlpValueDialog: FC = ({ open, + datum: nlpValue, closeDialog, - data, canHaveSynonyms, callback, }) => { const { t } = useTranslate(); const { toast } = useToast(); const { query } = useRouter(); - const { refetch: refetchEntity } = useGet(data?.entity || String(query.id), { - entity: EntityType.NLP_ENTITY, - format: Format.FULL, - }); + const { refetch: refetchEntity } = useGet( + nlpValue?.entity || String(query.id), + { + entity: EntityType.NLP_ENTITY, + format: Format.FULL, + }, + ); const { mutateAsync: createNlpValue } = useCreate(EntityType.NLP_VALUE, { onError: () => { toast.error(t("message.internal_server_error")); }, - onSuccess(data) { + onSuccess(datum) { refetchEntity(); closeDialog(); toast.success(t("message.success_save")); - callback?.(data); + callback?.(datum); }, }); const { mutateAsync: updateNlpValue } = useUpdate(EntityType.NLP_VALUE, { onError: () => { toast.error(t("message.internal_server_error")); }, - onSuccess(data) { + onSuccess(datum) { closeDialog(); toast.success(t("message.success_save")); - callback?.(data); + callback?.(datum); }, }); const { reset, register, handleSubmit, control } = useForm({ defaultValues: { - value: data?.value || "", - expressions: data?.expressions || [], + value: nlpValue?.value || "", + expressions: nlpValue?.expressions || [], }, }); const validationRules = { @@ -84,8 +88,8 @@ export const NlpValueDialog: FC = ({ description: {}, }; const onSubmitForm = async (params: INlpValueAttributes) => { - if (data) { - updateNlpValue({ id: data.id, params }); + if (nlpValue) { + updateNlpValue({ id: nlpValue.id, params }); } else { createNlpValue({ ...params, entity: String(query.id) }); } @@ -96,21 +100,23 @@ export const NlpValueDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (nlpValue) { reset({ - value: data.value, - expressions: data.expressions, + value: nlpValue.value, + expressions: nlpValue.expressions, }); } else { reset(); } - }, [data, reset]); + }, [nlpValue, reset]); return ( - {data ? t("title.edit_nlp_value") : t("title.new_nlp_entity_value")} + {nlpValue + ? t("title.edit_nlp_value") + : t("title.new_nlp_entity_value")} diff --git a/frontend/src/components/nlp/components/NlpEntity.tsx b/frontend/src/components/nlp/components/NlpEntity.tsx index 983b4b67..43c096a7 100644 --- a/frontend/src/components/nlp/components/NlpEntity.tsx +++ b/frontend/src/components/nlp/components/NlpEntity.tsx @@ -1,15 +1,16 @@ /* - * 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 AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import { Button, Chip, Grid } from "@mui/material"; -import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { useRouter } from "next/router"; import { DeleteDialog } from "@/app-components/dialogs"; @@ -37,7 +38,7 @@ const NlpEntity = () => { const router = useRouter(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const hasPermission = useHasPermission(); const { t } = useTranslate(); const { toast } = useToast(); @@ -79,7 +80,7 @@ const NlpEntity = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], @@ -145,8 +146,6 @@ const NlpEntity = () => { }, actionEntityColumns, ]; - const handleSelectionChange = (selection: GridRowSelectionModel) => - deleteDialogCtl.setData?.(selection as string[]); return ( @@ -202,7 +201,10 @@ const NlpEntity = () => { columns={nlpEntityColumns} {...nlpEntityGrid} checkboxSelection - onRowSelectionModelChange={handleSelectionChange} + rowSelectionModel={deleteDialogCtl.data || []} + onRowSelectionModelChange={(rowSelectionModel) => + deleteDialogCtl.setData?.(rowSelectionModel as string[]) + } /> diff --git a/frontend/src/components/nlp/components/NlpSample.tsx b/frontend/src/components/nlp/components/NlpSample.tsx index fb5d9b2d..2ddc77fd 100644 --- a/frontend/src/components/nlp/components/NlpSample.tsx +++ b/frontend/src/components/nlp/components/NlpSample.tsx @@ -1,11 +1,12 @@ /* - * 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 CircleIcon from "@mui/icons-material/Circle"; import ClearIcon from "@mui/icons-material/Clear"; import DeleteIcon from "@mui/icons-material/Delete"; @@ -22,7 +23,7 @@ import { Stack, Typography, } from "@mui/material"; -import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { useState } from "react"; import { useQueryClient } from "react-query"; @@ -74,7 +75,7 @@ export default function NlpSample() { const { t } = useTranslate(); const { toast } = useToast(); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const queryClient = useQueryClient(); const [type, setType] = useState("all"); const [language, setLanguage] = useState(undefined); @@ -154,7 +155,7 @@ export default function NlpSample() { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], @@ -266,8 +267,6 @@ export default function NlpSample() { }, actionColumns, ]; - const handleSelectionChange = (selection: GridRowSelectionModel) => - deleteDialogCtl.setData?.(selection as string[]); const handleImportChange = async (file: File) => { await importDataset(file); }; @@ -399,7 +398,9 @@ export default function NlpSample() { columns={columns} {...dataGridProps} checkboxSelection - onRowSelectionModelChange={handleSelectionChange} + onRowSelectionModelChange={(rowSelectionModel) => + deleteDialogCtl.setData?.(rowSelectionModel as string[]) + } /> diff --git a/frontend/src/components/nlp/components/NlpValues.tsx b/frontend/src/components/nlp/components/NlpValues.tsx index 0129128a..b0f0978e 100644 --- a/frontend/src/components/nlp/components/NlpValues.tsx +++ b/frontend/src/components/nlp/components/NlpValues.tsx @@ -1,17 +1,18 @@ /* - * 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 { faGraduationCap } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import DeleteIcon from "@mui/icons-material/Delete"; import { Box, Button, ButtonGroup, Chip, Grid, Slide } from "@mui/material"; -import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { GridColDef } from "@mui/x-data-grid"; import { useRouter } from "next/router"; import { useEffect, useState } from "react"; @@ -45,7 +46,7 @@ export const NlpValues = ({ entityId }: { entityId: string }) => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const hasPermission = useHasPermission(); const [direction, setDirection] = useState<"up" | "down">("up"); const { data: nlpEntity, refetch: refetchEntity } = useGet(entityId, { @@ -71,7 +72,7 @@ export const NlpValues = ({ entityId }: { entityId: string }) => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), }, ], t("label.operations"), @@ -128,8 +129,6 @@ export const NlpValues = ({ entityId }: { entityId: string }) => { }, []); const canHaveSynonyms = nlpEntity?.lookups?.[0] === NlpLookups.keywords; - const handleSelectionChange = (selection: GridRowSelectionModel) => - deleteDialogCtl.setData?.(selection as string[]); return ( @@ -197,7 +196,7 @@ export const NlpValues = ({ entityId }: { entityId: string }) => { { + callback={async () => { refetchEntity(); }} /> @@ -215,14 +214,15 @@ export const NlpValues = ({ entityId }: { entityId: string }) => { {}} /> + deleteDialogCtl.setData?.(rowSelectionModel as string[]) + } /> diff --git a/frontend/src/components/roles/PermissionsDialog.tsx b/frontend/src/components/roles/PermissionsDialog.tsx index dca38329..afc5191a 100644 --- a/frontend/src/components/roles/PermissionsDialog.tsx +++ b/frontend/src/components/roles/PermissionsDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 AddIcon from "@mui/icons-material/Add"; import DeleteOutlinedIcon from "@mui/icons-material/DeleteOutlined"; import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; @@ -13,17 +14,17 @@ import { Accordion, AccordionDetails, AccordionSummary, + Button, Dialog, + DialogActions, + DialogContent, + Divider, Grid, MenuItem, Paper, Typography, - DialogContent, - DialogActions, - Button, - Divider, } from "@mui/material"; -import { useState, FC, useEffect } from "react"; +import { FC, useEffect, useState } from "react"; import { IconButton } from "@/app-components/buttons/IconButton"; import { DialogTitle } from "@/app-components/dialogs/DialogTitle"; @@ -67,7 +68,7 @@ const AccordionModelHead = () => ( export const PermissionsDialog: FC = ({ open, - data, + datum: permission, closeDialog: closeFunction, }) => { const { t } = useTranslate(); @@ -78,7 +79,7 @@ export const PermissionsDialog: FC = ({ hasCount: false, }, ); - const getPermisionFromCache = useGetFromCache(EntityType.PERMISSION); + const getPermissionFromCache = useGetFromCache(EntityType.PERMISSION); const { mutateAsync: createPermission } = useCreate(EntityType.PERMISSION, { onError: (error: Error & { statusCode?: number }) => { if (error.statusCode === 409) { @@ -127,7 +128,7 @@ export const PermissionsDialog: FC = ({ - {data?.role.name} + {permission?.role.name} {models?.map((model) => { return ( @@ -161,11 +162,8 @@ export const PermissionsDialog: FC = ({ > {model.permissions - ?.map((p) => getPermisionFromCache(p)) - ?.filter( - (permission) => - permission && permission.role === data?.role.id, - ) + ?.map((p) => getPermissionFromCache(p)) + ?.filter((p) => p && p.role === permission?.role.id) .map((p) => p as IPermission) .map(({ id, action, relation }, index) => { return ( @@ -212,11 +210,11 @@ export const PermissionsDialog: FC = ({ color="primary" variant="contained" onClick={() => { - if (data?.role.id) + if (permission?.role.id) createPermission({ ...payload, model: model.id, - role: data.role.id, + role: permission.role.id, }); reset(); }} diff --git a/frontend/src/components/roles/RoleDialog.tsx b/frontend/src/components/roles/RoleDialog.tsx index 144c1387..862d3168 100644 --- a/frontend/src/components/roles/RoleDialog.tsx +++ b/frontend/src/components/roles/RoleDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { FC, useEffect } from "react"; import { useForm } from "react-hook-form"; @@ -26,7 +27,7 @@ import { IRole, IRoleAttributes } from "@/types/role.types"; export type RoleDialogProps = DialogControlProps; export const RoleDialog: FC = ({ open, - data, + datum: role, closeDialog, ...rest }) => { @@ -64,8 +65,8 @@ export const RoleDialog: FC = ({ }, }; const onSubmitForm = async (params: IRoleAttributes) => { - if (data) { - updateRole({ id: data.id, params }); + if (role) { + updateRole({ id: role.id, params }); } else { createRole(params); } @@ -76,20 +77,20 @@ export const RoleDialog: FC = ({ }, [open, reset]); useEffect(() => { - if (data) { + if (role) { reset({ - name: data.name, + name: role.name, }); } else { reset(); } - }, [data, reset]); + }, [role, reset]); return ( - {data ? t("title.edit_role") : t("title.new_role")} + {role ? t("title.edit_role") : t("title.new_role")} diff --git a/frontend/src/components/roles/index.tsx b/frontend/src/components/roles/index.tsx index da356821..a74ed8c1 100644 --- a/frontend/src/components/roles/index.tsx +++ b/frontend/src/components/roles/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { faUniversalAccess } from "@fortawesome/free-solid-svg-icons"; import AddIcon from "@mui/icons-material/Add"; import { Button, Grid, Paper } from "@mui/material"; @@ -39,7 +40,7 @@ export const Roles = () => { const { toast } = useToast(); const addDialogCtl = useDialog(false); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const permissionDialogCtl = useDialog<{ role: IRole; }>(false); @@ -71,7 +72,7 @@ export const Roles = () => { { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], diff --git a/frontend/src/components/subscribers/EditSubscriberDialog.tsx b/frontend/src/components/subscribers/EditSubscriberDialog.tsx index 0b2897bf..9a308a5f 100644 --- a/frontend/src/components/subscribers/EditSubscriberDialog.tsx +++ b/frontend/src/components/subscribers/EditSubscriberDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { Button, Dialog, @@ -14,7 +15,7 @@ import { Grid, } from "@mui/material"; import Link from "next/link"; -import { useEffect, FC, useState } from "react"; +import { FC, useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import DialogButtons from "@/app-components/buttons/DialogButtons"; @@ -39,7 +40,7 @@ export type EditSubscriberDialogProps = DialogControlProps<{ }>; export const EditSubscriberDialog: FC = ({ open, - data, + datum, closeDialog, ...rest }) => { @@ -65,17 +66,17 @@ export const EditSubscriberDialog: FC = ({ labels: {}, }; const onSubmitForm = async (params: ISubscriberAttributes) => { - if (data?.subscriber.id) - updateSubscriber({ id: data?.subscriber.id, params }); + if (datum?.subscriber.id) + updateSubscriber({ id: datum?.subscriber.id, params }); }; useEffect(() => { - if (data?.subscriber) setFullName(getFullName(data?.subscriber)); + if (datum?.subscriber) setFullName(getFullName(datum?.subscriber)); if (open) { - reset({ labels: data?.subscriber?.labels }); + reset({ labels: datum?.subscriber?.labels }); } - }, [open, reset, data]); + }, [open, reset, datum]); return ( diff --git a/frontend/src/components/translations/EditTranslationDialog.tsx b/frontend/src/components/translations/EditTranslationDialog.tsx index f3d3fcbe..edd26576 100644 --- a/frontend/src/components/translations/EditTranslationDialog.tsx +++ b/frontend/src/components/translations/EditTranslationDialog.tsx @@ -1,11 +1,12 @@ /* - * 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, @@ -37,7 +38,7 @@ import TranslationInput from "./TranslationInput"; export type EditTranslationDialogProps = DialogControlProps; export const EditTranslationDialog: FC = ({ open, - data, + datum: translation, closeDialog, ...rest }) => { @@ -59,15 +60,15 @@ export const EditTranslationDialog: FC = ({ }, }); const { reset, control, handleSubmit } = useForm({ - defaultValues: data, + defaultValues: translation, }); const onSubmitForm = async (params: ITranslationAttributes) => { - if (data?.id) updateTranslation({ id: data.id, params }); + if (translation?.id) updateTranslation({ id: translation.id, params }); }; useEffect(() => { - if (open) reset(data); - }, [open, reset, data]); + if (open) reset(translation); + }, [open, reset, translation]); return ( @@ -78,7 +79,7 @@ export const EditTranslationDialog: FC = ({ {t("label.original_text")} - {data?.str} + {translation?.str} {languages diff --git a/frontend/src/components/translations/index.tsx b/frontend/src/components/translations/index.tsx index 1d7a2f7b..9df7d68f 100644 --- a/frontend/src/components/translations/index.tsx +++ b/frontend/src/components/translations/index.tsx @@ -1,11 +1,12 @@ /* - * 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 { faLanguage } from "@fortawesome/free-solid-svg-icons"; import AutorenewIcon from "@mui/icons-material/Autorenew"; import { Button, Chip, Grid, Paper, Stack } from "@mui/material"; @@ -43,7 +44,7 @@ export const Translations = () => { }, ); const editDialogCtl = useDialog(false); - const deleteDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); const { onSearch, searchPayload } = useSearch({ $iLike: ["str"], }); @@ -73,7 +74,7 @@ export const Translations = () => { }, { label: ActionColumnLabel.Delete, - action: (row) => deleteDialogCtl.openDialog([row.id]), + action: (row) => deleteDialogCtl.openDialog(row.id), requires: [PermissionAction.DELETE], }, ], diff --git a/frontend/src/components/users/EditUserDialog.tsx b/frontend/src/components/users/EditUserDialog.tsx index 092bad94..d674e82d 100644 --- a/frontend/src/components/users/EditUserDialog.tsx +++ b/frontend/src/components/users/EditUserDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 { Button, Dialog, @@ -40,7 +41,7 @@ export type EditUserDialogProps = DialogControlProps<{ export const EditUserDialog: FC = ({ open, - data, + datum, closeDialog, ...rest }) => { @@ -62,7 +63,7 @@ export const EditUserDialog: FC = ({ reset, formState: { errors }, } = useForm({ - defaultValues: { roles: data?.roles.map((role) => role.id) }, + defaultValues: { roles: datum?.roles.map((role) => role.id) }, }); const validationRules = { roles: { @@ -70,18 +71,18 @@ export const EditUserDialog: FC = ({ }, }; const onSubmitForm = async (params: IUserAttributes) => { - if (data?.user.id) + if (datum?.user.id) updateUser({ - id: data.user.id, + id: datum.user.id, params, }); }; useEffect(() => { - if (data?.user) setFullName(getFullName(data?.user)); + if (datum?.user) setFullName(getFullName(datum?.user)); - if (open) reset({ roles: data?.user?.roles }); - }, [open, reset, data]); + if (open) reset({ roles: datum?.user?.roles }); + }, [open, reset, datum]); return ( @@ -108,7 +109,7 @@ export const EditUserDialog: FC = ({ name="roles" rules={validationRules.roles} control={control} - defaultValue={data?.roles?.map(({ id }) => id) || []} + defaultValue={datum?.roles?.map(({ id }) => id) || []} render={({ field }) => { const { onChange, ...rest } = field; diff --git a/frontend/src/components/visual-editor/BlockDialog.tsx b/frontend/src/components/visual-editor/BlockDialog.tsx index 27bb00e8..4830e317 100644 --- a/frontend/src/components/visual-editor/BlockDialog.tsx +++ b/frontend/src/components/visual-editor/BlockDialog.tsx @@ -1,11 +1,12 @@ /* - * 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 ChatBubbleOutlineOutlinedIcon from "@mui/icons-material/ChatBubbleOutlineOutlined"; import SettingsApplicationsIcon from "@mui/icons-material/SettingsApplications"; import { @@ -47,7 +48,7 @@ type TSelectedTab = "triggers" | "options" | "messages"; const BlockDialog: FC = ({ open, - data: block, + datum: block, closeDialog, ...rest }) => { diff --git a/frontend/src/components/visual-editor/v2/Diagrams.tsx b/frontend/src/components/visual-editor/v2/Diagrams.tsx index 4fa0a934..c71fcafb 100644 --- a/frontend/src/components/visual-editor/v2/Diagrams.tsx +++ b/frontend/src/components/visual-editor/v2/Diagrams.tsx @@ -1,11 +1,12 @@ /* - * 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 { Add, MoveUp } from "@mui/icons-material"; import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; @@ -74,8 +75,8 @@ const Diagrams = () => { const [engine, setEngine] = useState(); const [canvas, setCanvas] = useState(); const [selectedBlockId, setSelectedBlockId] = useState(); - const deleteDialogCtl = useDialog(false); - const moveDialogCtl = useDialog(false); + const deleteDialogCtl = useDialog(false); + const moveDialogCtl = useDialog(false); const addCategoryDialogCtl = useDialog(false); const { mutateAsync: updateBlocks } = useUpdateMany(EntityType.BLOCK); const { @@ -203,7 +204,8 @@ const Diagrams = () => { setter: setSelectedBlockId, updateFn: updateBlock, onRemoveNode: (ids, next) => { - deleteDialogCtl.openDialog(ids); + deleteDialogCtl.setData?.(ids); + deleteDialogCtl.openDialog(); deleteCallbackRef.current = next; }, onDbClickNode: (event, id) => { @@ -445,7 +447,8 @@ const Diagrams = () => { }); engine?.repaintCanvas(); }; - deleteDialogCtl.openDialog(ids); + deleteDialogCtl.setData?.(ids); + deleteDialogCtl.openDialog(); } }; const handleMoveButton = () => { @@ -453,12 +456,11 @@ const Diagrams = () => { const ids = selectedEntities?.map((model) => model.getID()); if (ids && selectedEntities) { - moveDialogCtl.openDialog(ids); + moveDialogCtl.setData?.(ids); + moveDialogCtl.openDialog(); } }; - const onDelete = async () => { - const ids = deleteDialogCtl?.data; - + const onDelete = async (ids: string[]) => { if (!ids || ids?.length === 0) { return; } @@ -530,12 +532,15 @@ const Diagrams = () => { - {...deleteDialogCtl} callback={onDelete} /> + { + if (Array.isArray(data)) onDelete(data); + }} + /> diff --git a/frontend/src/hooks/useDialog.tsx b/frontend/src/hooks/useDialog.tsx index 6d7bd447..13b03d3f 100644 --- a/frontend/src/hooks/useDialog.tsx +++ b/frontend/src/hooks/useDialog.tsx @@ -7,7 +7,7 @@ */ import { DialogProps } from "@mui/material"; -import { Dispatch, SetStateAction, useState } from "react"; +import { useState } from "react"; export type DialogControlProps = Omit, "openDialog">; type TCloseDialog = ( @@ -15,19 +15,25 @@ type TCloseDialog = ( reason?: "backdropClick" | "escapeKeyDown", ) => void; type TFnVoid = (data?: T) => void; -export type DialogControl = DialogProps & { - data?: T; - setData?: Dispatch>; - callback?: TFnVoid; + +export type DialogControl = DialogProps & { + data?: T[]; + datum?: T; + setData?: TFnVoid; + callback?: (data?: T | T[]) => Promise; openDialog: TFnVoid; closeDialog: TCloseDialog; }; export const useDialog = (initialState: boolean): DialogControl => { const [open, setOpen] = useState(initialState); - const [data, setData] = useState(undefined); - const openDialog: TFnVoid = (data) => { - if (data) setData(data); + const [data, setData] = useState(undefined); + const [datum, setDatum] = useState(undefined); + const openDialog: TFnVoid = (datum) => { + setDatum(datum); + if (datum) { + setData(undefined); + } setOpen(true); }; const closeDialog: TCloseDialog = (event, reason) => { @@ -36,11 +42,18 @@ export const useDialog = (initialState: boolean): DialogControl => { } }; - return { open, openDialog, closeDialog, data, setData }; + return { + open, + data, + datum, + setData, + openDialog, + closeDialog, + }; }; export const getDisplayDialogs = ({ open, closeDialog, - data, -}: DialogControl): DialogControlProps => ({ open, closeDialog, data }); + datum, +}: DialogControl): DialogControlProps => ({ open, datum, closeDialog });