Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: reminders notice letters #118

Merged
merged 49 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
fe92094
feat: initialized vite + ts
prwozny Jan 30, 2025
10d52b3
fix: upgraded deprecated artificat
prwozny Jan 30, 2025
495456e
fix: adapted html file to vite
prwozny Jan 30, 2025
26aa2e6
fix: upgraded node version
prwozny Jan 30, 2025
b527319
Merge branch 'develop' into feat-vite
prwozny Jan 30, 2025
f82e3ce
feat : vitest support, first test replaced, package bumped
prwozny Jan 31, 2025
6649f84
fix: removed useless mock
prwozny Jan 31, 2025
2768b1c
feat : add husky + pre push
prwozny Jan 31, 2025
119f200
fix: making sure only to test .spec files
prwozny Jan 31, 2025
8ec84d2
feat: converted DateFormatter to vitest
prwozny Jan 31, 2025
a8940e3
fix : convert utils TUs to vitest
prwozny Jan 31, 2025
0841503
fix: using vitest coverage
prwozny Jan 31, 2025
96a1f66
fix: revert change
prwozny Jan 31, 2025
972f0d7
fix: set default dev server
prwozny Feb 3, 2025
7eff600
feat: replaced react-notifications by react-toastify, better app comp…
prwozny Feb 3, 2025
fc42e0c
fix: no authentifcation test
prwozny Feb 3, 2025
a386f0d
fix: no authentifcation test
prwozny Feb 3, 2025
1acad6e
fix: formatting + bootstrap ui package bump
prwozny Feb 3, 2025
c38f246
fix: update build-and-test.yml
prwozny Feb 5, 2025
3b3f7eb
feat : add notice letter and reminders column
prwozny Feb 5, 2025
11826b3
feat : add vite env
prwozny Feb 5, 2025
fe97103
Merge branch 'feat-vite' of https://github.com/InseeFr/Sonor into fea…
prwozny Feb 5, 2025
f3c4ba2
fix: removed unused local
prwozny Feb 5, 2025
d697ad9
fix : token, useConfiguration, vite env
prwozny Feb 5, 2025
a3f7191
fix: default lang fix
prwozny Feb 5, 2025
0a6ad57
feat: modified label for testing
prwozny Feb 5, 2025
f04d410
fix: add timemout
prwozny Feb 5, 2025
3cf68e2
fix: add timeout for it
prwozny Feb 5, 2025
d5e6e40
fix: wait for text display instead of using timeouts
prwozny Feb 5, 2025
7bad4ab
Merge branch 'feat-vite' into feat-reminders-notice-letters
prwozny Feb 5, 2025
1287bce
feat: retrieving from api noticeCount, reminderCount
prwozny Feb 5, 2025
e05a7f0
Merge branch 'develop' into feat-reminders-notice-letters
prwozny Feb 6, 2025
87ac45f
fix : converted to test dataformatter (temp)
prwozny Feb 6, 2025
d6f053c
feat: supporting new api format
prwozny Feb 10, 2025
3feaeea
fix: removed unused import
prwozny Feb 10, 2025
9a6c5dd
fix: removed playwright
prwozny Feb 10, 2025
466c3ee
fix: update docker/config
prwozny Feb 10, 2025
5928827
fix: config update for env support
prwozny Feb 10, 2025
8fc09b1
fix: updated build folder
prwozny Feb 11, 2025
114cdf0
fix: removed env.sh (as we use vite now) + removed coverage from dist…
prwozny Feb 11, 2025
87d6bba
fix: update package.json
prwozny Feb 11, 2025
371630a
fix: test update
prwozny Feb 11, 2025
2ced571
fix: config.json update version
prwozny Feb 11, 2025
ddd9d76
fix: updated vite config
prwozny Feb 12, 2025
e0d17ed
feat: sort support for notice and reminders
prwozny Feb 12, 2025
f5ae40a
fix: version update
prwozny Feb 12, 2025
e65bad7
fix: snapshot update
prwozny Feb 12, 2025
614abe6
fix: ColCompletionRate as N/A if NaN
prwozny Feb 12, 2025
cde7090
fix : corrected comments
prwozny Feb 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ ENV NGINX_GROUP=nginx
USER $NGINX_USER_ID

# Add build to nginx root webapp
COPY --from=builder --chown=$NGINX_USER:$NGINX_GROUP /pearl/build /usr/share/nginx/html
COPY --from=builder --chown=$NGINX_USER:$NGINX_GROUP /sonor/build /usr/share/nginx/html

