diff --git a/submit-api/migrations/versions/77862b346adf_add_requested_by_eao_package_status.py b/submit-api/migrations/versions/77862b346adf_add_requested_by_eao_package_status.py
new file mode 100644
index 000000000..551903f33
--- /dev/null
+++ b/submit-api/migrations/versions/77862b346adf_add_requested_by_eao_package_status.py
@@ -0,0 +1,22 @@
+"""Add REQUESTED_BY_EAO package status
+
+Revision ID: 77862b346adf
+Revises: e27054af162b
+Create Date: 2026-03-02 16:02:40.724455
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '77862b346adf'
+down_revision = 'e27054af162b'
+branch_labels = None
+depends_on = None
+
+def upgrade():
+ op.execute("ALTER TYPE packagestatus ADD VALUE IF NOT EXISTS 'REQUESTED_BY_EAO';")
+
+def downgrade():
+ pass
\ No newline at end of file
diff --git a/submit-api/src/submit_api/models/account_project.py b/submit-api/src/submit_api/models/account_project.py
index 11ef6bda9..ecdd88171 100644
--- a/submit-api/src/submit_api/models/account_project.py
+++ b/submit-api/src/submit_api/models/account_project.py
@@ -33,7 +33,8 @@ class AccountProject(BaseModel):
primaryjoin='AccountProjectWork.account_project_id==AccountProject.id',
lazy='select',
cascade='all, delete',
- passive_deletes=True)
+ passive_deletes=True,
+ back_populates='account_project')
@property
def latest_packages(self):
diff --git a/submit-api/src/submit_api/models/account_project_work.py b/submit-api/src/submit_api/models/account_project_work.py
index 72ac35931..d46b54841 100644
--- a/submit-api/src/submit_api/models/account_project_work.py
+++ b/submit-api/src/submit_api/models/account_project_work.py
@@ -40,7 +40,12 @@ class AccountProjectWork(BaseModel):
comment='Whether this association is currently active'
)
- account_project = db.relationship('AccountProject', foreign_keys=[account_project_id], lazy='joined')
+ account_project = db.relationship(
+ 'AccountProject',
+ foreign_keys=[account_project_id],
+ lazy='joined',
+ back_populates='account_project_works')
+
work = db.relationship('TrackWork', foreign_keys=[work_id], lazy='joined')
packages = db.relationship(
@@ -48,8 +53,8 @@ class AccountProjectWork(BaseModel):
primaryjoin='Package.account_project_work_id==AccountProjectWork.id',
lazy='select',
cascade='all, delete',
- passive_deletes=True
- )
+ passive_deletes=True,
+ back_populates='account_project_work')
@classmethod
def find_by_account_project_id(cls, account_project_id: int):
diff --git a/submit-api/src/submit_api/models/package.py b/submit-api/src/submit_api/models/package.py
index 3dff44e1f..e7db7a456 100644
--- a/submit-api/src/submit_api/models/package.py
+++ b/submit-api/src/submit_api/models/package.py
@@ -57,6 +57,7 @@ class PackageStatus(enum.Enum):
REVISION_REQUIRED = 'REVISION_REQUIRED'
NO_REVISION_REQUIRED = 'NO_REVISION_REQUIRED'
RESUBMITTED = 'RESUBMITTED'
+ REQUESTED_BY_EAO = 'REQUESTED_BY_EAO'
@classmethod
def check_value(cls, value):
@@ -83,7 +84,7 @@ class Package(BaseModel):
account_project_work_id = Column(db.Integer, ForeignKey(
'account_project_works.id', ondelete='SET NULL'), nullable=True)
account_project_work = db.relationship('AccountProjectWork', foreign_keys=[
- account_project_work_id], lazy='joined')
+ account_project_work_id], lazy='joined', back_populates='packages')
submitted_on = Column(db.DateTime, nullable=True)
submitted_by = Column(db.String, ForeignKey(
'users.auth_guid', name='packages_submitted_by_fkey'), nullable=True)
diff --git a/submit-api/src/submit_api/schemas/project.py b/submit-api/src/submit_api/schemas/project.py
index 6f96f2d5c..41032287d 100644
--- a/submit-api/src/submit_api/schemas/project.py
+++ b/submit-api/src/submit_api/schemas/project.py
@@ -8,6 +8,7 @@
from submit_api.schemas.package import PackageSchema, StaffPackageSchema
from submit_api.schemas.proponent import ProponentSchema
+from submit_api.schemas.track_work import TrackWorkSchema
class ProjectSchema(Schema):
@@ -48,6 +49,19 @@ class Meta: # pylint: disable=too-few-public-methods
items = fields.Function(lambda obj: [])
+class AccountProjectWorkSchema(Schema):
+ """Account project work schema."""
+
+ class Meta: # pylint: disable=too-few-public-methods
+ """Exclude unknown fields in the deserialized output."""
+
+ unknown = EXCLUDE
+
+ id = fields.Int(data_key="id")
+ work_id = fields.Int(data_key="work_id")
+ work = fields.Nested(TrackWorkSchema, data_key="work")
+
+
class AccountProjectSchema(Schema):
"""Account project schema."""
@@ -61,6 +75,7 @@ class Meta: # pylint: disable=too-few-public-methods
project_id = fields.Int(data_key="project_id")
project = fields.Nested(ProjectSchema, data_key="project")
latest_packages = fields.List(fields.Nested(AccountProjectPackageSchema), data_key="packages")
+ account_project_works = fields.List(fields.Nested(AccountProjectWorkSchema, data_key="account_project_works"))
class StaffAccountProjectPackageSchema(StaffPackageSchema):
diff --git a/submit-api/src/submit_api/schemas/track_phase.py b/submit-api/src/submit_api/schemas/track_phase.py
new file mode 100644
index 000000000..fe40ab8a1
--- /dev/null
+++ b/submit-api/src/submit_api/schemas/track_phase.py
@@ -0,0 +1,23 @@
+"""TrackPhase schema.
+
+This module defines the schema for the track_phase entity.
+"""
+from marshmallow import EXCLUDE, Schema, fields
+
+
+class TrackPhaseSchema(Schema):
+ """Track phase schema."""
+
+ class Meta: # pylint: disable=too-few-public-methods
+ """Exclude unknown fields in the deserialized output."""
+
+ unknown = EXCLUDE
+
+ id = fields.Int(data_key="id")
+ name = fields.Str(data_key="name")
+ ea_act_id = fields.Int(data_key="ea_act_id", allow_none=True)
+ work_type_id = fields.Int(data_key="work_type_id")
+ work_type_name = fields.Str(data_key="work_type_name", allow_none=True)
+ sort_order = fields.Int(data_key="sort_order", allow_none=True)
+ number_of_days = fields.Int(data_key="number_of_days", allow_none=True)
+ legislated = fields.Boolean(data_key="legislated")
diff --git a/submit-api/src/submit_api/schemas/track_work.py b/submit-api/src/submit_api/schemas/track_work.py
new file mode 100644
index 000000000..ffaedcf30
--- /dev/null
+++ b/submit-api/src/submit_api/schemas/track_work.py
@@ -0,0 +1,23 @@
+"""TrackWork schema.
+
+This module defines the schema for the track_work entity.
+"""
+from marshmallow import EXCLUDE, Schema, fields
+
+from submit_api.schemas.track_phase import TrackPhaseSchema
+
+
+class TrackWorkSchema(Schema):
+ """Track work schema."""
+
+ class Meta: # pylint: disable=too-few-public-methods
+ """Exclude unknown fields in the deserialized output."""
+
+ unknown = EXCLUDE
+
+ id = fields.Int(data_key="id")
+ project_id = fields.Int(data_key="project_id")
+ current_phase_id = fields.Int(data_key="current_phase_id", allow_none=True)
+ work_state = fields.Str(data_key="work_state", allow_none=True)
+ title = fields.Str(data_key="title", allow_none=True)
+ current_phase = fields.Nested(TrackPhaseSchema, data_key="current_phase", allow_none=True)
diff --git a/submit-web/src/components/App/PackageStatusChip/index.tsx b/submit-web/src/components/App/PackageStatusChip/index.tsx
index f799dc042..ea14b80f1 100644
--- a/submit-web/src/components/App/PackageStatusChip/index.tsx
+++ b/submit-web/src/components/App/PackageStatusChip/index.tsx
@@ -229,6 +229,16 @@ const statusStyles: Record<
},
label: "Resubmitted",
},
+ REQUESTED_BY_EAO: {
+ sx: {
+ borderRadius: 1,
+ border: `1px solid ${BCDesignTokens.supportBorderColorWarning}`,
+ background: BCDesignTokens.supportSurfaceColorWarning,
+ height: "24px",
+ width: "139px",
+ },
+ label: "Requested by EAO",
+ },
};
type PackageStatusChipProps = Readonly<{
diff --git a/submit-web/src/components/App/Projects/Project.tsx b/submit-web/src/components/App/Projects/Project.tsx
index 490064d34..337e6453a 100644
--- a/submit-web/src/components/App/Projects/Project.tsx
+++ b/submit-web/src/components/App/Projects/Project.tsx
@@ -1,17 +1,9 @@
-import { Box, Button, Divider, styled, Typography } from "@mui/material";
-import { BCDesignTokens } from "epic.theme";
-import AddIcon from "@mui/icons-material/Add";
-import { ProjectStatus } from "@/components/App/registration/addProjects/ProjectStatus";
-import { PROJECT_STATUS } from "@/components/App/registration/addProjects/ProjectCard/constants";
-import ProjectTable from "@/components/App/Projects/ProjectTable";
+import { ContentBox } from "@/components/Shared/Layouts/ContentBox";
import { AccountProject } from "@/models/Project";
+import { Box, styled } from "@mui/material";
import { useNavigate } from "@tanstack/react-router";
-import { ContentBox } from "@/components/Shared/Layouts/ContentBox";
-import { When } from "react-if";
-import { useAccount } from "@/store/accountStore";
-import { USER_TYPE } from "@/models/User";
-import PermissionsGate from "@/components/Shared/PermissionGate";
-import { ACCOUNT_USER_PERMISSIONS } from "@/models/Role";
+import { ProjectSubmissionsCard } from "./ProjectSubmissionsCard";
+import { PROJECT_STATUS } from "@/components/App/registration/addProjects/ProjectCard/constants";
export const CardInnerBox = styled(Box)({
display: "flex",
@@ -28,16 +20,10 @@ type ProjectParam = {
export const Project = ({ accountProject }: ProjectParam) => {
const navigate = useNavigate();
- const { userType } = useAccount();
-
- const activeSubmissionPackages = accountProject.packages.filter(
- (subPackage) => !subPackage.completed_on,
- );
- const pastSubmissionPackages = accountProject.packages.filter((subPackage) =>
- Boolean(subPackage.completed_on),
- );
const { name, ea_certificate } = accountProject.project;
+ const currentPhase =
+ accountProject.account_project_works?.at(-1)?.work?.current_phase ?? null;
const handleNewSubmission = () => {
navigate({
@@ -52,89 +38,21 @@ export const Project = ({ accountProject }: ProjectParam) => {
topLabel={accountProject.project.proponent?.name || ""}
bottomLabel={ea_certificate ? `EAC # ${ea_certificate}` : ""}
>
-
-
-
-
- Management Plans & Related Documents
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Active Submissions
-
-
-
-
-
-
- Review Completed by the EAO
-
-
-
-
-
-
+ {currentPhase?.work_type_name == "ASSESSMENT" ? (
+
+ ) : (
+
+ )}
);
};
diff --git a/submit-web/src/components/App/Projects/ProjectSubmissionsCard.tsx b/submit-web/src/components/App/Projects/ProjectSubmissionsCard.tsx
new file mode 100644
index 000000000..2b13ac0e2
--- /dev/null
+++ b/submit-web/src/components/App/Projects/ProjectSubmissionsCard.tsx
@@ -0,0 +1,129 @@
+import ProjectTable from "@/components/App/Projects/ProjectTable";
+import { ProjectStatus } from "@/components/App/registration/addProjects/ProjectStatus";
+import PermissionsGate from "@/components/Shared/PermissionGate";
+import { SubmissionPackage } from "@/models/Package";
+import { ACCOUNT_USER_PERMISSIONS } from "@/models/Role";
+import { USER_TYPE } from "@/models/User";
+import { useAccount } from "@/store/accountStore";
+import AddIcon from "@mui/icons-material/Add";
+import { Box, Button, Divider, styled, Typography } from "@mui/material";
+import { BCDesignTokens } from "epic.theme";
+import { When } from "react-if";
+import { PROJECT_STATUS } from "../registration/addProjects/ProjectCard/constants";
+
+export const CardInnerBox = styled(Box)({
+ display: "flex",
+ alignItems: "flex-start",
+ justifyContent: "center",
+ flexDirection: "column",
+ height: "100%",
+ padding: "0 12px",
+});
+
+type ProjectSubmissionsCardProps = {
+ title: string;
+ status: string;
+ packages: SubmissionPackage[];
+ onNewSubmission: () => void;
+};
+
+export const ProjectSubmissionsCard = ({
+ title,
+ status,
+ packages,
+ onNewSubmission,
+}: ProjectSubmissionsCardProps) => {
+ const { userType } = useAccount();
+
+ const activeSubmissionPackages = packages.filter(
+ (subPackage) => !subPackage.completed_on,
+ );
+ const pastSubmissionPackages = packages.filter((subPackage) =>
+ Boolean(subPackage.completed_on),
+ );
+
+ return (
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Active Submissions
+
+
+
+
+
+
+
+
+ Review Completed by the EAO
+
+
+
+
+
+
+
+ );
+};
diff --git a/submit-web/src/components/App/Projects/ProjectTable/ProponentTableRow.tsx b/submit-web/src/components/App/Projects/ProjectTable/ProponentTableRow.tsx
index 103643211..7bb3e66fa 100644
--- a/submit-web/src/components/App/Projects/ProjectTable/ProponentTableRow.tsx
+++ b/submit-web/src/components/App/Projects/ProjectTable/ProponentTableRow.tsx
@@ -53,10 +53,12 @@ export default function ProponentTableRow({ subPackage }: ProjectRowProps) {
- {dateUtils.formatDate(subPackage.submitted_on)}
+ {subPackage.submitted_on
+ ? dateUtils.formatDate(subPackage.submitted_on)
+ : "-"}
- {subPackage.submitted_by ?? ""}
+ {subPackage.submitted_by ?? "-"}
= {
width: "128px",
},
},
+ REQUESTED_BY_EAO: {
+ sx: {
+ borderRadius: 1,
+ border: `1px solid ${BCDesignTokens.supportBorderColorInfo}`,
+ background: BCDesignTokens.themeBlue20,
+ height: "24px",
+ width: "104px",
+ },
+ label: "Requested by EAO",
+ },
};
type SubmissionStatusChipProps = Readonly<{
diff --git a/submit-web/src/components/App/registration/addProjects/ProjectCard/constants.ts b/submit-web/src/components/App/registration/addProjects/ProjectCard/constants.ts
index 6b6b9e0a9..c1984057b 100644
--- a/submit-web/src/components/App/registration/addProjects/ProjectCard/constants.ts
+++ b/submit-web/src/components/App/registration/addProjects/ProjectCard/constants.ts
@@ -1,3 +1,4 @@
export const PROJECT_STATUS = {
- POST_DECISION: "Post Decision",
+ EARLY_ENGAGEMENT: "EARLY_ENGAGEMENT",
+ POST_DECISION: "POST_DECISION",
};
diff --git a/submit-web/src/components/App/registration/addProjects/ProjectStatus.tsx b/submit-web/src/components/App/registration/addProjects/ProjectStatus.tsx
index ab7d727d6..c57a23fbe 100644
--- a/submit-web/src/components/App/registration/addProjects/ProjectStatus.tsx
+++ b/submit-web/src/components/App/registration/addProjects/ProjectStatus.tsx
@@ -1,32 +1,45 @@
import { Caption2 } from "@/components/Shared/Typographies";
-import { Case, Default, Switch } from "react-if";
import ModeStandbyIcon from "@mui/icons-material/ModeStandby";
import { Stack } from "@mui/material";
-import { PROJECT_STATUS } from "./ProjectCard/constants";
import { EAOColors } from "epic.theme";
+type StyleProps = {
+ color: string;
+ label: string;
+};
+
+const statusStyles: Record = {
+ POST_DECISION: {
+ color: EAOColors.DecisionDark,
+ label: "Post-Decision",
+ },
+ EARLY_ENGAGEMENT: {
+ color: "#5583B5",
+ label: "Early Engagement",
+ },
+};
+
type ProjectStatusProps = {
status: string;
};
export const ProjectStatus = ({ status }: ProjectStatusProps) => {
+ const style = statusStyles[status];
+
+ if (!style) {
+ return null;
+ }
+
return (
-
-
-
-
-
- Post-Decision
-
-
-
-
- {status}
-
-
+
+
+
+ {style.label}
+
+
);
};
diff --git a/submit-web/src/models/Package.ts b/submit-web/src/models/Package.ts
index c80f07673..39919634b 100644
--- a/submit-web/src/models/Package.ts
+++ b/submit-web/src/models/Package.ts
@@ -44,7 +44,8 @@ export type PackageStatus =
| "PASSED_CONSULTATION_CHECK"
| "AWAITING_MANAGER_APPROVAL"
| "FAILED_CONSULTATION_CHECK"
- | "CREATED";
+ | "CREATED"
+ | "REQUESTED_BY_EAO";
export const PACKAGE_STATUS: Record<
PackageStatus,
@@ -118,6 +119,10 @@ export const PACKAGE_STATUS: Record<
value: "REVIEWED",
label: "Reviewed",
},
+ REQUESTED_BY_EAO: {
+ value: "REQUESTED_BY_EAO",
+ label: "Requested by EAO",
+ },
};
export type SubmissionPackageMeta = Record;
diff --git a/submit-web/src/models/Project.ts b/submit-web/src/models/Project.ts
index cbaf8c133..c9d1f177f 100644
--- a/submit-web/src/models/Project.ts
+++ b/submit-web/src/models/Project.ts
@@ -1,5 +1,6 @@
import { SubmissionPackage } from "./Package";
import { Proponent } from "./Proponent";
+import { TrackWork } from "./TrackWork";
export type Project = {
id: number;
@@ -14,12 +15,19 @@ export const getProjectProponentId = (project: Project): number => {
return project.proponent_id ?? 0;
};
+export type AccountProjectWork = {
+ id: number;
+ work_id: number;
+ work: TrackWork;
+};
+
export type AccountProject = {
id: number;
project_id: number;
account_id: number;
project: Project;
packages: SubmissionPackage[];
+ account_project_works?: AccountProjectWork[];
};
export const createDefaultAccountProject = (): AccountProject => ({
diff --git a/submit-web/src/models/TrackPhase.ts b/submit-web/src/models/TrackPhase.ts
new file mode 100644
index 000000000..9aec376b2
--- /dev/null
+++ b/submit-web/src/models/TrackPhase.ts
@@ -0,0 +1,10 @@
+export type TrackPhase = {
+ id: number;
+ name: string;
+ ea_act_id?: number;
+ work_type_id: number;
+ work_type_name?: string;
+ sort_order?: number;
+ number_of_days?: number;
+ legislated: boolean;
+};
diff --git a/submit-web/src/models/TrackWork.ts b/submit-web/src/models/TrackWork.ts
new file mode 100644
index 000000000..55e041754
--- /dev/null
+++ b/submit-web/src/models/TrackWork.ts
@@ -0,0 +1,10 @@
+import { TrackPhase } from "./TrackPhase";
+
+export type TrackWork = {
+ id: number;
+ project_id: number;
+ current_phase_id?: number;
+ work_state?: string;
+ title?: string;
+ current_phase?: TrackPhase;
+};