Skip to content

Commit

Permalink
cms, jsk, emp global search frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
saigonbitmaster committed Apr 15, 2023
1 parent 04f8344 commit 9e772a4
Show file tree
Hide file tree
Showing 6 changed files with 785 additions and 35 deletions.
4 changes: 2 additions & 2 deletions api/src/customapi/search.controller.ts
Expand Up @@ -23,13 +23,13 @@ export class SearchController {
const result: any = await this.service.findAllEmp(mongooseQuery.filter);
return res.json(result);
}

@Get('searchjsk')
async indexJsk(@Response() res: any, @Query() query) {
const mongooseQuery = queryTransform(query);
const result: any = await this.service.findAllJsk(mongooseQuery.filter);
return res.json(result);
}

@Get('searchcms')
async indexCms(@Response() res: any, @Query() query) {
const mongooseQuery = queryTransform(query);
const result: any = await this.service.findAllCms(mongooseQuery.filter);
Expand Down
166 changes: 155 additions & 11 deletions cms/src/layout/search.tsx
Expand Up @@ -2,6 +2,14 @@ import * as React from "react";
import { styled, alpha } from "@mui/material/styles";
import InputBase from "@mui/material/InputBase";
import SearchIcon from "@mui/icons-material/Search";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";
import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined";
import IconButton from "@mui/material/IconButton";
import SearchResult from "./searchResult";

import { useDataProvider } from "react-admin";

const Search = styled("div")(({ theme }) => ({
position: "relative",
Expand Down Expand Up @@ -37,24 +45,160 @@ const StyledInputBase = styled(InputBase)(({ theme }) => ({
transition: theme.transitions.create("width"),
width: "100%",
[theme.breakpoints.up("sm")]: {
width: "25ch",
width: "30ch",
"&:focus": {
width: "30ch",
width: "50ch",
},
},
},
}));

const style = {
position: "absolute" as "absolute",
top: 55,
right: 0,
width: 600,
height: "auto",
bgcolor: "background.paper",
alignSelf: "flex-start",
p: 2,
};

export default function SearchAppBar() {
const dataProvider = useDataProvider();
const [data, setData] = React.useState([]);
const [count, setCount] = React.useState(0);

const [open, setOpen] = React.useState(false);
const handleClose = () => setOpen(false);

const onKeyDown = (event) => {
if (event.code === "Enter") {
dataProvider
.customMethod(
"customapis/searchcms",
{
filter: {
text: value,
skip: 0,
limit: rowsPerPage,
},
},
"GET"
)
.then((result) => {
setData(result.data.data);
setCount(result.data.count);
setOpen(true);
})
.catch((error) => console.error(error));
}
};

const [value, setValue] = React.useState("");

const onChange = (event) => {
setValue(event.target.value);
};

//page change
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);

const emptyRows =
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - count) : 0;

const handleChangePage = (
event: React.MouseEvent<HTMLButtonElement> | null,
newPage: number
) => {
setPage(newPage);
};

const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};

React.useEffect(() => {
dataProvider
.customMethod(
"customapis/searchcms",
{
filter: {
text: value,
skip: page * rowsPerPage,
limit: rowsPerPage,
},
},
"GET"
)
.then((result) => {
setData(result.data.data);
})
.catch((error) => console.error(error));
}, [page, rowsPerPage]);

return (
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
placeholder="Search…"
inputProps={{ "aria-label": "search" }}
/>
</Search>
<Box
sx={{
display: "flex",
alignItems: "flex-end",
flexDirection: "column",
p: 0,
m: 0,
bgcolor: "background.paper",
borderRadius: 1,
}}
>
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
placeholder="Search…"
inputProps={{ "aria-label": "search" }}
onChange={onChange}
onKeyDown={onKeyDown}
value={value}
/>
</Search>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<IconButton
aria-label="close"
sx={{ ml: "auto", float: "right", p: 0 }}
onClick={handleClose}
>
<CloseOutlinedIcon />
</IconButton>
<Typography
id="modal-modal-title"
variant="subtitle2"
sx={{ textAlign: "center", color: "text.secondary" }}
>
{count} results
</Typography>

<SearchResult
count={count}
rows={data}
rowClick={handleClose}
page={page}
rowsPerPage={rowsPerPage}
emptyRows={emptyRows}
handleChangePage={handleChangePage}
handleChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Box>
</Modal>
</Box>
);
}
159 changes: 159 additions & 0 deletions cms/src/layout/searchResult.tsx
@@ -0,0 +1,159 @@
import * as React from "react";
import { useTheme } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableFooter from "@mui/material/TableFooter";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import IconButton from "@mui/material/IconButton";
import FirstPageIcon from "@mui/icons-material/FirstPage";
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import LastPageIcon from "@mui/icons-material/LastPage";
import Link from "@mui/material/Link";

interface TablePaginationActionsProps {
count: number;
page: number;
rowsPerPage: number;
onPageChange: (
event: React.MouseEvent<HTMLButtonElement>,
newPage: number
) => void;
}

function TablePaginationActions(props: TablePaginationActionsProps) {
const theme = useTheme();
const { count, page, rowsPerPage, onPageChange } = props;

const handleFirstPageButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, 0);
};

const handleBackButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, page - 1);
};

const handleNextButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, page + 1);
};

const handleLastPageButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};

return (
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
<IconButton
onClick={handleFirstPageButtonClick}
disabled={page === 0}
aria-label="first page"
>
{theme.direction === "rtl" ? <LastPageIcon /> : <FirstPageIcon />}
</IconButton>
<IconButton
onClick={handleBackButtonClick}
disabled={page === 0}
aria-label="previous page"
>
{theme.direction === "rtl" ? (
<KeyboardArrowRight />
) : (
<KeyboardArrowLeft />
)}
</IconButton>
<IconButton
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
{theme.direction === "rtl" ? (
<KeyboardArrowLeft />
) : (
<KeyboardArrowRight />
)}
</IconButton>
<IconButton
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
{theme.direction === "rtl" ? <FirstPageIcon /> : <LastPageIcon />}
</IconButton>
</Box>
);
}

export default function CustomPaginationActionsTable(props) {
const {
page,
rowsPerPage,
emptyRows,
handleChangePage,
handleChangeRowsPerPage,
rows,
} = props;
console.log(10, props);
return (
<TableContainer>
<Table
sx={{ minWidth: 500, border: "none" }}
aria-label="custom pagination table"
>
<TableBody>
{rows.map((row) => (
<TableRow key={row._id}>
<TableCell component="th" scope="row" style={{ width: 160 }}>
{row.text}
</TableCell>
<TableCell style={{ width: 160 }} align="right">
<Link href={row.link} onClick={props.rowClick}>
{" "}
{row.link}
</Link>
</TableCell>
</TableRow>
))}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
style={{ width: 160, borderBottom: "none" }}
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
colSpan={3}
count={props.count}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
inputProps: {
"aria-label": "rows per page",
},
native: true,
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
);
}

0 comments on commit 9e772a4

Please sign in to comment.