mirror of
https://github.com/hexastack/hexabot
synced 2025-01-22 18:45:57 +00:00
fix: add content import functionality
This commit is contained in:
parent
e70c705d10
commit
e0dd09d491
99
frontend/src/components/contents/ContentImportDialog.tsx
Normal file
99
frontend/src/components/contents/ContentImportDialog.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright © 2024 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 CloseIcon from "@mui/icons-material/Close";
|
||||
import { Button, Dialog, DialogActions, DialogContent } from "@mui/material";
|
||||
import { FC, useState } from "react";
|
||||
import { useQuery } from "react-query";
|
||||
|
||||
import AttachmentInput from "@/app-components/attachment/AttachmentInput";
|
||||
import { DialogTitle } from "@/app-components/dialogs/DialogTitle";
|
||||
import { ContentContainer } from "@/app-components/dialogs/layouts/ContentContainer";
|
||||
import { ContentItem } from "@/app-components/dialogs/layouts/ContentItem";
|
||||
import { useApiClient } from "@/hooks/useApiClient";
|
||||
import { DialogControlProps } from "@/hooks/useDialog";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { useTranslate } from "@/hooks/useTranslate";
|
||||
import { IContentType } from "@/types/content-type.types";
|
||||
|
||||
export type ContentImportDialogProps = DialogControlProps<{
|
||||
contentType?: IContentType;
|
||||
}>;
|
||||
|
||||
export const ContentImportDialog: FC<ContentImportDialogProps> = ({
|
||||
open,
|
||||
data,
|
||||
closeDialog,
|
||||
...rest
|
||||
}) => {
|
||||
const [attachmentId, setAttachementId] = useState<string | null>(null);
|
||||
const { t } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const { apiClient } = useApiClient();
|
||||
const { refetch, isFetching } = useQuery(
|
||||
["importContent", data?.contentType?.id, attachmentId],
|
||||
async () => {
|
||||
await apiClient.importContent(data?.contentType?.id!, attachmentId!)},
|
||||
{
|
||||
enabled: false,
|
||||
onSuccess: () => {
|
||||
handleCloseDialog();
|
||||
toast.success(t("message.success_save"));
|
||||
},
|
||||
onError: () => {
|
||||
toast.error(t("message.internal_server_error"));
|
||||
},
|
||||
}
|
||||
);
|
||||
const handleCloseDialog = () => {
|
||||
closeDialog();
|
||||
setAttachementId(null);
|
||||
};
|
||||
const handleImportClick = () => {
|
||||
if (attachmentId && data?.contentType?.id) {
|
||||
refetch();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth onClose={handleCloseDialog} {...rest}>
|
||||
<DialogTitle onClose={handleCloseDialog}>{t("title.import")}</DialogTitle>
|
||||
<DialogContent>
|
||||
<ContentContainer>
|
||||
<ContentItem>
|
||||
<AttachmentInput
|
||||
format="basic"
|
||||
accept="text/csv"
|
||||
onChange={(id, _) => {
|
||||
setAttachementId(id);
|
||||
}}
|
||||
label=""
|
||||
value={attachmentId}
|
||||
/>
|
||||
</ContentItem>
|
||||
</ContentContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
disabled={!attachmentId || isFetching}
|
||||
onClick={handleImportClick}
|
||||
>
|
||||
{t("button.import")}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<CloseIcon />}
|
||||
variant="outlined"
|
||||
onClick={handleCloseDialog}
|
||||
disabled={isFetching}
|
||||
>
|
||||
{t("button.cancel")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
@ -9,6 +9,7 @@
|
||||
import { faAlignLeft } from "@fortawesome/free-solid-svg-icons";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import UploadIcon from "@mui/icons-material/Upload";
|
||||
import { Button, Chip, Grid, Paper, Switch, Typography } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
@ -38,6 +39,7 @@ import { PermissionAction } from "@/types/permission.types";
|
||||
import { getDateTimeFormatter } from "@/utils/date";
|
||||
|
||||
import { ContentDialog } from "./ContentDialog";
|
||||
import { ContentImportDialog } from "./ContentImportDialog";
|
||||
|
||||
export const Contents = () => {
|
||||
const { t } = useTranslate();
|
||||
@ -58,6 +60,9 @@ export const Contents = () => {
|
||||
$eq: [{ entity: String(query.id) }],
|
||||
$iLike: ["title"],
|
||||
});
|
||||
const importDialogCtl = useDialog<{
|
||||
contentType?: IContentType;
|
||||
}>(false);
|
||||
const hasPermission = useHasPermission();
|
||||
const { data: contentType } = useGet(String(query.id), {
|
||||
entity: EntityType.CONTENT_TYPE,
|
||||
@ -137,6 +142,18 @@ export const Contents = () => {
|
||||
</Button>
|
||||
</Grid>
|
||||
) : null}
|
||||
{hasPermission(EntityType.CONTENT, PermissionAction.CREATE) ? (
|
||||
<Grid item>
|
||||
<Button
|
||||
startIcon={<UploadIcon />}
|
||||
variant="contained"
|
||||
onClick={() => importDialogCtl.openDialog({ contentType })}
|
||||
sx={{ float: "right" }}
|
||||
>
|
||||
{t("button.import")}
|
||||
</Button>
|
||||
</Grid>
|
||||
) : null}
|
||||
</Grid>
|
||||
</PageHeader>
|
||||
</Grid>
|
||||
@ -144,6 +161,7 @@ export const Contents = () => {
|
||||
<Paper>
|
||||
<ContentDialog {...getDisplayDialogs(addDialogCtl)} />
|
||||
<ContentDialog {...getDisplayDialogs(editDialogCtl)} />
|
||||
<ContentImportDialog {...getDisplayDialogs(importDialogCtl)} />
|
||||
<DeleteDialog
|
||||
{...deleteDialogCtl}
|
||||
callback={() => {
|
||||
|
@ -35,6 +35,7 @@ export const ROUTES = {
|
||||
RESET: "/user/reset",
|
||||
NLP_SAMPLE_IMPORT: "/nlpsample/import",
|
||||
NLP_SAMPLE_PREDICT: "/nlpsample/message",
|
||||
CONTENT_IMPORT: "/content/import",
|
||||
// Entities
|
||||
[EntityType.SUBSCRIBER]: "/subscriber",
|
||||
[EntityType.LABEL]: "/label",
|
||||
@ -209,6 +210,14 @@ export class ApiClient {
|
||||
return data;
|
||||
}
|
||||
|
||||
async importContent(contentTypeId: string, attachementId: string) {
|
||||
const { data } = await this.request.get(
|
||||
`${ROUTES.CONTENT_IMPORT}/${contentTypeId}/${attachementId}`,
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async predictNlp(text: string) {
|
||||
const { data } = await this.request.get<INlpDatasetSampleAttributes>(
|
||||
`${ROUTES.NLP_SAMPLE_PREDICT}`,
|
||||
|
Loading…
Reference in New Issue
Block a user