From 4894dd3affe1a319e8137a4739a05f533b819781 Mon Sep 17 00:00:00 2001 From: Tom Chapman Date: Fri, 23 Aug 2024 16:29:57 -0700 Subject: [PATCH 1/2] fix double click to get back to workplan listing page --- epictrack-web/src/hooks/useRouterLocationStateForHelpPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/epictrack-web/src/hooks/useRouterLocationStateForHelpPage.tsx b/epictrack-web/src/hooks/useRouterLocationStateForHelpPage.tsx index aa0e48d36..55d7edaad 100644 --- a/epictrack-web/src/hooks/useRouterLocationStateForHelpPage.tsx +++ b/epictrack-web/src/hooks/useRouterLocationStateForHelpPage.tsx @@ -20,6 +20,7 @@ const useRouterLocationStateForHelpPage = ( navigate(`${location.pathname}${location.search}`, { state: { helpPageTags: newtags }, + replace: true, // modify current entry in history stack rather than adding duplicate }); }, dependencies); }; From 07b025e4efbfb186cd7420d05eb3b11eac48dd80 Mon Sep 17 00:00:00 2001 From: Tom Chapman Date: Thu, 29 Aug 2024 10:33:13 -0700 Subject: [PATCH 2/2] add eac_signed and eac_expires to project form and model --- ...2_add_eac_signed_and_expires_fields_to_.py | 40 +++++++++++++++++++ epictrack-api/src/api/models/project.py | 4 +- .../api/schemas/request/project_request.py | 12 ++++++ .../src/components/project/Dialog/index.tsx | 6 +++ .../components/project/ProjectForm/index.tsx | 15 +++++++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 epictrack-api/migrations/versions/08209ce361c2_add_eac_signed_and_expires_fields_to_.py diff --git a/epictrack-api/migrations/versions/08209ce361c2_add_eac_signed_and_expires_fields_to_.py b/epictrack-api/migrations/versions/08209ce361c2_add_eac_signed_and_expires_fields_to_.py new file mode 100644 index 000000000..5d6398a02 --- /dev/null +++ b/epictrack-api/migrations/versions/08209ce361c2_add_eac_signed_and_expires_fields_to_.py @@ -0,0 +1,40 @@ +"""add eac signed and expires fields to project + +Revision ID: 08209ce361c2 +Revises: 19227722dffc +Create Date: 2024-08-29 08:45:46.100404 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '08209ce361c2' +down_revision = '19227722dffc' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('projects', schema=None) as batch_op: + batch_op.add_column(sa.Column('eac_signed', sa.Date(), nullable=True)) + batch_op.add_column(sa.Column('eac_expires', sa.Date(), nullable=True)) + + with op.batch_alter_table('projects_history', schema=None) as batch_op: + batch_op.add_column(sa.Column('eac_signed', sa.Date(), autoincrement=False, nullable=True)) + batch_op.add_column(sa.Column('eac_expires', sa.Date(), autoincrement=False, nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('projects_history', schema=None) as batch_op: + batch_op.drop_column('eac_expires') + batch_op.drop_column('eac_signed') + + with op.batch_alter_table('projects', schema=None) as batch_op: + batch_op.drop_column('eac_expires') + batch_op.drop_column('eac_signed') + # ### end Alembic commands ### diff --git a/epictrack-api/src/api/models/project.py b/epictrack-api/src/api/models/project.py index 0ba06e1e8..aa4026d30 100644 --- a/epictrack-api/src/api/models/project.py +++ b/epictrack-api/src/api/models/project.py @@ -14,7 +14,7 @@ """Model to manage Project.""" import enum -from sqlalchemy import Boolean, Column, Enum, Float, ForeignKey, Integer, String, Text, func +from sqlalchemy import Boolean, Column, Date, Enum, Float, ForeignKey, Integer, String, Text, func from sqlalchemy.orm import relationship from .base_model import BaseModelVersioned @@ -64,6 +64,8 @@ class Project(BaseModelVersioned): region_id_env = Column(ForeignKey("regions.id"), nullable=True) region_id_flnro = Column(ForeignKey("regions.id"), nullable=True) abbreviation = Column(String(10), nullable=True, unique=True) + eac_signed = Column(Date(), nullable=True) + eac_expires = Column(Date(), nullable=True) sub_type = relationship("SubType", foreign_keys=[sub_type_id], lazy="select") type = relationship("Type", foreign_keys=[type_id], lazy="select") proponent = relationship("Proponent", foreign_keys=[proponent_id], lazy="select") diff --git a/epictrack-api/src/api/schemas/request/project_request.py b/epictrack-api/src/api/schemas/request/project_request.py index e0c70a248..bbd6962b1 100644 --- a/epictrack-api/src/api/schemas/request/project_request.py +++ b/epictrack-api/src/api/schemas/request/project_request.py @@ -118,6 +118,18 @@ class ProjectBodyParameterSchema(RequestBodyParameterSchema): load_default=None ) + eac_signed = fields.Date( + metadata={"description": "Date the EAC was signed on"}, + allow_none=True, + load_default=None + ) + + eac_expires = fields.Date( + metadata={"description": "Date the EAC expires on"}, + allow_none=True, + load_default=None + ) + is_active = fields.Bool(metadata={"description": "Active state of the project"}) is_project_closed = fields.Bool(metadata={"description": "Closed state of the project"}, default=False) diff --git a/epictrack-web/src/components/project/Dialog/index.tsx b/epictrack-web/src/components/project/Dialog/index.tsx index c1b872cc4..15ded778d 100644 --- a/epictrack-web/src/components/project/Dialog/index.tsx +++ b/epictrack-web/src/components/project/Dialog/index.tsx @@ -67,6 +67,12 @@ export const ProjectDialog = ({ }; const saveProject = async (data: any) => { + if (data.eac_signed) { + data.eac_signed = new Date(data.eac_signed).toISOString().split("T")[0]; + } + if (data.eac_expires) { + data.eac_expires = new Date(data.eac_expires).toISOString().split("T")[0]; + } if (projectId) { await editProject(data); } else { diff --git a/epictrack-web/src/components/project/ProjectForm/index.tsx b/epictrack-web/src/components/project/ProjectForm/index.tsx index 986f4ed5e..a06211a4f 100644 --- a/epictrack-web/src/components/project/ProjectForm/index.tsx +++ b/epictrack-web/src/components/project/ProjectForm/index.tsx @@ -26,6 +26,7 @@ import typeService from "services/typeService"; import proponentService from "services/proponentService/proponentService"; import { useAppSelector } from "hooks"; import { sort } from "utils"; +import ControlledDatePicker from "components/shared/controlledInputComponents/ControlledDatePicker"; const schema = yup.object().shape({ name: yup @@ -449,6 +450,20 @@ export default function ProjectForm({ /> + + EAC Signed + + + + EAC Expires + +