From 420a5fc4dfef309b36f5280fabe883d272cb6ecb Mon Sep 17 00:00:00 2001 From: Jose Nieves Date: Sun, 19 Dec 2021 13:48:30 +0100 Subject: [PATCH 1/2] #30-feat: implement action bar component --- .../03-organisms/Actions/actionBar.tsx | 60 +++++++++++++++++++ .../components/03-organisms/Actions/index.ts | 3 + 2 files changed, 63 insertions(+) create mode 100644 decide/administration/frontend/src/components/03-organisms/Actions/actionBar.tsx create mode 100644 decide/administration/frontend/src/components/03-organisms/Actions/index.ts diff --git a/decide/administration/frontend/src/components/03-organisms/Actions/actionBar.tsx b/decide/administration/frontend/src/components/03-organisms/Actions/actionBar.tsx new file mode 100644 index 0000000000..8a53803ba2 --- /dev/null +++ b/decide/administration/frontend/src/components/03-organisms/Actions/actionBar.tsx @@ -0,0 +1,60 @@ +import React, { ReactElement } from "react"; + +import { Box } from "@mui/system"; +import { Divider } from "@mui/material"; +import { IconButton } from "components/01-atoms"; + +type Action = { + title: string; + icon: ReactElement; + onClick?: () => void; +}; + +const Component = (props: { + selection?: any[]; + actions?: ReactElement[]; + selectedActions?: Action[]; + bulkActions?: Action[]; +}) => { + const individualEnabled = React.useMemo( + () => props.selection && props.selection?.length === 1, + [props.selection] + ); + const bulkEnabled = React.useMemo( + () => props.selection && props.selection.length >= 1, + [props.selection] + ); + + return ( + + + {props.actions} + + {props.selectedActions?.map((action, index) => ( + + ))} + + {props.bulkActions?.map((action, index) => ( + + ))} + + + ); +}; + +export default Component; diff --git a/decide/administration/frontend/src/components/03-organisms/Actions/index.ts b/decide/administration/frontend/src/components/03-organisms/Actions/index.ts new file mode 100644 index 0000000000..97acd74418 --- /dev/null +++ b/decide/administration/frontend/src/components/03-organisms/Actions/index.ts @@ -0,0 +1,3 @@ +import ActionBar from "./actionBar"; + +export { ActionBar }; From 805b4e895315ea909f38dab76d252d611b3e1d91 Mon Sep 17 00:00:00 2001 From: Jose Nieves Date: Sun, 19 Dec 2021 13:48:51 +0100 Subject: [PATCH 2/2] #30-feat: integrate action bar component --- .../components/02-molecules/Table/table.tsx | 11 ++++- .../src/components/03-organisms/index.ts | 4 +- .../frontend/src/components/pages/page.tsx | 5 +-- .../src/components/pages/users/users.tsx | 44 ++++++++++++++++--- .../templates/users/newUserForm.tsx | 14 +++--- .../components/templates/users/userTable.tsx | 11 +++-- 6 files changed, 70 insertions(+), 19 deletions(-) diff --git a/decide/administration/frontend/src/components/02-molecules/Table/table.tsx b/decide/administration/frontend/src/components/02-molecules/Table/table.tsx index 9d7d42e2ee..7ea2d95ae9 100644 --- a/decide/administration/frontend/src/components/02-molecules/Table/table.tsx +++ b/decide/administration/frontend/src/components/02-molecules/Table/table.tsx @@ -2,7 +2,15 @@ import * as React from "react"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; -const Component = (props: { rows: any[]; columns: GridColDef[] }) => { +const Component = (props: { + rows: any[]; + columns: GridColDef[]; + setSelected: any; +}) => { + const filterRows = (ids: any[]) => { + return props.rows.filter((row: any) => ids.includes(row.id)); + }; + return (
{ rows={props.rows} columns={props.columns} checkboxSelection + onSelectionModelChange={(e) => props.setSelected(filterRows(e))} />
); diff --git a/decide/administration/frontend/src/components/03-organisms/index.ts b/decide/administration/frontend/src/components/03-organisms/index.ts index cb0ff5c3b5..7471c3f3f5 100644 --- a/decide/administration/frontend/src/components/03-organisms/index.ts +++ b/decide/administration/frontend/src/components/03-organisms/index.ts @@ -1 +1,3 @@ -export {}; +import { ActionBar } from "./Actions"; + +export { ActionBar }; diff --git a/decide/administration/frontend/src/components/pages/page.tsx b/decide/administration/frontend/src/components/pages/page.tsx index 4d1ffd8b6a..c974858d75 100644 --- a/decide/administration/frontend/src/components/pages/page.tsx +++ b/decide/administration/frontend/src/components/pages/page.tsx @@ -9,15 +9,12 @@ const Page = (props: { }) => { return ( <> - + <Box id="content" className="m-2 inline-block w-10/12"> {props.children} </Box> </Box> - <Box id="actions" className="m-2 inline-block w-1/12"> - {" "} - </Box> </> ); }; diff --git a/decide/administration/frontend/src/components/pages/users/users.tsx b/decide/administration/frontend/src/components/pages/users/users.tsx index 8986da52b1..3d1d6dc5a5 100644 --- a/decide/administration/frontend/src/components/pages/users/users.tsx +++ b/decide/administration/frontend/src/components/pages/users/users.tsx @@ -1,8 +1,13 @@ import React from "react"; +import { Delete } from "@mui/icons-material"; + +import { userApi } from "api"; +import { userType } from "types"; + +import { ActionBar } from "components/03-organisms"; import { NewUserForm, UserTable } from "components/templates/users"; import Page from "../page"; -import { userApi } from "api"; // todo: fetch users from api and set rows to the response const rows = [ @@ -19,6 +24,7 @@ const rows = [ const UsersPage = () => { const [users, setUsers] = React.useState(rows); + const [selected, setSelected] = React.useState([]); React.useEffect(() => { userApi.getUsers().then((response) => { @@ -27,11 +33,39 @@ const UsersPage = () => { }); }, []); + const idList = React.useMemo( + () => selected.map((user: userType.User) => user.id), + [selected] + ); + + const handleDelete = () => { + console.log(idList); + }; + return ( - <Page title="Users"> - <UserTable users={users || rows} /> - <NewUserForm /> - </Page> + <> + <Page title="Users"> + <UserTable users={users || rows} setSelected={setSelected} /> + </Page> + <ActionBar + selection={selected} + actions={[ + <NewUserForm + initialUser={selected.length === 1 ? selected[0] : undefined} + />, + ]} + bulkActions={[ + { + icon: <Delete />, + title: "Delete", + onClick: () => { + console.log("delete"); + handleDelete(); + }, + }, + ]} + /> + </> ); }; diff --git a/decide/administration/frontend/src/components/templates/users/newUserForm.tsx b/decide/administration/frontend/src/components/templates/users/newUserForm.tsx index 89b4192a6b..47058ebbfc 100644 --- a/decide/administration/frontend/src/components/templates/users/newUserForm.tsx +++ b/decide/administration/frontend/src/components/templates/users/newUserForm.tsx @@ -2,16 +2,18 @@ import React from "react"; import { SubmitHandler, useForm } from "react-hook-form"; import { userType } from "types"; import { ModalPage, Modal } from "components/02-molecules"; -import { Add } from "@mui/icons-material"; +import { Add, Edit } from "@mui/icons-material"; import { FormItem } from "components/01-atoms/Input"; -const Component = (props: { initialUser?: userType.User[] }) => { +const Component = (props: { initialUser?: userType.User }) => { const { control, getValues, setError, formState: { errors }, - } = useForm<{ username: string; username2: string }>(); + } = useForm<{ username: string; username2: string }>({ + defaultValues: { username: props.initialUser?.firstName || "" }, + }); const [sent, setSent] = React.useState(false); @@ -23,6 +25,8 @@ const Component = (props: { initialUser?: userType.User[] }) => { const onSubmit: SubmitHandler<{ username: string; username2: string }> = ( data ) => { + //todo: if initialUser empty then call create new user + //todo: if initialUser is not empty, then call update console.log("submit:", data); //Todo: call api and create user, //Todo: if created then close modal if not, call onSubmitFailed @@ -35,7 +39,7 @@ const Component = (props: { initialUser?: userType.User[] }) => { <Modal onSubmit={() => onSubmit(getValues())} title="New User" - openerIcon={<Add />} + openerIcon={props.initialUser ? <Edit /> : <Add />} externalClose={sent} pages={[ <ModalPage description="Indique la informaciĆ³n del Usuario"> @@ -43,7 +47,7 @@ const Component = (props: { initialUser?: userType.User[] }) => { control={control} name="username" error={errors.username?.message} - ></FormItem.TextInput> + /> </ModalPage>, ]} /> diff --git a/decide/administration/frontend/src/components/templates/users/userTable.tsx b/decide/administration/frontend/src/components/templates/users/userTable.tsx index dd7084c92b..a0cc21a80c 100644 --- a/decide/administration/frontend/src/components/templates/users/userTable.tsx +++ b/decide/administration/frontend/src/components/templates/users/userTable.tsx @@ -7,7 +7,6 @@ import { Table } from "components/02-molecules"; // todo: set correct columns const columns: GridColDef[] = [ - { field: "id", headerName: "ID" }, { field: "firstName", headerName: "First name", @@ -26,8 +25,14 @@ const columns: GridColDef[] = [ }, ]; -const Component = (props: { users: userType.User[] }) => { - return <Table rows={props.users} columns={columns} />; +const Component = (props: { users: userType.User[]; setSelected: any }) => { + return ( + <Table + rows={props.users} + columns={columns} + setSelected={props.setSelected} + /> + ); }; export default Component;