mirror of
https://github.com/hexastack/hexabot
synced 2024-11-24 04:53:41 +00:00
Merge pull request #102 from Hexastack/fix/align-datagrid-switch
fix(frontend): align data grid toggle action
This commit is contained in:
commit
04ce4f2c87
@ -42,7 +42,6 @@ export class UserStub extends BaseSchema {
|
||||
|
||||
@Prop({
|
||||
type: String,
|
||||
unique: true,
|
||||
required: true,
|
||||
})
|
||||
password: string;
|
||||
|
@ -6,11 +6,12 @@
|
||||
* 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 { styled } from "@mui/material";
|
||||
import { useTheme } from "@mui/material";
|
||||
import {
|
||||
DataGridProps,
|
||||
gridClasses,
|
||||
GridColDef,
|
||||
GridValidRowModel,
|
||||
DataGrid as MuiDataGrid,
|
||||
} from "@mui/x-data-grid";
|
||||
|
||||
@ -18,22 +19,34 @@ import { renderHeader } from "./columns/renderHeader";
|
||||
import { styledPaginationSlots } from "./DataGridStyledPagination";
|
||||
import { NoDataOverlay } from "./NoDataOverlay";
|
||||
|
||||
const StyledDataGrid = styled(MuiDataGrid)(({ theme }) => ({
|
||||
"& .MuiDataGrid-overlayWrapper": {
|
||||
height: "fit-content",
|
||||
},
|
||||
export const StyledDataGrid = <T extends GridValidRowModel = any>(
|
||||
props: DataGridProps<T>,
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
const { sx, ...otherProps } = props;
|
||||
|
||||
[`& .${gridClasses.row}`]: {
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
"@media (hover: none)": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
return (
|
||||
<MuiDataGrid
|
||||
{...otherProps}
|
||||
sx={{
|
||||
"& .MuiDataGrid-overlayWrapper": {
|
||||
height: "fit-content",
|
||||
},
|
||||
[`& .${gridClasses.row}`]: {
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
"@media (hover: none)": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
},
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const DataGrid = ({
|
||||
export const DataGrid = <T extends GridValidRowModel = any>({
|
||||
columns,
|
||||
rows = [],
|
||||
autoHeight = true,
|
||||
@ -46,8 +59,8 @@ export const DataGrid = ({
|
||||
showColumnVerticalBorder = false,
|
||||
sx = { border: "none" },
|
||||
...rest
|
||||
}: DataGridProps) => {
|
||||
const styledColumns: GridColDef[] = columns.map((col) => ({
|
||||
}: DataGridProps<T>) => {
|
||||
const styledColumns: GridColDef<T>[] = columns.map((col) => ({
|
||||
disableColumnMenu: true,
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
@ -56,7 +69,7 @@ export const DataGrid = ({
|
||||
}));
|
||||
|
||||
return (
|
||||
<StyledDataGrid
|
||||
<StyledDataGrid<T>
|
||||
autoHeight={autoHeight}
|
||||
disableRowSelectionOnClick={disableRowSelectionOnClick}
|
||||
slots={slots}
|
||||
|
@ -9,7 +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 { Button, Chip, Grid, Paper, Typography } from "@mui/material";
|
||||
import { Button, Chip, Grid, Paper, Switch, Typography } from "@mui/material";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@ -24,13 +24,14 @@ import { renderHeader } from "@/app-components/tables/columns/renderHeader";
|
||||
import { DataGrid } from "@/app-components/tables/DataGrid";
|
||||
import { useDelete } from "@/hooks/crud/useDelete";
|
||||
import { useFind } from "@/hooks/crud/useFind";
|
||||
import { useGet } from "@/hooks/crud/useGet";
|
||||
import { useGet, useGetFromCache } from "@/hooks/crud/useGet";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { getDisplayDialogs, useDialog } from "@/hooks/useDialog";
|
||||
import { useHasPermission } from "@/hooks/useHasPermission";
|
||||
import { useSearch } from "@/hooks/useSearch";
|
||||
import { useToast } from "@/hooks/useToast";
|
||||
import { PageHeader } from "@/layout/content/PageHeader";
|
||||
import { EntityType } from "@/services/types";
|
||||
import { EntityType, Format } from "@/services/types";
|
||||
import { IContentType } from "@/types/content-type.types";
|
||||
import { IContent } from "@/types/content.types";
|
||||
import { PermissionAction } from "@/types/permission.types";
|
||||
@ -62,17 +63,26 @@ export const Contents = () => {
|
||||
entity: EntityType.CONTENT_TYPE,
|
||||
});
|
||||
const { dataGridProps } = useFind(
|
||||
{ entity: EntityType.CONTENT },
|
||||
{ entity: EntityType.CONTENT, format: Format.FULL },
|
||||
{
|
||||
params: searchPayload,
|
||||
},
|
||||
);
|
||||
const { mutateAsync: updateContent } = useUpdate(EntityType.CONTENT, {
|
||||
onError: (error) => {
|
||||
toast.error(error.message || t("message.internal_server_error"));
|
||||
},
|
||||
onSuccess() {
|
||||
toast.success(t("message.success_save"));
|
||||
},
|
||||
});
|
||||
const { mutateAsync: deleteContent } = useDelete(EntityType.CONTENT, {
|
||||
onSuccess: () => {
|
||||
deleteDialogCtl.closeDialog();
|
||||
toast.success(t("message.item_delete_success"));
|
||||
},
|
||||
});
|
||||
const getEntityFromCache = useGetFromCache(EntityType.CONTENT_TYPE);
|
||||
const actionColumns = useActionColumns<IContent>(
|
||||
EntityType.CONTENT,
|
||||
[
|
||||
@ -108,7 +118,7 @@ export const Contents = () => {
|
||||
|
||||
<PageHeader
|
||||
icon={faAlignLeft}
|
||||
chip={<Chip label={data?.name} variant="title" />}
|
||||
chip={<Chip label={data?.name} size="medium" variant="title" />}
|
||||
title={t("title.content")}
|
||||
>
|
||||
<Grid justifyContent="flex-end" gap={1} container alignItems="center">
|
||||
@ -143,7 +153,7 @@ export const Contents = () => {
|
||||
|
||||
<Grid padding={2} container>
|
||||
<Grid item width="100%">
|
||||
<DataGrid
|
||||
<DataGrid<IContent>
|
||||
{...dataGridProps}
|
||||
disableColumnFilter
|
||||
showCellVerticalBorder={false}
|
||||
@ -155,25 +165,39 @@ export const Contents = () => {
|
||||
field: "entity",
|
||||
headerName: t("label.entity"),
|
||||
flex: 1,
|
||||
valueGetter: (row) => row["name"],
|
||||
valueGetter: (row: IContent) => {
|
||||
const contentType = getEntityFromCache(row.id);
|
||||
|
||||
return contentType?.name;
|
||||
},
|
||||
},
|
||||
{
|
||||
maxWidth: 120,
|
||||
field: "status",
|
||||
headerName: t("label.status"),
|
||||
resizable: false,
|
||||
disableColumnMenu: true,
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
renderCell: (params) => (
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Chip
|
||||
label={t(
|
||||
params.row.status
|
||||
? "label.enabled"
|
||||
: "label.disabled",
|
||||
)}
|
||||
variant={params.row.status ? "enabled" : "disabled"}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Switch
|
||||
checked={params.value}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "primary checkbox" }}
|
||||
disabled={
|
||||
!hasPermission(
|
||||
EntityType.CONTENT,
|
||||
PermissionAction.UPDATE,
|
||||
)
|
||||
}
|
||||
onChange={() => {
|
||||
updateContent({
|
||||
id: params.row.id,
|
||||
params: {
|
||||
status: !params.row.status,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -107,6 +107,9 @@ export const ContextVars = () => {
|
||||
checked={params.value}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "primary checkbox" }}
|
||||
disabled={
|
||||
!hasPermission(EntityType.CONTEXT_VAR, PermissionAction.UPDATE)
|
||||
}
|
||||
onChange={() => {
|
||||
updateContextVar({
|
||||
id: params.row.id,
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import { Flag } from "@mui/icons-material";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import { Button, Grid, Paper } from "@mui/material";
|
||||
import { Button, Grid, Paper, Switch } from "@mui/material";
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useQueryClient } from "react-query";
|
||||
@ -92,13 +92,6 @@ export const Languages = () => {
|
||||
const actionColumns = useActionColumns<ILanguage>(
|
||||
EntityType.LANGUAGE,
|
||||
[
|
||||
{
|
||||
label: ActionColumnLabel.Toggle,
|
||||
action: (row) => toggleDefault(row),
|
||||
requires: [PermissionAction.UPDATE],
|
||||
getState: (row) => row.isDefault,
|
||||
helperText: t("button.mark_as_default"),
|
||||
},
|
||||
{
|
||||
label: ActionColumnLabel.Edit,
|
||||
action: (row) => editDialogCtl.openDialog(row),
|
||||
@ -131,15 +124,6 @@ export const Languages = () => {
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
},
|
||||
{
|
||||
flex: 1,
|
||||
field: "isDefault",
|
||||
headerName: t("label.is_default"),
|
||||
disableColumnMenu: true,
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
valueGetter: (value) => (value ? t("label.yes") : t("label.no")),
|
||||
},
|
||||
{
|
||||
flex: 1,
|
||||
field: "isRTL",
|
||||
@ -149,6 +133,28 @@ export const Languages = () => {
|
||||
headerAlign: "left",
|
||||
valueGetter: (value) => (value ? t("label.yes") : t("label.no")),
|
||||
},
|
||||
{
|
||||
maxWidth: 120,
|
||||
field: "isDefault",
|
||||
headerName: t("label.is_default"),
|
||||
disableColumnMenu: true,
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
renderCell: (params) => (
|
||||
<Switch
|
||||
checked={params.value}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "primary checkbox" }}
|
||||
disabled={
|
||||
params.value ||
|
||||
!hasPermission(EntityType.LANGUAGE, PermissionAction.UPDATE)
|
||||
}
|
||||
onChange={() => {
|
||||
toggleDefault(params.row);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
minWidth: 140,
|
||||
field: "createdAt",
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import { faUsers } from "@fortawesome/free-solid-svg-icons";
|
||||
import PersonAddAlt1Icon from "@mui/icons-material/PersonAddAlt1";
|
||||
import { Button, Grid, Paper } from "@mui/material";
|
||||
import { Button, Grid, Paper, Switch } from "@mui/material";
|
||||
import { GridColDef } from "@mui/x-data-grid";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@ -23,6 +23,7 @@ import { buildRenderPicture } from "@/app-components/tables/columns/renderPictur
|
||||
import { DataGrid } from "@/app-components/tables/DataGrid";
|
||||
import { useFind } from "@/hooks/crud/useFind";
|
||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||
import { useAuth } from "@/hooks/useAuth";
|
||||
import { useConfig } from "@/hooks/useConfig";
|
||||
import { getDisplayDialogs, useDialog } from "@/hooks/useDialog";
|
||||
import { useHasPermission } from "@/hooks/useHasPermission";
|
||||
@ -42,6 +43,7 @@ export const Users = () => {
|
||||
const { ssoEnabled } = useConfig();
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const { user } = useAuth();
|
||||
const { mutateAsync: updateUser } = useUpdate(EntityType.USER, {
|
||||
onError: (error) => {
|
||||
toast.error(error.message || t("message.internal_server_error"));
|
||||
@ -136,33 +138,29 @@ export const Users = () => {
|
||||
maxWidth: 120,
|
||||
field: "state",
|
||||
headerName: t("label.status"),
|
||||
resizable: false,
|
||||
disableColumnMenu: true,
|
||||
renderCell: (params) => (
|
||||
<Grid justifyContent="center" alignItems="center">
|
||||
<Button
|
||||
variant="contained"
|
||||
color={params.row.state ? "success" : "error"}
|
||||
sx={{
|
||||
paddingX: 2,
|
||||
paddingY: 1,
|
||||
}}
|
||||
onClick={() => {
|
||||
updateUser({
|
||||
id: params.row.id,
|
||||
params: {
|
||||
state: !params.row.state,
|
||||
},
|
||||
});
|
||||
}}
|
||||
disabled={ssoEnabled}
|
||||
>
|
||||
{t(params.row.state ? "label.enabled" : "label.disabled")}
|
||||
</Button>
|
||||
</Grid>
|
||||
),
|
||||
headerAlign: "center",
|
||||
renderHeader,
|
||||
headerAlign: "left",
|
||||
renderCell: (params) => (
|
||||
<Switch
|
||||
checked={params.value}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "primary checkbox" }}
|
||||
disabled={
|
||||
params.row.id === user?.id ||
|
||||
ssoEnabled ||
|
||||
!hasPermission(EntityType.USER, PermissionAction.UPDATE)
|
||||
}
|
||||
onChange={() => {
|
||||
updateUser({
|
||||
id: params.row.id,
|
||||
params: {
|
||||
state: !params.row.state,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
minWidth: 140,
|
||||
|
Loading…
Reference in New Issue
Block a user