Skip to content

Commit

Permalink
Kanban flow (#5406)
Browse files Browse the repository at this point in the history
Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
Co-authored-by: Gigin George <mail.gigin@gmail.com>
  • Loading branch information
3 people authored Apr 26, 2023
1 parent c4de2b5 commit f013a27
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 47 deletions.
15 changes: 14 additions & 1 deletion src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const LocalStorageKeys = {
export interface OptionsType {
id: number;
text: string;
label?: string;
desc?: string;
disabled?: boolean;
}
Expand Down Expand Up @@ -135,7 +136,7 @@ export const FACILITY_TYPES: Array<OptionsType> = [
// { id: 1600, text: "District War Room" },
];

export const SHIFTING_CHOICES: Array<OptionsType> = [
export const SHIFTING_CHOICES_WARTIME: Array<OptionsType> = [
{ id: 10, text: "PENDING" },
{ id: 15, text: "ON HOLD" },
{ id: 20, text: "APPROVED" },
Expand All @@ -147,6 +148,18 @@ export const SHIFTING_CHOICES: Array<OptionsType> = [
{ id: 70, text: "TRANSFER IN PROGRESS" },
{ id: 80, text: "COMPLETED" },
{ id: 90, text: "PATIENT EXPIRED" },
{ id: 100, text: "CANCELLED" },
];

export const SHIFTING_CHOICES_PEACETIME: Array<OptionsType> = [
{ id: 20, text: "APPROVED", label: "PATIENTS TO BE SHIFTED" },
{ id: 40, text: "DESTINATION APPROVED" },
// { id: 50, text: "DESTINATION REJECTED" },
{ id: 60, text: "PATIENT TO BE PICKED UP", label: "TRANSPORTATION ARRANGED" },
{ id: 70, text: "TRANSFER IN PROGRESS" },
{ id: 80, text: "COMPLETED" },
{ id: 90, text: "PATIENT EXPIRED" },
{ id: 100, text: "CANCELLED" },
];

export const SHIFTING_VEHICLE_CHOICES: Array<OptionsType> = [
Expand Down
27 changes: 23 additions & 4 deletions src/Components/Common/components/ButtonV2.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Link } from "raviger";
import { useTranslation } from "react-i18next";
import CareIcon from "../../../CAREUI/icons/CareIcon";
import AuthorizedChild from "../../../CAREUI/misc/AuthorizedChild";
import { AuthorizedElementProps } from "../../../Utils/AuthorizeFor";
import CareIcon from "../../../CAREUI/icons/CareIcon";
import { Link } from "raviger";
import { classNames } from "../../../Utils/utils";
import { useTranslation } from "react-i18next";

export type ButtonSize = "small" | "default" | "large";
export type ButtonShape = "square" | "circle";
Expand Down Expand Up @@ -75,6 +75,14 @@ export type ButtonProps = RawButtonProps &
* Whether the button should be having a Id.
*/
id?: string | undefined;
/**
* Tooltip showed when hovered over.
*/
tooltip?: string;
/**
* Class for tooltip
*/
tooltipClassName?: string;
};

const ButtonV2 = ({
Expand All @@ -91,6 +99,8 @@ const ButtonV2 = ({
children,
href,
target,
tooltip,
tooltipClassName,
...props
}: ButtonProps) => {
const className = classNames(
Expand Down Expand Up @@ -132,7 +142,16 @@ const ButtonV2 = ({
}

return (
<button {...props} disabled={disabled || loading} className={className}>
<button
{...props}
disabled={disabled || loading}
className={classNames(className, tooltip && "tooltip")}
>
{tooltip && (
<span className={classNames("tooltip-text", tooltipClassName)}>
{tooltip}
</span>
)}
{children}
</button>
);
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Patient/ShiftCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export const ShiftCreate = (props: patientShiftProps) => {
setIsLoading(true);

const data = {
status: "PENDING",
status: wartime_shifting ? "PENDING" : "APPROVED",
orgin_facility: props.facilityId,
shifting_approving_facility: (
state.form.shifting_approving_facility || {}
Expand Down
46 changes: 31 additions & 15 deletions src/Components/Shifting/BoardView.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from "react";
import {
SHIFTING_CHOICES_PEACETIME,
SHIFTING_CHOICES_WARTIME,
} from "../../Common/constants";

import BadgesList from "./BadgesList";
import { ExportButton } from "../Common/Export";
import ListFilter from "./ListFilter";
import { SHIFTING_CHOICES } from "../../Common/constants";
import SearchInput from "../Form/SearchInput";
import ShiftingBoard from "./ShiftingBoard";
import { downloadShiftRequests } from "../../Redux/actions";
Expand All @@ -12,6 +14,7 @@ import loadable from "@loadable/component";
import { navigate } from "raviger";
import useConfig from "../../Common/hooks/useConfig";
import useFilters from "../../Common/hooks/useFilters";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import withScrolling from "react-dnd-scrolling";

Expand All @@ -25,16 +28,28 @@ export default function BoardView() {
});
const { wartime_shifting } = useConfig();

const shiftStatusOptions = SHIFTING_CHOICES.map((obj) => obj.text).filter(
(choice) => wartime_shifting || choice !== "PENDING"
);
const shiftStatusOptions = wartime_shifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME;

const COMPLETED = wartime_shifting
? [
"COMPLETED",
"REJECTED",
"CANCELLED",
"DESTINATION REJECTED",
"PATIENT EXPIRED",
]
: ["CANCELLED", "PATIENT EXPIRED"];

const COMPLETED = ["COMPLETED", "REJECTED", "DESTINATION REJECTED"];
const ACTIVE = shiftStatusOptions.filter(
(option) => !COMPLETED.includes(option)
const completedBoards = shiftStatusOptions.filter((option) =>
COMPLETED.includes(option.text)
);
const activeBoards = shiftStatusOptions.filter(
(option) => !COMPLETED.includes(option.text)
);

const [boardFilter, setBoardFilter] = useState(ACTIVE);
const [boardFilter, setBoardFilter] = useState(activeBoards);
const [isLoading] = useState(false);
const { t } = useTranslation();

Expand Down Expand Up @@ -68,22 +83,22 @@ export default function BoardView() {
<button
className={
"flex leading-none border-2 border-gray-200 rounded-full items-center transition-colors duration-300 ease-in focus:outline-none hover:text-blue-400 focus:text-blue-400 rounded-r-full px-4 py-2" +
(boardFilter === ACTIVE
(boardFilter[0].text === activeBoards[0].text
? " bg-white text-gray-800"
: " bg-gray-200 text-sm text-gray-500")
}
onClick={() => setBoardFilter(ACTIVE)}
onClick={() => setBoardFilter(activeBoards)}
>
<span>{t("active")}</span>
</button>
<button
className={
"flex leading-none border-2 border-gray-200 rounded-full items-center transition-colors duration-300 ease-in focus:outline-none hover:text-blue-400 focus:text-blue-400 rounded-r-full px-4 py-2" +
(boardFilter === COMPLETED
(boardFilter[0].text === completedBoards[0].text
? " bg-white text-gray-800"
: " bg-gray-200 text-sm text-gray-500")
}
onClick={() => setBoardFilter(COMPLETED)}
onClick={() => setBoardFilter(completedBoards)}
>
<span>{t("completed")}</span>
</button>
Expand Down Expand Up @@ -116,9 +131,10 @@ export default function BoardView() {
) : (
boardFilter.map((board) => (
<ShiftingBoard
key={board}
key={board.text}
filterProp={qParams}
board={board}
board={board.text}
title={board.label}
formatFilter={formatFilter}
/>
))
Expand Down
11 changes: 7 additions & 4 deletions src/Components/Shifting/ListFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import {
} from "../../Common/constants";
import { DateRangePicker, getDate } from "../Common/DateRangePicker";
import React, { useEffect, useState } from "react";
import {
SHIFTING_CHOICES_PEACETIME,
SHIFTING_CHOICES_WARTIME,
} from "../../Common/constants";
import { getAnyFacility, getUserList } from "../../Redux/actions";

import { CircularProgress } from "@material-ui/core";
Expand All @@ -14,7 +18,6 @@ import { FieldLabel } from "../Form/FormFields/FormField";
import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover";
import { LegacySelectField } from "../Common/HelperInputFields";
import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField";
import { SHIFTING_CHOICES } from "../../Common/constants";
import { UserSelect } from "../Common/UserSelect2";
import moment from "moment";
import { navigate } from "raviger";
Expand Down Expand Up @@ -57,9 +60,9 @@ export default function ListFilter(props: any) {
const [isAssignedUserLoading, setAssignedUserLoading] = useState(false);
const { t } = useTranslation();

const shiftStatusOptions = SHIFTING_CHOICES.map((obj) => obj.text).filter(
(choice) => wartime_shifting || choice !== "PENDING"
);
const shiftStatusOptions = (
wartime_shifting ? SHIFTING_CHOICES_WARTIME : SHIFTING_CHOICES_PEACETIME
).map((option) => option.text);

const [filterState, setFilterState] = useMergeState({
orgin_facility: filter.orgin_facility || "",
Expand Down
24 changes: 22 additions & 2 deletions src/Components/Shifting/ShiftDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as Notification from "../../Utils/Notifications.js";

import { GENDER_TYPES, TEST_TYPE_CHOICES } from "../../Common/constants";
import {
GENDER_TYPES,
SHIFTING_CHOICES_PEACETIME,
SHIFTING_CHOICES_WARTIME,
TEST_TYPE_CHOICES,
} from "../../Common/constants";
import { Link, navigate } from "raviger";
import React, { useCallback, useState } from "react";
import { deleteShiftRecord, getShiftDetails } from "../../Redux/actions";
Expand Down Expand Up @@ -38,6 +43,10 @@ export default function ShiftDetails(props: { id: string }) {
React.useState(false);
const { t } = useTranslation();

const shiftStatusOptions = wartime_shifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME;

const fetchData = useCallback(
async (status: statusType) => {
setIsLoading(true);
Expand Down Expand Up @@ -552,6 +561,15 @@ export default function ShiftDetails(props: { id: string }) {
options={
<div className="flex gap-2">
<ButtonV2
tooltip={
["COMPLETED", "CANCELLED"].includes(data.status)
? `A shifting request, once ${data.status.toLowerCase()} cannot be updated`
: ""
}
tooltipClassName="tooltip-top -translate-x-28 -translate-y-1 text-xs"
disabled={
data.status === "COMPLETED" || data.status === "CANCELLED"
}
onClick={() => navigate(`/shifting/${data.external_id}/update`)}
>
{t("update_status_details")}
Expand Down Expand Up @@ -591,7 +609,9 @@ export default function ShiftDetails(props: { id: string }) {
<div>
<span className="font-semibold leading-relaxed">Status: </span>
<span className="badge badge-pill badge-primary py-1 px-2">
{data.status}
{shiftStatusOptions.find(
(option) => data.status === option.text
)?.label || data.status}
</span>
</div>
<div>
Expand Down
31 changes: 17 additions & 14 deletions src/Components/Shifting/ShiftDetailsUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
BREATHLESSNESS_LEVEL,
FACILITY_TYPES,
PATIENT_CATEGORIES,
SHIFTING_CHOICES,
SHIFTING_CHOICES_PEACETIME,
SHIFTING_CHOICES_WARTIME,
SHIFTING_VEHICLE_CHOICES,
} from "../../Common/constants";
import {
Expand All @@ -31,17 +32,17 @@ import { LegacyErrorHelperText } from "../Common/HelperInputFields";
import { LegacySelectField } from "../Common/HelperInputFields";
import PatientCategorySelect from "../Patient/PatientCategorySelect";
import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField";
import { SelectFormField } from "../Form/FormFields/SelectFormField.js";
import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
import TextFormField from "../Form/FormFields/TextFormField";
import { UserSelect } from "../Common/UserSelect";
import { classNames } from "../../Utils/utils.js";
import loadable from "@loadable/component";
import { parsePhoneNumberFromString } from "libphonenumber-js";
import useAppHistory from "../../Common/hooks/useAppHistory";
import useConfig from "../../Common/hooks/useConfig";
import { useDispatch } from "react-redux";
import { useTranslation } from "react-i18next";
import { FieldChangeEvent } from "../Form/FormFields/Utils.js";
import { classNames } from "../../Utils/utils.js";

const Loading = loadable(() => import("../Common/Loading"));
const PageTitle = loadable(() => import("../Common/PageTitle"));
Expand Down Expand Up @@ -93,9 +94,9 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
errors: { ...initError },
};

const shiftStatusOptions = SHIFTING_CHOICES.map((obj) => obj.text).filter(
(choice) => wartime_shifting || choice !== "PENDING"
);
const shiftStatusOptions = wartime_shifting
? SHIFTING_CHOICES_WARTIME
: SHIFTING_CHOICES_PEACETIME;

let requiredFields: any = {
reason: {
Expand Down Expand Up @@ -177,6 +178,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
form[name] = value;
dispatch({ type: "set_form", form });
};

const handleTextAreaChange = (e: any) => {
const form = { ...state.form };
const { name, value } = e;
Expand All @@ -191,7 +193,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
dispatch({ type: "set_form", form });
};

const handleFormFieldChange = (event: any) => {
const handleFormFieldChange = (event: FieldChangeEvent<unknown>) => {
dispatch({
type: "set_form",
form: { ...state.form, [event.name]: event.value },
Expand Down Expand Up @@ -333,15 +335,16 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => {
<CardContent>
<div className="grid gap-4 grid-cols-1 md:grid-cols-2">
<div className="md:col-span-1">
<FieldLabel>{t("status")}</FieldLabel>
<LegacySelectField
<SelectFormField
name="status"
variant="outlined"
margin="dense"
optionArray={true}
value={state.form.status}
label="Status"
required
options={shiftStatusOptions}
onChange={handleChange}
value={state.form.status}
optionLabel={(option) => option.label || option.text}
optionValue={(option) => option.text}
optionSelectedLabel={(option) => option.label || option.text}
onChange={handleFormFieldChange}
className={classNames(
"bg-white",
wartime_shifting ? " h-14 " : " h-12 ",
Expand Down
Loading

0 comments on commit f013a27

Please sign in to comment.