mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'data-layer-rewrite' of https://github.com/rowyio/rowy into data-layer-rewrite
This commit is contained in:
34
src/App.tsx
34
src/App.tsx
@@ -6,7 +6,7 @@ import Loading from "@src/components/Loading";
|
||||
import ProjectSourceFirebase from "@src/sources/ProjectSourceFirebase";
|
||||
import ConfirmDialog from "@src/components/ConfirmDialog";
|
||||
import RowyRunModal from "@src/components/RowyRunModal";
|
||||
import NotFound from "@src/pages/NotFound";
|
||||
import NotFound from "@src/pages/NotFoundPage";
|
||||
import RequireAuth from "@src/layouts/RequireAuth";
|
||||
|
||||
import {
|
||||
@@ -17,21 +17,21 @@ import {
|
||||
import { ROUTES } from "@src/constants/routes";
|
||||
import useKeyPressWithAtom from "@src/hooks/useKeyPressWithAtom";
|
||||
|
||||
import TableGroupRedirectPage from "./pages/TableGroupRedirect";
|
||||
import JotaiTestPage from "@src/pages/Test/JotaiTest";
|
||||
import SignOutPage from "@src/pages/Auth/SignOut";
|
||||
import TableGroupRedirectPage from "./pages/TableGroupRedirectPage";
|
||||
import JotaiTestPage from "@src/pages/Test/JotaiTestPage";
|
||||
import SignOutPage from "@src/pages/Auth/SignOutPage";
|
||||
|
||||
// prettier-ignore
|
||||
const AuthPage = lazy(() => import("@src/pages/Auth/index" /* webpackChunkName: "AuthPage" */));
|
||||
const AuthPage = lazy(() => import("@src/pages/Auth/AuthPage" /* webpackChunkName: "AuthPage" */));
|
||||
// prettier-ignore
|
||||
const SignUpPage = lazy(() => import("@src/pages/Auth/SignUp" /* webpackChunkName: "SignUpPage" */));
|
||||
const SignUpPage = lazy(() => import("@src/pages/Auth/SignUpPage" /* webpackChunkName: "SignUpPage" */));
|
||||
// prettier-ignore
|
||||
const JwtAuthPage = lazy(() => import("@src/pages/Auth/JwtAuth" /* webpackChunkName: "JwtAuthPage" */));
|
||||
const JwtAuthPage = lazy(() => import("@src/pages/Auth/JwtAuthPage" /* webpackChunkName: "JwtAuthPage" */));
|
||||
// prettier-ignore
|
||||
const ImpersonatorAuthPage = lazy(() => import("@src/pages/Auth/ImpersonatorAuth" /* webpackChunkName: "ImpersonatorAuthPage" */));
|
||||
const ImpersonatorAuthPage = lazy(() => import("@src/pages/Auth/ImpersonatorAuthPage" /* webpackChunkName: "ImpersonatorAuthPage" */));
|
||||
|
||||
// prettier-ignore
|
||||
const SetupPage = lazy(() => import("@src/pages/Setup" /* webpackChunkName: "SetupPage" */));
|
||||
const SetupPage = lazy(() => import("@src/pages/SetupPage" /* webpackChunkName: "SetupPage" */));
|
||||
|
||||
// prettier-ignore
|
||||
const Navigation = lazy(() => import("@src/layouts/Navigation" /* webpackChunkName: "Navigation" */));
|
||||
@@ -39,22 +39,22 @@ const Navigation = lazy(() => import("@src/layouts/Navigation" /* webpackChunkNa
|
||||
const TableSettingsDialog = lazy(() => import("@src/components/TableSettingsDialog" /* webpackChunkName: "TableSettingsDialog" */));
|
||||
|
||||
// prettier-ignore
|
||||
const TablesPage = lazy(() => import("@src/pages/Tables" /* webpackChunkName: "TablesPage" */));
|
||||
const TablesPage = lazy(() => import("@src/pages/TablesPage" /* webpackChunkName: "TablesPage" */));
|
||||
// prettier-ignore
|
||||
const TablePage = lazy(() => import("@src/pages/Table" /* webpackChunkName: "TablePage" */));
|
||||
const TablePage = lazy(() => import("@src/pages/TablePage" /* webpackChunkName: "TablePage" */));
|
||||
|
||||
// prettier-ignore
|
||||
const FunctionPage = lazy(() => import("@src/pages/Function" /* webpackChunkName: "FunctionPage" */));
|
||||
const FunctionPage = lazy(() => import("@src/pages/FunctionPage" /* webpackChunkName: "FunctionPage" */));
|
||||
// prettier-ignore
|
||||
const UserSettingsPage = lazy(() => import("@src/pages/Settings/UserSettings" /* webpackChunkName: "UserSettingsPage" */));
|
||||
const UserSettingsPage = lazy(() => import("@src/pages/Settings/UserSettingsPage" /* webpackChunkName: "UserSettingsPage" */));
|
||||
// prettier-ignore
|
||||
const ProjectSettingsPage = lazy(() => import("@src/pages/Settings/ProjectSettings" /* webpackChunkName: "ProjectSettingsPage" */));
|
||||
const ProjectSettingsPage = lazy(() => import("@src/pages/Settings/ProjectSettingsPage" /* webpackChunkName: "ProjectSettingsPage" */));
|
||||
// prettier-ignore
|
||||
const UserManagementPage = lazy(() => import("@src/pages/Settings/UserManagement" /* webpackChunkName: "UserManagementPage" */));
|
||||
const UserManagementPage = lazy(() => import("@src/pages/Settings/UserManagementPage" /* webpackChunkName: "UserManagementPage" */));
|
||||
|
||||
// prettier-ignore
|
||||
const ThemeTestPage = lazy(() => import("@src/pages/Test/ThemeTest" /* webpackChunkName: "ThemeTestPage" */));
|
||||
// const RowyRunTestPage = lazy(() => import("@src/pages/RowyRunTest" /* webpackChunkName: "RowyRunTestPage" */));
|
||||
const ThemeTestPage = lazy(() => import("@src/pages/Test/ThemeTestPage" /* webpackChunkName: "ThemeTestPage" */));
|
||||
// const RowyRunTestPage = lazy(() => import("@src/pages/RowyRunTestPage" /* webpackChunkName: "RowyRunTestPage" */));
|
||||
|
||||
export default function App() {
|
||||
const [currentUser] = useAtom(currentUserAtom, globalScope);
|
||||
|
||||
@@ -5,7 +5,7 @@ import MultiSelect from "@rowy/multiselect";
|
||||
import { Typography, Link } from "@mui/material";
|
||||
import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon";
|
||||
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettings";
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettingsPage";
|
||||
import { authOptions } from "@src/config/firebaseui";
|
||||
|
||||
export default function Authentication({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { lazy, Suspense, useState } from "react";
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettings";
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettingsPage";
|
||||
import { merge, unset } from "lodash-es";
|
||||
|
||||
import { FormControlLabel, Checkbox, Collapse } from "@mui/material";
|
||||
|
||||
@@ -13,7 +13,7 @@ import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon";
|
||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||
|
||||
import LogoRowyRun from "@src/assets/LogoRowyRun";
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettings";
|
||||
import { IProjectSettingsChildProps } from "@src/pages/Settings/ProjectSettingsPage";
|
||||
import { WIKI_LINKS } from "@src/constants/externalLinks";
|
||||
import useUpdateCheck from "@src/hooks/useUpdateCheck";
|
||||
import { runRoutes } from "@src/constants/runRoutes";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettings";
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettingsPage";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { Grid, Avatar, Typography, Button } from "@mui/material";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { lazy, Suspense, useState } from "react";
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettings";
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettingsPage";
|
||||
import { merge, unset } from "lodash-es";
|
||||
|
||||
import { FormControlLabel, Checkbox, Collapse } from "@mui/material";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useAtom } from "jotai";
|
||||
import { merge } from "lodash-es";
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettings";
|
||||
import { IUserSettingsChildProps } from "@src/pages/Settings/UserSettingsPage";
|
||||
|
||||
import {
|
||||
FormControl,
|
||||
|
||||
172
src/components/TableModals/ExportModal/ExportModal.tsx
Normal file
172
src/components/TableModals/ExportModal/ExportModal.tsx
Normal file
@@ -0,0 +1,172 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import { RESET } from "jotai/utils";
|
||||
import { ITableModalProps } from "@src/components/TableModals/TableModals";
|
||||
import {
|
||||
query as firestoreQuery,
|
||||
Query,
|
||||
collection,
|
||||
collectionGroup,
|
||||
where,
|
||||
orderBy,
|
||||
limit,
|
||||
} from "firebase/firestore";
|
||||
|
||||
import { DialogContent, Tab, Divider } from "@mui/material";
|
||||
import TabContext from "@mui/lab/TabContext";
|
||||
import TabList from "@mui/lab/TabList";
|
||||
import TabPanel from "@mui/lab/TabPanel";
|
||||
|
||||
import Modal from "@src/components/Modal";
|
||||
import ExportDetails from "./ModalContentsExport";
|
||||
import DownloadDetails from "./ModalContentsDownload";
|
||||
|
||||
import { globalScope } from "@src/atoms/globalScope";
|
||||
import {
|
||||
tableScope,
|
||||
tableSettingsAtom,
|
||||
tableFiltersAtom,
|
||||
tableOrdersAtom,
|
||||
tableModalAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { firebaseDbAtom } from "@src/sources/ProjectSourceFirebase";
|
||||
import { TableRow } from "@src/types/table";
|
||||
|
||||
export interface IExportModalContentsProps {
|
||||
query: Query<TableRow>;
|
||||
closeModal: () => void;
|
||||
}
|
||||
|
||||
// TODO: Generalize and remove Firestore dependencies
|
||||
export default function Export({ onClose }: ITableModalProps) {
|
||||
const setModal = useSetAtom(tableModalAtom, tableScope);
|
||||
const [mode, setMode] = useState<"Export" | "Download">("Export");
|
||||
|
||||
const [firebaseDb] = useAtom(firebaseDbAtom, globalScope);
|
||||
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
|
||||
const [tableFilters] = useAtom(tableFiltersAtom, tableScope);
|
||||
const [tableOrders] = useAtom(tableOrdersAtom, tableScope);
|
||||
|
||||
const tableCollection = tableSettings.collection;
|
||||
const isCollectionGroup = tableSettings.tableType === "collectionGroup";
|
||||
const query = useMemo(() => {
|
||||
const _path = tableCollection.replaceAll("~2F", "/") ?? "";
|
||||
let collectionRef = isCollectionGroup
|
||||
? (collectionGroup(firebaseDb, _path) as Query<TableRow>)
|
||||
: (collection(firebaseDb, _path) as Query<TableRow>);
|
||||
// add filters
|
||||
const filters = tableFilters.map((filter) =>
|
||||
where(filter.key, filter.operator, filter.value)
|
||||
);
|
||||
// optional order results
|
||||
const orders = tableOrders.map((order) =>
|
||||
orderBy(order.key, order.direction)
|
||||
);
|
||||
// TODO: paginate
|
||||
return firestoreQuery(collectionRef, ...filters, ...orders, limit(10_000));
|
||||
}, [
|
||||
firebaseDb,
|
||||
tableCollection,
|
||||
isCollectionGroup,
|
||||
tableFilters,
|
||||
tableOrders,
|
||||
]);
|
||||
|
||||
const handleClose = () => {
|
||||
setModal(RESET);
|
||||
setMode("Export");
|
||||
};
|
||||
|
||||
return (
|
||||
<TabContext value={mode}>
|
||||
<Modal
|
||||
onClose={handleClose}
|
||||
sx={{
|
||||
"& .MuiDialog-paper": {
|
||||
maxWidth: { sm: 440 },
|
||||
height: { sm: 640 },
|
||||
},
|
||||
}}
|
||||
title={mode}
|
||||
header={
|
||||
<>
|
||||
<DialogContent style={{ flexGrow: 0, flexShrink: 0 }}>
|
||||
{tableFilters.length !== 0 || tableOrders.length !== 0
|
||||
? "The filters and sorting applied to the table will be applied to the export"
|
||||
: "No filters or sorting will be applied on the exported data"}
|
||||
. Limited to 10,000 rows.
|
||||
</DialogContent>
|
||||
|
||||
<TabList
|
||||
onChange={(_, v) => setMode(v)}
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
variant="fullWidth"
|
||||
aria-label="Modal tabs"
|
||||
action={(actions) =>
|
||||
setTimeout(() => actions?.updateIndicator(), 200)
|
||||
}
|
||||
sx={{ mt: 1 }}
|
||||
>
|
||||
<Tab style={{ minWidth: 0 }} label="Export" value="Export" />
|
||||
<Tab
|
||||
style={{ minWidth: 0 }}
|
||||
label="Download attachments"
|
||||
value="Download"
|
||||
/>
|
||||
</TabList>
|
||||
<Divider style={{ marginTop: -1 }} />
|
||||
</>
|
||||
}
|
||||
ScrollableDialogContentProps={{
|
||||
disableTopDivider: true,
|
||||
disableBottomDivider: true,
|
||||
}}
|
||||
>
|
||||
<TabPanel
|
||||
value="Export"
|
||||
sx={{
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
marginBottom: "calc(var(--dialog-spacing) * -1)",
|
||||
padding: 0,
|
||||
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height:
|
||||
"calc(100% - var(--dialog-contents-spacing) + var(--dialog-spacing))",
|
||||
|
||||
"& > * + *": {
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
"&[hidden]": { display: "none" },
|
||||
}}
|
||||
>
|
||||
<ExportDetails query={query} closeModal={handleClose} />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel
|
||||
value="Download"
|
||||
sx={{
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
marginBottom: "calc(var(--dialog-spacing) * -1)",
|
||||
padding: 0,
|
||||
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height:
|
||||
"calc(100% - var(--dialog-contents-spacing) + var(--dialog-spacing))",
|
||||
|
||||
"& > * + *": {
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
"&[hidden]": { display: "none" },
|
||||
}}
|
||||
>
|
||||
<DownloadDetails query={query} closeModal={handleClose} />
|
||||
</TabPanel>
|
||||
</Modal>
|
||||
</TabContext>
|
||||
);
|
||||
}
|
||||
2
src/components/TableModals/ExportModal/index.ts
Normal file
2
src/components/TableModals/ExportModal/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./ExportModal";
|
||||
export { default } from "./ExportModal";
|
||||
@@ -8,6 +8,8 @@ const CloudLogsModal = lazy(() => import("./CloudLogsModal" /* webpackChunkName:
|
||||
// prettier-ignore
|
||||
const ExtensionsModal = lazy(() => import("./ExtensionsModal" /* webpackChunkName: "TableModals-ExtensionsModal" */));
|
||||
// prettier-ignore
|
||||
const ExportModal = lazy(() => import("./ExportModal" /* webpackChunkName: "TableModals-ExportModal" */));
|
||||
// prettier-ignore
|
||||
const WebhooksModal = lazy(() => import("./WebhooksModal" /* webpackChunkName: "TableModals-WebhooksModal" */));
|
||||
// prettier-ignore
|
||||
const ImportExistingWizard = lazy(() => import("./ImportExistingWizard" /* webpackChunkName: "TableModals-ImportExistingWizard" */));
|
||||
@@ -28,6 +30,7 @@ export default function TableModals() {
|
||||
if (tableModal === "cloudLogs") return <CloudLogsModal onClose={onClose} />;
|
||||
if (tableModal === "extensions") return <ExtensionsModal onClose={onClose} />;
|
||||
if (tableModal === "webhooks") return <WebhooksModal onClose={onClose} />;
|
||||
if (tableModal === "export") return <ExportModal onClose={onClose} />;
|
||||
if (tableModal === "importExisting")
|
||||
return <ImportExistingWizard onClose={onClose} />;
|
||||
if (tableModal === "importCsv") return <ImportCsvWizard onClose={onClose} />;
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import { RESET } from "jotai/utils";
|
||||
import {
|
||||
query as firestoreQuery,
|
||||
Query,
|
||||
collection,
|
||||
collectionGroup,
|
||||
where,
|
||||
orderBy,
|
||||
limit,
|
||||
} from "firebase/firestore";
|
||||
|
||||
import { DialogContent, Tab, Divider } from "@mui/material";
|
||||
import TabContext from "@mui/lab/TabContext";
|
||||
import TabList from "@mui/lab/TabList";
|
||||
import TabPanel from "@mui/lab/TabPanel";
|
||||
|
||||
import TableToolbarButton from "@src/components/TableToolbar/TableToolbarButton";
|
||||
import { Export as ExportIcon } from "@src/assets/icons";
|
||||
|
||||
import Modal from "@src/components/Modal";
|
||||
import ExportDetails from "./ModalContentsExport";
|
||||
import DownloadDetails from "./ModalContentsDownload";
|
||||
|
||||
import { globalScope } from "@src/atoms/globalScope";
|
||||
import {
|
||||
tableScope,
|
||||
tableSettingsAtom,
|
||||
tableFiltersAtom,
|
||||
tableOrdersAtom,
|
||||
tableModalAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { firebaseDbAtom } from "@src/sources/ProjectSourceFirebase";
|
||||
import { TableRow } from "@src/types/table";
|
||||
|
||||
export interface IExportModalContentsProps {
|
||||
query: Query<TableRow>;
|
||||
closeModal: () => void;
|
||||
}
|
||||
|
||||
// TODO: Generalize and remove Firestore dependencies
|
||||
export default function Export() {
|
||||
const [modal, setModal] = useAtom(tableModalAtom, tableScope);
|
||||
const open = modal === "export";
|
||||
const setOpen = (open: boolean) => setModal(open ? "export" : RESET);
|
||||
const [mode, setMode] = useState<"Export" | "Download">("Export");
|
||||
|
||||
const [firebaseDb] = useAtom(firebaseDbAtom, globalScope);
|
||||
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
|
||||
const [tableFilters] = useAtom(tableFiltersAtom, tableScope);
|
||||
const [tableOrders] = useAtom(tableOrdersAtom, tableScope);
|
||||
|
||||
const tableCollection = tableSettings.collection;
|
||||
const isCollectionGroup = tableSettings.tableType === "collectionGroup";
|
||||
const query = useMemo(() => {
|
||||
const _path = tableCollection.replaceAll("~2F", "/") ?? "";
|
||||
let collectionRef = isCollectionGroup
|
||||
? (collectionGroup(firebaseDb, _path) as Query<TableRow>)
|
||||
: (collection(firebaseDb, _path) as Query<TableRow>);
|
||||
// add filters
|
||||
const filters = tableFilters.map((filter) =>
|
||||
where(filter.key, filter.operator, filter.value)
|
||||
);
|
||||
// optional order results
|
||||
const orders = tableOrders.map((order) =>
|
||||
orderBy(order.key, order.direction)
|
||||
);
|
||||
// TODO: paginate
|
||||
return firestoreQuery(collectionRef, ...filters, ...orders, limit(10_000));
|
||||
}, [
|
||||
firebaseDb,
|
||||
tableCollection,
|
||||
isCollectionGroup,
|
||||
tableFilters,
|
||||
tableOrders,
|
||||
]);
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
setMode("Export");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableToolbarButton
|
||||
title="Export/Download"
|
||||
onClick={() => setOpen(true)}
|
||||
icon={<ExportIcon />}
|
||||
/>
|
||||
|
||||
{open && (
|
||||
<TabContext value={mode}>
|
||||
<Modal
|
||||
onClose={handleClose}
|
||||
sx={{
|
||||
"& .MuiDialog-paper": {
|
||||
maxWidth: { sm: 440 },
|
||||
height: { sm: 640 },
|
||||
},
|
||||
}}
|
||||
title={mode}
|
||||
header={
|
||||
<>
|
||||
<DialogContent style={{ flexGrow: 0, flexShrink: 0 }}>
|
||||
{tableFilters.length !== 0 || tableOrders.length !== 0
|
||||
? "The filters and sorting applied to the table will be applied to the export"
|
||||
: "No filters or sorting will be applied on the exported data"}
|
||||
. Limited to 10,000 rows.
|
||||
</DialogContent>
|
||||
|
||||
<TabList
|
||||
onChange={(_, v) => setMode(v)}
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
variant="fullWidth"
|
||||
aria-label="Modal tabs"
|
||||
action={(actions) =>
|
||||
setTimeout(() => actions?.updateIndicator(), 200)
|
||||
}
|
||||
sx={{ mt: 1 }}
|
||||
>
|
||||
<Tab style={{ minWidth: 0 }} label="Export" value="Export" />
|
||||
<Tab
|
||||
style={{ minWidth: 0 }}
|
||||
label="Download attachments"
|
||||
value="Download"
|
||||
/>
|
||||
</TabList>
|
||||
<Divider style={{ marginTop: -1 }} />
|
||||
</>
|
||||
}
|
||||
ScrollableDialogContentProps={{
|
||||
disableTopDivider: true,
|
||||
disableBottomDivider: true,
|
||||
}}
|
||||
>
|
||||
<TabPanel
|
||||
value="Export"
|
||||
sx={{
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
marginBottom: "calc(var(--dialog-spacing) * -1)",
|
||||
padding: 0,
|
||||
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height:
|
||||
"calc(100% - var(--dialog-contents-spacing) + var(--dialog-spacing))",
|
||||
|
||||
"& > * + *": {
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
"&[hidden]": { display: "none" },
|
||||
}}
|
||||
>
|
||||
<ExportDetails query={query} closeModal={handleClose} />
|
||||
</TabPanel>
|
||||
|
||||
<TabPanel
|
||||
value="Download"
|
||||
sx={{
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
marginBottom: "calc(var(--dialog-spacing) * -1)",
|
||||
padding: 0,
|
||||
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height:
|
||||
"calc(100% - var(--dialog-contents-spacing) + var(--dialog-spacing))",
|
||||
|
||||
"& > * + *": {
|
||||
marginTop: "var(--dialog-contents-spacing)",
|
||||
},
|
||||
"&[hidden]": { display: "none" },
|
||||
}}
|
||||
>
|
||||
<DownloadDetails query={query} closeModal={handleClose} />
|
||||
</TabPanel>
|
||||
</Modal>
|
||||
</TabContext>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./Export";
|
||||
export { default } from "./Export";
|
||||
@@ -4,6 +4,7 @@ import { useAtom, useSetAtom } from "jotai";
|
||||
import { Stack } from "@mui/material";
|
||||
import WebhookIcon from "@mui/icons-material/Webhook";
|
||||
import {
|
||||
Export as ExportIcon,
|
||||
Extension as ExtensionIcon,
|
||||
CloudLogs as CloudLogsIcon,
|
||||
} from "@src/assets/icons";
|
||||
@@ -34,8 +35,6 @@ import { FieldType } from "@src/constants/fields";
|
||||
// prettier-ignore
|
||||
const Filters = lazy(() => import("./Filters" /* webpackChunkName: "Filters" */));
|
||||
// prettier-ignore
|
||||
const Export = lazy(() => import("./Export" /* webpackChunkName: "Export" */));
|
||||
// prettier-ignore
|
||||
const ImportCsv = lazy(() => import("./ImportCsv" /* webpackChunkName: "ImportCsv" */));
|
||||
// prettier-ignore
|
||||
const ReExecute = lazy(() => import("./ReExecute" /* webpackChunkName: "ReExecute" */));
|
||||
@@ -101,7 +100,11 @@ export default function TableToolbar() {
|
||||
</Suspense>
|
||||
)}
|
||||
<Suspense fallback={<ButtonSkeleton />}>
|
||||
<Export />
|
||||
<TableToolbarButton
|
||||
title="Export/Download"
|
||||
onClick={() => openTableModal("export")}
|
||||
icon={<ExportIcon />}
|
||||
/>
|
||||
</Suspense>
|
||||
{userRoles.includes("ADMIN") && (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user