mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix: update modals logic
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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é",
|
||||
|
||||
@@ -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<AttachmentThumbnailProps> = ({
|
||||
});
|
||||
const { toast } = useToast();
|
||||
const { t } = useTranslate();
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
|
||||
if (!attachment) {
|
||||
return t("message.attachment_not_found") + id;
|
||||
@@ -141,7 +142,7 @@ const AttachmentThumbnail: FC<AttachmentThumbnailProps> = ({
|
||||
variant="contained"
|
||||
startIcon={<DeleteOutlineOutlinedIcon />}
|
||||
onClick={(e) => {
|
||||
deleteDialogCtl.openDialog([attachment.id]);
|
||||
deleteDialogCtl.openDialog(attachment.id);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
|
||||
@@ -94,7 +94,7 @@ const AttachmentUploader: FC<FileUploadProps> = ({
|
||||
onUploadComplete && onUploadComplete();
|
||||
},
|
||||
});
|
||||
const libraryDialogCtl = useDialog<IAttachment | null | undefined>(false);
|
||||
const libraryDialogCtl = useDialog<IAttachment | null>(false);
|
||||
const stopDefaults = (e: DragEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@@ -140,7 +140,9 @@ const AttachmentUploader: FC<FileUploadProps> = ({
|
||||
<Grid>
|
||||
<AttachmentDialog
|
||||
{...getDisplayDialogs(libraryDialogCtl)}
|
||||
callback={onChange}
|
||||
callback={async (data) => {
|
||||
if (!Array.isArray(data)) onChange?.(data);
|
||||
}}
|
||||
accept={accept}
|
||||
/>
|
||||
<Grid container>
|
||||
|
||||
@@ -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<T = string> = DialogControl<T>;
|
||||
export const DeleteDialog = <T extends any = string>({
|
||||
export type DeleteDialogProps<T extends string = string> = DialogControl<T>;
|
||||
export const DeleteDialog = <T extends string = string>({
|
||||
open,
|
||||
closeDialog: closeFunction,
|
||||
datum,
|
||||
data: ids,
|
||||
callback,
|
||||
entity = EntityType.ATTACHMENT,
|
||||
@@ -40,6 +42,9 @@ export const DeleteDialog = <T extends any = string>({
|
||||
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 extends any = string>({
|
||||
<ErrorIcon sx={{ fontSize: "28px" }} color="error" />
|
||||
</Grid>
|
||||
<Grid item alignSelf="center">
|
||||
<Typography>{t("message.item_delete_confirm")}</Typography>
|
||||
<Typography>
|
||||
{t(
|
||||
`${
|
||||
hasMultipleItems(ids)
|
||||
? "message.items_delete_confirm"
|
||||
: "message.item_delete_confirm"
|
||||
}`,
|
||||
{ "0": getItemsFromData(ids).length.toString() },
|
||||
)}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DialogContent>
|
||||
@@ -73,16 +87,10 @@ export const DeleteDialog = <T extends any = string>({
|
||||
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
|
||||
|
||||
@@ -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<string> {
|
||||
export interface MoveDialogProps
|
||||
extends Omit<DialogControl<string>, "callback"> {
|
||||
categories: ICategory[];
|
||||
callback?: (newCategoryId?: string) => Promise<void>;
|
||||
openDialog: (data?: string) => void;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<ICategory>;
|
||||
|
||||
export const CategoryDialog: FC<CategoryDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: category,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -57,7 +58,7 @@ export const CategoryDialog: FC<CategoryDialogProps> = ({
|
||||
formState: { errors },
|
||||
handleSubmit,
|
||||
} = useForm<ICategoryAttributes>({
|
||||
defaultValues: { label: data?.label || "" },
|
||||
defaultValues: { label: category?.label || "" },
|
||||
});
|
||||
const validationRules = {
|
||||
label: {
|
||||
@@ -65,8 +66,8 @@ export const CategoryDialog: FC<CategoryDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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<CategoryDialogProps> = ({
|
||||
}, [open, reset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
if (category) {
|
||||
reset({
|
||||
label: data.label,
|
||||
label: category.label,
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}, [data, reset]);
|
||||
}, [category, reset]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_category") : t("title.new_category")}
|
||||
{category ? t("title.edit_category") : t("title.new_category")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<ICategory>(false);
|
||||
const editDialogCtl = useDialog<ICategory>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const hasPermission = useHasPermission();
|
||||
const { onSearch, searchPayload } = useSearch<ICategory>({
|
||||
$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 (
|
||||
<Grid container gap={3} flexDirection="column">
|
||||
@@ -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")}
|
||||
</Button>
|
||||
@@ -165,7 +164,10 @@ export const Categories = () => {
|
||||
columns={columns}
|
||||
{...dataGridProps}
|
||||
checkboxSelection
|
||||
onRowSelectionModelChange={handleSelectionChange}
|
||||
rowSelectionModel={deleteDialogCtl.data || []}
|
||||
onRowSelectionModelChange={(rowSelectionModel) =>
|
||||
deleteDialogCtl.setData?.(rowSelectionModel as string[])
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Paper>
|
||||
|
||||
@@ -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<IContentType>;
|
||||
export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: contentType,
|
||||
closeDialog,
|
||||
}) => {
|
||||
const { toast } = useToast();
|
||||
@@ -40,7 +41,7 @@ export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm<IContentTypeAttributes>({
|
||||
defaultValues: { name: data?.name || "" },
|
||||
defaultValues: { name: contentType?.name || "" },
|
||||
});
|
||||
const CloseAndReset = () => {
|
||||
closeDialog();
|
||||
@@ -76,9 +77,9 @@ export const ContentTypeDialog: FC<ContentTypeDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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<ContentTypeDialogProps> = ({
|
||||
}, [open, reset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
if (contentType) {
|
||||
reset({
|
||||
name: data.name,
|
||||
name: contentType.name,
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}, [data, reset]);
|
||||
}, [contentType, reset]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth onClose={CloseAndReset}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={CloseAndReset}>
|
||||
{data ? t("title.edit_content_type") : t("title.new_content_type")}
|
||||
{contentType
|
||||
? t("title.edit_content_type")
|
||||
: t("title.new_content_type")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<IContentType>;
|
||||
|
||||
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}
|
||||
>
|
||||
<DialogTitle onClose={handleClose}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{t("title.manage_fields")}
|
||||
</DialogTitle>
|
||||
<form
|
||||
@@ -150,7 +147,7 @@ export const EditContentTypeFieldsDialog = ({
|
||||
fields,
|
||||
},
|
||||
});
|
||||
handleClose();
|
||||
closeDialog();
|
||||
})}
|
||||
>
|
||||
<DialogContent>
|
||||
|
||||
@@ -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<IContentType>(false);
|
||||
const editDialogCtl = useDialog<IContentType>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
// data fetching
|
||||
const { onSearch, searchPayload } = useSearch<IContentType>({
|
||||
$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],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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<ContentDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
const { content, contentType } = data || {
|
||||
const { content, contentType } = datum || {
|
||||
content: undefined,
|
||||
contentType: undefined,
|
||||
};
|
||||
|
||||
@@ -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<ContentImportDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -38,10 +37,10 @@ export const ContentImportDialog: FC<ContentImportDialogProps> = ({
|
||||
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<ContentImportDialogProps> = ({
|
||||
setAttachmentId(null);
|
||||
};
|
||||
const handleImportClick = () => {
|
||||
if (attachmentId && data?.contentType?.id) {
|
||||
if (attachmentId && datum?.contentType?.id) {
|
||||
refetch();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
// data fetching
|
||||
const { onSearch, searchPayload } = useSearch<IContent>({
|
||||
$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 = () => {
|
||||
<ContentDialog {...getDisplayDialogs(editDialogCtl)} />
|
||||
<ContentImportDialog
|
||||
{...getDisplayDialogs(importDialogCtl)}
|
||||
callback={() => {
|
||||
callback={async () => {
|
||||
refetch();
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -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<IContextVar>;
|
||||
export const ContextVarDialog: FC<ContextVarDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: contextVar,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -67,9 +68,9 @@ export const ContextVarDialog: FC<ContextVarDialogProps> = ({
|
||||
control,
|
||||
} = useForm<IContextVarAttributes>({
|
||||
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<ContextVarDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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<ContextVarDialogProps> = ({
|
||||
}, [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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_context_var") : t("title.new_context_var")}
|
||||
{contextVar
|
||||
? t("title.edit_context_var")
|
||||
: t("title.new_context_var")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<IContextVar>(false);
|
||||
const editDialogCtl = useDialog<IContextVar>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const hasPermission = useHasPermission();
|
||||
const { onSearch, searchPayload } = useSearch<IContextVar>({
|
||||
$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 (
|
||||
<Grid container gap={3} flexDirection="column">
|
||||
<ContextVarDialog {...getDisplayDialogs(addDialogCtl)} />
|
||||
<ContextVarDialog {...getDisplayDialogs(editDialogCtl)} />
|
||||
|
||||
<DeleteDialog
|
||||
{...deleteDialogCtl}
|
||||
entity={EntityType.CONTEXT_VAR}
|
||||
@@ -196,7 +194,10 @@ export const ContextVars = () => {
|
||||
columns={columns}
|
||||
{...dataGridProps}
|
||||
checkboxSelection
|
||||
onRowSelectionModelChange={handleSelectionChange}
|
||||
rowSelectionModel={deleteDialogCtl.data || []}
|
||||
onRowSelectionModelChange={(rowSelectionModel) =>
|
||||
deleteDialogCtl.setData?.(rowSelectionModel as string[])
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Paper>
|
||||
|
||||
@@ -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<ILabel>;
|
||||
export const LabelDialog: FC<LabelDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: label,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -59,9 +60,9 @@ export const LabelDialog: FC<LabelDialogProps> = ({
|
||||
handleSubmit,
|
||||
} = useForm<ILabelAttributes>({
|
||||
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<LabelDialogProps> = ({
|
||||
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<LabelDialogProps> = ({
|
||||
}, [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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_label") : t("title.new_label")}
|
||||
{label ? t("title.edit_label") : t("title.new_label")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<ILabel>(false);
|
||||
const editDialogCtl = useDialog<ILabel>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const hasPermission = useHasPermission();
|
||||
const { onSearch, searchPayload } = useSearch<ILabel>({
|
||||
$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],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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<ILanguage>;
|
||||
export const LanguageDialog: FC<LanguageDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: language,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -64,9 +65,9 @@ export const LanguageDialog: FC<LanguageDialogProps> = ({
|
||||
control,
|
||||
} = useForm<ILanguageAttributes>({
|
||||
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<LanguageDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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<LanguageDialogProps> = ({
|
||||
}, [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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_label") : t("title.new_label")}
|
||||
{language ? t("title.edit_label") : t("title.new_label")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<ILanguage>(false);
|
||||
const editDialogCtl = useDialog<ILanguage>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const queryClient = useQueryClient();
|
||||
const hasPermission = useHasPermission();
|
||||
const { onSearch, searchPayload } = useSearch<ILanguage>({
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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<INlpEntity>;
|
||||
export const NlpEntityDialog: FC<NlpEntityDialogProps> = ({
|
||||
open,
|
||||
datum: nlpEntity,
|
||||
closeDialog,
|
||||
data,
|
||||
...rest
|
||||
}) => {
|
||||
const { t } = useTranslate();
|
||||
@@ -70,9 +71,9 @@ export const NlpEntityDialog: FC<NlpEntityDialogProps> = ({
|
||||
handleSubmit,
|
||||
} = useForm<INlpEntityAttributes>({
|
||||
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<NlpEntityDialogProps> = ({
|
||||
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<NlpEntityDialogProps> = ({
|
||||
}, [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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_nlp_entity") : t("title.new_nlp_entity")}
|
||||
{nlpEntity ? t("title.edit_nlp_entity") : t("title.new_nlp_entity")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
{!data ? (
|
||||
{!nlpEntity ? (
|
||||
<ContentItem>
|
||||
<FormControl>
|
||||
<FormLabel>{t("label.lookup_strategies")}</FormLabel>
|
||||
|
||||
@@ -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<INlpDatasetSample>;
|
||||
export const NlpSampleDialog: FC<NlpSampleDialogProps> = ({
|
||||
open,
|
||||
data: sample,
|
||||
datum: nlpSample,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -44,10 +45,10 @@ export const NlpSampleDialog: FC<NlpSampleDialogProps> = ({
|
||||
},
|
||||
});
|
||||
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<NlpSampleDialogProps> = ({
|
||||
{t("title.edit_nlp_sample")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<NlpDatasetSample sample={sample} submitForm={onSubmitForm} />
|
||||
<NlpDatasetSample sample={nlpSample} submitForm={onSubmitForm} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -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<INlpValue> & {
|
||||
|
||||
export const NlpValueDialog: FC<NlpValueDialogProps> = ({
|
||||
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<TNlpValueAttributesWithRequiredExpressions>({
|
||||
defaultValues: {
|
||||
value: data?.value || "",
|
||||
expressions: data?.expressions || [],
|
||||
value: nlpValue?.value || "",
|
||||
expressions: nlpValue?.expressions || [],
|
||||
},
|
||||
});
|
||||
const validationRules = {
|
||||
@@ -84,8 +88,8 @@ export const NlpValueDialog: FC<NlpValueDialogProps> = ({
|
||||
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<NlpValueDialogProps> = ({
|
||||
}, [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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_nlp_value") : t("title.new_nlp_entity_value")}
|
||||
{nlpValue
|
||||
? t("title.edit_nlp_value")
|
||||
: t("title.new_nlp_entity_value")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<INlpEntity>(false);
|
||||
const editDialogCtl = useDialog<INlpEntity>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(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 (
|
||||
<Grid item xs={12}>
|
||||
@@ -202,7 +201,10 @@ const NlpEntity = () => {
|
||||
columns={nlpEntityColumns}
|
||||
{...nlpEntityGrid}
|
||||
checkboxSelection
|
||||
onRowSelectionModelChange={handleSelectionChange}
|
||||
rowSelectionModel={deleteDialogCtl.data || []}
|
||||
onRowSelectionModelChange={(rowSelectionModel) =>
|
||||
deleteDialogCtl.setData?.(rowSelectionModel as string[])
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -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<INlpDatasetSample>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const queryClient = useQueryClient();
|
||||
const [type, setType] = useState<NlpSampleType | "all">("all");
|
||||
const [language, setLanguage] = useState<string | undefined>(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[])
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -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<INlpValue>(false);
|
||||
const editDialogCtl = useDialog<INlpValue>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(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 (
|
||||
<Grid container gap={2} flexDirection="column">
|
||||
@@ -197,7 +196,7 @@ export const NlpValues = ({ entityId }: { entityId: string }) => {
|
||||
<NlpValueDialog
|
||||
{...addDialogCtl}
|
||||
canHaveSynonyms={canHaveSynonyms}
|
||||
callback={() => {
|
||||
callback={async () => {
|
||||
refetchEntity();
|
||||
}}
|
||||
/>
|
||||
@@ -215,14 +214,15 @@ export const NlpValues = ({ entityId }: { entityId: string }) => {
|
||||
<NlpValueDialog
|
||||
{...editDialogCtl}
|
||||
canHaveSynonyms={canHaveSynonyms}
|
||||
callback={() => {}}
|
||||
/>
|
||||
<Grid padding={1} marginTop={2} container>
|
||||
<DataGrid
|
||||
columns={columns}
|
||||
{...dataGridProps}
|
||||
checkboxSelection
|
||||
onRowSelectionModelChange={handleSelectionChange}
|
||||
onRowSelectionModelChange={(rowSelectionModel) =>
|
||||
deleteDialogCtl.setData?.(rowSelectionModel as string[])
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
@@ -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<PermissionsDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: permission,
|
||||
closeDialog: closeFunction,
|
||||
}) => {
|
||||
const { t } = useTranslate();
|
||||
@@ -78,7 +79,7 @@ export const PermissionsDialog: FC<PermissionsDialogProps> = ({
|
||||
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<PermissionsDialogProps> = ({
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography fontWeight={700} sx={{ marginBottom: 2 }}>
|
||||
{data?.role.name}
|
||||
{permission?.role.name}
|
||||
</Typography>
|
||||
{models?.map((model) => {
|
||||
return (
|
||||
@@ -161,11 +162,8 @@ export const PermissionsDialog: FC<PermissionsDialogProps> = ({
|
||||
>
|
||||
<AccordionModelHead />
|
||||
{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<PermissionsDialogProps> = ({
|
||||
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();
|
||||
}}
|
||||
|
||||
@@ -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<IRole>;
|
||||
export const RoleDialog: FC<RoleDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: role,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -64,8 +65,8 @@ export const RoleDialog: FC<RoleDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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<RoleDialogProps> = ({
|
||||
}, [open, reset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
if (role) {
|
||||
reset({
|
||||
name: data.name,
|
||||
name: role.name,
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}, [data, reset]);
|
||||
}, [role, reset]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
<form onSubmit={handleSubmit(onSubmitForm)}>
|
||||
<DialogTitle onClose={closeDialog}>
|
||||
{data ? t("title.edit_role") : t("title.new_role")}
|
||||
{role ? t("title.edit_role") : t("title.new_role")}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
|
||||
@@ -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<IRole>(false);
|
||||
const editDialogCtl = useDialog<IRole>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(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],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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<EditSubscriberDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -65,17 +66,17 @@ export const EditSubscriberDialog: FC<EditSubscriberDialogProps> = ({
|
||||
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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
|
||||
@@ -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<ITranslation>;
|
||||
export const EditTranslationDialog: FC<EditTranslationDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum: translation,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -59,15 +60,15 @@ export const EditTranslationDialog: FC<EditTranslationDialogProps> = ({
|
||||
},
|
||||
});
|
||||
const { reset, control, handleSubmit } = useForm<ITranslationAttributes>({
|
||||
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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
@@ -78,7 +79,7 @@ export const EditTranslationDialog: FC<EditTranslationDialogProps> = ({
|
||||
<DialogContent>
|
||||
<ContentItem>
|
||||
<FormLabel>{t("label.original_text")}</FormLabel>
|
||||
<Typography component="p">{data?.str}</Typography>
|
||||
<Typography component="p">{translation?.str}</Typography>
|
||||
</ContentItem>
|
||||
<ContentContainer>
|
||||
{languages
|
||||
|
||||
@@ -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<ITranslation>(false);
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const { onSearch, searchPayload } = useSearch<ITranslation>({
|
||||
$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],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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<EditUserDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
datum,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
@@ -62,7 +63,7 @@ export const EditUserDialog: FC<EditUserDialogProps> = ({
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm<IUserAttributes>({
|
||||
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<EditUserDialogProps> = ({
|
||||
},
|
||||
};
|
||||
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 (
|
||||
<Dialog open={open} fullWidth onClose={closeDialog} {...rest}>
|
||||
@@ -108,7 +109,7 @@ export const EditUserDialog: FC<EditUserDialogProps> = ({
|
||||
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;
|
||||
|
||||
|
||||
@@ -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<BlockDialogProps> = ({
|
||||
open,
|
||||
data: block,
|
||||
datum: block,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
|
||||
@@ -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<DiagramEngine | undefined>();
|
||||
const [canvas, setCanvas] = useState<JSX.Element | undefined>();
|
||||
const [selectedBlockId, setSelectedBlockId] = useState<string | undefined>();
|
||||
const deleteDialogCtl = useDialog<string[]>(false);
|
||||
const moveDialogCtl = useDialog<string[] | string>(false);
|
||||
const deleteDialogCtl = useDialog<string>(false);
|
||||
const moveDialogCtl = useDialog<string>(false);
|
||||
const addCategoryDialogCtl = useDialog<ICategory>(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 = () => {
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<CategoryDialog {...getDisplayDialogs(addCategoryDialogCtl)} />
|
||||
<BlockDialog {...getDisplayDialogs(editDialogCtl)} />
|
||||
<DeleteDialog<string[]> {...deleteDialogCtl} callback={onDelete} />
|
||||
<DeleteDialog
|
||||
{...deleteDialogCtl}
|
||||
callback={async (data) => {
|
||||
if (Array.isArray(data)) onDelete(data);
|
||||
}}
|
||||
/>
|
||||
<MoveDialog
|
||||
open={moveDialogCtl.open}
|
||||
openDialog={moveDialogCtl.openDialog}
|
||||
{...moveDialogCtl}
|
||||
callback={onMove}
|
||||
closeDialog={moveDialogCtl.closeDialog}
|
||||
categories={categories}
|
||||
/>
|
||||
<Grid sx={{ bgcolor: "#fff", padding: "0" }}>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { DialogProps } from "@mui/material";
|
||||
import { Dispatch, SetStateAction, useState } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
export type DialogControlProps<T> = Omit<DialogControl<T>, "openDialog">;
|
||||
type TCloseDialog = <E extends React.MouseEvent | Event | Object>(
|
||||
@@ -15,19 +15,25 @@ type TCloseDialog = <E extends React.MouseEvent | Event | Object>(
|
||||
reason?: "backdropClick" | "escapeKeyDown",
|
||||
) => void;
|
||||
type TFnVoid<T> = (data?: T) => void;
|
||||
export type DialogControl<T = null> = DialogProps & {
|
||||
data?: T;
|
||||
setData?: Dispatch<SetStateAction<T | undefined>>;
|
||||
callback?: TFnVoid<T>;
|
||||
|
||||
export type DialogControl<T = never> = DialogProps & {
|
||||
data?: T[];
|
||||
datum?: T;
|
||||
setData?: TFnVoid<T[]>;
|
||||
callback?: (data?: T | T[]) => Promise<void>;
|
||||
openDialog: TFnVoid<T>;
|
||||
closeDialog: TCloseDialog;
|
||||
};
|
||||
|
||||
export const useDialog = <T,>(initialState: boolean): DialogControl<T> => {
|
||||
const [open, setOpen] = useState(initialState);
|
||||
const [data, setData] = useState<T | undefined>(undefined);
|
||||
const openDialog: TFnVoid<T> = (data) => {
|
||||
if (data) setData(data);
|
||||
const [data, setData] = useState<T[] | undefined>(undefined);
|
||||
const [datum, setDatum] = useState<T | undefined>(undefined);
|
||||
const openDialog: TFnVoid<T> = (datum) => {
|
||||
setDatum(datum);
|
||||
if (datum) {
|
||||
setData(undefined);
|
||||
}
|
||||
setOpen(true);
|
||||
};
|
||||
const closeDialog: TCloseDialog = (event, reason) => {
|
||||
@@ -36,11 +42,18 @@ export const useDialog = <T,>(initialState: boolean): DialogControl<T> => {
|
||||
}
|
||||
};
|
||||
|
||||
return { open, openDialog, closeDialog, data, setData };
|
||||
return {
|
||||
open,
|
||||
data,
|
||||
datum,
|
||||
setData,
|
||||
openDialog,
|
||||
closeDialog,
|
||||
};
|
||||
};
|
||||
|
||||
export const getDisplayDialogs = <T,>({
|
||||
open,
|
||||
closeDialog,
|
||||
data,
|
||||
}: DialogControl<T>): DialogControlProps<T> => ({ open, closeDialog, data });
|
||||
datum,
|
||||
}: DialogControl<T>): DialogControlProps<T> => ({ open, datum, closeDialog });
|
||||
|
||||
Reference in New Issue
Block a user