Skip to content

Commit

Permalink
Merge pull request #112 from jadmsaadaot/SUBMIT-task#149-B
Browse files Browse the repository at this point in the history
Integrate UI Package status with newly implemented package.status
  • Loading branch information
jadmsaadaot authored Oct 17, 2024
2 parents d3fb8a6 + d73dfa8 commit 9a9dfe1
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 51 deletions.
55 changes: 55 additions & 0 deletions submit-api/migrations/versions/e1e1b81ad5c8_rename_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
""" Rename aggregated_item_statuses to status
Revision ID: e1e1b81ad5c8
Revises: 8dff03f931d7
Create Date: 2024-10-16 11:09:18.732646
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ENUM, ARRAY

# revision identifiers, used by Alembic.
revision = 'e1e1b81ad5c8'
down_revision = '8dff03f931d7'
branch_labels = None
depends_on = None


def upgrade():
# Remove the existing status column
op.drop_column('packages', 'status')

# Rename aggregated_item_statuses to status
op.alter_column(
'packages',
'aggregated_item_statuses',
new_column_name='status',
existing_type=ARRAY(
ENUM('NEW_SUBMISSION', 'IN_REVIEW', 'APPROVED', 'REJECTED', 'SUBMITTED', name='packagestatus')),
nullable=False
)


def downgrade():
# Add the status column back

# Rename status back to aggregated_item_statuses
op.alter_column(
'packages',
'status',
new_column_name='aggregated_item_statuses',
existing_type=ARRAY(ENUM('NEW_SUBMISSION', 'IN_REVIEW', 'APPROVED', 'REJECTED', 'SUBMITTED', name='packagestatus')),
nullable=False
)
op.add_column(
'packages',
sa.Column('status', ENUM('NEW_SUBMISSION', 'IN_REVIEW', 'APPROVED', 'REJECTED', 'SUBMITTED', name='packagestatus'), nullable=True)
)
# populate status column with the first member of the existing aggregated_item_statuses or 'NEW_SUBMISSION' if empty
op.execute(
"UPDATE packages SET status = COALESCE(aggregated_item_statuses[1], 'NEW_SUBMISSION')"
)
# make status column not nullable
op.alter_column('packages', 'status', nullable=False)
# ### end Alembic commands ###
9 changes: 1 addition & 8 deletions submit-api/src/submit_api/models/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class Package(BaseModel):
name = Column(db.String(255), nullable=False)
type_id = Column(db.Integer, ForeignKey('package_types.id'), nullable=False)
type = db.relationship('PackageType', foreign_keys=[type_id], lazy='joined')
status = Column(Enum(PackageStatus), nullable=False, default=PackageStatus.NEW_SUBMISSION.value)
submitted_on = Column(db.DateTime, nullable=True)
submitted_by = Column(db.String(255), nullable=True)
submitted_by_account_user = db.relationship(
Expand All @@ -45,13 +44,7 @@ class Package(BaseModel):
)
meta = db.relationship('PackageMetadata', backref='package', lazy='select')
items = db.relationship('Item', backref='package', lazy='joined', order_by='Item.sort_order')
aggregated_item_statuses = Column(db.ARRAY(Enum(PackageStatus)), nullable=False, default=list)

# @hybrid_property
# def aggregated_item_statuses(self):
# """Aggregate item statuses."""
# aggregated_statuses = PackageQueries.aggregate_item_statuses(self.items)
# return aggregated_statuses
status = Column(db.ARRAY(Enum(PackageStatus)), nullable=False, default=[PackageStatus.NEW_SUBMISSION.value])

@classmethod
def get_package_by_id_with_items(cls, package_id: int):
Expand Down
9 changes: 5 additions & 4 deletions submit-api/src/submit_api/models/queries/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ def aggregate_item_statuses(cls, items: list):
return aggregated_statuses_list

@staticmethod
def update_package_status(package_id, session):
def update_package_status(package_id, session, package=None):
"""Update the status of the package based on the statuses of its items."""
package = session.query(PackageModel).filter_by(id=package_id).one()
if not package:
package = session.query(PackageModel).filter_by(id=package_id).one()
# Determine new package statuses based on item statuses
new_statuses = PackageQueries.aggregate_item_statuses(package.items)
if set(package.aggregated_item_statuses) != set(new_statuses):
package.aggregated_item_statuses = list(new_statuses)
if set(package.status) != set(new_statuses):
package.status = list(new_statuses)
session.add(package)
3 changes: 1 addition & 2 deletions submit-api/src/submit_api/schemas/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ class Meta: # pylint: disable=too-few-public-methods
name = fields.Str(data_key="name")
type = fields.Nested(PackageTypeSchema, data_key="type")
type_id = fields.Int(data_key="type_id")
status = fields.Enum(data_key="status", enum=PackageStatus)
status = fields.List(fields.Enum(enum=PackageStatus), enum=PackageStatus, data_key="status")
submitted_on = fields.DateTime(data_key="submitted_on")
submitted_by_account_user = fields.Pluck(AccountUserSchema, "full_name", data_key="submitted_by")
meta = fields.Nested(PackageMetadataSchema, data_key="meta", many=True)
items = fields.Nested(ItemSchema, data_key="items", many=True)
aggregated_item_statuses = fields.List(fields.Enum(enum=PackageStatus), data_key="aggregated_item_statuses")
3 changes: 1 addition & 2 deletions submit-api/src/submit_api/schemas/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ class Meta: # pylint: disable=too-few-public-methods
id = fields.Int(data_key="id")
name = fields.Str(data_key="name")
type = fields.Nested(PackageTypeSchema, data_key="type")
status = fields.Enum(data_key="status", enum=PackageStatus)
status = fields.List(fields.Enum(enum=PackageStatus), data_key="status")
submitted_on = fields.DateTime(data_key="submitted_on")
submitted_by_account_user = fields.Pluck(AccountUserSchema, "full_name", data_key="submitted_by")
items = fields.Function(lambda obj: [])
aggregated_item_statuses = fields.List(fields.Enum(enum=PackageStatus), data_key="aggregated_item_statuses")


class AccountProjectSchema(Schema):
Expand Down
10 changes: 8 additions & 2 deletions submit-api/src/submit_api/services/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from submit_api.models.package import PackageStatus
from submit_api.models.package_metadata import PackageMetadata as PackageMetadataModel
from submit_api.models.package_item_type import PackageItemType as PackageItemTypeModel
from submit_api.models.queries.package import PackageQueries
from submit_api.utils.token_info import TokenInfo


Expand Down Expand Up @@ -91,6 +92,11 @@ def _get_and_validate_complete_package(package_id) -> PackageModel:
raise BadRequestError("All items must be completed before completing the package")
return package

@staticmethod
def _update_package_status(package_id, session, package=None):
"""Update the status of the package based on the statuses of its items."""
PackageQueries.update_package_status(package_id, session, package)

@staticmethod
def _update_items_status(items, status, session):
"""Update status of all items in the package."""
Expand All @@ -103,7 +109,6 @@ def _update_package_submission_details(package, session):
"""Update package submission details."""
package.submitted_on = datetime.utcnow()
package.submitted_by = TokenInfo.get_id()
package.status = PackageStatus.SUBMITTED
session.add(package)

@classmethod
Expand All @@ -112,8 +117,9 @@ def submit_package(cls, package_id):
package = cls._get_and_validate_complete_package(package_id)

with session_scope() as session:
cls._update_items_status(package.items, ItemStatus.SUBMITTED.value, session)
cls._update_package_status(package_id, session, package)
cls._update_package_submission_details(package, session)
cls._update_items_status(package.items, ItemStatus.SUBMITTED, session)
session.flush()
session.commit()
return package
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PackageStatus } from "@/models/Package";
import { Box, Stack } from "@mui/material";
import PackageStatusChip from ".";

type PackageStatusChipStackProps = {
status: PackageStatus[];
};
export const PackageStatusChipStack = ({
status,
}: PackageStatusChipStackProps) => {
return (
<Box sx={{ display: "inline-block" }}>
<Stack direction="column" spacing={1} width={"fit-content"}>
{status.map((value) => (
<PackageStatusChip key={value} status={value} />
))}
</Stack>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PackageStatus } from "@/models/Package";
import { Chip } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import { BCDesignTokens, EAOColors } from "epic.theme";

type StyleProps = {
sx: Record<string, string | number>;
Expand Down Expand Up @@ -45,6 +45,24 @@ const statusStyles: Record<PackageStatus, StyleProps> = {
},
label: "Completed",
},
PARTIALLY_COMPLETED: {
label: "Partially Completed",
sx: {
borderRadius: 1,
border: `1px solid ${BCDesignTokens.supportBorderColorWarning}`,
background: BCDesignTokens.supportSurfaceColorWarning,
height: "24px",
},
},
NEW_SUBMISSION: {
sx: {
borderRadius: 1,
border: `1px solid ${EAOColors.DecisionDark}`,
background: EAOColors.DecisionLight,
height: "24px",
},
label: "New Submission",
},
};

export default function PackageStatusChip({
Expand Down
15 changes: 12 additions & 3 deletions submit-web/src/components/Projects/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,19 @@ export const Project = ({ accountProject }: ProjectParam) => {
const navigate = useNavigate();

const activeSubmissionPackages = accountProject.packages.filter(
(subPackage) => subPackage.status === PACKAGE_STATUS.IN_REVIEW.value
(subPackage) =>
!subPackage.status.some(
(status) =>
status === PACKAGE_STATUS.APPROVED.value ||
status === PACKAGE_STATUS.REJECTED.value,
),
);
const pastSubmissionPackages = accountProject.packages.filter(
(subPackage) => subPackage.status !== PACKAGE_STATUS.IN_REVIEW.value
const pastSubmissionPackages = accountProject.packages.filter((subPackage) =>
subPackage.status.some(
(status) =>
status === PACKAGE_STATUS.APPROVED.value ||
status === PACKAGE_STATUS.REJECTED.value,
),
);

const { name, ea_certificate } = accountProject.project;
Expand Down
12 changes: 4 additions & 8 deletions submit-web/src/components/Projects/ProjectTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,14 @@ export default function SubmissionPackageTable({
}}
>
<TableRow>
<StyledTableHeadCell colSpan={6}>
Submission Name
</StyledTableHeadCell>
<StyledTableHeadCell colSpan={2} align="right">
<StyledTableHeadCell>Submission Name</StyledTableHeadCell>
<StyledTableHeadCell align="right">
Date Submitted
</StyledTableHeadCell>
<StyledTableHeadCell colSpan={2} align="right">
<StyledTableHeadCell align="right">
Submitted By
</StyledTableHeadCell>
<StyledTableHeadCell colSpan={2} align="center">
Status
</StyledTableHeadCell>
<StyledTableHeadCell align="center">Status</StyledTableHeadCell>
</TableRow>
</TableHead>
)}
Expand Down
12 changes: 4 additions & 8 deletions submit-web/src/components/Projects/ProjectTableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ArrowForwardIos } from "@mui/icons-material";
import { Link, TableCell, TableRow, Typography } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import PackageStatusChip from "./ProjectStatusChip";
import { SubmissionPackage } from "@/models/Package";
import dayjs from "dayjs";
import { PackageStatusChipStack } from "../PackageStatusChip/PackageStatusChipStack";

interface ProjectRowProps {
subPackage: SubmissionPackage;
Expand All @@ -27,7 +27,6 @@ export default function ProjectTableRow({
}}
>
<TableCell
colSpan={6}
sx={{
borderTop: border,
borderBottom: border,
Expand Down Expand Up @@ -59,7 +58,6 @@ export default function ProjectTableRow({
</Link>
</TableCell>
<TableCell
colSpan={2}
align="right"
sx={{
borderTop: border,
Expand All @@ -72,7 +70,6 @@ export default function ProjectTableRow({
: "--"}
</TableCell>
<TableCell
colSpan={2}
align="right"
sx={{
borderTop: border,
Expand All @@ -83,8 +80,7 @@ export default function ProjectTableRow({
{subPackage.submitted_by ?? "--"}
</TableCell>
<TableCell
colSpan={2}
align="right"
align="center"
sx={{
borderTop: border,
borderTopRightRadius: 5,
Expand All @@ -94,14 +90,14 @@ export default function ProjectTableRow({
py: BCDesignTokens.layoutPaddingXsmall,
}}
>
<PackageStatusChip status={subPackage.status} />
<PackageStatusChipStack status={subPackage.status} />
</TableCell>
</TableRow>
<TableRow key={`empty-row-${subPackage.id}`} sx={{ py: 1 }}>
<TableCell
component="th"
scope="row"
colSpan={12}
colSpan={4}
sx={{
border: 0,
py: BCDesignTokens.layoutPaddingXsmall,
Expand Down
17 changes: 14 additions & 3 deletions submit-web/src/models/Package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export type PackageStatus =
| "APPROVED"
| "REJECTED"
| "COMPLETED"
| "SUBMITTED";
| "SUBMITTED"
| "PARTIALLY_COMPLETED"
| "NEW_SUBMISSION";

export const PACKAGE_STATUS: Record<
PackageStatus,
{ value: PackageStatus; label: string }
Expand All @@ -35,12 +38,20 @@ export const PACKAGE_STATUS: Record<
value: "SUBMITTED",
label: "Submitted",
},
PARTIALLY_COMPLETED: {
value: "PARTIALLY_COMPLETED",
label: "Partially Completed",
},
NEW_SUBMISSION: {
value: "NEW_SUBMISSION",
label: "New Submission",
},
};

export type SubmissionPackage = {
id: number;
name: string;
status: PackageStatus;
status: PackageStatus[];
submitted_on?: string;
submitted_by?: string;
type_id: number;
Expand All @@ -51,7 +62,7 @@ export type SubmissionPackage = {
export const createDefaultSubmissionPackage = (): SubmissionPackage => ({
id: 0,
name: "",
status: PACKAGE_STATUS.IN_REVIEW.value,
status: [PACKAGE_STATUS.IN_REVIEW.value],
type_id: 0,
type: {
id: 0,
Expand Down
Loading

0 comments on commit 9a9dfe1

Please sign in to comment.