diff --git a/common/utils/apiFragments.js b/common/utils/apiFragments.js index fed5999e0..e9628977f 100644 --- a/common/utils/apiFragments.js +++ b/common/utils/apiFragments.js @@ -170,6 +170,11 @@ export const OBSERVED_INFRACTIONS_FRAGMENT = gql` type unit extra + business { + id + transportType + businessType + } } `; diff --git a/common/utils/regulation/groupAlertsByDay.js b/common/utils/regulation/groupAlertsByDay.js index 0a71c7000..976c7ef99 100644 --- a/common/utils/regulation/groupAlertsByDay.js +++ b/common/utils/regulation/groupAlertsByDay.js @@ -14,20 +14,28 @@ export const getAlertsGroupedByDay = observedInfractions => { return Object.entries(infractionsGroupedByLabel).map( ([label, infractions]) => { const firstInfraction = infractions[0]; - const { sanction, type, description, unit } = firstInfraction; + const { sanction, type, unit } = firstInfraction; return { alerts: infractions.map( - ({ date, isReportable, isReported, extra }) => ({ + ({ + date, + isReportable, + isReported, + extra, + business, + description + }) => ({ ...(unit === PERIOD_UNITS.DAY && { day: date }), ...(unit === PERIOD_UNITS.WEEK && { week: date }), checked: isReported, reportable: isReportable, - extra + extra, + business, + description }) ), infringementLabel: label, type, - description, sanction }; } diff --git a/web/admin/components/ExpendituresCard.js b/web/admin/components/ExpendituresCard.js index 9fe39ee34..8b325f755 100644 --- a/web/admin/components/ExpendituresCard.js +++ b/web/admin/components/ExpendituresCard.js @@ -5,20 +5,11 @@ import { regroupExpendituresSpendingDateByType } from "common/utils/expenditures"; import Chip from "@mui/material/Chip"; -import Typography from "@mui/material/Typography"; import { MissionInfoCard } from "./MissionInfoCard"; import React from "react"; import Grid from "@mui/material/Grid"; -import { makeStyles } from "@mui/styles"; import { useModals } from "common/utils/modals"; -import { fr } from "@codegouvfr/react-dsfr"; - -export const useStyles = makeStyles(theme => ({ - noExpenditureLabel: { - color: fr.colors.decisions.text.mention.grey.default, - fontStyle: "italic" - } -})); +import { Description } from "../../common/typography/Description"; export function ExpendituresCard({ title, @@ -30,7 +21,6 @@ export function ExpendituresCard({ loading, titleProps = {} }) { - const classes = useStyles(); const modals = useModals(); const expenditureCount = Array.isArray(expenditures) @@ -80,9 +70,9 @@ export function ExpendituresCard({ })} ) : ( - + Aucun frais n'a été enregistré pour cette journée - + )} ); diff --git a/web/admin/components/MissionDetails/MissionDetailsObservations.js b/web/admin/components/MissionDetails/MissionDetailsObservations.js index 7fbab1d4f..e21a49269 100644 --- a/web/admin/components/MissionDetails/MissionDetailsObservations.js +++ b/web/admin/components/MissionDetails/MissionDetailsObservations.js @@ -7,6 +7,7 @@ import { Event } from "../../../common/Event"; import { useMissionDetailsStyles } from "./MissionDetailsStyle"; import { useModals } from "common/utils/modals"; import { Button } from "@codegouvfr/react-dsfr/Button"; +import { Description } from "../../../common/typography/Description"; export function MissionDetailsObservations({ mission, @@ -63,9 +64,7 @@ export function MissionDetailsObservations({ ))} ) : ( - - Aucune observation sur cette mission - + Aucune observation sur cette mission )} ); diff --git a/web/admin/components/MissionDetails/MissionDetailsStyle.js b/web/admin/components/MissionDetails/MissionDetailsStyle.js index 0ffaae34a..816e4ec8e 100644 --- a/web/admin/components/MissionDetails/MissionDetailsStyle.js +++ b/web/admin/components/MissionDetails/MissionDetailsStyle.js @@ -1,5 +1,4 @@ import { makeStyles } from "@mui/styles"; -import { fr } from "@codegouvfr/react-dsfr"; export const useMissionDetailsStyles = makeStyles(theme => ({ missionSubTitle: { @@ -28,10 +27,6 @@ export const useMissionDetailsStyles = makeStyles(theme => ({ employeeCard: { width: "100%" }, - noCommentText: { - fontStyle: "italic", - color: fr.colors.decisions.text.mention.grey.default - }, validationButton: { marginTop: theme.spacing(4) }, diff --git a/web/admin/components/MissionVehicleInfo.js b/web/admin/components/MissionVehicleInfo.js index 76992e4a2..c8c92d306 100644 --- a/web/admin/components/MissionVehicleInfo.js +++ b/web/admin/components/MissionVehicleInfo.js @@ -2,17 +2,10 @@ import React from "react"; import { getVehicleName } from "common/utils/vehicles"; import { VehicleField } from "../../common/VehicleField"; import { EditableMissionInfo } from "./EditableMissionInfo"; -import { makeStyles } from "@mui/styles"; - -export const useStyles = makeStyles(theme => ({ - placeholder: { - fontStyle: "italic", - color: theme.palette.grey[500] - } -})); +import { useTypographyStyles } from "../../common/typography/TypographyStyles"; export function MissionVehicleInfo({ vehicle, editVehicle, vehicles }) { - const classes = useStyles(); + const typographyClasses = useTypographyStyles(); return ( Aucun véhicule utilisé + + Aucun véhicule utilisé + ) } renderEditMode={(newVehicle, setNewVehicle) => ( diff --git a/web/admin/components/styles/ValidationsStyle.js b/web/admin/components/styles/ValidationsStyle.js index b65eb9885..c573f079b 100644 --- a/web/admin/components/styles/ValidationsStyle.js +++ b/web/admin/components/styles/ValidationsStyle.js @@ -7,11 +7,6 @@ export const useStyles = makeStyles(theme => ({ display: "flex", alignItems: "center" }, - explanation: { - marginBottom: theme.spacing(2), - fontStyle: "italic", - textAlign: "justify" - }, container: { padding: theme.spacing(2), flexShrink: 1, diff --git a/web/admin/panels/Company.js b/web/admin/panels/Company.js index b5523035a..12ae2a93d 100644 --- a/web/admin/panels/Company.js +++ b/web/admin/panels/Company.js @@ -47,11 +47,6 @@ export const usePanelStyles = makeStyles(theme => ({ marginTop: theme.spacing(1), flexShrink: 0 }, - explanation: { - marginBottom: theme.spacing(2), - fontStyle: "italic", - textAlign: "justify" - }, title: { marginBottom: theme.spacing(2), display: "flex", diff --git a/web/admin/panels/Employees.js b/web/admin/panels/Employees.js index 1ada286aa..d2107c1f1 100644 --- a/web/admin/panels/Employees.js +++ b/web/admin/panels/Employees.js @@ -33,6 +33,7 @@ import { BusinessDropdown } from "../components/BusinessDropdown"; import Stack from "@mui/material/Stack"; import Notice from "../../common/Notice"; import { Button } from "@codegouvfr/react-dsfr/Button"; +import { Explanation } from "../../common/typography/Explanation"; const useStyles = makeStyles(theme => ({ title: { @@ -40,10 +41,6 @@ const useStyles = makeStyles(theme => ({ justifyContent: "space-between", alignItems: "center" }, - explanation: { - fontStyle: "italic", - textAlign: "justify" - }, successText: { color: theme.palette.success.main }, @@ -800,12 +797,12 @@ export function Employees({ company, containerRef }) { )} - + Invitez vos salariés en renseignant leurs adresses e-mail (certaines adresses n’apparaissent pas dans la liste ci-dessous car les salariés ont choisi de ne pas vous les communiquer), afin qu'ils puissent enregistrer du temps de travail pour l'entreprise. - + {areThereEmploymentsWithoutBusinessType && ( a.companyId === companyId) .map(a => ({ ...a, address: a })); - return [ - - - Adresses fréquentes ({knownAddresses.length}) - - - , - - Vous pouvez ajouter ici les lieux de travail fréquents dans votre - entreprise, comme le dépôt. Ces lieux seront proposés aux salariés - lorsqu'ils renseigneront le début et la fin de mission dans leur outil - mobile. - , - { - try { - const apiResponse = await api.graphQlMutate( - EDIT_KNOWN_ADDRESS_MUTATION, - { - companyKnownAddressId: address.id, - alias - }, - { context: { nonPublicApi: true } } - ); - adminStore.dispatch({ - type: ADMIN_ACTIONS.update, - payload: { - id: address.id, - entity: "knownAddresses", - update: { - ...apiResponse.data.locations.editKnownAddress, - companyId - } - } - }); - } catch (err) { - captureSentryException(err); - } - }} - validateRow={({ address }) => !!address} - onRowAdd={async ({ address, alias }) => { - await alerts.withApiErrorHandling(async () => { - const apiResponse = await api.graphQlMutate( - CREATE_KNOWN_ADDRESS_MUTATION, - { - alias, - companyId, - ...buildBackendPayloadForAddress(address) - }, - { context: { nonPublicApi: true } } - ); - adminStore.dispatch({ - type: ADMIN_ACTIONS.create, - payload: { - entity: "knownAddresses", - items: [ - { - ...apiResponse.data.locations.createKnownAddress, + return ( + <> + + + Adresses fréquentes ({knownAddresses.length}) + + + + + Vous pouvez ajouter ici les lieux de travail fréquents dans votre + entreprise, comme le dépôt. Ces lieux seront proposés aux salariés + lorsqu'ils renseigneront le début et la fin de mission dans leur outil + mobile. + + { + try { + const apiResponse = await api.graphQlMutate( + EDIT_KNOWN_ADDRESS_MUTATION, + { + companyKnownAddressId: address.id, + alias + }, + { context: { nonPublicApi: true } } + ); + adminStore.dispatch({ + type: ADMIN_ACTIONS.update, + payload: { + id: address.id, + entity: "knownAddresses", + update: { + ...apiResponse.data.locations.editKnownAddress, companyId } - ] - } - }); - }, "create-known-address"); - }} - onRowDelete={address => - modals.open("confirmation", { - textButtons: true, - title: "Confirmer suppression", - handleConfirm: async () => { - try { - await api.graphQlMutate( - TERMINATE_KNOWN_ADDRESS_MUTATION, - { - companyKnownAddressId: address.id - }, - { context: { nonPublicApi: true } } - ); - adminStore.dispatch({ - type: ADMIN_ACTIONS.delete, - payload: { id: address.id, entity: "knownAddresses" } - }); - } catch (err) { - captureSentryException(err); - } + } + }); + } catch (err) { + captureSentryException(err); } - }) - } - /> - ]; + }} + validateRow={({ address }) => !!address} + onRowAdd={async ({ address, alias }) => { + await alerts.withApiErrorHandling(async () => { + const apiResponse = await api.graphQlMutate( + CREATE_KNOWN_ADDRESS_MUTATION, + { + alias, + companyId, + ...buildBackendPayloadForAddress(address) + }, + { context: { nonPublicApi: true } } + ); + adminStore.dispatch({ + type: ADMIN_ACTIONS.create, + payload: { + entity: "knownAddresses", + items: [ + { + ...apiResponse.data.locations.createKnownAddress, + companyId + } + ] + } + }); + }, "create-known-address"); + }} + onRowDelete={address => + modals.open("confirmation", { + textButtons: true, + title: "Confirmer suppression", + handleConfirm: async () => { + try { + await api.graphQlMutate( + TERMINATE_KNOWN_ADDRESS_MUTATION, + { + companyKnownAddressId: address.id + }, + { context: { nonPublicApi: true } } + ); + adminStore.dispatch({ + type: ADMIN_ACTIONS.delete, + payload: { id: address.id, entity: "knownAddresses" } + }); + } catch (err) { + captureSentryException(err); + } + } + }) + } + /> + + ); } diff --git a/web/admin/panels/Validations.js b/web/admin/panels/Validations.js index a34436084..3078eb320 100644 --- a/web/admin/panels/Validations.js +++ b/web/admin/panels/Validations.js @@ -46,6 +46,7 @@ import { unselectAndGetAllTeams } from "../store/reducers/team"; import { usePageTitle } from "../../common/UsePageTitle"; +import { Explanation } from "../../common/typography/Explanation"; const VALIDATION_TABS = [ { @@ -419,9 +420,7 @@ function ValidationPanel() { )} - - {VALIDATION_TABS[tab].explanation} - + {VALIDATION_TABS[tab].explanation} - + Les véhicules que vous ajoutez ici seront proposés aux salariés lorsqu'ils renseigneront les informations d'une mission dans leur outil mobile. - + + {admin.email} - + )), [employment] ); diff --git a/web/common/typography/Description.js b/web/common/typography/Description.js new file mode 100644 index 000000000..a582d4381 --- /dev/null +++ b/web/common/typography/Description.js @@ -0,0 +1,19 @@ +import Typography from "@mui/material/Typography"; +import React from "react"; +import { cx } from "@codegouvfr/react-dsfr/tools/cx"; +import { fr } from "@codegouvfr/react-dsfr"; + +export const Description = ({ children, className, style, ...otherProps }) => { + return ( + + {children} + + ); +}; diff --git a/web/common/typography/Explanation.js b/web/common/typography/Explanation.js new file mode 100644 index 000000000..551b89f17 --- /dev/null +++ b/web/common/typography/Explanation.js @@ -0,0 +1,18 @@ +import Typography from "@mui/material/Typography"; +import React from "react"; + +export const Explanation = ({ children, sx, style, ...otherProps }) => { + return ( + + {children} + + ); +}; diff --git a/web/common/typography/FieldTitle.js b/web/common/typography/FieldTitle.js new file mode 100644 index 000000000..a08c1310c --- /dev/null +++ b/web/common/typography/FieldTitle.js @@ -0,0 +1,23 @@ +import { cx } from "@codegouvfr/react-dsfr/tools/cx"; +import Typography from "@mui/material/Typography"; +import React from "react"; +import { useTypographyStyles } from "./TypographyStyles"; + +export const FieldTitle = ({ + uppercaseTitle = false, + className = {}, + children, + ...otherProps +}) => { + const classes = useTypographyStyles({ uppercaseTitle }); + return ( + + {children} + + ); +}; diff --git a/web/common/typography/TypographyStyles.js b/web/common/typography/TypographyStyles.js new file mode 100644 index 000000000..4298d11f4 --- /dev/null +++ b/web/common/typography/TypographyStyles.js @@ -0,0 +1,12 @@ +import { fr } from "@codegouvfr/react-dsfr"; +import { makeStyles } from "@mui/styles"; + +export const useTypographyStyles = makeStyles(theme => ({ + fieldName: { + color: fr.colors.decisions.text.mention.grey.default, + fontSize: props => (props.uppercaseTitle ? "0.75rem" : "0.875rem") + }, + disabled: { + color: fr.colors.decisions.text.disabled.grey.default + } +})); diff --git a/web/control/VerifyXlsxSignature.js b/web/control/VerifyXlsxSignature.js index 0eabcd5ff..863725b21 100644 --- a/web/control/VerifyXlsxSignature.js +++ b/web/control/VerifyXlsxSignature.js @@ -122,9 +122,6 @@ const useStyles = makeStyles(theme => ({ response: { textAlign: "justify", marginTop: theme.spacing(2) - }, - placeholder: { - padding: theme.spacing(2) } })); @@ -214,7 +211,7 @@ export function XlsxVerifier() { > {fileName && } - + {fileName ? fileName : "Déposez votre fichier ici ou cliquez pour choisir un fichier. Seuls les .xlsx sont acceptés."} diff --git a/web/control/components/AlertGroup.js b/web/control/components/Alerts/AlertGroup.js similarity index 68% rename from web/control/components/AlertGroup.js rename to web/control/components/Alerts/AlertGroup.js index 594af8d2c..e1efc3eaa 100644 --- a/web/control/components/AlertGroup.js +++ b/web/control/components/Alerts/AlertGroup.js @@ -3,12 +3,15 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import Typography from "@mui/material/Typography"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; -import { formatAlertText, RegulatoryAlert } from "./RegulatoryAlert"; +import { formatAlertText, RegulatoryAlert } from "../RegulatoryAlert"; import { makeStyles } from "@mui/styles"; import Grid from "@mui/material/Grid"; import Accordion from "@mui/material/Accordion"; import AccordionSummary from "@mui/material/AccordionSummary"; import AccordionDetails from "@mui/material/AccordionDetails"; +import { groupBy } from "lodash"; +import { formatActivity } from "common/utils/businessTypes"; +import { Description } from "../../../common/typography/Description"; const useStyles = makeStyles(theme => { return { @@ -41,10 +44,6 @@ const useStyles = makeStyles(theme => { }, notReportableAlert: { backgroundColor: theme.palette.warning.light - }, - description: { - fontStyle: "italic", - color: theme.palette.grey[600] } }; }); @@ -63,10 +62,16 @@ const getAlertsNumber = ( const isReportable = sanction => sanction.includes("NATINF"); +const BusinessTypeTitle = ({ business }) => ( + + Infraction(s) liée(s) au {formatActivity(business)} +  : + +); + export function AlertGroup({ alerts, infringementLabel, - description, type, sanction, setPeriodOnFocus, @@ -74,6 +79,7 @@ export function AlertGroup({ isReportingInfractions, onUpdateInfraction, readOnlyAlerts, + displayBusinessType = false, titleProps = {} }) { const [open, setOpen] = React.useState(false); @@ -88,6 +94,11 @@ export function AlertGroup({ readOnlyAlerts ); + const alertsGroupedByBusinessTypes = React.useMemo( + () => groupBy(alerts, alert => alert.business.id), + [alerts] + ); + return ( - {description} - - {alerts.map((alert, index) => ( - - - - ))} - + {Object.entries(alertsGroupedByBusinessTypes).map( + ([businessId, alertsByBusiness]) => { + const firstAlert = alertsByBusiness[0]; + const { + description: alertDescription, + business: alertBusiness + } = firstAlert; + return ( + + {displayBusinessType && ( + + )} + {alertDescription} + + {alertsByBusiness.map((alert, index) => ( + + + + ))} + + + ); + } + )} ); diff --git a/web/control/components/Alerts/BusinessTypesFromGroupedAlerts.js b/web/control/components/Alerts/BusinessTypesFromGroupedAlerts.js new file mode 100644 index 000000000..ffb3d8827 --- /dev/null +++ b/web/control/components/Alerts/BusinessTypesFromGroupedAlerts.js @@ -0,0 +1,26 @@ +import { fr } from "@codegouvfr/react-dsfr"; +import { Box, Typography } from "@mui/material"; +import { makeStyles } from "@mui/styles"; +import React from "react"; +import { FieldTitle } from "../../../common/typography/FieldTitle"; + +const useStyles = makeStyles(theme => ({ + businessTypesContainer: { + backgroundColor: fr.colors.decisions.background.default.grey.hover + } +})); + +export const DisplayBusinessTypes = ({ businessTypes }) => { + const classes = useStyles(); + + if (!businessTypes || businessTypes.length === 0) { + return null; + } + + return ( + + Type(s) d'activité + {businessTypes.join(", ")} + + ); +}; diff --git a/web/control/components/AlertsInHistory.js b/web/control/components/AlertsInHistory.js index 2366ab339..8ba432cef 100644 --- a/web/control/components/AlertsInHistory.js +++ b/web/control/components/AlertsInHistory.js @@ -3,7 +3,7 @@ import { InfoCard } from "../../common/InfoCard"; import { MissionReviewSection } from "../../pwa/components/MissionReviewSection"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; -import { AlertCard } from "./AlertGroup"; +import { AlertCard } from "./Alerts/AlertGroup"; import { WarningComputedAlerts } from "./UserReadAlerts"; export function AlertsInHistory({ alertsInPeriod }) { diff --git a/web/control/components/RegulatoryAlert.js b/web/control/components/RegulatoryAlert.js index 36adf567d..b65cc83e4 100644 --- a/web/control/components/RegulatoryAlert.js +++ b/web/control/components/RegulatoryAlert.js @@ -177,7 +177,7 @@ export function RegulatoryAlert({ label: "", nativeInputProps: { name: "", - value: alert.checked, + checked: alert.checked, onChange: e => { const alertDate = alert.day || alert.week || alert.month; onUpdateInfraction(sanction, alertDate, e.target.checked); @@ -203,6 +203,7 @@ export function RegulatoryAlert({ ); } }} + to="/" > {formatAlertPeriod(alert, type)} diff --git a/web/control/components/UserReadAlerts.js b/web/control/components/UserReadAlerts.js index f676d5fd2..5ed2e2276 100644 --- a/web/control/components/UserReadAlerts.js +++ b/web/control/components/UserReadAlerts.js @@ -5,15 +5,20 @@ import Container from "@mui/material/Container"; import Divider from "@mui/material/Divider"; import ListItem from "@mui/material/ListItem"; import List from "@mui/material/List"; -import { AlertGroup } from "./AlertGroup"; import { prettyFormatDayHour } from "common/utils/time"; import Stack from "@mui/material/Stack"; import { Button } from "@codegouvfr/react-dsfr/Button"; import Notice from "../../common/Notice"; +import { AlertGroup } from "./Alerts/AlertGroup"; +import { FieldTitle } from "../../common/typography/FieldTitle"; +import { DisplayBusinessTypes } from "./Alerts/BusinessTypesFromGroupedAlerts"; +import { getBusinessTypesFromGroupedAlerts } from "../utils/businessTypesFromGroupedAlerts"; +import { Description } from "../../common/typography/Description"; const useStyles = makeStyles(theme => ({ container: { - paddingBottom: theme.spacing(4) + paddingBottom: theme.spacing(4), + marginTop: theme.spacing(2) }, linkContainer: { textAlign: "center", @@ -24,12 +29,6 @@ const useStyles = makeStyles(theme => ({ color: theme.palette.grey[600], marginTop: theme.spacing(2) }, - subtitle: { - color: theme.palette.grey[600] - }, - helpText: { - fontWeight: "bold" - }, divider: { marginTop: theme.spacing(4), marginBottom: theme.spacing(4) @@ -65,98 +64,122 @@ export function UserReadAlerts({ }) { const classes = useStyles(); + const businessTypes = React.useMemo( + () => getBusinessTypesFromGroupedAlerts(groupedAlerts), + [groupedAlerts] + ); + return ( - - {isReportingInfractions && ( - - {totalAlertsNumber === 1 - ? HELPER_TEXT_SINGLE_INFRACTION - : HELPER_TEXT_SEVERAL_INFRACTIONS} - - )} - {!isReportingInfractions && reportedInfractionsLastUpdateTime && ( - - {`Date de la dernière modification des infractions retenues : ${prettyFormatDayHour( - reportedInfractionsLastUpdateTime - )}`} - - )} - {!noLic && ( - <> - - Infractions calculées par Mobilic - {" "} - - {businesses && businesses.length > 1 && ( - {`Attention, veuillez noter que ce salarié effectue des missions pour différents secteurs d’activité + + {!noLic && } + + + {isReportingInfractions && ( + + {totalAlertsNumber === 1 + ? HELPER_TEXT_SINGLE_INFRACTION + : HELPER_TEXT_SEVERAL_INFRACTIONS} + + )} + {!isReportingInfractions && ( + + Infractions retenues + + )} + {!isReportingInfractions && reportedInfractionsLastUpdateTime && ( + + {`Date de la dernière modification des infractions retenues : ${prettyFormatDayHour( + reportedInfractionsLastUpdateTime + )}`} + + )} + {!noLic && ( + <> + + Infractions calculées par Mobilic + + + {businesses && businesses.length > 1 && ( + {`Attention, veuillez noter que ce salarié effectue des missions pour différents secteurs d’activité (${businesses.join(", ")}).`} - } - /> + } + /> + )} + + )} + {groupedAlerts?.length > 0 ? ( + + {groupedAlerts + .sort((alert1, alert2) => + alert1.sanction.localeCompare(alert2.sanction) + ) + .map(group => ( + + 1 + } + /> + + ))} + + ) : ( + + Il n'y a aucune alerte réglementaire sur la période + )} - - )} - {groupedAlerts?.length > 0 ? ( - - {groupedAlerts - .sort((alert1, alert2) => - alert1.sanction.localeCompare(alert2.sanction) - ) - .map(group => ( - - + {isReportingInfractions ? ( + + + + + ) : ( + !noLic && ( + + Les données collectées par Mobilic sont déclaratives et + sont donc susceptibles d'erreurs ou d'oublis. En cas de + données manquantes ou inexactes les alertes réglementaires + ne peuvent pas être remontées correctement. +
+ Mobilic sert à faciliter le travail d'enquête des + inspecteurs sans se substituer à lui. + + } /> -
- ))} -
- ) : ( - - Il n'y a aucune alerte réglementaire sur la période - - )} - <> - {isReportingInfractions ? ( - - - - - ) : ( - !noLic && ( - - Les données collectées par Mobilic sont déclaratives et sont - donc susceptibles d'erreurs ou d'oublis. En cas de données - manquantes ou inexactes les alertes réglementaires ne peuvent - pas être remontées correctement. -
- Mobilic sert à faciliter le travail d'enquête des inspecteurs - sans se substituer à lui. - - } - /> - ) - )} - - + ) + )} + + +
+
); } diff --git a/web/control/components/UserReadInfo.js b/web/control/components/UserReadInfo.js index 17f6555f5..a14301eb9 100644 --- a/web/control/components/UserReadInfo.js +++ b/web/control/components/UserReadInfo.js @@ -78,7 +78,11 @@ export function UserReadInfo({ const classes = useStyles(); return ( - + {controlData && ( diff --git a/web/control/components/UserReadTabs.js b/web/control/components/UserReadTabs.js index c978c2c0e..45b5aaedb 100644 --- a/web/control/components/UserReadTabs.js +++ b/web/control/components/UserReadTabs.js @@ -39,7 +39,6 @@ const useStyles = makeStyles(theme => ({ display: "flex" }, panelContainer: { - paddingTop: theme.spacing(3), margin: "auto", display: "flex", flexGrow: 1, diff --git a/web/control/utils/businessTypesFromGroupedAlerts.js b/web/control/utils/businessTypesFromGroupedAlerts.js new file mode 100644 index 000000000..ff1c2acb8 --- /dev/null +++ b/web/control/utils/businessTypesFromGroupedAlerts.js @@ -0,0 +1,11 @@ +import { formatActivity } from "common/utils/businessTypes"; + +export const getBusinessTypesFromGroupedAlerts = groupedAlerts => [ + ...new Set( + groupedAlerts.reduce( + (arr, group) => + arr.concat(group.alerts.map(alert => formatActivity(alert.business))), + [] + ) + ) +]; diff --git a/web/controller/components/controlBulletin/ControlBulletinFormStep3.js b/web/controller/components/controlBulletin/ControlBulletinFormStep3.js index 89e5d2aca..251b21523 100644 --- a/web/controller/components/controlBulletin/ControlBulletinFormStep3.js +++ b/web/controller/components/controlBulletin/ControlBulletinFormStep3.js @@ -4,7 +4,7 @@ import Stack from "@mui/material/Stack"; import { Typography } from "@mui/material"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; -import { AlertGroup } from "../../../control/components/AlertGroup"; +import { AlertGroup } from "../../../control/components/Alerts/AlertGroup"; import { Input } from "../../../common/forms/Input"; import Notice from "../../../common/Notice"; diff --git a/web/home/AccountInfo/UserControlSection.js b/web/home/AccountInfo/UserControlSection.js index 877d210b1..9aea7b68e 100644 --- a/web/home/AccountInfo/UserControlSection.js +++ b/web/home/AccountInfo/UserControlSection.js @@ -10,6 +10,7 @@ import Grid from "@mui/material/Grid"; import Skeleton from "@mui/material/Skeleton"; import { prettyFormatDayHour } from "common/utils/time"; import Notice from "../../common/Notice"; +import { FieldTitle } from "../../common/typography/FieldTitle"; const useStyles = makeStyles(theme => ({ section: { @@ -18,9 +19,6 @@ const useStyles = makeStyles(theme => ({ mainTitle: { marginBottom: theme.spacing(1), textAlign: "left" - }, - controlHistory: { - color: theme.palette.grey[600] } })); @@ -63,13 +61,7 @@ export function UserControlSection() { de route" size="small" /> - - HISTORIQUE DES CONTRÔLES - + Historique De Contrôles {controlsDate.map(prettyFormatDayHour).join(" ; ")} diff --git a/web/home/CompanyDetails.js b/web/home/CompanyDetails.js index 47e851607..195db154a 100644 --- a/web/home/CompanyDetails.js +++ b/web/home/CompanyDetails.js @@ -8,21 +8,12 @@ import { useAdminStore } from "../admin/store/store"; import { formatPhoneNumber } from "common/utils/phoneNumber"; import { formatActivity } from "common/utils/businessTypes"; import { Button } from "@codegouvfr/react-dsfr/Button"; +import { useTypographyStyles } from "../common/typography/TypographyStyles"; const useStyles = makeStyles(theme => ({ actionButton: { marginLeft: "2rem" }, - subTitle: { - fontSize: "0.875rem", - fontWeight: 400 - }, - subTitleLabel: { - color: theme.palette.grey[700] - }, - missingSubTitle: { - color: theme.palette.grey[800] - }, phoneNumberData: { color: "black" } @@ -30,6 +21,7 @@ const useStyles = makeStyles(theme => ({ export default function CompanyDetails({ company }) { const classes = useStyles(); + const typographyClasses = useTypographyStyles(); const modals = useModals(); const adminStore = useAdminStore(); @@ -44,22 +36,28 @@ export default function CompanyDetails({ company }) { {company?.name} - - Numéro de téléphone :{" "} + + Numéro de téléphone :{" "} {company?.phoneNumber ? formatPhoneNumber(company.phoneNumber) : "aucun numéro de téléphone renseigné"} - - Activité principale :{" "} + + Activité principale :{" "} {printActivity || "non renseignée"} diff --git a/web/home/HideEmail.js b/web/home/HideEmail.js index 202a004e1..63e7cef1f 100644 --- a/web/home/HideEmail.js +++ b/web/home/HideEmail.js @@ -1,19 +1,12 @@ import React from "react"; -import { makeStyles } from "@mui/styles"; import { Checkbox } from "@codegouvfr/react-dsfr/Checkbox"; import { useUpdateHideEmail } from "./useUpdateHideEmail"; - -const useStyles = makeStyles(theme => ({ - fieldName: { - color: theme.palette.grey[700], - fontSize: "0.875rem" - } -})); +import { useTypographyStyles } from "../common/typography/TypographyStyles"; export function HideEmail({ employment }) { const updateHideEmail = useUpdateHideEmail(employment); const { hideEmail } = employment; - const classes = useStyles(); + const classes = useTypographyStyles(); return ( ({ - fieldName: { - color: theme.palette.grey[700], - fontSize: "0.875rem" - }, fieldValue: { fontWeight: props => (props.bold ? "bold" : 400), whiteSpace: "inherit" - }, - valuePlaceholder: { - color: theme.palette.grey[600] } })); @@ -33,6 +28,7 @@ export function InfoItem({ valuePlaceholder }) { const classes = useStyles({ bold }); + const typographyClasses = useTypographyStyles(); const title = React.useMemo( () => actionTitle || (value ? "Modifier" : "Ajouter") @@ -42,18 +38,13 @@ export function InfoItem({ <> - + {name} - + {value || valuePlaceholder} diff --git a/web/pwa/components/ActivityList.js b/web/pwa/components/ActivityList.js index 9c5aa0cad..60bad5685 100644 --- a/web/pwa/components/ActivityList.js +++ b/web/pwa/components/ActivityList.js @@ -29,13 +29,9 @@ import { VerticalTimeline } from "common/components/VerticalTimeline"; import ToggleButtonGroup from "@mui/material/ToggleButtonGroup"; import ToggleButton from "@mui/material/ToggleButton"; import { ActivitiesPieChart } from "common/components/ActivitiesPieChart"; -import { fr } from "@codegouvfr/react-dsfr"; +import { Description } from "../../common/typography/Description"; const useStyles = makeStyles(theme => ({ - infoText: { - color: fr.colors.decisions.text.mention.grey.default, - fontStyle: "italic" - }, longBreak: { color: theme.palette.success.main }, @@ -249,6 +245,11 @@ export function ActivityList({ return ( + {hasActivitiesBeforeMinTime && ( + + Les activités avant minuit le jour précédent ne sont pas incluses. + + )} {canDisplayChart && ( )} - {hasActivitiesBeforeMinTime && ( - - Les activités avant minuit le jour précédent ne sont pas incluses. - - )} {(view === "list" || !canDisplayChart) && ( - {augmentedAndSortedActivities.length === 0 && !disableEmptyMessage && ( - - Pas d'activités sur cette journée - - )} + {augmentedAndSortedActivities.length === 0 && + !disableEmptyMessage && ( + Pas d'activités sur cette journée + )} {augmentedAndSortedActivities.map((activity, index) => ( )} {hasActivitiesAfterMaxTime && ( - + Les activités après minuit le jour suivant ne sont pas incluses. - + )} ); diff --git a/web/pwa/components/history/HolidayRecap.js b/web/pwa/components/history/HolidayRecap.js index a7dba3d02..c3cd86172 100644 --- a/web/pwa/components/history/HolidayRecap.js +++ b/web/pwa/components/history/HolidayRecap.js @@ -7,18 +7,12 @@ import Stack from "@mui/material/Stack"; import DateRangeIcon from "@mui/icons-material/DateRange"; import { formatRangeString } from "../WorkTimeSummary"; import { formatTimer, prettyFormatDay } from "common/utils/time"; +import { FieldTitle } from "../../../common/typography/FieldTitle"; export const useStyles = makeStyles(theme => ({ - subtitle: { - textTransform: "uppercase", - color: theme.palette.grey[500] - }, title: { fontWeight: "bold", - fontSize: "1.6rem" - }, - description: { - color: theme.palette.grey[700] + fontSize: "1.375rem" }, container: { textAlign: "left", @@ -47,12 +41,14 @@ export function HolidayRecap({ mission }) { Congé ou absence {deletedInfo} - Motif Renseigné - {mission.name} - + Motif Renseigné + + {mission.name} + + {formatRangeString(mission.startTime, mission.endTime)} ( {formatTimer(mission.endTime - mission.startTime)}) - + ); diff --git a/web/regulatory/RegulatoryText.js b/web/regulatory/RegulatoryText.js index 54675fef8..4861437c5 100644 --- a/web/regulatory/RegulatoryText.js +++ b/web/regulatory/RegulatoryText.js @@ -1,37 +1,22 @@ import React from "react"; -import { makeStyles } from "@mui/styles"; -import Typography from "@mui/material/Typography"; import Notice from "../common/Notice"; -import { fr } from "@codegouvfr/react-dsfr"; - -const useStyles = makeStyles(theme => ({ - infoText: { - marginTop: theme.spacing(1), - marginBottom: theme.spacing(1), - color: fr.colors.decisions.text.mention.grey.default, - fontStyle: "italic" - } -})); +import { Description } from "../common/typography/Description"; export function RegulatoryTextDayBeforeAndAfter() { - const classes = useStyles(); - return ( - + Les seuils affichés prennent en compte le temps de travail du jour suivant et du jour précédent. - + ); } export function RegulatoryTextWeekBeforeAndAfter() { - const classes = useStyles(); - return ( - + Les seuils hebdomadaires prennent en compte le temps de travail de la semaine complète. - + ); } diff --git a/web/signup/company/OptInForSiretsSelectionStep.js b/web/signup/company/OptInForSiretsSelectionStep.js index 823c26f06..971fa181c 100644 --- a/web/signup/company/OptInForSiretsSelectionStep.js +++ b/web/signup/company/OptInForSiretsSelectionStep.js @@ -7,14 +7,6 @@ import Radio from "@mui/material/Radio"; import { Button } from "@codegouvfr/react-dsfr/Button"; const useStyles = makeStyles(theme => ({ - button: { - marginTop: theme.spacing(2) - }, - noSirenText: { - display: "block", - fontStyle: "italic", - paddingTop: theme.spacing(6) - }, verticalFormButton: { marginTop: theme.spacing(4) }, diff --git a/web/signup/company/SelectSiretsStep.js b/web/signup/company/SelectSiretsStep.js index 15f36e641..79958f697 100644 --- a/web/signup/company/SelectSiretsStep.js +++ b/web/signup/company/SelectSiretsStep.js @@ -12,25 +12,8 @@ import { Input } from "../../common/forms/Input"; import { Button } from "@codegouvfr/react-dsfr/Button"; const useStyles = makeStyles(theme => ({ - button: { - marginTop: theme.spacing(2) - }, - noSirenText: { - display: "block", - fontStyle: "italic", - paddingTop: theme.spacing(6) - }, verticalFormButton: { marginTop: theme.spacing(4) - }, - radioButton: { - textAlign: "left", - marginBottom: theme.spacing(2) - }, - siretName: { - minWidth: 350, - maxWidth: 500, - marginBottom: theme.spacing(2) } }));