# Copy nginx configuration
RUN rm /etc/nginx/conf.d/default.conf
COPY --from=builder --chown=$NGINX_USER:$NGINX_GROUP /pearl/nginx.conf /etc/nginx/conf.d/nginx.conf
COPY --from=builder --chown=$NGINX_USER:$NGINX_GROUP /sonor/nginx.conf /etc/nginx/conf.d/nginx.conf

# Add entrypoint and start nginx server
RUN chmod 755 /usr/share/nginx/html/vite-envs.sh
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sonor",
"version": "0.8.0",
"version": "0.9.4",
"private": true,
"dependencies": {
"@tanstack/react-query": "4.0.5",
Expand Down Expand Up @@ -92,7 +92,6 @@
},
"devDependencies": {
"@originjs/vite-plugin-federation": "^1.2.1",
"@playwright/test": "^1.49.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.2.0",
"@testing-library/user-event": "^7.2.1",
Expand Down Expand Up @@ -121,6 +120,7 @@
"stylelint": "^16.11.0",
"stylelint-config-standard": "^36.0.1",
"vite": "^4.2.1",
"vite-envs": "^4.4.11",
"vite-tsconfig-paths": "^3.6.0",
"vitest": "^2.1.8"
}
Expand Down
22 changes: 0 additions & 22 deletions scripts/env.sh

This file was deleted.

18 changes: 9 additions & 9 deletions src/components/App/App.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { screen, render, act } from '@testing-library/react';
import { App } from './App';
import { mockOidcForUser, mockOidcFailed } from '../CustomHooks/useAuth';
import { it, vi } from 'vitest';
import D from '../../i18n';
import { OIDC } from '../../utils/constants.json';
import { screen, render, act } from "@testing-library/react";
import { App } from "./App";
import { mockOidcForUser, mockOidcFailed } from "../CustomHooks/useAuth";
import { it, vi } from "vitest";
import D from "../../i18n";
import { OIDC } from "../../utils/constants.json";

