Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: quick edit cbc project data #3297

Merged
merged 19 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions app/backend/lib/excel_import/cbc_project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,26 @@ const readSummary = async (wb, sheet) => {
phase: project['C'],
intake: project['D'],
projectStatus: project['E'],
changeRequestPending: project['F'],
changeRequestPending: project?.['F']
? project?.['F'].toLowerCase() === 'yes'
: null,
projectTitle: project['G'],
projectDescription: project['H'],
applicantContractualName: project['I'],
currentOperatingName: project['J'],
eightThirtyMillionFunding: project['K'],
eightThirtyMillionFunding: project?.['K']
? project?.['K'].toLowerCase() === 'yes'
: null,
federalFundingSource: project['L'],
federalProjectNumber: project['M'],
projectType: project['N'],
transportProjectType: project['O'],
highwayProjectType: project['P'],
lastMileProjectType: project['Q'],
lastMileMinimumSpeed: project['R'],
connectedCoastNetworkDependant: project['S'],
connectedCoastNetworkDependant: project?.['S']
? project?.['S'].toLowerCase() === 'yes'
: null,
projectLocations: project['T'],
communitiesAndLocalesCount: validateNumber(
project['U'],
Expand Down Expand Up @@ -201,9 +207,15 @@ const readSummary = async (wb, sheet) => {
errorLog,
projectNumber
),
nditConditionalApprovalLetterSent: project['AF'],
bindingAgreementSignedNditRecipient: project['AG'],
announcedByProvince: project['AH'],
nditConditionalApprovalLetterSent: project?.['AF']
? project?.['AF'].toLowerCase() === 'yes'
: null,
bindingAgreementSignedNditRecipient: project?.['AG']
? project?.['AG'].toLowerCase() === 'yes'
: null,
announcedByProvince: project?.['AH']
? project?.['AH'].toLowerCase() === 'yes'
: null,
dateApplicationReceived: validateDate(
project['AI'],
'dateApplicationReceived',
Expand Down Expand Up @@ -262,7 +274,7 @@ const readSummary = async (wb, sheet) => {
primaryNewsRelease: project['AS'],
secondaryNewsRelease: project['AT'],
notes: project['AU'],
locked: project['AV'],
locked: project?.['AV'] ? project?.['AV'].toLowerCase() === 'x' : null,
lastReviewed: validateDate(
project['AW'],
'lastReviewed',
Expand Down
13 changes: 10 additions & 3 deletions app/components/Analyst/CBC/AssignField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ const StyledDropdown = styled.select`
border-radius: 4px;
`;

const AssignField = ({ fieldName, fieldOptions, fieldType, cbc }) => {
const AssignField = ({
fieldName,
fieldOptions,
fieldType,
cbc,
isFormEditMode,
}) => {
const queryFragment = useFragment(
graphql`
fragment AssignField_query on Cbc {
cbcDataByCbcId {
cbcDataByCbcId(first: 500) @connection(key: "CbcData__cbcDataByCbcId") {
edges {
node {
jsonData
Expand All @@ -43,7 +49,8 @@ const AssignField = ({ fieldName, fieldOptions, fieldType, cbc }) => {
: jsonData[fieldName] || null
);

const allowEdit = useFeature('show_cbc_edit').value ?? false;
const allowEdit =
(useFeature('show_cbc_edit').value ?? false) && !isFormEditMode;

const handleChange = (e) => {
const { rowId } = queryFragment.cbcDataByCbcId.edges[0].node;
Expand Down
9 changes: 7 additions & 2 deletions app/components/Analyst/CBC/CbcAnalystLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ const StyledFormDiv = styled(FormDiv)`
interface Props {
children: JSX.Element[] | JSX.Element;
query: any;
isFormEditMode?: boolean;
}

const CbcAnalystLayout: React.FC<Props> = ({ children, query }) => {
const CbcAnalystLayout: React.FC<Props> = ({
children,
query,
isFormEditMode = false,
}) => {
const queryFragment = useFragment(
graphql`
fragment CbcAnalystLayout_query on Query {
Expand All @@ -35,7 +40,7 @@ const CbcAnalystLayout: React.FC<Props> = ({ children, query }) => {
);
return (
<StyledContainer>
<CbcHeader query={queryFragment} />
<CbcHeader query={queryFragment} isFormEditMode={isFormEditMode} />
<StyledFlex>
<NavigationSidebar />
<StyledFormDiv>{children}</StyledFormDiv>
Expand Down
17 changes: 13 additions & 4 deletions app/components/Analyst/CBC/CbcChangeStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,23 @@ interface Props {
cbc: any;
status: string;
statusList: any;
isFormEditMode: boolean;
}

const CbcChangeStatus: React.FC<Props> = ({ cbc, status, statusList }) => {
const CbcChangeStatus: React.FC<Props> = ({
cbc,
status,
statusList,
isFormEditMode,
}) => {
const queryFragment = useFragment(
graphql`
fragment CbcChangeStatus_query on Cbc {
cbcDataByCbcId {
cbcDataByCbcId(first: 500) @connection(key: "CbcData__cbcDataByCbcId") {
__id
edges {
node {
id
jsonData
sharepointTimestamp
rowId
Expand All @@ -94,7 +102,8 @@ const CbcChangeStatus: React.FC<Props> = ({ cbc, status, statusList }) => {
);
const [updateStatus] = useUpdateCbcDataByRowIdMutation();
const [currentStatus, setCurrentStatus] = useState(getStatus(status));
const allowEdit = useFeature('show_cbc_edit').value ?? false;
const allowEdit =
(useFeature('show_cbc_edit').value ?? false) && !isFormEditMode;

const handleChange = (e) => {
const newStatus = e.target.value;
Expand Down Expand Up @@ -124,7 +133,7 @@ const CbcChangeStatus: React.FC<Props> = ({ cbc, status, statusList }) => {
onChange={(e) => {
// eslint-disable-next-line no-void
void (() => handleChange(e))();
}} // Use draft status for colour so it changes as user selects it
}}
statusStyles={statusStyles[getStatus(status)]}
value={currentStatus}
id="change-status"
Expand Down
64 changes: 24 additions & 40 deletions app/components/Analyst/CBC/CbcForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CircularProgress from '@mui/material/CircularProgress';
import { RJSFSchema } from '@rjsf/utils';
import Button from '@button-inc/bcgov-theme/Button';
import ProjectTheme from '../Project/ProjectTheme';
import { ProjectFormProps } from '../Project/ProjectFormProps';

const LoadingContainer = styled.div`
display: block;
Expand All @@ -21,46 +22,29 @@ const LoadingItem = styled.div`
justify-content: center;
`;

const StyledBtn = styled(Button)`
margin: 0 8px;
padding: 8px 16px;
const StyledContainer = styled.div`
display: flex;
flex-direction: row;
margin: 20px auto;
`;

interface Props {
additionalContext?: any;
before?: React.ReactNode;
children?: React.ReactNode;
formAnimationHeight?: number;
formAnimationHeightOffset?: number;
formData: any;
formHeader?: string | React.ReactNode | JSX.Element;
handleChange: any;
showEditBtn?: boolean;
/** The hidden submit button's ref, used to enforce validation on the form
* (the red-outline we see on widgets) */
hiddenSubmitRef?: any;
isExpanded?: boolean;
isFormEditMode: boolean;
isFormAnimated?: boolean;
liveValidate?: boolean;
onSubmit: any;
resetFormData: any;
saveBtnText?: string;
saveBtnDisabled?: boolean;
cancelBtnDisabled?: boolean;
schema: RJSFSchema;
setFormData?: any;
setIsFormEditMode: any;
submitting?: boolean;
submittingText?: string;
theme?: any;
title: string;
uiSchema?: any;
saveDataTestId?: string;
validate?: any;
}
const StyledBtn = styled(Button)`
@media (min-width: 1024px) {
position: fixed;
bottom: 5vh;
left: 80vw;

&:nth-child(2) {
left: 85vw;
}
}
@media (max-width: 1900px) {
margin: 0 8px;
padding: 8px 16px;
}
`;

const CbcForm: React.FC<Props> = ({
const CbcForm: React.FC<ProjectFormProps> = ({
additionalContext,
before,
children,
Expand Down Expand Up @@ -136,7 +120,7 @@ const CbcForm: React.FC<Props> = ({
)}
</FormBase>
{isFormEditMode && (
<>
<StyledContainer>
<StyledBtn
data-testid={saveDataTestId}
id={`${title.toLowerCase().split(' ').join('-')}-save-button`}
Expand All @@ -151,13 +135,13 @@ const CbcForm: React.FC<Props> = ({
variant="secondary"
disabled={cancelBtnDisabled}
onClick={() => {
setFormData();
resetFormData();
setIsFormEditMode(false);
}}
>
Cancel
</StyledBtn>
</>
</StyledContainer>
)}
</div>
)}
Expand Down
9 changes: 7 additions & 2 deletions app/components/Analyst/CBC/CbcHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,19 @@ const StyledPendingChangeRequests = styled(StyledItem)`

interface Props {
query: any;
isFormEditMode: boolean;
}

const CbcHeader: React.FC<Props> = ({ query }) => {
const CbcHeader: React.FC<Props> = ({ query, isFormEditMode }) => {
const queryFragment = useFragment(
graphql`
fragment CbcHeader_query on Query {
cbcByRowId(rowId: $rowId) {
projectNumber
rowId
sharepointTimestamp
cbcDataByCbcId {
cbcDataByCbcId(first: 500)
@connection(key: "CbcData__cbcDataByCbcId") {
edges {
node {
jsonData
Expand Down Expand Up @@ -117,6 +119,7 @@ const CbcHeader: React.FC<Props> = ({ query }) => {
{ description: 'Reporting Complete', name: 'complete', id: 2 },
{ description: 'Agreement Signed', name: 'approved', id: 3 },
]}
isFormEditMode={isFormEditMode}
/>
</StyledItem>
<StyledAssign>
Expand All @@ -127,6 +130,7 @@ const CbcHeader: React.FC<Props> = ({ query }) => {
fieldOptions={['1', '2', '3', '4', '4b']}
fieldType="string"
cbc={cbcByRowId}
isFormEditMode={isFormEditMode}
/>
</StyledAssign>
<StyledAssign>
Expand All @@ -137,6 +141,7 @@ const CbcHeader: React.FC<Props> = ({ query }) => {
fieldOptions={[null, 1, 2, 3, 4]}
fieldType="number"
cbc={cbcByRowId}
isFormEditMode={isFormEditMode}
/>
</StyledAssign>
<StyledPendingChangeRequests>
Expand Down
59 changes: 59 additions & 0 deletions app/components/Analyst/CBC/CbcTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ThemeProps, getDefaultRegistry } from '@rjsf/core';
import {
CheckboxWidget,
CheckboxesWidget,
MoneyWidget,
NumberWidget,
NumericStringWidget,
RadioWidget,
SelectWidget,
TextAreaWidget,
TextWidget,
DatePickerWidget,
} from 'lib/theme/widgets';
import ArrayBooleanField from '../../Review/fields/ArrayBooleanField';
import ReviewCheckboxField from '../../Review/fields/ReviewCheckboxField';
import ReviewInlineArrayField from '../../Review/fields/ReviewInlineArrayField';
import ReviewObjectFieldTemplate from '../../Review/ReviewObjectFieldTemplate';
import ReviewSectionField from '../../Review/ReviewSectionField';
import ReviewArrayFieldTemplate from '../../Review/fields/ReviewArrayFieldTemplate';
import ReviewFieldTemplate from '../../Review/fields/ReviewFieldTemplate';
import DefaultWidget from '../../Review/widgets/DefaultWidget';
import BooleanWidget from '../../Review/widgets/BooleanWidget';
import FileWidget from '../../Review/widgets/FileWidget';

const { templates } = getDefaultRegistry();

const CbcTheme: ThemeProps = {
fields: {
SectionField: ReviewSectionField,
InlineArrayField: ReviewInlineArrayField,
ArrayBooleanField,
ReviewCheckboxField,
},
widgets: {
TextAreaWidget,
DatePickerWidget,
CheckboxesWidget,
CheckboxWidget,
FileWidget,
RadioWidget,
SelectWidget,
TextWidget,
MoneyWidget,
BooleanWidget,
DefaultWidget,
ReadOnlyMoneyWidget: DefaultWidget,
NumberWidget,
NumericStringWidget,
ReadOnlyWidget: DefaultWidget,
},
templates: {
...templates,
ObjectFieldTemplate: ReviewObjectFieldTemplate,
FieldTemplate: ReviewFieldTemplate,
ArrayFieldTemplate: ReviewArrayFieldTemplate,
},
};

export default CbcTheme;
Loading
Loading