Skip to content

Commit e893c79

Browse files
Special history - proponent name (#1498)
* WIP * proponent name special history --------- Co-authored-by: Tom Chapman <tchapman000@gmail.com>
1 parent 039cd1d commit e893c79

File tree

6 files changed

+104
-16
lines changed

6 files changed

+104
-16
lines changed

epictrack-api/src/api/services/proponent.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
from api.exceptions import ResourceExistsError, ResourceNotFoundError
2121
from api.models import Proponent, db
22+
from api.models.special_field import EntityEnum
2223
from api.models.staff import Staff
24+
from api.services.special_field import SpecialFieldService
2325
from api.utils.token_info import TokenInfo
2426

2527

@@ -52,6 +54,15 @@ def create_proponent(cls, payload: dict):
5254
if exists:
5355
raise ResourceExistsError("Proponent with same name exists")
5456
proponent = Proponent(**payload)
57+
proponent.flush()
58+
proponent_name_special_field_data = {
59+
"entity": EntityEnum.PROPONENT,
60+
"entity_id": proponent.id,
61+
"field_name": "name",
62+
"field_value": proponent.name,
63+
"active_from": proponent.created_at
64+
}
65+
SpecialFieldService.create_special_field_entry(proponent_name_special_field_data)
5566
proponent.save()
5667
return proponent
5768

epictrack-web/src/components/proponent/ProponentForm.tsx

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { TextField, Grid, Box } from "@mui/material";
2+
import { TextField, Grid, Box, IconButton } from "@mui/material";
33
import { FormProvider, useForm } from "react-hook-form";
44
import * as yup from "yup";
55
import { yupResolver } from "@hookform/resolvers/yup";
@@ -11,7 +11,15 @@ import ControlledSelectV2 from "../shared/controlledInputComponents/ControlledSe
1111
import { MasterContext } from "../shared/MasterContext";
1212
import proponentService from "../../services/proponentService/proponentService";
1313
import ControlledSwitch from "../shared/controlledInputComponents/ControlledSwitch";
14-
import LockClosed from "../../assets/images/lock-closed.svg";
14+
import { When, If, Then, Else } from "react-if";
15+
import {
16+
SpecialFieldEntityEnum,
17+
SpecialFields,
18+
} from "../../constants/application-constant";
19+
import Icons from "../icons";
20+
import { IconProps } from "../icons/type";
21+
import { Palette } from "../../styles/theme";
22+
import { SpecialFieldGrid } from "../shared/specialField";
1523

1624
const schema = yup.object().shape({
1725
name: yup
@@ -33,10 +41,14 @@ const schema = yup.object().shape({
3341
}),
3442
});
3543

44+
const LockClosedIcon: React.FC<IconProps> = Icons["LockClosedIcon"];
45+
const LockOpenIcon: React.FC<IconProps> = Icons["LockOpenIcon"];
46+
3647
export default function ProponentForm({ ...props }) {
3748
const [staffs, setStaffs] = React.useState<Staff[]>([]);
3849
const [disabled, setDisabled] = React.useState<boolean>();
3950
const ctx = React.useContext(MasterContext);
51+
const [specialField, setSpecialField] = React.useState<string>("");
4052

4153
React.useEffect(() => {
4254
ctx.setFormId("proponent-form");
@@ -100,17 +112,24 @@ export default function ProponentForm({ ...props }) {
100112
}}
101113
>
102114
<ETFormLabel required>Name</ETFormLabel>
103-
<ETFormLabel>
104-
<Box
105-
sx={{
106-
opacity: disabled ? "100" : "0",
107-
cursor: "pointer",
108-
}}
109-
component="img"
110-
src={LockClosed}
111-
alt="Lock"
112-
/>
113-
</ETFormLabel>
115+
<When condition={disabled}>
116+
<If condition={specialField === SpecialFields.PROPONENT.NAME}>
117+
<Then>
118+
<IconButton onClick={() => setSpecialField("")}>
119+
<LockOpenIcon fill={Palette.primary.accent.main} />
120+
</IconButton>
121+
</Then>
122+
<Else>
123+
<IconButton
124+
onClick={() =>
125+
setSpecialField(SpecialFields.PROPONENT.NAME)
126+
}
127+
>
128+
<LockClosedIcon fill={Palette.primary.accent.main} />
129+
</IconButton>
130+
</Else>
131+
</If>
132+
</When>
114133
</Box>
115134
<Box sx={{ paddingTop: "4px" }}>
116135
<TextField
@@ -126,8 +145,9 @@ export default function ProponentForm({ ...props }) {
126145
</Grid>
127146
<Grid item xs={6}>
128147
<ETFormLabel>Relationship Holder</ETFormLabel>
129-
<Box sx={{ paddingTop: "4px" }}>
148+
<Box sx={{ paddingTop: Boolean(specialField) ? "15px" : "11px" }}>
130149
<ControlledSelectV2
150+
disabled={Boolean(specialField)}
131151
placeholder="Select"
132152
defaultValue={(ctx.item as Proponent)?.relationship_holder_id}
133153
options={staffs || []}
@@ -137,8 +157,54 @@ export default function ProponentForm({ ...props }) {
137157
></ControlledSelectV2>
138158
</Box>
139159
</Grid>
160+
<Grid item xs={12}>
161+
<When condition={Boolean(specialField)}>
162+
<SpecialFieldGrid
163+
entity={SpecialFieldEntityEnum.PROPONENT}
164+
entity_id={(ctx.item as Proponent)?.id}
165+
fieldName={specialField}
166+
fieldLabel={
167+
specialField === SpecialFields.PROPONENT.NAME
168+
? "Proponent Name"
169+
: "Name"
170+
}
171+
fieldType={"text"}
172+
title={
173+
specialField === SpecialFields.PROPONENT.NAME
174+
? "Proponet History"
175+
: (ctx.item as Proponent)?.name
176+
}
177+
description={
178+
<>
179+
<When
180+
condition={
181+
specialField === SpecialFields.PROJECT.PROPONENT
182+
}
183+
>
184+
Update the Proponent of this Project.{" "}
185+
<a href="#">Click this link</a> for detailed instructions.
186+
</When>
187+
<When
188+
condition={specialField === SpecialFields.PROJECT.NAME}
189+
>
190+
Update the legal name of the Project and the dates each
191+
name was in legal use. <a href="#">Click this link</a> for
192+
detailed instructions
193+
</When>
194+
</>
195+
}
196+
onSave={() => {
197+
// TODO: Refresh form field value for the specific field?
198+
// OR do we just call form save/submit handler
199+
ctx.setId(props.proponentId);
200+
ctx.getById(props.proponentId);
201+
}}
202+
/>
203+
</When>
204+
</Grid>
140205
<Grid item xs={6} sx={{ paddingTop: "30px !important" }}>
141206
<ControlledSwitch
207+
disabled={Boolean(specialField)}
142208
sx={{ paddingLeft: "0px", marginRight: "10px" }}
143209
name="is_active"
144210
/>

epictrack-web/src/components/shared/CustomSwitch.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const CustomSwitch = styled((props: SwitchProps) => (
99
{...props}
1010
disabled={props.disabled}
1111
/>
12-
))(() => ({
12+
))((props: SwitchProps) => ({
1313
width: 40,
1414
height: 24,
1515
padding: 0,
@@ -20,7 +20,9 @@ export const CustomSwitch = styled((props: SwitchProps) => (
2020
transform: "translateX(16px)",
2121
color: "#FFFFFF",
2222
"& + .MuiSwitch-track": {
23-
backgroundColor: Palette.primary.accent.main,
23+
backgroundColor: `${
24+
props.disabled ? Palette.neutral.light : Palette.primary.accent.main
25+
}`,
2426
opacity: 1,
2527
},
2628
},

epictrack-web/src/components/shared/MasterContext.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface MasterContextProps {
2828
setFormId: Dispatch<SetStateAction<string | undefined>>;
2929
onDialogClose(event: any, reason: any): any;
3030
setFormStyle: Dispatch<SetStateAction<SxProps | undefined>>;
31+
getById: (id: string) => Promise<void>;
3132
}
3233

3334
export const MasterContext = createContext<MasterContextProps>({
@@ -48,6 +49,9 @@ export const MasterContext = createContext<MasterContextProps>({
4849
setFormId: () => ({}),
4950
onDialogClose: (event: any, reason: any) => ({}),
5051
setFormStyle: () => ({}),
52+
getById: async (id: string) => {
53+
return Promise.resolve();
54+
},
5155
});
5256

5357
export const MasterProvider = ({
@@ -172,6 +176,7 @@ export const MasterProvider = ({
172176
return (
173177
<MasterContext.Provider
174178
value={{
179+
getById,
175180
title,
176181
setTitle,
177182
data,

epictrack-web/src/components/shared/specialField/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ export const SpecialFieldGrid = ({
218218
isLoading: loading,
219219
},
220220
enableSorting: false,
221+
enableBottomToolbar: false,
221222
editDisplayMode: "row",
222223
createDisplayMode: "row",
223224
enableFilters: false,

epictrack-web/src/constants/application-constant.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,7 @@ export const SpecialFields = {
101101
NAME: "name",
102102
PROPONENT: "proponent_id",
103103
},
104+
PROPONENT: {
105+
NAME: "name",
106+
},
104107
};

0 commit comments

Comments
 (0)