vi.mock('components/CustomHooks/useConfiguration', () => ({
vi.mock("components/CustomHooks/useConfiguration", () => ({
useConfiguration: () => ({
AUTHENTICATION_MODE: OIDC,
}),
}));

it('Component is displayed ', async () => {
it("Component is displayed ", async () => {
mockOidcForUser();
render(<App />);
await screen.findByText(D.surveyList);
});

it('Component is not displayed ', async () => {
it("Component is not displayed ", async () => {
mockOidcFailed();
render(<App />);
await screen.findByText(D.cannotAuth);
Expand Down
42 changes: 27 additions & 15 deletions src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useEffect, useRef, useState } from 'react';
import { ANONYMOUS, OIDC } from '../../utils/constants.json';
import DataFormatter from '../../utils/DataFormatter';
import D from '../../i18n';
import View from 'components/View/View';
import { useIsAuthenticated } from 'components/CustomHooks/useAuth';
import { toast } from 'react-toastify';
import { useConfiguration } from 'components/CustomHooks/useConfiguration';
import { useEffect, useRef, useState } from "react";
import { ANONYMOUS, OIDC } from "../../utils/constants.json";
import DataFormatter from "../../utils/DataFormatter";
import D from "../../i18n";
import View from "components/View/View";
import { useIsAuthenticated } from "components/CustomHooks/useAuth";
import { toast } from "react-toastify";
import { useConfiguration } from "components/CustomHooks/useConfiguration";

export const App = () => {
const [authenticated, setAuthenticated] = useState(false);
Expand All @@ -23,9 +23,15 @@ export const App = () => {
timeoutIdRef.current = setTimeout(() => renewTokens, 5 * 60 * 1000);
};

const events = ['mousemove', 'mousedown', 'keypress', 'touchstart', 'click'];
const events = [
"mousemove",
"mousedown",
"keypress",
"touchstart",
"click",
];

events.forEach(event => {
events.forEach((event) => {
window.addEventListener(event, resetInactivityTimeout);
});

Expand All @@ -35,7 +41,7 @@ export const App = () => {
if (timeoutIdRef.current) {
clearTimeout(timeoutIdRef.current);
}
events.forEach(event => {
events.forEach((event) => {
window.removeEventListener(event, resetInactivityTimeout);
});
};
Expand All @@ -44,17 +50,23 @@ export const App = () => {
useEffect(() => {
if (configuration.AUTHENTICATION_MODE === ANONYMOUS) {
const dataRetreiver = new DataFormatter();
dataRetreiver.getUserInfo(data => {
dataRetreiver.getUserInfo((data) => {
if (data.error) {
setContactFailed(true);
} else {
setAuthenticated(true);
setData(data);
}
});
} else if (configuration.AUTHENTICATION_MODE === OIDC && tokens?.accessToken) {
const dataRetreiver = new DataFormatter(tokens.accessToken, configuration);
dataRetreiver.getUserInfo(data => {
} else if (
configuration.AUTHENTICATION_MODE === OIDC &&
tokens?.accessToken
) {
const dataRetreiver = new DataFormatter(
tokens.accessToken,
configuration
);
dataRetreiver.getUserInfo((data) => {
setAuthenticated(data !== undefined);
setData(data);
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/Header.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ DataFormatter.mockImplementation(() => ({
getDataForCampaignPortal: (a, cb) => cb(campaignPortalData),
getDataForListSU: (a, cb) => cb(listSU),
getUserInfo: cb => cb(userData),
getDataForMonitoringTable: (survey, date, pagination, mode, cb) => {
getDataForMonitoringTable: (survey, date, mode, cb) => {
switch (mode) {
case C.BY_INTERVIEWER_ONE_SURVEY:
cb(respModeByInterviewers1Survey);
Expand Down
85 changes: 47 additions & 38 deletions src/components/MonitoringTable/FollowUpTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ import C from '../../utils/constants.json';
import D from '../../i18n';
import './MonitoringTable.css';

function FollowUpTable({
data, sort, displayedLines, pagination, mode, handleSort,
}) {
// TODO : better handling of NaN values
function FollowUpTable({ data, sort, displayedLines, pagination, mode, handleSort }) {
const totalDemRow = mode !== C.BY_INTERVIEWER_ONE_SURVEY || (
<tr>
<th className="ColFirstCol">{D.totalDEM}</th>
<th className="ColumnSpacing" />
<th className="YellowHeader ColCompletionRate">
{Number.isNaN(data.total.dem.completionRate) || (
<>
{(data.total.dem.completionRate * 100).toFixed(1)}
%
</>
{Number.isNaN(data.total.dem.completionRate) ? (
'N/A'
) : (
<>{(data.total.dem.completionRate * 100).toFixed(1)}%</>
)}
</th>
<th className="ColumnSpacing" />
Expand All @@ -33,6 +31,8 @@ function FollowUpTable({
<th className="YellowHeader ColAtLeastOneContact">{data.total.dem.atLeastOneContact}</th>
<th className="YellowHeader ColAppointmentTaken">{data.total.dem.appointmentTaken}</th>
<th className="YellowHeader ColInterviewStarted">{data.total.dem.interviewStarted}</th>
<th className="YellowHeader ColNoticeLetter">{data.total.dem.noticeLetter}</th>
<th className="YellowHeader ColReminders">{data.total.dem.reminders}</th>
</tr>
);

Expand All @@ -44,10 +44,7 @@ function FollowUpTable({
<th className="ColumnSpacing" />
<th className="YellowHeader ColCompletionRate">
{Number.isNaN(data.total.france.completionRate) || (
<>
{(data.total.france.completionRate * 100).toFixed(1)}
%
</>
<>{(data.total.france.completionRate * 100).toFixed(1)}%</>
)}
</th>
<th className="ColumnSpacing" />
Expand All @@ -62,6 +59,8 @@ function FollowUpTable({
<th className="YellowHeader ColAtLeastOneContact">{data.total.france.atLeastOneContact}</th>
<th className="YellowHeader ColAppointmentTaken">{data.total.france.appointmentTaken}</th>
<th className="YellowHeader ColInterviewStarted">{data.total.france.interviewStarted}</th>
<th className="YellowHeader ColNoticeLetter">{data.total.france.noticeLetter}</th>
<th className="YellowHeader ColReminders">{data.total.france.reminders}</th>
</tr>
</tfoot>
);
Expand All @@ -77,7 +76,11 @@ function FollowUpTable({
firstColumnTitle = D.interviewer;
firstColumnSortAttribute = 'CPinterviewer';
}
function handleSortFunct(property) { return () => { handleSort(property); }; }
function handleSortFunct(property) {
return () => {
handleSort(property);
};
}

return (
<Table id="FollowUpTable" className="CustomTable" bordered striped hover responsive size="sm">
Expand All @@ -87,9 +90,13 @@ function FollowUpTable({
<th className="ColumnSpacing" />
<th className="EmptyHeader ColCompletionRate" />
<th rowSpan="2" className="ColumnSpacing" />
<th colSpan="6" className="CenteredText">{D.numberOfSurveyUnits}</th>
<th colSpan="6" className="CenteredText">
{D.numberOfSurveyUnits}
</th>
<th rowSpan="2" className="ColumnSpacing" />
<th colSpan="4" className="YellowHeader CenteredText">{D.suCollectionsOngoing}</th>
<th colSpan="10" className="YellowHeader CenteredText">
{D.suCollectionsOngoing}
</th>
</tr>
<tr>
<th
Expand All @@ -108,24 +115,15 @@ function FollowUpTable({
{D.completionRate}
<SortIcon val="completionRate" sort={sort} />
</th>
<th
onClick={handleSortFunct('total')}
className="Clickable ColAllocated"
>
<th onClick={handleSortFunct('total')} className="Clickable ColAllocated">
{D.allocated}
<SortIcon val="total" sort={sort} />
</th>
<th
onClick={handleSortFunct('notStarted')}
className="Clickable ColNotStarted"
>
<th onClick={handleSortFunct('notStarted')} className="Clickable ColNotStarted">
{D.notStarted}
<SortIcon val="notStarted" sort={sort} />
</th>
<th
onClick={handleSortFunct('onGoing')}
className="Clickable ColOngoing"
>
<th onClick={handleSortFunct('onGoing')} className="Clickable ColOngoing">
{D.inProgressInterviewer}
<SortIcon val="onGoing" sort={sort} />
</th>
Expand All @@ -136,17 +134,11 @@ function FollowUpTable({
{D.waitingForIntReview}
<SortIcon val="waitingForIntValidation" sort={sort} />
</th>
<th
onClick={handleSortFunct('intValidated')}
className="Clickable ColIntVal"
>
<th onClick={handleSortFunct('intValidated')} className="Clickable ColIntVal">
{D.reviewedByInterviewer}
<SortIcon val="intValidated" sort={sort} />
</th>
<th
onClick={handleSortFunct('demValidated')}
className="Clickable ColDemVal"
>
<th onClick={handleSortFunct('demValidated')} className="Clickable ColDemVal">
{D.reviewedEnded}
<SortIcon val="demValidated" sort={sort} />
</th>
Expand Down Expand Up @@ -178,16 +170,33 @@ function FollowUpTable({
{D.interviewStarted}
<SortIcon val="interviewStarted" sort={sort} />
</th>
<th
className="YellowHeader Clickable CenteredText"
onClick={handleSortFunct('noticeLetter')}
>
{D.noticeLetter}
<SortIcon val="noticeLetter" sort={sort} />
</th>
<th
className="YellowHeader Clickable CenteredText"
onClick={handleSortFunct('reminders')}
>
{D.reminders}
<SortIcon val="reminders" sort={sort} />
</th>
</tr>
</thead>
<tbody>
{displayedLines
.slice(
(pagination.page - 1) * pagination.size,
Math.min(pagination.page * pagination.size, displayedLines.length),
Math.min(pagination.page * pagination.size, displayedLines.length)
)
.map((line) => (
<FollowUpTableLine key={line.campaignId || line.interviewerId || line.site} data={line} />
.map(line => (
<FollowUpTableLine
key={line.campaignId || line.interviewerId || line.site}
data={line}
/>
))}
</tbody>
{tableFooter}
Expand Down
11 changes: 5 additions & 6 deletions src/components/MonitoringTable/FollowUpTableLine.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ function FollowUpTableLine({ data }) {
atLeastOneContact,
appointmentTaken,
interviewStarted,
noticeLetter,
reminders,
} = data;
const interviewerName = interviewerFirstName
? `${interviewerLastName} ${interviewerFirstName}`
Expand All @@ -26,12 +28,7 @@ function FollowUpTableLine({ data }) {
<td className="ColFirstCol">{interviewerName || survey || site}</td>
<td className="ColumnSpacing" />
<td className="ColCompletionRate">
{Number.isNaN(completionRate) || (
<>
{(completionRate * 100).toFixed(1)}
%
</>
)}
{Number.isNaN(completionRate) ? 'NaN' : <>{(completionRate * 100).toFixed(1)}%</>}
</td>
<td className="ColumnSpacing" />
<td className="ColAllocated">{total}</td>
Expand All @@ -45,6 +42,8 @@ function FollowUpTableLine({ data }) {
<td className="ColAtLeastOneContact">{atLeastOneContact}</td>
<td className="ColAppointmentTaken">{appointmentTaken}</td>
<td className="ColInterviewStarted">{interviewStarted}</td>
<td className="ColNoticeLetter">{noticeLetter}</td>
<td className="ColReminders">{reminders}</td>
</tr>
);
}
Expand Down
6 changes: 6 additions & 0 deletions src/components/MonitoringTable/MonitoringTable.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@
}
#MonitoringTable .ColInterviewStarted{
width: 7%;
}
#MonitoringTable .ColNoticeLetter{
width: 7%;
}
#MonitoringTable .ColReminders{
width: 7%;
}
Loading
Loading