Skip to content

Commit

Permalink
feat: 🎸 enable select dropdown to multiple
Browse files Browse the repository at this point in the history
  • Loading branch information
yeukfei02 committed Jan 7, 2023
1 parent 2d3f28f commit 7002fde
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX "index_incident_on_incidentRef" ON "Incident"("incidentRef");
1 change: 1 addition & 0 deletions apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ model Incident {
@@index([creator_id], map: "index_incident_on_creator_id")
@@index([assignee_id], map: "index_incident_on_assignee_id")
@@index([status], map: "index_incident_on_status")
@@index([incidentRef], map: "index_incident_on_incidentRef")
@@index([created_at], map: "index_incident_on_created_at")
@@index([updated_at], map: "index_incident_on_updated_at")
}
Expand Down
6 changes: 3 additions & 3 deletions apps/api/src/incident/dto/getIncidents.dto.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { UserRole, IncidentType, Status } from '@prisma/client';
import { UserRole } from '@prisma/client';

export class GetIncidentsDto {
userRole: UserRole;
userId: string;
searchText?: string;
incidentType?: IncidentType;
status?: Status;
incidentType?: string[];
status?: string[];
page?: number;
perPage?: number;
sortByCreatedAt?: boolean;
Expand Down
6 changes: 3 additions & 3 deletions apps/api/src/incident/incident.repository.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { Incident, UserRole, Status } from '@prisma/client';
import { Incident, UserRole, Status, IncidentType } from '@prisma/client';
import { PrismaService } from '../prisma.service';
import { v4 as uuidv4 } from 'uuid';
import { AssignIncidentStatusDto } from './dto/assignIncidentStatus.dto';
Expand Down Expand Up @@ -108,12 +108,12 @@ export class IncidentRepository {
}),
...(incidentType && {
type: {
in: [incidentType],
in: incidentType as IncidentType[],
},
}),
...(status && {
status: {
in: [status],
in: status as Status[],
},
}),
},
Expand Down
22 changes: 12 additions & 10 deletions apps/web/src/components/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import DialogTitle from '@mui/material/DialogTitle';
import CustomSnackBar from '../customSnackBar/CustomSnackBar';
import IncidentCardList from '../incidentCardList/IncidentCardList';
import CustomAppBar from '../customAppBar/CustomAppBar';
import { IncidentType, Status, UserRole } from '@prisma/client';
import { IncidentType, UserRole } from '@prisma/client';
import * as incidentService from '../../services/incidentService';
import CustomBreadcrumbs from '../customBreadcrumbs/CustomBreadcrumbs';
import SearchAndFilter from '../searchAndFilter/SearchAndFilter';
Expand All @@ -33,8 +33,8 @@ function Dashboard() {
const [description, setDescription] = useState('');
const [createIncidentIncidentType, setCreateIncidentIncidentType] =
useState<IncidentType>();
const [incidentType, setIncidentType] = useState<IncidentType>();
const [status, setStatus] = useState<Status>();
const [incidentType, setIncidentType] = useState<string[]>([]);
const [status, setStatus] = useState<string[]>([]);

const [incidents, setIncidents] = useState([]);
const [totalPageCount, setTotalPageCount] = useState(0);
Expand Down Expand Up @@ -70,8 +70,8 @@ function Dashboard() {

const getIncidents = async (
searchText?: string,
incidentType?: IncidentType,
status?: Status,
incidentType?: string[],
status?: string[],
page?: number,
sortByCreatedAt?: boolean,
sortByUpdatedAt?: boolean
Expand Down Expand Up @@ -123,11 +123,13 @@ function Dashboard() {
};

const handleIncidentTypeChange = (event: SelectChangeEvent) => {
setIncidentType(event.target.value as IncidentType);
const { value } = event.target;
setIncidentType(typeof value === 'string' ? value.split(',') : value);
};

const handleStatusChange = (event: SelectChangeEvent) => {
setStatus(event.target.value as Status);
const { value } = event.target;
setStatus(typeof value === 'string' ? value.split(',') : value);
};

const handleCreateIncidentButtonClick = () => {
Expand All @@ -150,8 +152,8 @@ function Dashboard() {

const handleClearFilterClick = () => {
setSearchText('');
setIncidentType(undefined);
setStatus(undefined);
setIncidentType([]);
setStatus([]);
setPage(1);
setSortByCreatedAt(false);
setSortByUpdatedAt(false);
Expand Down Expand Up @@ -186,7 +188,7 @@ function Dashboard() {

setTitle('');
setDescription('');
setIncidentType(undefined);
setIncidentType([]);

await getIncidents(searchText);
}
Expand Down
78 changes: 61 additions & 17 deletions apps/web/src/components/searchAndFilter/SearchAndFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import FormControl from '@mui/material/FormControl';
import Grid from '@mui/material/Grid';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import Box from '@mui/material/Box';
import OutlinedInput from '@mui/material/OutlinedInput';
import Chip from '@mui/material/Chip';
import InputLabel from '@mui/material/InputLabel';
import { IncidentType, Status } from '@prisma/client';

interface Props {
searchText: string;
incidentType: IncidentType | undefined;
status: Status | undefined;
incidentType: string[];
status: string[];
page: number;
sortByCreatedAt: boolean;
sortByUpdatedAt: boolean;
Expand All @@ -30,6 +33,17 @@ interface Props {
handleClearFilterClick: () => void;
}

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};

function SearchAndFilter({
searchText,
incidentType,
Expand All @@ -46,6 +60,19 @@ function SearchAndFilter({
handleSearchTextChange,
handleClearFilterClick,
}: Props) {
const incidentTypesData = [
IncidentType.HIGH,
IncidentType.MEDIUM,
IncidentType.LOW,
];

const statusesData = [
Status.UNASSIGNED,
Status.ASSIGNED,
Status.ACKNOWLEDGED,
Status.RESOLVED,
];

return (
<div className="p-3">
<div className="mb-5">
Expand All @@ -71,32 +98,49 @@ function SearchAndFilter({
Incident Type
</InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={incidentType ? incidentType : ''}
label="Incident Type"
value={incidentType}
multiple
onChange={handleIncidentTypeChange}
input={<OutlinedInput id="select-multiple-chip" label="Chip" />}
renderValue={(selected) => (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{(selected as unknown as string[]).map((value, i) => (
<Chip key={i} label={value} />
))}
</Box>
)}
MenuProps={MenuProps}
>
<MenuItem value={IncidentType.HIGH}>High</MenuItem>
<MenuItem value={IncidentType.MEDIUM}>Medium</MenuItem>
<MenuItem value={IncidentType.LOW}>Low</MenuItem>
{incidentTypesData.map((incidentType, i) => (
<MenuItem key={i} value={incidentType}>
{incidentType}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
<Grid item xs={12} sm={6}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-helper-label">Status</InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={status ? status : ''}
label="Incident Type"
value={status}
multiple
onChange={handleStatusChange}
input={<OutlinedInput id="select-multiple-chip" label="Chip" />}
renderValue={(selected) => (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{(selected as unknown as string[]).map((value, i) => (
<Chip key={i} label={value} />
))}
</Box>
)}
MenuProps={MenuProps}
>
<MenuItem value={Status.UNASSIGNED}>Unassigned</MenuItem>
<MenuItem value={Status.ASSIGNED}>Assigned</MenuItem>
<MenuItem value={Status.ACKNOWLEDGED}>Acknowledged</MenuItem>
<MenuItem value={Status.RESOLVED}>Resolved</MenuItem>
{statusesData.map((status, i) => (
<MenuItem key={i} value={status}>
{status}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
Expand Down
9 changes: 5 additions & 4 deletions apps/web/src/services/incidentService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import axios from 'axios';
import { UserRole, IncidentType, Status } from '@prisma/client';
import { getRootUrl } from '../helper/helper';
import _ from 'lodash';

const rootUrl = getRootUrl();

Expand Down Expand Up @@ -33,8 +34,8 @@ export const getIncidents = async (
userRole: UserRole,
userId: string,
searchText?: string,
incidentType?: IncidentType,
status?: Status,
incidentType?: string[],
status?: string[],
page?: number,
perPage?: number,
sortByCreatedAt?: boolean,
Expand All @@ -44,8 +45,8 @@ export const getIncidents = async (
userRole: userRole,
userId: userId,
...(searchText && { searchText: searchText }),
...(incidentType && { incidentType: incidentType }),
...(status && { status: status }),
...(!_.isEmpty(incidentType) && { incidentType: incidentType }),
...(!_.isEmpty(status) && { status: status }),
...(page && {
page: page,
}),
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dayjs": "^1.11.7",
"helmet": "^6.0.1",
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.21",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "6.4.3",
Expand Down Expand Up @@ -57,6 +58,7 @@
"@types/helmet": "^4.0.0",
"@types/jest": "28.1.1",
"@types/jsonwebtoken": "^9.0.0",
"@types/lodash": "^4.14.191",
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.9",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,11 @@
dependencies:
"@types/node" "*"

"@types/lodash@^4.14.191":
version "4.14.191"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa"
integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==

"@types/mime@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
Expand Down

0 comments on commit 7002fde

Please sign in to comment.