Skip to content

Commit

Permalink
Merge branch 'develop' into TASK-346_exportWorkers
Browse files Browse the repository at this point in the history
  • Loading branch information
pectom authored Mar 9, 2021
2 parents 4860dd6 + 25835b4 commit 2cc8ed2
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { WorkerType } from "../../../../src/common-models/worker-info.model";

const addWorker = (workerName: string, position: WorkerType) => {
const addWorker = (workerName: string, position: WorkerType): Cypress.Chainable => {
cy.get('[data-cy="btn-management-tab"]').click();
cy.get('[data-cy="management-page-title"]').should("be.visible");
cy.get('[data-cy="btn-add-worker"]').click();
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/e2e/management-tab/edit-worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ context("Tab management", () => {

it("Should be able to set worker name", () => {
cy.get('[data-cy="name"]').type(newWorker);
cy.get(`[value=\"${newWorker}\"]`).should("be.visible");
cy.get(`[value="${newWorker}"]`).should("be.visible");
});

it("Should be able to set worker position", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function App(): JSX.Element {
<RouteButtonsComponent tabs={tabs} disabled={disableRouteButtons} />
</Box>
<Box className={classes.drawer}>
<JiraLikeDrawer />
<JiraLikeDrawer width={690} />
</Box>
</Box>
{isElectron() ? <></> : <NetlifyProFooter />}
Expand Down
7 changes: 6 additions & 1 deletion src/assets/styles/styles/custom/_error-list-item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.red-rectangle {
border-radius: 4px;
width: 0.8%;
width: 4.5px;
position: absolute;
height: 100%;
background-color: $error-red;
Expand All @@ -29,6 +29,7 @@
flex: 1;
text-align: center;
padding-left: 15px;
padding-right: 25px;
position: relative;

.error-title-content {
Expand All @@ -47,6 +48,10 @@
margin: 10px 10px;
text-align: justify;
font-family: "Roboto";
strong {
letter-spacing: 1.5px;
font-weight: bolder;
}
}

.error-btn {
Expand Down
5 changes: 2 additions & 3 deletions src/assets/styles/styles/custom/_tables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ p {
font-size: 13px;
border-radius: 4px;
z-index: 3;
max-width: 500px;
}

.cell-details-popper {
Expand All @@ -331,16 +332,14 @@ p {
padding: 10px;
font-size: 13px;
border-radius: 4px;
// position: absolute;
// margin-left: 35px;
z-index: 2;
box-shadow: 0 1.4px 1.1px rgba(0, 0, 0, 0.034), 0 3.3px 2.7px rgba(0, 0, 0, 0.048),
0 6.2px 5px rgba(0, 0, 0, 0.06), 0 11.1px 8.5px rgba(0, 0, 0, 0.072),
0 20.8px 25.4px rgba(0, 0, 0, 0.086), 0 50px 50px rgba(0, 0, 0, 0.12);
overflow: hidden;
}

.errorTootlip-item {
.errorTooltip-item {
margin: 0px !important;
.error-title {
flex: 0.5 !important;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import React from "react";
import DrawerHeader from "./drawer-header.component";
import { Box } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { makeStyles, Theme } from "@material-ui/core/styles";
import { useJiraLikeDrawer } from "./jira-like-drawer-context";
import ScssVars from "../../../assets/styles/styles/custom/_variables.module.scss";

const useStyles = makeStyles({
export interface StyleProps {
width: number;
}

const useStyles = makeStyles<Theme, StyleProps>({
drawer: {
minWidth: 690,
width: ({ width }): number => width,
height: `calc(100vh - ${
parseInt(ScssVars.headerHeight.slice(0, -2)) +
parseInt(ScssVars.drawerHeaderHeight.slice(0, -2)) +
Expand All @@ -20,8 +24,8 @@ const useStyles = makeStyles({
},
});

export default function JiraLikeDrawer(): JSX.Element {
const classes = useStyles();
export default function JiraLikeDrawer(width): JSX.Element {
const classes = useStyles(width);
const { title, open, setOpen, childrenComponent } = useJiraLikeDrawer();

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function ErrorTooltipProvider({
key={`${error.kind}_${index}`}
error={ErrorMessageHelper.getErrorMessage(error)}
interactable={false}
className="errorTootlip-item"
className="errorTooltip-item"
showTitle={showErrorTitle}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function ErrorList({ errors = [] }: Options): JSX.Element {
{
errorType: ScheduleErrorType.AON,
errors: errors.filter((e) => e.type === ScheduleErrorType.DSS),
errorDescription: "Niedozwolona sekwencja zmian",
errorDescription: "Naruszenie wymaganej przerwy",
},
{
errorType: ScheduleErrorType.AON,
Expand Down
85 changes: 48 additions & 37 deletions src/helpers/error-message.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ import {
ParseErrorCode,
ScheduleError,
} from "../common-models/schedule-error.model";
import { SHIFTS as shifts } from "../common-models/shift-info.model";
import { ColorHelper } from "./colors/color.helper";
import { Color, Colors } from "./colors/color.model";
import { ShiftHelper } from "./shifts.helper";
import { TranslationHelper } from "./translations.helper";

type Error = ScheduleErrorLevel;

Expand All @@ -32,12 +35,6 @@ export class ErrorMessageHelper {
}

public static getErrorMessage(error: ScheduleError): ScheduleErrorMessageModel {
const dayTimeTranslations = {
MORNING: "porannej",
AFTERNOON: "popołudniowej",
NIGHT: "nocnej",
};

const kind = error.kind;
let message: string;
let title = "Nie rozpoznano błędu";
Expand All @@ -48,18 +45,17 @@ export class ErrorMessageHelper {
switch (error.kind) {
case AlgorithmErrorCode.AlwaysAtLeastOneNurse:
i = 0;
message = `Brak pielęgniarek w dniu <strong>${error.day + 1} na zmianie ${
error.day_time ? dayTimeTranslations[error.day_time] : ""
}</strong>`;
if (error.segments[i][0] !== 1 && error.segments[i][1] !== 24) {
message += ` w godzinach <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
message = `Brak pielęgniarek`;
if (error.segments[i][0] !== 1 || error.segments[i][1] !== 24) {
message += ` w godzinach <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
}
while (error.segments[i + 1]) {
i++;
if (error.segments[i][0] !== 1 && error.segments[i][1] !== 24) {
message += `, <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
if (error.segments[i][0] !== 1 || error.segments[i][1] !== 24) {
message += `, <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
}
}
message += `.`;
type = ScheduleErrorType.AON;
title = "date";
if (error.day) {
Expand All @@ -68,17 +64,17 @@ export class ErrorMessageHelper {
break;
case AlgorithmErrorCode.WorkerNumberDuringDay:
i = 0;
message = `Za mało pracowników w trakcie dnia w dniu <strong>${error.day + 1}</strong>`;
if (error.segments && error.segments[i][0] !== 1 && error.segments[i][1] !== 24) {
message += ` w godzinach <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
message = `Za mało pracowników w trakcie dnia`;
if (error.segments && (error.segments[i][0] !== 6 || error.segments[i][1] !== 22)) {
message += ` w godzinach <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
while (error.segments[i + 1]) {
i++;
if (error.segments[i][0] !== 1 && error.segments[i][1] !== 24) {
message += `, <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
if (error.segments[i][0] !== 6 || error.segments[i][1] !== 22) {
message += `, <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
}
}
}
message += `, potrzeba <strong>${error.required}</strong>, jest <strong>${error.actual}</strong>`;
message += `: potrzeba <b>${error.required}</b>, jest <b>${error.actual}</b>.`;
type = ScheduleErrorType.WND;
title = "date";
if (error.day) {
Expand All @@ -87,56 +83,71 @@ export class ErrorMessageHelper {
break;
case AlgorithmErrorCode.WorkerNumberDuringNight:
i = 0;
message = `Za mało pracowników w nocy w dniu <strong>${error.day + 1}</strong>`;
if (error.segments && error.segments[i][0] !== 22 && error.segments[i][1] !== 6) {
message += ` w godzinach <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
message = `Za mało pracowników w nocy`;
if (error.segments && (error.segments[i][0] !== 22 || error.segments[i][1] !== 6)) {
message += ` w godzinach <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
while (error.segments[i + 1]) {
i++;
if (error.segments[i][0] !== 22 && error.segments[i][1] !== 6) {
message += `, <strong>${error.segments[i][0]}-${error.segments[i][1]}</strong>`;
if (error.segments[i][0] !== 22 || error.segments[i][1] !== 6) {
message += `, <b>${error.segments[i][0]}-${error.segments[i][1]}</b>`;
}
}
}
message += `, potrzeba <strong>${error.required}</strong>, jest <strong>${error.actual}</strong>`;
message += `: potrzeba <b>${error.required}</b>, jest <b>${error.actual}</b>.`;
type = ScheduleErrorType.WNN;
title = "date";
if (error.day) {
day += error.day;
}
break;
case AlgorithmErrorCode.DissalowedShiftSequence:
message = `Niedozwolona sekwencja zmian dla pracownika <strong>${
const timeNeeded = ShiftHelper.requiredFreeTimeAfterShift(shifts[error.preceding]);
const [earliestPossible, nextDay] = ShiftHelper.nextLegalShiftStart(
shifts[error.preceding]
);
let tooEarly = earliestPossible - shifts[error.succeeding].from;
if (tooEarly < 1) tooEarly += 24;
message = `Pracownik <strong>${
error.worker
}</strong> w dniu <strong>${error.day + 1}</strong>: <strong>${
error.succeeding
}</strong> po <strong>${error.preceding}</strong>`;
}</strong> potrzebuje ${timeNeeded} godzin przerwy po zmianie <strong>${
error.preceding
}</strong>
(${shifts[error.preceding].from}-${shifts[error.preceding].to}).
Nie może mieć zmiany wcześniej niż o ${earliestPossible}`;
if (nextDay) message += ` następnego dnia`;
message += `. Przypisana zmiana <strong>${error.succeeding}</strong> (${
shifts[error.succeeding].from
}-${shifts[error.succeeding].to}) zaczyna się
o ${tooEarly} ${TranslationHelper.hourAccusativus(tooEarly)} za wcześnie.`;
type = ScheduleErrorType.DSS;
title = "date";
if (error.day) {
day += error.day;
}
break;
case AlgorithmErrorCode.LackingLongBreak:
message = `Brak wymaganej długiej przerwy dla pracownika <strong>${
error.worker
}</strong> w tygodniu <strong>${error.week + 1}</strong>`;
message = `Brak wymaganej długiej przerwy w tygodniu <b>${error.week + 1}</b>.`;
type = ScheduleErrorType.LLB;
title = `${error.worker}`;
break;
case AlgorithmErrorCode.WorkerUnderTime:
message = `Pracownik <strong>${error.worker}</strong> ma <strong>${error.hours}</strong> niedogodzin`;
message = `Pracownik ma <b>${error.hours}</b> niedo${TranslationHelper.hourAccusativus(
error.hours
)}.`;
type = ScheduleErrorType.WUH;
title = `${error.worker}`;
break;
case AlgorithmErrorCode.WorkerOvertime:
message = `Pracownik <strong>${error.worker}</strong> ma <strong>${error.hours}</strong> nadgodzin`;
message = `Pracownik ma <b>${error.hours}</b> nad${TranslationHelper.hourAccusativus(
error.hours
)}.`;
type = ScheduleErrorType.WOH;
title = `${error.worker}`;
break;
case ParseErrorCode.UNKNOWN_VALUE:
message = `Nieznana wartość zmiany: "${error.actual}" dla pracownika ${
error.worker
} w dniu ${error.day! + 1}. Przyjęto, że zmiana to wolne.`;
message = `Nieznana wartość zmiany: "${error.actual}" w dniu ${
error.day! + 1
}. Przyjęto, że zmiana to wolne.`;
type = ScheduleErrorType.ILLEGAL_SHIFT_VALUE;
title = `${error.worker}`;
break;
Expand Down
15 changes: 15 additions & 0 deletions src/helpers/shifts.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ export class ShiftHelper {
return duration === 0 ? 24 : duration;
}

public static requiredFreeTimeAfterShift(shift: Shift): number {
if (this.shiftCodeToWorkTime(shift) < 9) return 11;
if (this.shiftCodeToWorkTime(shift) > 12) return 24;
return 16;
}

public static nextLegalShiftStart(shift: Shift): [number, boolean] {
const sum = shift.to + this.requiredFreeTimeAfterShift(shift);
if (sum > 24) {
if ((shift.to + this.requiredFreeTimeAfterShift(shift)) % 24 === 0) return [24, true];
return [(shift.to + this.requiredFreeTimeAfterShift(shift)) % 24, true];
}
return [sum, false];
}

public static groupShiftsByWorkerType(
shifts: ShiftInfoModel = {},
workerTypes: { [workerName: string]: WorkerType } = {}
Expand Down
7 changes: 7 additions & 0 deletions src/helpers/translations.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ export class TranslationHelper {
SU: "nd",
};
}

public static hourAccusativus(key: number): string {
if (key === 1) return "godzinę";
if (key === 12 || key === 13 || key === 14) return "godzin";
if ((key - 2) % 10 === 0 || (key - 3) % 10 === 0 || (key - 4) % 10 === 0) return "godziny";
return "godzin";
}
}

0 comments on commit 2cc8ed2

Please sign in to comment.