Skip to content

Commit

Permalink
Confetti (#2147)
Browse files Browse the repository at this point in the history
* setup confetti api fix

* setup endpoints

* remove unused attributes

* setup workphase by id

* set up event_position check

* add work phase in response

* fix migration error

* clean up type declaration

* fix linting

* removing trailing white space

* flake 8

* flake 8

* confetti related changes

---------

Co-authored-by: David Nunez <david.nunez@aot-technologies.com>
  • Loading branch information
dinesh-aot and djnunez-aot authored Apr 19, 2024
1 parent c2b78ac commit ee117cf
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def upgrade():
batch_op.add_column(sa.Column('description', sa.String(), autoincrement=False, nullable=True))

with op.batch_alter_table('special_fields', schema=None) as batch_op:
batch_op.drop_index('entity_field_index')
batch_op.create_index('entity_field_index', ['entity', 'entity_id', 'field_name', 'time_range'], unique=False)

# ### end Alembic commands ###
Expand Down
1 change: 0 additions & 1 deletion epictrack-api/src/api/actions/set_event_date.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Disable work start date action handler"""

from datetime import timedelta

from api.actions.base import ActionFactory
from api.models import db
from api.models.event import Event
Expand Down
24 changes: 22 additions & 2 deletions epictrack-api/src/api/resources/work.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from api.utils.caching import AppCache
from api.utils.datetime_helper import get_start_of_day
from api.utils.util import cors_preflight

from api.models.work_phase import WorkPhase

API = Namespace("works", description="Works")

Expand Down Expand Up @@ -286,7 +286,7 @@ def post():


@cors_preflight("GET")
@API.route("/work-phases/<int:work_phase_id>", methods=["GET", "OPTIONS"])
@API.route("/work-phases/<int:work_phase_id>/template-upload-status", methods=["GET", "OPTIONS"])
class WorkPhaseTemplateStatus(Resource):
"""Endpoints to get work phase template upload status"""

Expand All @@ -306,6 +306,26 @@ def get(work_phase_id):
)


@cors_preflight("GET")
@API.route("/work-phases/<int:work_phase_id>", methods=["GET", "OPTIONS"])
class WorkPhaseId(Resource):
"""Endpoints to get work phase template upload status"""

@staticmethod
@cors.crossdomain(origin="*")
@auth.require
@profiletime
def get(work_phase_id):
"""Get the status if template upload is available"""
req.WorkIdPhaseIdPathParameterSchema().load(request.view_args)
work_phase = WorkPhase.find_by_id(work_phase_id)
print(work_phase.name)
return (
res.WorkPhaseByIdResponseSchema().dump({'work_phase': work_phase}),
HTTPStatus.OK,
)


@cors_preflight("GET,POST")
@API.route("/<int:work_id>/first-nations", methods=["GET", "POST", "OPTIONS"])
class WorkFirstNations(Resource):
Expand Down
2 changes: 1 addition & 1 deletion epictrack-api/src/api/schemas/response/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@
from .work_response import (
WorkIssuesResponseSchema, WorkIssueUpdatesResponseSchema, WorkPhaseAdditionalInfoResponseSchema,
WorkPhaseResponseSchema, WorkPhaseTemplateAvailableResponse, WorkResourceResponseSchema, WorkResponseSchema,
WorkStaffRoleReponseSchema, WorkStatusResponseSchema)
WorkStaffRoleReponseSchema, WorkStatusResponseSchema, WorkPhaseByIdResponseSchema)
6 changes: 6 additions & 0 deletions epictrack-api/src/api/schemas/response/work_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ class Meta(
staff = fields.Nested(WorkStaffRoleReponseSchema(many=True), dump_default=[])


class WorkPhaseByIdResponseSchema(Schema):
"""Schema for additional work phase details"""

work_phase = fields.Nested(WorkPhaseResponseSchema, dump_only=True)


class WorkPhaseAdditionalInfoResponseSchema(Schema):
"""Schema for additional work phase details"""

Expand Down
2 changes: 1 addition & 1 deletion epictrack-api/tests/unit/apis/test_works.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ def test_work_phase_template_upload_status(client, auth_header):
work_response_json = work_response.json
assert work_response.status_code == HTTPStatus.CREATED
url = urljoin(
API_BASE_URL, f"works/work-phases/{work_response_json['current_work_phase_id']}"
API_BASE_URL, f"works/work-phases/{work_response_json['current_work_phase_id']}/template-upload-status"
)
response = client.get(url, headers=auth_header)
assert response.status_code == HTTPStatus.OK
Expand Down
54 changes: 34 additions & 20 deletions epictrack-web/src/components/workPlan/event/EventList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import ImportTaskEvent from "../task/ImportTaskEvent";
import {
TemplateStatus,
Work,
WorkPhase,
WorkPhaseAdditionalInfo,
} from "../../../models/work";
import { SnackbarKey, closeSnackbar } from "notistack";
Expand Down Expand Up @@ -315,12 +316,12 @@ const EventList = () => {
);
const workPhases = workPhasesResult.data as WorkPhaseAdditionalInfo[];
setWorkPhases(workPhases);
if (selectedWorkPhase) {
const selectedWp = workPhases.filter(
(p) => p.work_phase.id === selectedWorkPhase.work_phase.id
)[0];
setSelectedWorkPhase(selectedWp);
}
// if (selectedWorkPhase) {
// const selectedWp = workPhases.filter(
// (p) => p.work_phase.id === selectedWorkPhase.work_phase.id
// )[0];
// setSelectedWorkPhase(selectedWp);
// }
setLoading(false);
}
}, []);
Expand All @@ -336,21 +337,14 @@ const EventList = () => {
setShowTemplateForm(false);
setShowMilestoneForm(false);
getCombinedEvents();
getWorkById();
getWorkPhases();
getTemplateUploadStatus()
.then(() => {
return getWorkById();
})
.then(() => {
if (
milestoneEvent?.event_configuration.event_position ===
EventPosition.END
) {
dispatch(showConfetti(true));
}
setTaskEvent(undefined);
setMilestoneEvent(undefined);
});
getTemplateUploadStatus();
if (
milestoneEvent?.event_configuration?.event_position === EventPosition.END
) {
getWorkPhaseById();
}
};

const onTemplateFormSaveHandler = (templateId: number) => {
Expand Down Expand Up @@ -509,6 +503,26 @@ const EventList = () => {
}
}, [selectedWorkPhase?.work_phase.phase.id]);

const getWorkPhaseById = React.useCallback(async () => {
const workPhaseId = selectedWorkPhase?.work_phase.id;
if (workPhaseId) {
try {
const workPhase = (await workService.getWorkPhaseById(
Number(workPhaseId)
)) as WorkPhase;

if (workPhase?.is_completed) {
dispatch(showConfetti(true));
}
} catch (error) {
console.error(
`Error fetching work phase with ID: ${workPhaseId}`,
error
);
}
}
}, [selectedWorkPhase?.work_phase.id]);

React.useEffect(() => {
getTemplateUploadStatus();
}, [selectedWorkPhase]);
Expand Down
15 changes: 7 additions & 8 deletions epictrack-web/src/components/workPlan/phase/PhaseAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,20 @@ const SummaryItem = (props: SummaryItemProps) => {

const PhaseAccordion = ({ phase, ...rest }: PhaseAccordionProps) => {
const [expanded, setExpanded] = React.useState<boolean>(false);
const ctx = useContext(WorkplanContext);
const { selectedWorkPhase, setSelectedWorkPhase } =
useContext(WorkplanContext);
const isSelectedPhase = React.useMemo<boolean>(
() => phase.work_phase.id === ctx.selectedWorkPhase?.work_phase.id,
[ctx.selectedWorkPhase]
() => phase.work_phase.id === selectedWorkPhase?.work_phase.id,
[selectedWorkPhase]
);
React.useEffect(
() =>
setExpanded(phase.work_phase.id === ctx.selectedWorkPhase?.work_phase.id),
[phase, ctx.selectedWorkPhase]
() => setExpanded(phase.work_phase.id === selectedWorkPhase?.work_phase.id),
[phase, selectedWorkPhase]
);
const onExpandHandler = (expand: boolean) => {
setExpanded(expand);
ctx.setSelectedWorkPhase(phase);
setSelectedWorkPhase(phase);
};

const fromDate = React.useMemo(
() =>
Moment(phase.work_phase.start_date).isSameOrAfter(Moment())
Expand Down
4 changes: 3 additions & 1 deletion epictrack-web/src/constants/api-endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ const Endpoints = {
DOWNLOAD_WORK_PLAN: "works/workplan/download",
WORK_TEAM_MEMBERS: "works/:work_id/staff-roles",
WORK_TEAM_MEMBER: "works/staff-roles/:work_staff_id",
CHECK_TEMPLATE_UPLOAD_STATUS: "works/work-phases/:work_phase_id",
CHECK_TEMPLATE_UPLOAD_STATUS:
"works/work-phases/:work_phase_id/template-upload-status",
WORK_FIRST_NATION_NOTES: "works/:work_id/first-nation-notes",
WORK_NOTES: "works/:work_id/notes",
WORK_FIRST_NATIONS: "works/:work_id/first-nations",
DOWNLOAD_WORK_FIRST_NATIONS: "works/:work_id/first-nations/download",
WORK_FIRST_NATION: "works/first-nations/:work_first_nation_id",
WORK_IMPORT_FIRST_NATIONS: "works/:work_id/first-nations/import",
GET_ALL_WORK_TYPES: "works/types",
GET_WORK_PHASE_BY_ID: "works/work-phases/:work_phase_id",
},
WorkTypes: {
GET_ALL: "work-types",
Expand Down
29 changes: 27 additions & 2 deletions epictrack-web/src/services/workService/workService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import ServiceBase from "../common/serviceBase";
import { MasterBase } from "../../models/type";
import { StaffWorkRole } from "../../models/staff";
import { WorkFirstNation } from "../../models/firstNation";
import { Work } from "../../models/work";
import { Work, WorkPhase } from "../../models/work";
import { WorkType } from "../../models/workType";

import { AxiosResponse } from "axios";
interface WorkPhaseResponse {
work_phase: WorkPhase;
}
class WorkService implements ServiceBase {
async getAll(is_active = undefined) {
return await http.GetRequest<Work[]>(Endpoints.Works.WORKS, { is_active });
Expand Down Expand Up @@ -100,6 +103,28 @@ class WorkService implements ServiceBase {
return await http.GetRequest(Endpoints.Works.WORKS + `/${workId}/phases`);
}

async getWorkPhaseById(workPhaseId: number): Promise<WorkPhase | null> {
try {
const endpoint = Endpoints.Works.GET_WORK_PHASE_BY_ID.replace(
":work_phase_id",
workPhaseId.toString()
);
const result: AxiosResponse<WorkPhaseResponse> = await http.GetRequest(
endpoint
);

if (!result.data || !result.data.work_phase) {
console.error(`No work phase found with ID: ${workPhaseId}`);
return null;
}

return result.data.work_phase;
} catch (error) {
console.error(`Error fetching work phase with ID: ${workPhaseId}`, error);
return null;
}
}

async downloadWorkplan(workPhaseId: number) {
return await http.PostRequest(
Endpoints.Works.DOWNLOAD_WORK_PLAN + `?work_phase_id=${workPhaseId}`,
Expand Down

0 comments on commit ee117cf

Please sign in to comment.