diff --git a/web-ui/package.json b/web-ui/package.json index ce1b3e0750..7872942a32 100644 --- a/web-ui/package.json +++ b/web-ui/package.json @@ -48,13 +48,14 @@ "universal-cookie": "^4.0.4" }, "scripts": { - "start": "vite", + "build-storybook": "storybook build", "build": "vite build", - "serve": "vite preview", - "test": "vitest", "coverage": "vitest run --coverage --watch=false", + "format": "prettier --write 'src/**/*.{css,html,js,jsx}'", + "serve": "vite preview", + "start": "vite", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "test": "vitest" }, "eslintConfig": { "extends": "react-app" @@ -88,7 +89,7 @@ "jest-fetch-mock": "^3.0.3", "jsdom": "^24.0.0", "msw": "^2.2.13", - "prettier": "2.8.1", + "prettier": "3.2.5", "prop-types": "^15.8.1", "react-test-renderer": "^18.2.0", "storybook": "^8.0.4", diff --git a/web-ui/src/App.css b/web-ui/src/App.css index fd4a6cf288..26fa739d14 100644 --- a/web-ui/src/App.css +++ b/web-ui/src/App.css @@ -9,9 +9,9 @@ } @media print { - :root { - --nav-width: 0px; - } + :root { + --nav-width: 0px; + } .App { padding-left: 0; diff --git a/web-ui/src/App.jsx b/web-ui/src/App.jsx index cc0c739c6b..bb0b79caf1 100644 --- a/web-ui/src/App.jsx +++ b/web-ui/src/App.jsx @@ -1,56 +1,56 @@ -import React from "react"; -import { Router } from "react-router-dom"; -import { ErrorBoundary } from "react-error-boundary"; -import { createBrowserHistory } from "history"; +import React from 'react'; +import { Router } from 'react-router-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import { createBrowserHistory } from 'history'; -import Routes from "./components/routes/Routes"; -import Menu from "./components/menu/Menu"; -import ErrorFallback from "./pages/ErrorBoundaryPage"; -import { AppContextProvider } from "./context/AppContext"; -import SnackBarWithContext from "./components/snackbar/SnackBarWithContext"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; -import { LocalizationProvider } from "@mui/x-date-pickers"; -import { createTheme, ThemeProvider } from "@mui/material/styles"; +import Routes from './components/routes/Routes'; +import Menu from './components/menu/Menu'; +import ErrorFallback from './pages/ErrorBoundaryPage'; +import { AppContextProvider } from './context/AppContext'; +import SnackBarWithContext from './components/snackbar/SnackBarWithContext'; +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; +import { LocalizationProvider } from '@mui/x-date-pickers'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; -import "./App.css"; +import './App.css'; const customHistory = createBrowserHistory(); const theme = createTheme({ palette: { primary: { - light: "#6085d9", - main: "#2559a7", - dark: "#003177", - contrastText: "#fff", + light: '#6085d9', + main: '#2559a7', + dark: '#003177', + contrastText: '#fff' }, secondary: { - light: "#ffe8a2", - main: "#feb672", - dark: "#c88645", - contrastText: "#000", + light: '#ffe8a2', + main: '#feb672', + dark: '#c88645', + contrastText: '#000' }, background: { - default: "#F5F5F6", - paper: "#fff", - }, + default: '#F5F5F6', + paper: '#fff' + } }, components: { MuiCssBaseline: { styleOverrides: { body: { - fontSize: "0.875rem", + fontSize: '0.875rem', lineHeight: 1.43, - letterSpacing: "0.01071rem", - }, - }, + letterSpacing: '0.01071rem' + } + } }, MuiTextField: { defaultProps: { - variant: "standard", - }, - }, - }, + variant: 'standard' + } + } + } }); function App() { @@ -64,9 +64,9 @@ function App() {
diff --git a/web-ui/src/api/actionitem.js b/web-ui/src/api/actionitem.js index 91516f6891..c284bd3cea 100644 --- a/web-ui/src/api/actionitem.js +++ b/web-ui/src/api/actionitem.js @@ -1,30 +1,38 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const actionItemUrl = "/services/action-items" +const actionItemUrl = '/services/action-items'; export const createActionItem = async (actionItem, cookie) => { return resolve({ - method: "post", + method: 'post', url: actionItemUrl, data: actionItem, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateActionItem = async (actionItem, cookie) => { return resolve({ - method: "put", + method: 'put', url: actionItemUrl, data: actionItem, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteActionItem = async (id, cookie) => { return resolve({ - method: "delete", + method: 'delete', url: `${actionItemUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -33,16 +41,15 @@ export const findActionItem = async (checkinId, createdById, cookie) => { url: actionItemUrl, params: { checkinid: checkinId, - createdbyid: createdById, + createdbyid: createdById }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getActionItem = async (id, cookie) => { return resolve({ url: `${actionItemUrl}/?id=${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; - diff --git a/web-ui/src/api/agenda.js b/web-ui/src/api/agenda.js index e0a7c69e29..1169f281e1 100644 --- a/web-ui/src/api/agenda.js +++ b/web-ui/src/api/agenda.js @@ -1,30 +1,38 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const agendaURL = "/services/agenda-items"; +const agendaURL = '/services/agenda-items'; export const createAgendaItem = async (agendaItem, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: agendaURL, data: agendaItem, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateAgendaItem = async (agendaItem, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: agendaURL, data: agendaItem, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteAgendaItem = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${agendaURL}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -33,15 +41,15 @@ export const getAgendaItem = async (checkinId, createdById, cookie) => { url: agendaURL, params: { checkinid: checkinId, - createdbyid: createdById, + createdbyid: createdById }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getAgendaItemById = async (id, cookie) => { return resolve({ url: `${agendaURL}/?id=${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; diff --git a/web-ui/src/api/api.js b/web-ui/src/api/api.js index a593788308..810809647f 100644 --- a/web-ui/src/api/api.js +++ b/web-ui/src/api/api.js @@ -1,17 +1,20 @@ -import { UPDATE_TOAST } from "../context/actions"; +import { UPDATE_TOAST } from '../context/actions'; import qs from 'qs'; export const BASE_API_URL = import.meta.env.VITE_APP_API_URL ? import.meta.env.VITE_APP_API_URL - : "http://localhost:8080"; + : 'http://localhost:8080'; -export const getAvatarURL = (email) => +export const getAvatarURL = email => BASE_API_URL + - "/services/member-profiles/member-photos/" + + '/services/member-profiles/member-photos/' + encodeURIComponent(email); function fetchAbsolute(fetch) { - return baseUrl => (url, otherParams) => url.startsWith('/') ? fetch(baseUrl + url, { credentials: 'include', ...otherParams }) : fetch(url, { credentials: 'include', ...otherParams }) + return baseUrl => (url, otherParams) => + url.startsWith('/') + ? fetch(baseUrl + url, { credentials: 'include', ...otherParams }) + : fetch(url, { credentials: 'include', ...otherParams }); } let myFetch = null; @@ -20,7 +23,7 @@ export const getMyFetch = async () => { if (!myFetch) { myFetch = fetchAbsolute(fetch)(BASE_API_URL); -/* + /* I'm not sure this was working before, but we need to figure out an approach for fetch. I will open an issue for this. @@ -53,11 +56,11 @@ export const getMyFetch = async () => { */ } return myFetch; -} +}; -export const resolve = async (payload) => { +export const resolve = async payload => { let { url } = payload; - const { params = null, data = null, ...rest} = payload; + const { params = null, data = null, ...rest } = payload; const myFetch = await getMyFetch(); // Convert params to fetch style... @@ -69,29 +72,29 @@ export const resolve = async (payload) => { const promise = myFetch(url, rest); const resolved = { payload: null, - error: null, + error: null }; resolved.payload = await promise; - if(!resolved.payload.ok) { + if (!resolved.payload.ok) { const statusText = resolved.payload.statusText; resolved.error = await resolved.payload.json(); if (window.snackDispatch) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: resolved?.error?.message || statusText, - }, + severity: 'error', + toast: resolved?.error?.message || statusText + } }); } } else { - const contentType = resolved.payload.headers.get("Content-Type"); - const contentLength = resolved.payload.headers.get("Content-Length"); - if (contentType && contentType.indexOf("text/csv") !== -1) { + const contentType = resolved.payload.headers.get('Content-Type'); + const contentLength = resolved.payload.headers.get('Content-Length'); + if (contentType && contentType.indexOf('text/csv') !== -1) { resolved.payload.data = await resolved.payload.blob(); } else if (contentLength && contentLength > 0) { - if (contentType && contentType.indexOf("application/json") !== -1) { + if (contentType && contentType.indexOf('application/json') !== -1) { resolved.payload.data = await resolved.payload.json(); } else { resolved.payload.data = await resolved.payload.text(); diff --git a/web-ui/src/api/api.test.js b/web-ui/src/api/api.test.js index 243f2029cc..17c77f3b99 100644 --- a/web-ui/src/api/api.test.js +++ b/web-ui/src/api/api.test.js @@ -1,15 +1,19 @@ -import { resolve } from "./api.js"; -import { http, HttpResponse } from "msw"; -import { setupServer } from "msw/node"; +import { resolve } from './api.js'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; -const successResult = { id: 123, name: "test result" }; +const successResult = { id: 123, name: 'test result' }; -const server = setupServer(...[ - http.get("http://localhost:8080/fail", () => { - return HttpResponse.json({ message: 'Internal Server PROBLEM' }, { status: 500 }); +const server = setupServer( + ...[ + http.get('http://localhost:8080/fail', () => { + return HttpResponse.json( + { message: 'Internal Server PROBLEM' }, + { status: 500 } + ); }), - http.get("http://localhost:8080/success", () => { - return HttpResponse.json(successResult); + http.get('http://localhost:8080/success', () => { + return HttpResponse.json(successResult); }) ] ); @@ -18,18 +22,18 @@ beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -test("Error Resolve", async () => { +test('Error Resolve', async () => { window.snackDispatch = () => {}; let res = await resolve({ - url: "/fail" + url: '/fail' }); - expect(res.error.message).toStrictEqual("Internal Server PROBLEM"); + expect(res.error.message).toStrictEqual('Internal Server PROBLEM'); }); -test("Resolve", async () => { - window.snackDispatch = () => {}; - let res = await resolve({ - url: "/success" - }); - expect(res.payload.data).toStrictEqual(successResult); +test('Resolve', async () => { + window.snackDispatch = () => {}; + let res = await resolve({ + url: '/success' + }); + expect(res.payload.data).toStrictEqual(successResult); }); diff --git a/web-ui/src/api/birthdayanniversary.js b/web-ui/src/api/birthdayanniversary.js index 816cc306ce..bbe464d52a 100644 --- a/web-ui/src/api/birthdayanniversary.js +++ b/web-ui/src/api/birthdayanniversary.js @@ -1,25 +1,25 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const anniversaryReportUrl = "/services/reports/anniversaries"; -const birthdayReportUrl = "/services/reports/birthdays"; -const celebrationsToday = "/services/today"; +const anniversaryReportUrl = '/services/reports/anniversaries'; +const birthdayReportUrl = '/services/reports/birthdays'; +const celebrationsToday = '/services/today'; export const getAnniversaries = async (months, cookie) => { const results = []; for (let month of months) { const res = await resolve({ url: `${anniversaryReportUrl}?month=${month}`, - headers: { "X-CSRF-Header": cookie, Accept: "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); results.push(...res.payload.data); } return results; }; -export const getTodaysCelebrations = async (cookie) => { +export const getTodaysCelebrations = async cookie => { return resolve({ url: celebrationsToday, - headers: { "X-CSRF-Header": cookie, Accept: "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -28,7 +28,7 @@ export const getBirthdays = async (months, cookie) => { for (let month of months) { const res = await resolve({ url: `${birthdayReportUrl}?month=${month}`, - headers: { "X-CSRF-Header": cookie, Accept: "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); results.push(...res.payload.data); } diff --git a/web-ui/src/api/checkins.js b/web-ui/src/api/checkins.js index bb66ac80db..51a4c64328 100644 --- a/web-ui/src/api/checkins.js +++ b/web-ui/src/api/checkins.js @@ -1,17 +1,17 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const checkinsUrl = "/services/check-ins"; -const checkinsNoteUrl = "/services/checkin-notes"; -const checkinsPrivateNoteUrl = "/services/private-notes"; +const checkinsUrl = '/services/check-ins'; +const checkinsNoteUrl = '/services/checkin-notes'; +const checkinsPrivateNoteUrl = '/services/private-notes'; export const getMemberCheckinsByPDL = async (memberId, pdlId, cookie) => { return resolve({ url: checkinsUrl, params: { teamMemberId: memberId, - pdlId: pdlId, + pdlId: pdlId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -19,16 +19,16 @@ export const getCheckinByMemberId = async (id, cookie) => { return resolve({ url: checkinsUrl, params: { - teamMemberId: id, + teamMemberId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllCheckins = async (cookie) => { +export const getAllCheckins = async cookie => { return resolve({ url: checkinsUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -36,9 +36,9 @@ export const getCheckinByPdlId = async (id, cookie) => { return resolve({ url: checkinsUrl, params: { - pdlId: id, + pdlId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -47,10 +47,14 @@ export const createCheckin = async ( cookie ) => { return resolve({ - method: "POST", + method: 'POST', url: checkinsUrl, data: { teamMemberId, pdlId, checkInDate, completed }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -58,9 +62,9 @@ export const getNoteByCheckinId = async (id, cookie) => { return resolve({ url: checkinsNoteUrl, params: { - checkinid: id, + checkinid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -69,10 +73,14 @@ export const updateCheckin = async ( cookie ) => { return resolve({ - method: "PUT", + method: 'PUT', url: checkinsUrl, data: { completed, id, teamMemberId, pdlId, checkInDate }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -81,10 +89,14 @@ export const createCheckinNote = async ( cookie ) => { return resolve({ - method: "POST", + method: 'POST', url: checkinsNoteUrl, data: { checkinid, createdbyid, description }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -93,10 +105,14 @@ export const updateCheckinNote = async ( cookie ) => { return resolve({ - method: "PUT", + method: 'PUT', url: checkinsNoteUrl, data: { id, checkinid, createdbyid, description }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -104,9 +120,9 @@ export const getPrivateNoteByCheckinId = async (id, cookie) => { return resolve({ url: checkinsPrivateNoteUrl, params: { - checkinid: id, + checkinid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -115,10 +131,14 @@ export const createPrivateNote = async ( cookie ) => { return resolve({ - method: "POST", + method: 'POST', url: checkinsPrivateNoteUrl, data: { checkinid, createdbyid, description }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -127,9 +147,13 @@ export const updatePrivateNote = async ( cookie ) => { return resolve({ - method: "PUT", + method: 'PUT', url: checkinsPrivateNoteUrl, data: { id, checkinid, createdbyid, description }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; diff --git a/web-ui/src/api/feedback.js b/web-ui/src/api/feedback.js index 1d1ca6fd95..bacfb9c3b2 100644 --- a/web-ui/src/api/feedback.js +++ b/web-ui/src/api/feedback.js @@ -1,218 +1,281 @@ import qs from 'qs'; -import { resolve } from "./api.js"; -import { getFeedbackTemplateWithQuestions } from './feedbacktemplate.js' +import { resolve } from './api.js'; +import { getFeedbackTemplateWithQuestions } from './feedbacktemplate.js'; -const feedbackSuggestionURL = "/services/feedback/suggestions"; -const feedbackRequestURL = "/services/feedback/requests"; -const answerURL = "/services/feedback/answers"; -const questionAndAnswerURL = "/services/feedback/questions-and-answers" +const feedbackSuggestionURL = '/services/feedback/suggestions'; +const feedbackRequestURL = '/services/feedback/requests'; +const answerURL = '/services/feedback/answers'; +const questionAndAnswerURL = '/services/feedback/questions-and-answers'; -export const findReviewRequestsByPeriodAndTeamMembers = async (period, teamMemberIds, cookie) => { +export const findReviewRequestsByPeriodAndTeamMembers = async ( + period, + teamMemberIds, + cookie +) => { return resolve({ url: feedbackRequestURL, params: { reviewPeriodId: period?.id, templateId: period?.reviewTemplateId, - requesteeIds: teamMemberIds, + requesteeIds: teamMemberIds }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const findSelfReviewRequestsByPeriodAndTeamMembers = async (period, teamMemberIds, cookie) => { +export const findSelfReviewRequestsByPeriodAndTeamMembers = async ( + period, + teamMemberIds, + cookie +) => { return resolve({ url: feedbackRequestURL, params: { reviewPeriodId: period?.id, templateId: period?.selfReviewTemplateId, - requesteeIds: teamMemberIds, + requesteeIds: teamMemberIds }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const findSelfReviewRequestsByPeriodAndTeamMember = async (period, teamMemberId, cookie) => { +export const findSelfReviewRequestsByPeriodAndTeamMember = async ( + period, + teamMemberId, + cookie +) => { return resolve({ url: feedbackRequestURL, params: { reviewPeriodId: period?.id, templateId: period?.selfReviewTemplateId, requesteeId: teamMemberId, - recipientId: teamMemberId, + recipientId: teamMemberId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getFeedbackSuggestion = async (id, cookie) => { return resolve({ url: `${feedbackSuggestionURL}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createFeedbackRequest = async (feedbackRequest, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: feedbackRequestURL, data: feedbackRequest, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateFeedbackRequest = async (feedbackRequest, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: feedbackRequestURL, data: feedbackRequest, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const cancelFeedbackRequest = async (feedbackRequest, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: feedbackRequestURL, data: { ...feedbackRequest, - status: "canceled", + status: 'canceled', dueDate: null }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; export const deleteFeedbackRequestById = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${feedbackRequestURL}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getFeedbackRequestById = async (id, cookie) => { return resolve({ url: `${feedbackRequestURL}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAnswerByRequestAndQuestionId = async (requestId, questionId, cookie) => { +export const getAnswerByRequestAndQuestionId = async ( + requestId, + questionId, + cookie +) => { return resolve({ url: `${questionAndAnswerURL}`, params: { questionId: questionId, - requestId: requestId, + requestId: requestId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); +}; -} - -export const getAllAnswersFromRequestAndQuestionId = async (requestId, questions, cookie) => { - let answerReqs = [] - questions.forEach((question) => { - answerReqs.push(resolve({ - url: `${questionAndAnswerURL}`, - params: { - questionId: question.id, - requestId: requestId, - }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, - })); +export const getAllAnswersFromRequestAndQuestionId = async ( + requestId, + questions, + cookie +) => { + let answerReqs = []; + questions.forEach(question => { + answerReqs.push( + resolve({ + url: `${questionAndAnswerURL}`, + params: { + questionId: question.id, + requestId: requestId + }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } + }) + ); }); - return Promise.all(answerReqs).then((res) => { - let finalReturn = [] - res.forEach((questionAnswerPair) => { - if (questionAnswerPair && questionAnswerPair.payload && questionAnswerPair.payload.data && !questionAnswerPair.error) { - finalReturn.push(questionAnswerPair.payload.data) + return Promise.all(answerReqs).then(res => { + let finalReturn = []; + res.forEach(questionAnswerPair => { + if ( + questionAnswerPair && + questionAnswerPair.payload && + questionAnswerPair.payload.data && + !questionAnswerPair.error + ) { + finalReturn.push(questionAnswerPair.payload.data); } - }) + }); return finalReturn; }); -} +}; export const getQuestionsByRequestId = async (requestId, cookie) => { const requestRes = await getFeedbackRequestById(requestId, cookie); if (requestRes.payload && requestRes.payload.data && !requestRes.error) { - return getFeedbackTemplateWithQuestions(requestRes.payload.data.templateId, cookie); + return getFeedbackTemplateWithQuestions( + requestRes.payload.data.templateId, + cookie + ); } -} +}; export const saveSingleAnswer = (answer, cookie) => { return resolve({ url: answerURL, - method: "POST", + method: 'POST', data: answer, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; export const updateSingleAnswer = (answer, cookie) => { return resolve({ url: answerURL, - method: "PUT", + method: 'PUT', data: answer, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; export const updateAllAnswers = (answers, cookie) => { const answerReqs = []; - answers.forEach((answer) => { - answerReqs.push(resolve({ - method: "PUT", - url: answerURL, - data: answer, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, - })); + answers.forEach(answer => { + answerReqs.push( + resolve({ + method: 'PUT', + url: answerURL, + data: answer, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } + }) + ); }); - return Promise.all(answerReqs).then((res) => { + return Promise.all(answerReqs).then(res => { return res; }); -} +}; -export const getFeedbackRequestsByCreator = async(creatorId, cookie) => { +export const getFeedbackRequestsByCreator = async (creatorId, cookie) => { return resolve({ url: feedbackRequestURL, params: { creatorId: creatorId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; -export const getFeedbackRequestsByRecipient = async(recipientId, cookie) => { +export const getFeedbackRequestsByRecipient = async (recipientId, cookie) => { return resolve({ url: feedbackRequestURL, params: { recipientId: recipientId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; -export const getFeedbackRequestsByRequestee = async(requesteeId, oldestDate, cookie) => { +export const getFeedbackRequestsByRequestee = async ( + requesteeId, + oldestDate, + cookie +) => { return resolve({ url: feedbackRequestURL, params: { requesteeId, oldestDate }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; -export const getFeedbackRequestsByRequestees = async(requesteeIds, oldestDate, cookie) => { +export const getFeedbackRequestsByRequestees = async ( + requesteeIds, + oldestDate, + cookie +) => { return resolve({ url: feedbackRequestURL, params: { requesteeIds, oldestDate }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; diff --git a/web-ui/src/api/feedbackanswer.js b/web-ui/src/api/feedbackanswer.js index 5034b5e395..efa48b42d7 100644 --- a/web-ui/src/api/feedbackanswer.js +++ b/web-ui/src/api/feedbackanswer.js @@ -1,22 +1,26 @@ -import { resolve } from "./api.js"; -import { chain } from "lodash"; +import { resolve } from './api.js'; +import { chain } from 'lodash'; -const feedbackAnswerUrl = "/services/feedback/answers"; -const questionsAndAnswersUrl = "/services/feedback/questions-and-answers"; +const feedbackAnswerUrl = '/services/feedback/answers'; +const questionsAndAnswersUrl = '/services/feedback/questions-and-answers'; export const createFeedbackAnswer = async (feedbackAnswer, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: feedbackAnswerUrl, data: feedbackAnswer, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const getFeedbackAnswerById = async (feedbackAnswerId, cookie) => { return resolve({ url: `${feedbackAnswerUrl}/${feedbackAnswerId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -26,63 +30,63 @@ export const getAnswersFromRequest = async (feedbackRequestId, cookie) => { params: { requestId: feedbackRequestId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; export const getQuestionAndAnswer = async (requestId, cookie) => { return resolve({ url: `${questionsAndAnswersUrl}/${requestId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; export const getQuestionsAndAnswers = async (feedbackRequests, cookie) => { - const qnaReqs = feedbackRequests.map((request) => { + const qnaReqs = feedbackRequests.map(request => { return getQuestionAndAnswer(request, cookie); }); - return Promise.all(qnaReqs).then((qnaRes) => { + return Promise.all(qnaReqs).then(qnaRes => { if (!qnaRes || qnaRes.error) { return null; } // Destructure question data to top of object - const questionsAndAnswers = qnaRes.map((qna) => { + const questionsAndAnswers = qnaRes.map(qna => { if (!qna || !qna.payload || !qna.payload.data) { return null; } - return qna.payload.data.map((obj) => { + return qna.payload.data.map(obj => { return { answer: { ...obj.answer, responder: obj.request.recipientId }, ...obj.question - } + }; }); }); // Destructure arrays of questions to prepare for grouping const responses = []; - questionsAndAnswers.forEach((quesAndAns) => { + questionsAndAnswers.forEach(quesAndAns => { responses.push(...quesAndAns); }); // Chain questions and answers so that questions are a top level, while answers are a property of the top level object return chain(responses) - .groupBy("id") + .groupBy('id') .map((val, key) => { // Obtain array of answers that are related to this question - let answersForThisQuestion = val.map((val) => { + let answersForThisQuestion = val.map(val => { return { id: val.answer.id, answer: val.answer.answer, requestId: val.answer.requestId, sentiment: val.answer.sentiment, responder: val.answer.responder - } + }; }); // Map aforementioned array of answers to a top-level question object that they all share @@ -93,9 +97,9 @@ export const getQuestionsAndAnswers = async (feedbackRequests, cookie) => { questionNumber: questionInfo.questionNumber, inputType: questionInfo.inputType, templateId: questionInfo.templateId, - answers: answersForThisQuestion, + answers: answersForThisQuestion }; }) .value(); }); -} +}; diff --git a/web-ui/src/api/feedbacktemplate.js b/web-ui/src/api/feedbacktemplate.js index b021abcf0e..0355c75e03 100644 --- a/web-ui/src/api/feedbacktemplate.js +++ b/web-ui/src/api/feedbacktemplate.js @@ -1,72 +1,95 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const feedbackTemplateUrl = "/services/feedback/templates"; -const templateQuestionsUrl = "/services/feedback/template_questions"; +const feedbackTemplateUrl = '/services/feedback/templates'; +const templateQuestionsUrl = '/services/feedback/template_questions'; export const createFeedbackTemplate = async (feedbackTemplate, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: feedbackTemplateUrl, data: feedbackTemplate, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; -export const createFeedbackTemplateWithQuestion = async (template, question, cookie) => { - +export const createFeedbackTemplateWithQuestion = async ( + template, + question, + cookie +) => { const templateReq = resolve({ - method: "POST", + method: 'POST', url: feedbackTemplateUrl, data: template, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); - const questionReq = templateReq.then((templateRes) => { + const questionReq = templateReq.then(templateRes => { if (!templateRes.error && templateRes.payload && templateRes.payload.data) { question.templateId = templateRes.payload.data.id; return resolve({ - method: "POST", + method: 'POST', url: templateQuestionsUrl, data: question, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); } }); - return Promise.all([templateReq, questionReq]).then(([templateRes, questionRes]) => { - return {templateRes, questionRes}; - }); -} + return Promise.all([templateReq, questionReq]).then( + ([templateRes, questionRes]) => { + return { templateRes, questionRes }; + } + ); +}; export const createTemplateQuestions = async (questions, cookie) => { const questionReqs = []; - questions.forEach((question) => { - questionReqs.push(resolve({ - method: "POST", - url: templateQuestionsUrl, - data: question, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, - })); + questions.forEach(question => { + questionReqs.push( + resolve({ + method: 'POST', + url: templateQuestionsUrl, + data: question, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } + }) + ); }); - Promise.all(questionReqs).then((res) => { + Promise.all(questionReqs).then(res => { return res; }); -} +}; export const getFeedbackTemplate = async (feedbackTemplateId, cookie) => { return resolve({ url: `${feedbackTemplateUrl}/${feedbackTemplateId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getFeedbackQuestion = async (questionId, cookie) => { return resolve({ url: `${templateQuestionsUrl}/${questionId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; export const getQuestionsOnTemplate = async (templateId, cookie) => { return resolve({ @@ -74,31 +97,32 @@ export const getQuestionsOnTemplate = async (templateId, cookie) => { params: { templateId: templateId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; export const getFeedbackTemplateWithQuestions = async (templateId, cookie) => { const templateReq = getFeedbackTemplate(templateId, cookie); const questionsReq = getQuestionsOnTemplate(templateId, cookie); - const [templateRes, questionsRes] = await Promise.all([templateReq, questionsReq]); + const [templateRes, questionsRes] = await Promise.all([ + templateReq, + questionsReq + ]); const templateData = - templateRes.payload && - templateRes.payload.data && - !templateRes.error + templateRes.payload && templateRes.payload.data && !templateRes.error ? templateRes.payload.data : null; let questionsData = - questionsRes.payload && - questionsRes.payload.data && - !questionsRes.error + questionsRes.payload && questionsRes.payload.data && !questionsRes.error ? questionsRes.payload.data : null; - questionsData = questionsData ? questionsData.sort((a,b) => a.questionNumber - b.questionNumber): null; + questionsData = questionsData + ? questionsData.sort((a, b) => a.questionNumber - b.questionNumber) + : null; let templateWithQuestions = {}; if (templateData) { if (questionsData) { @@ -110,23 +134,23 @@ export const getFeedbackTemplateWithQuestions = async (templateId, cookie) => { } return templateWithQuestions; -} +}; export const softDeleteAdHocTemplates = async (creatorId, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${feedbackTemplateUrl}/creator/${creatorId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; -export const getAllFeedbackTemplates = async (cookie) => { +export const getAllFeedbackTemplates = async cookie => { return resolve({ url: feedbackTemplateUrl, params: { creatorId: null, title: null }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} \ No newline at end of file +}; diff --git a/web-ui/src/api/github.js b/web-ui/src/api/github.js index fa339ffba8..5b3408fa0b 100644 --- a/web-ui/src/api/github.js +++ b/web-ui/src/api/github.js @@ -1,15 +1,19 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; const githubURL = `/services/github-issue`; export const newGitHubIssue = async (body, title, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: githubURL, data: { body: body, - title: title, + title: title }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; diff --git a/web-ui/src/api/guild.js b/web-ui/src/api/guild.js index 7431c0ce58..a09fc9cbaa 100644 --- a/web-ui/src/api/guild.js +++ b/web-ui/src/api/guild.js @@ -1,12 +1,12 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; const guildUrl = `/services/guilds`; const guildMemberUrl = `/services/guilds/members`; -export const getAllGuildMembers = async (cookie) => { +export const getAllGuildMembers = async cookie => { return resolve({ url: guildMemberUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -14,18 +14,22 @@ export const getMembersByGuild = async (id, cookie) => { return resolve({ url: guildMemberUrl, params: { - guildid: id, + guildid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const updateGuild = async (guild, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: guildUrl, data: guild, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -33,49 +37,57 @@ export const getGuildsForMember = async (id, cookie) => { return resolve({ url: guildUrl, params: { - memberid: id, + memberid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json"}, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllGuilds = async (cookie) => { +export const getAllGuilds = async cookie => { return resolve({ url: guildUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createGuild = async (guild, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: guildUrl, data: guild, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const addGuildMember = async (id, isLead, guildId, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: guildMemberUrl, data: { memberId: id, lead: isLead, guildId: guildId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteGuildMember = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: guildMemberUrl + `/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const deleteGuild = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${guildUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; diff --git a/web-ui/src/api/hours.js b/web-ui/src/api/hours.js index 2b8c65a731..623c31cdea 100644 --- a/web-ui/src/api/hours.js +++ b/web-ui/src/api/hours.js @@ -1,4 +1,4 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; const hoursUrl = `/services/employee/hours`; @@ -6,17 +6,21 @@ export const getEmployeeHours = async (cookie, employeeId) => { return resolve({ url: hoursUrl, params: { - employeeId, + employeeId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const postEmployeeHours = async (cookie, file) => { return resolve({ - method: "POST", - url: hoursUrl + "/upload", + method: 'POST', + url: hoursUrl + '/upload', data: file, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "multipart/form-data" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'multipart/form-data' + } }); }; diff --git a/web-ui/src/api/member.js b/web-ui/src/api/member.js index 4b15c79275..ca527b4bc7 100644 --- a/web-ui/src/api/member.js +++ b/web-ui/src/api/member.js @@ -1,30 +1,29 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const memberProfileUrl = "/services/member-profiles"; -const memberProfileReportUrl = "/services/reports/member"; +const memberProfileUrl = '/services/member-profiles'; +const memberProfileReportUrl = '/services/reports/member'; - -export const getAllMembers = async (cookie) => { +export const getAllMembers = async cookie => { return resolve({ url: memberProfileUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllTerminatedMembers = async (cookie) => { +export const getAllTerminatedMembers = async cookie => { return resolve({ url: memberProfileUrl, params: { - terminated: true, + terminated: true }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllPDLs = async (cookie) => { +export const getAllPDLs = async cookie => { return resolve({ - url: "/services/roles?role=PDL", - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + url: '/services/roles?role=PDL', + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -32,9 +31,9 @@ export const getMembersByPDL = async (id, cookie) => { return resolve({ url: memberProfileUrl, params: { - pdlId: id, + pdlId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -42,68 +41,84 @@ export const getMemberByEmail = async (email, cookie) => { return resolve({ url: memberProfileUrl, params: { - workEmail: email, + workEmail: email }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getMember = async (id, cookie) => { return resolve({ url: `${memberProfileUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const updateMember = async (member, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: memberProfileUrl, data: member, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; -export const getCurrentUser = async (cookie) => { +export const getCurrentUser = async cookie => { return resolve({ url: `${memberProfileUrl}/current`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createMember = async (newMember, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: memberProfileUrl, data: newMember, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteMember = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${memberProfileUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const reportAllMembersCsv = async (cookie) => { +export const reportAllMembersCsv = async cookie => { return resolve({ url: memberProfileReportUrl, - method: "POST", + method: 'POST', data: {}, - headers: { "X-CSRF-Header": cookie, 'Accept': 'text/csv', "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'text/csv', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const reportSelectedMembersCsv = async (memberIds, cookie) => { return resolve({ url: memberProfileReportUrl, - method: "POST", + method: 'POST', data: { memberIds: memberIds }, - headers: { "X-CSRF-Header": cookie, 'Accept': 'text/csv', "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'text/csv', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; diff --git a/web-ui/src/api/memberroles.js b/web-ui/src/api/memberroles.js index 8177ace6f9..487b5c8cee 100644 --- a/web-ui/src/api/memberroles.js +++ b/web-ui/src/api/memberroles.js @@ -1,10 +1,10 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const memberRolesUrl = "/services/roles/members" +const memberRolesUrl = '/services/roles/members'; -export const getMemberRolesList = async (cookie) => { - return resolve({ - url: memberRolesUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, - }); - }; \ No newline at end of file +export const getMemberRolesList = async cookie => { + return resolve({ + url: memberRolesUrl, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } + }); +}; diff --git a/web-ui/src/api/memberskill.js b/web-ui/src/api/memberskill.js index 24c5e08b08..785bcc59e1 100644 --- a/web-ui/src/api/memberskill.js +++ b/web-ui/src/api/memberskill.js @@ -1,12 +1,12 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const memberSkillUrl = "/services/member-skills"; -const skillReportUrl = "/reports/skills" +const memberSkillUrl = '/services/member-skills'; +const skillReportUrl = '/reports/skills'; -export const getMemberSkills = async (cookie) => { +export const getMemberSkills = async cookie => { return resolve({ url: memberSkillUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -14,9 +14,9 @@ export const getSelectedMemberSkills = async (id, cookie) => { return resolve({ url: memberSkillUrl, params: { - memberid: id, + memberid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -24,43 +24,55 @@ export const getSkillMembers = async (id, cookie) => { return resolve({ url: memberSkillUrl, params: { - skillid: id, + skillid: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const deleteMemberSkill = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${memberSkillUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createMemberSkill = async (memberskill, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: memberSkillUrl, data: memberskill, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateMemberSkill = async (memberskill, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: memberSkillUrl, data: memberskill, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const reportSkills = async (skillLevels, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: skillReportUrl, data: skillLevels, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; diff --git a/web-ui/src/api/notifications.js b/web-ui/src/api/notifications.js index 0748430499..e2cf8d5f9e 100644 --- a/web-ui/src/api/notifications.js +++ b/web-ui/src/api/notifications.js @@ -1,25 +1,37 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const emailNotificationURL = "/services/email-notifications"; -const emailNewsletterURL = "/services/email"; +const emailNotificationURL = '/services/email-notifications'; +const emailNewsletterURL = '/services/email'; const testEmailURL = import.meta.env.VITE_APP_API_URL - ? import.meta.env.VITE_APP_URL + "/feedback/submit?request=" - : "http://localhost:8080/feedback/submit?request="; + ? import.meta.env.VITE_APP_URL + '/feedback/submit?request=' + : 'http://localhost:8080/feedback/submit?request='; -export const sendReminderNotification = async (feedbackRequestId, recipients, cookie) => { - let subject = "Please fill out your OCI feedback request!" - let content = "Please go to " + testEmailURL + feedbackRequestId + " to complete this feedback request. Thanks!" +export const sendReminderNotification = async ( + feedbackRequestId, + recipients, + cookie +) => { + let subject = 'Please fill out your OCI feedback request!'; + let content = + 'Please go to ' + + testEmailURL + + feedbackRequestId + + ' to complete this feedback request. Thanks!'; return resolve({ - method: "POST", + method: 'POST', url: emailNotificationURL, - data: {subject: subject, content: content, recipients: recipients}, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + data: { subject: subject, content: content, recipients: recipients }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const sendEmail = async (subject, content, html, recipients, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: emailNewsletterURL, data: { subject: subject, @@ -27,6 +39,10 @@ export const sendEmail = async (subject, content, html, recipients, cookie) => { html: html, recipients: recipients }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; diff --git a/web-ui/src/api/permissions.js b/web-ui/src/api/permissions.js index 646f47adf3..0c6f04f5d4 100644 --- a/web-ui/src/api/permissions.js +++ b/web-ui/src/api/permissions.js @@ -1,10 +1,10 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const permissionsListUrl = "/services/permissions" +const permissionsListUrl = '/services/permissions'; -export const getPermissionsList = async (cookie) => { - return resolve({ - url: permissionsListUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, - }); - }; \ No newline at end of file +export const getPermissionsList = async cookie => { + return resolve({ + url: permissionsListUrl, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } + }); +}; diff --git a/web-ui/src/api/reviewperiods.js b/web-ui/src/api/reviewperiods.js index 5f89fe8886..e8ef3c65ae 100644 --- a/web-ui/src/api/reviewperiods.js +++ b/web-ui/src/api/reviewperiods.js @@ -1,43 +1,51 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const reviewPeriodsUrl = "/services/review-periods"; +const reviewPeriodsUrl = '/services/review-periods'; -export const getReviewPeriods = async (cookie) => { +export const getReviewPeriods = async cookie => { return resolve({ url: reviewPeriodsUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getReviewPeriod = async (id, cookie) => { return resolve({ url: `${reviewPeriodsUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createReviewPeriod = async (reviewPeriod, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: reviewPeriodsUrl, data: reviewPeriod, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateReviewPeriod = async (reviewPeriod, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: reviewPeriodsUrl, data: reviewPeriod, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const removeReviewPeriod = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${reviewPeriodsUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; diff --git a/web-ui/src/api/rolepermissions.js b/web-ui/src/api/rolepermissions.js index 2cfdb9d56a..b4e927c692 100644 --- a/web-ui/src/api/rolepermissions.js +++ b/web-ui/src/api/rolepermissions.js @@ -1,28 +1,36 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const rolePermissionsListUrl = "/services/roles/role-permissions"; +const rolePermissionsListUrl = '/services/roles/role-permissions'; -export const getRolePermissionsList = async (cookie) => { +export const getRolePermissionsList = async cookie => { return resolve({ url: rolePermissionsListUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const postRolePermission = async (roleData, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: rolePermissionsListUrl, data: roleData, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteRolePermission = async (roleData, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: rolePermissionsListUrl, data: roleData, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -}; \ No newline at end of file +}; diff --git a/web-ui/src/api/roles.js b/web-ui/src/api/roles.js index 82c73ced56..3af15f2b85 100644 --- a/web-ui/src/api/roles.js +++ b/web-ui/src/api/roles.js @@ -1,56 +1,71 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const roleURL = "/services/roles"; +const roleURL = '/services/roles'; -export const getAllRoles = async (cookie) => { +export const getAllRoles = async cookie => { return resolve({ url: roleURL, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; - -export const getAllUserRoles = async (cookie) => { +export const getAllUserRoles = async cookie => { return resolve({ url: roleURL + '/members', - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const removeUserFromRole = async (roleId, memberId, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: roleURL + `/members/${roleId}/${memberId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const addUserToRole = async (roleId, memberId, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: roleURL + '/members', data: { roleId, - memberId, + memberId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const addNewRole = async (role, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: roleURL, data: role, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateRole = async (role, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: roleURL, data: role, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -}; \ No newline at end of file +}; diff --git a/web-ui/src/api/skill.js b/web-ui/src/api/skill.js index c8b01139bd..1b9cf99824 100644 --- a/web-ui/src/api/skill.js +++ b/web-ui/src/api/skill.js @@ -1,53 +1,65 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const skillUrl = "/services/skills"; -const skillCombineUrl = "/services/skills/combine"; +const skillUrl = '/services/skills'; +const skillCombineUrl = '/services/skills/combine'; -export const getSkills = async (cookie) => { +export const getSkills = async cookie => { return resolve({ url: skillUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getSkill = async (id, cookie) => { return resolve({ url: `${skillUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createSkill = async (skill, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: skillUrl, data: skill, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateSkill = async (skill, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: skillUrl, data: skill, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const removeSkill = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: skillUrl + `/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const combineSkill = async (id, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: skillCombineUrl, data: id, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -}; \ No newline at end of file +}; diff --git a/web-ui/src/api/skillcategory.js b/web-ui/src/api/skillcategory.js index a7345f2cf1..8e958fcacc 100644 --- a/web-ui/src/api/skillcategory.js +++ b/web-ui/src/api/skillcategory.js @@ -1,85 +1,105 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const skillCategoryUrl = "/services/skills/categories"; -const skillCategorySkillUrl = "/services/skills/category-skills"; -const skillRecordsUrl = "/services/skills/records"; +const skillCategoryUrl = '/services/skills/categories'; +const skillCategorySkillUrl = '/services/skills/category-skills'; +const skillRecordsUrl = '/services/skills/records'; export const createSkillCategory = async (skillCategory, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: skillCategoryUrl, data: skillCategory, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const updateSkillCategory = async (skillCategory, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: skillCategoryUrl, data: skillCategory, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; -export const getSkillCategories = async (cookie) => { +export const getSkillCategories = async cookie => { return resolve({ url: `${skillCategoryUrl}/with-skills`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const getSkillCategory = async (categoryId, cookie) => { return resolve({ url: `${skillCategoryUrl}/${categoryId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json"}, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const deleteSkillCategory = async (categoryId, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${skillCategoryUrl}/${categoryId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); -} +}; export const createSkillCategorySkill = async (categoryId, skillId, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: skillCategorySkillUrl, data: { skillCategoryId: categoryId, skillId: skillId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; -export const createSkillCategorySkills = async (categoryId, skillIds, cookie) => { +export const createSkillCategorySkills = async ( + categoryId, + skillIds, + cookie +) => { const skillIdList = [...skillIds]; - const promises = skillIdList.map((skillId) => { + const promises = skillIdList.map(skillId => { return createSkillCategorySkill(categoryId, skillId, cookie); }); return Promise.all(promises); -} +}; export const deleteSkillCategorySkill = async (categoryId, skillId, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: skillCategorySkillUrl, data: { skillCategoryId: categoryId, skillId: skillId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); -} +}; -export const getSkillsCsv = async (cookie) => { +export const getSkillsCsv = async cookie => { return resolve({ url: `${skillRecordsUrl}/csv`, - headers: { "X-CSRF-Header": cookie, "Accept": "text/csv" } + headers: { 'X-CSRF-Header': cookie, Accept: 'text/csv' } }); -} \ No newline at end of file +}; diff --git a/web-ui/src/api/team.js b/web-ui/src/api/team.js index 1b32624f05..4ad214c5ab 100644 --- a/web-ui/src/api/team.js +++ b/web-ui/src/api/team.js @@ -1,12 +1,12 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; const teamUrl = `/services/teams`; const teamMemberUrl = `/services/teams/members`; -export const getAllTeamMembers = async (cookie) => { +export const getAllTeamMembers = async cookie => { return resolve({ url: teamMemberUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -14,18 +14,22 @@ export const getMembersByTeam = async (id, cookie) => { return resolve({ url: teamMemberUrl, params: { - teamId: id, + teamId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const updateTeam = async (team, cookie) => { return resolve({ - method: "PUT", + method: 'PUT', url: teamUrl, data: team, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; @@ -33,9 +37,9 @@ export const getTeamByMember = async (id, cookie) => { return resolve({ url: teamUrl, params: { - memberId: id, + memberId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; @@ -43,41 +47,49 @@ export const getTeamsByMember = async (id, cookie) => { return resolve({ url: teamMemberUrl, params: { - memberId: id, + memberId: id }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllTeams = async (cookie) => { +export const getAllTeams = async cookie => { return resolve({ url: teamUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const createTeam = async (team, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: teamUrl, data: team, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const addTeamMember = async (member, isLead, teamId, cookie) => { return resolve({ - method: "POST", + method: 'POST', url: teamMemberUrl, data: { memberId: member.id, lead: isLead, teamId: teamId }, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8" }, + headers: { + 'X-CSRF-Header': cookie, + Accept: 'application/json', + 'Content-Type': 'application/json;charset=UTF-8' + } }); }; export const deleteTeam = async (id, cookie) => { return resolve({ - method: "DELETE", + method: 'DELETE', url: `${teamUrl}/${id}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; diff --git a/web-ui/src/api/upload.js b/web-ui/src/api/upload.js index aaa5468e53..110b7dff41 100644 --- a/web-ui/src/api/upload.js +++ b/web-ui/src/api/upload.js @@ -1,34 +1,42 @@ -import { resolve } from "./api.js"; +import { resolve } from './api.js'; -const fileUrl = "/services/files"; +const fileUrl = '/services/files'; export const getFiles = async (checkinId, cookie) => { return resolve({ url: fileUrl + `?id=${checkinId}`, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; -export const getAllFiles = async (cookie) => { +export const getAllFiles = async cookie => { return resolve({ url: fileUrl, - headers: { "X-CSRF-Header": cookie, "Accept": "application/json" }, + headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' } }); }; export const uploadFile = async (formData, checkinId, cookie) => { return resolve({ - headers: { "Content-Type": "multipart/form-data", "X-CSRF-Header": cookie, "Accept": "application/json" }, - method: "POST", + headers: { + 'Content-Type': 'multipart/form-data', + 'X-CSRF-Header': cookie, + Accept: 'application/json' + }, + method: 'POST', url: fileUrl + `/${checkinId}`, - data: formData, + data: formData }); }; export const deleteFile = async (fileId, cookie) => { return resolve({ - headers: { "Content-Type": "multipart/form-data", "X-CSRF-Header": cookie, "Accept": "application/json" }, - method: "DELETE", - url: fileUrl + `/${fileId}`, + headers: { + 'Content-Type': 'multipart/form-data', + 'X-CSRF-Header': cookie, + Accept: 'application/json' + }, + method: 'DELETE', + url: fileUrl + `/${fileId}` }); }; diff --git a/web-ui/src/components/action_item/ActionItemsPanel.jsx b/web-ui/src/components/action_item/ActionItemsPanel.jsx index 9382ffa7b6..8ea5f2fbe9 100644 --- a/web-ui/src/components/action_item/ActionItemsPanel.jsx +++ b/web-ui/src/components/action_item/ActionItemsPanel.jsx @@ -1,27 +1,31 @@ -import React, { useState, useEffect, useContext } from "react"; -import { useParams } from "react-router-dom"; -import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; +import React, { useState, useEffect, useContext } from 'react'; +import { useParams } from 'react-router-dom'; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; import { findActionItem, deleteActionItem, updateActionItem, - createActionItem, -} from "../../api/actionitem.js"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_TOAST } from "../../context/actions"; -import { selectCsrfToken, selectCurrentUser, selectCheckin } from "../../context/selectors"; -import { debounce } from "lodash/function"; -import DragIndicator from "@mui/icons-material/DragIndicator"; + createActionItem +} from '../../api/actionitem.js'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_TOAST } from '../../context/actions'; +import { + selectCsrfToken, + selectCurrentUser, + selectCheckin +} from '../../context/selectors'; +import { debounce } from 'lodash/function'; +import DragIndicator from '@mui/icons-material/DragIndicator'; import Skeleton from '@mui/material/Skeleton'; -import IconButton from "@mui/material/IconButton"; -import SaveIcon from "@mui/icons-material/Done"; -import RemoveIcon from "@mui/icons-material/Remove"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import IconButton from '@mui/material/IconButton'; +import SaveIcon from '@mui/icons-material/Done'; +import RemoveIcon from '@mui/icons-material/Remove'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; -import "./ActionItemsPanel.css"; +import './ActionItemsPanel.css'; const doUpdate = async (actionItem, csrf) => { if (actionItem && csrf) { @@ -40,7 +44,7 @@ const ActionItemsPanel = () => { const currentCheckin = selectCheckin(state, checkinId); const [actionItems, setActionItems] = useState([]); - const [description, setDescription] = useState(""); + const [description, setDescription] = useState(''); const [isLoading, setIsLoading] = useState(false); const getActionItems = async (checkinId, csrf) => { @@ -82,12 +86,12 @@ const ActionItemsPanel = () => { }; const getItemStyle = (isDragging, draggableStyle) => ({ - display: "flex", - background: isDragging ? "lightgreen" : undefined, - ...draggableStyle, + display: 'flex', + background: isDragging ? 'lightgreen' : undefined, + ...draggableStyle }); - const onDragEnd = (result) => { + const onDragEnd = result => { if (!result || !result.destination) { return; } @@ -108,7 +112,7 @@ const ActionItemsPanel = () => { newPriority += 1; } - setActionItems((actionItems) => { + setActionItems(actionItems => { actionItems[sourceIndex].priority = newPriority; reorder(actionItems, sourceIndex, index); return actionItems; @@ -119,19 +123,19 @@ const ActionItemsPanel = () => { }; const makeActionItem = async () => { - if (!checkinId || !currentUserId || description === "" || !csrf) { + if (!checkinId || !currentUserId || description === '' || !csrf) { return; } let newActionItem = { checkinid: checkinId, createdbyid: currentUserId, - description: description, + description: description }; const res = await createActionItem(newActionItem, csrf); if (!res.error && res.payload && res.payload.data) { newActionItem.id = res.payload.data.id; newActionItem.priority = res.payload.data.priority; - setDescription(""); + setDescription(''); setActionItems([...actionItems, newActionItem]); } }; @@ -141,9 +145,9 @@ const ActionItemsPanel = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Action Items can only be edited by creator", - }, + severity: 'error', + toast: 'Action Items can only be edited by creator' + } }); return; } @@ -155,10 +159,10 @@ const ActionItemsPanel = () => { }); }; - const killActionItem = (id) => { + const killActionItem = id => { if (csrf) { deleteItem(id, csrf); - let newItems = actionItems.filter((actionItem) => { + let newItems = actionItems.filter(actionItem => { return actionItem.id !== id; }); setActionItems(newItems); @@ -185,20 +189,20 @@ const ActionItemsPanel = () => { )} >
- + {isLoading ? (
- - - + + +
) : ( handleDescriptionChange(index, e)} + onChange={e => handleDescriptionChange(index, e)} value={actionItem.description} /> )} @@ -208,7 +212,8 @@ const ActionItemsPanel = () => { aria-label="delete" className="delete-icon" onClick={() => killActionItem(actionItem.id)} - size="large"> + size="large" + >
@@ -222,10 +227,17 @@ const ActionItemsPanel = () => { return ( - } title="Action Items" titleTypographyProps={{variant: "h5", component: "h2"}} /> + } + title="Action Items" + titleTypographyProps={{ variant: 'h5', component: 'h2' }} + /> - + {(provided, snapshot) => (
{createActionItemEntries()} @@ -239,21 +251,21 @@ const ActionItemsPanel = () => { disabled={currentCheckin?.completed} className="text-input" placeholder="Add action item" - onChange={(e) => setDescription(e.target.value)} - onKeyPress={(e) => { - if (e.key === "Enter" && description !== "") { + onChange={e => setDescription(e.target.value)} + onKeyPress={e => { + if (e.key === 'Enter' && description !== '') { makeActionItem(); } }} - - value={description ? description : ""} + value={description ? description : ''} /> makeActionItem()} - size="large"> + size="large" + >
diff --git a/web-ui/src/components/action_item/ActionItemsPanel.test.jsx b/web-ui/src/components/action_item/ActionItemsPanel.test.jsx index 24931a8c46..5476f74548 100644 --- a/web-ui/src/components/action_item/ActionItemsPanel.test.jsx +++ b/web-ui/src/components/action_item/ActionItemsPanel.test.jsx @@ -1,71 +1,70 @@ -import React from "react"; -import { render } from "@testing-library/react"; -import ActionItemsPanel from "./ActionItemsPanel"; -import { AppContextProvider } from "../../context/AppContext"; -import {http, HttpResponse} from "msw"; -import { setupServer } from "msw/node"; -import { createMemoryHistory } from "history"; +import React from 'react'; +import { render } from '@testing-library/react'; +import ActionItemsPanel from './ActionItemsPanel'; +import { AppContextProvider } from '../../context/AppContext'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -const mockMemberId = "912834091823"; -const mockCheckinId = "837465917381"; +const mockMemberId = '912834091823'; +const mockCheckinId = '837465917381'; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { memberProfile: { id: mockMemberId, - name: "mr. test" - }, + name: 'mr. test' + } }, checkins: [ { id: mockCheckinId, - completed: false, + completed: false } ], guilds: [], teams: [], skills: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], - memberProfiles: [], - }, + memberProfiles: [] + } }; -const history = createMemoryHistory(`/checkins/${mockMemberId}/${mockCheckinId}`); +const history = createMemoryHistory( + `/checkins/${mockMemberId}/${mockCheckinId}` +); vi.mock('react-router-dom', async () => ({ - ...await vi.importActual('react-router-dom'), // use actual for all non-hook parts + ...(await vi.importActual('react-router-dom')), // use actual for all non-hook parts useParams: () => ({ memberId: mockMemberId, - checkinId: mockCheckinId, + checkinId: mockCheckinId }), - useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }), + useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }) })); window.snackDispatch = vi.fn(); const actionItems = [ - { id: "a1", description: "first action item" }, - { id: "a2", description: "second action item" }, - { id: "a3", description: "third action item" }, + { id: 'a1', description: 'first action item' }, + { id: 'a2', description: 'second action item' }, + { id: 'a3', description: 'third action item' } ]; const server = setupServer( - http.get( - "http://localhost:8080/services/member-profiles/current", - () => { - return HttpResponse.json({ id: "12345", name: "Test User" }); - } - ), - http.get("http://localhost:8080/services/teams/members", () => { - return HttpResponse.json([{ id: "12345", name: "Test User" }]); + http.get('http://localhost:8080/services/member-profiles/current', () => { + return HttpResponse.json({ id: '12345', name: 'Test User' }); + }), + http.get('http://localhost:8080/services/teams/members', () => { + return HttpResponse.json([{ id: '12345', name: 'Test User' }]); }), http.get( - "http://localhost:8080/services/action-items?checkinid=394810298371&createdbyid=912834091823", + 'http://localhost:8080/services/action-items?checkinid=394810298371&createdbyid=912834091823', () => { return HttpResponse.json(actionItems); } @@ -80,8 +79,8 @@ global.requestAnimationFrame = function (callback) { setTimeout(callback, 0); }; -describe("ActionItemsPanel", () => { - it("renders correctly", () => { +describe('ActionItemsPanel', () => { + it('renders correctly', () => { snapshot( @@ -91,26 +90,26 @@ describe("ActionItemsPanel", () => { ); }); -// we tried making it work according to the example here but wasted too much time -// https://www.freecodecamp.org/news/how-to-write-better-tests-for-drag-and-drop-operations-in-the-browser-f9a131f0b281/ - it.skip("handles drag and drop", () => { - const checkinid = "a1"; - const createdbyid = "a2"; + // we tried making it work according to the example here but wasted too much time + // https://www.freecodecamp.org/news/how-to-write-better-tests-for-drag-and-drop-operations-in-the-browser-f9a131f0b281/ + it.skip('handles drag and drop', () => { + const checkinid = 'a1'; + const createdbyid = 'a2'; const actionItems = [ { checkinid, createdbyid, - description: "stuff", - id: "f2d929a4-887d-43d8-82b1-decf4bb64926", - priority: 1.5, + description: 'stuff', + id: 'f2d929a4-887d-43d8-82b1-decf4bb64926', + priority: 1.5 }, { checkinid, createdbyid, - description: "description", - id: "887d-43d8-82b1-decf4bb64926", - priority: 2.5, - }, + description: 'description', + id: '887d-43d8-82b1-decf4bb64926', + priority: 2.5 + } ]; const { container } = render( @@ -126,7 +125,7 @@ describe("ActionItemsPanel", () => { return event; }; - let aic = container.querySelector(".action-items-container"); + let aic = container.querySelector('.action-items-container'); expect(aic).not.toBeNull(); let droppable = aic.firstChild; let firstChild = droppable.firstChild; @@ -135,25 +134,25 @@ describe("ActionItemsPanel", () => { expect(firstChild).not.toBeNull(); expect(secondChild).not.toBeNull(); - const firstText = firstChild.querySelector(".text-input").value; - const secondText = secondChild.querySelector(".text-input").value; + const firstText = firstChild.querySelector('.text-input').value; + const secondText = secondChild.querySelector('.text-input').value; - const dragHandle1 = firstChild.querySelector("span"); + const dragHandle1 = firstChild.querySelector('span'); dragHandle1.dispatchEvent( - createBubbledEvent("dragstart", { + createBubbledEvent('dragstart', { clientX: 0, - clientY: 0, + clientY: 0 }) ); droppable.dispatchEvent( - createBubbledEvent("drop", { clientX: 0, clientY: 73 }) + createBubbledEvent('drop', { clientX: 0, clientY: 73 }) ); firstChild = droppable.firstChild; secondChild = firstChild.nextSibling; - const newFirstText = firstChild.querySelector(".text-input").value; - const newSecondText = secondChild.querySelector(".text-input").value; + const newFirstText = firstChild.querySelector('.text-input').value; + const newSecondText = secondChild.querySelector('.text-input').value; expect(newFirstText).toBe(secondText); expect(newSecondText).toBe(firstText); diff --git a/web-ui/src/components/admin/permissions/DesktopTable.jsx b/web-ui/src/components/admin/permissions/DesktopTable.jsx index c80cd4661d..0fe5703c6b 100644 --- a/web-ui/src/components/admin/permissions/DesktopTable.jsx +++ b/web-ui/src/components/admin/permissions/DesktopTable.jsx @@ -6,10 +6,10 @@ import { TableRow, TableHead, TableContainer, - Checkbox, + Checkbox } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React from 'react' +import React from 'react'; const PREFIX = 'DesktopTable'; const classes = { @@ -18,24 +18,24 @@ const classes = { const StyledTableContainer = styled(TableContainer)({ [`& .${classes.table}`]: { - minWidth: 650, - }, + minWidth: 650 + } }); - -export default function DesktopTable({roles, allPermissions, handleChange}) { - +export default function DesktopTable({ roles, allPermissions, handleChange }) { return ( - Permissions + Permissions {roles.map(role => ( - {role.name} + + {role.name} ))} @@ -48,8 +48,10 @@ export default function DesktopTable({roles, allPermissions, handleChange}) { {roles.map(role => ( - handleChange(role, permission)} inputProps={{ 'aria-label': 'primary checkbox' }} /> diff --git a/web-ui/src/components/admin/permissions/DesktopTable.stories.jsx b/web-ui/src/components/admin/permissions/DesktopTable.stories.jsx index 42811982da..cb70373463 100644 --- a/web-ui/src/components/admin/permissions/DesktopTable.stories.jsx +++ b/web-ui/src/components/admin/permissions/DesktopTable.stories.jsx @@ -4,21 +4,20 @@ import DesktopTable from './DesktopTable'; export default { component: DesktopTable, - title: 'Check Ins/PermissionsTable(Desktop)', -} + title: 'Check Ins/PermissionsTable(Desktop)' +}; -const Template = (args) => { +const Template = args => { return ; -} +}; const tableProps = { roles: roles, allPermissions: allPermissions, - handleChange: handleChange, -} + handleChange: handleChange +}; export const PermissionsTableOnDesktop = Template.bind({}); PermissionsTableOnDesktop.args = { ...tableProps }; - diff --git a/web-ui/src/components/admin/permissions/DesktopTable.test.jsx b/web-ui/src/components/admin/permissions/DesktopTable.test.jsx index 0291a87f48..19d6737449 100644 --- a/web-ui/src/components/admin/permissions/DesktopTable.test.jsx +++ b/web-ui/src/components/admin/permissions/DesktopTable.test.jsx @@ -1,10 +1,10 @@ -import React from "react"; +import React from 'react'; import renderer from 'react-test-renderer'; -import DesktopTable from "./DesktopTable" -import {roles, allPermissions, handleChange} from "./sample-data" +import DesktopTable from './DesktopTable'; +import { roles, allPermissions, handleChange } from './sample-data'; -describe("DesktopTable", () => { - it("renders correctly", () => { +describe('DesktopTable', () => { + it('renders correctly', () => { snapshot( permission === searchPermission) - : - null; + const matchedPermission = searchPermission + ? allPermissions.find(permission => permission === searchPermission) + : null; const nextRole = () => { - if (roleIndex !== roles.length -1){ - setRoleIndex(prevIndex => prevIndex + 1) + if (roleIndex !== roles.length - 1) { + setRoleIndex(prevIndex => prevIndex + 1); } - } + }; const prevRole = () => { - if (roleIndex !== 0){ - setRoleIndex(prevIndex => prevIndex -1) + if (roleIndex !== 0) { + setRoleIndex(prevIndex => prevIndex - 1); } - } - + }; return ( -
+
setSearchPermission(value)} options={allPermissions} - getOptionLabel={(option) => option} - renderInput={(params) => } + getOptionLabel={option => option} + renderInput={params => ( + + )} /> - - @@ -77,49 +80,56 @@ export default function MobileTable({roles, allPermissions, handleChange}) { - Permissions - - {selectedRole.name} - + Permissions + + {selectedRole.name} + - {matchedPermission? + {matchedPermission ? ( {matchedPermission} - handleChange(selectedRole, matchedPermission)} inputProps={{ 'aria-label': 'primary checkbox' }} /> - : + ) : ( allPermissions.map(permission => ( {permission} - handleChange(selectedRole, permission)} - inputProps={{ 'aria-label': 'primary checkbox' }} - /> - + handleChange(selectedRole, permission)} + inputProps={{ 'aria-label': 'primary checkbox' }} + /> + - ) - ) - } + )) + )}
- ) + ); } - diff --git a/web-ui/src/components/admin/permissions/MobileTable.stories.jsx b/web-ui/src/components/admin/permissions/MobileTable.stories.jsx index 1f9344b2da..8d813cafd0 100644 --- a/web-ui/src/components/admin/permissions/MobileTable.stories.jsx +++ b/web-ui/src/components/admin/permissions/MobileTable.stories.jsx @@ -4,24 +4,24 @@ import PermissionsTableMobile from './MobileTable'; export default { component: PermissionsTableMobile, - title: 'Check Ins/PermissionsTable(Mobile)', -} + title: 'Check Ins/PermissionsTable(Mobile)' +}; -const MobileTemplate = (args) => { +const MobileTemplate = args => { return ( -
+
); -} +}; const tableProps = { roles: roles, allPermissions: allPermissions, - handleChange: handleChange, -} + handleChange: handleChange +}; export const PermissionTableOnMobile = MobileTemplate.bind({}); PermissionTableOnMobile.args = { ...tableProps -} +}; diff --git a/web-ui/src/components/admin/permissions/MobileTable.test.jsx b/web-ui/src/components/admin/permissions/MobileTable.test.jsx index c6a335335a..53042908df 100644 --- a/web-ui/src/components/admin/permissions/MobileTable.test.jsx +++ b/web-ui/src/components/admin/permissions/MobileTable.test.jsx @@ -1,9 +1,9 @@ -import React from "react"; -import MobileTable from "./MobileTable" -import {roles, allPermissions, handleChange} from "./sample-data" +import React from 'react'; +import MobileTable from './MobileTable'; +import { roles, allPermissions, handleChange } from './sample-data'; -describe("MobileTable", () => { - it("renders correctly", () => { +describe('MobileTable', () => { + it('renders correctly', () => { snapshot( - {showDesktop? - - : - - } -
- ) + + return
{showDesktop ? : }
; } diff --git a/web-ui/src/components/admin/permissions/sample-data.js b/web-ui/src/components/admin/permissions/sample-data.js index b55693ee42..b2ce0acfd6 100644 --- a/web-ui/src/components/admin/permissions/sample-data.js +++ b/web-ui/src/components/admin/permissions/sample-data.js @@ -1,66 +1,52 @@ const allPermissions = [ - "View Action Items", - "Edit Action Items", - "Create Action Items", - "Add Team Members", - "Delete Team Members" -] + 'View Action Items', + 'Edit Action Items', + 'Create Action Items', + 'Add Team Members', + 'Delete Team Members' +]; const admin = { id: 1, - name: "Admin", + name: 'Admin', permissions: [ - "View Action Items", - "Edit Action Items", - "Create Action Items", - "Add Team Members", - "Delete Team Members" + 'View Action Items', + 'Edit Action Items', + 'Create Action Items', + 'Add Team Members', + 'Delete Team Members' ] -} +}; const PDL = { id: 2, - name: "PDL", + name: 'PDL', permissions: [ - "View Action Items", - "Edit Action Items", - "Create Action Items", - "Add Team Members", + 'View Action Items', + 'Edit Action Items', + 'Create Action Items', + 'Add Team Members' ] -} +}; const teamLead = { id: 3, - name: "Team Lead", - permissions: [ - "View Action Items", - "Add Team Members", - ] -} + name: 'Team Lead', + permissions: ['View Action Items', 'Add Team Members'] +}; const teamMembers = { id: 4, - name: "Team Member", - permissions: [ - "View Action Items" - ] -} + name: 'Team Member', + permissions: ['View Action Items'] +}; -const roles = [ - admin, - PDL, - teamLead, - teamMembers -] +const roles = [admin, PDL, teamLead, teamMembers]; const handleChange = (role, permission) => { - alert(`toggle the permission titled "${permission}" for role: ${role.name}`) - console.log(role) - console.log(permission) -} + alert(`toggle the permission titled "${permission}" for role: ${role.name}`); + console.log(role); + console.log(permission); +}; -export { - allPermissions, - roles, - handleChange -} \ No newline at end of file +export { allPermissions, roles, handleChange }; diff --git a/web-ui/src/components/admin/roles/RoleUserCards.jsx b/web-ui/src/components/admin/roles/RoleUserCards.jsx index c3c332e2d7..5fe687f4dc 100644 --- a/web-ui/src/components/admin/roles/RoleUserCards.jsx +++ b/web-ui/src/components/admin/roles/RoleUserCards.jsx @@ -1,55 +1,59 @@ -import React from "react"; -import { getAvatarURL } from "../../../api/api.js"; +import React from 'react'; +import { getAvatarURL } from '../../../api/api.js'; -import DeleteIcon from "@mui/icons-material/Delete"; +import DeleteIcon from '@mui/icons-material/Delete'; import { Avatar, Divider, ListItem, ListItemText, ListItemAvatar, - Typography, -} from "@mui/material"; + Typography +} from '@mui/material'; const RoleUserCards = ({ roleMembers, onRemove, memberQuery }) => { roleMembers?.sort((a, b) => a.name?.localeCompare(b.name) || -1); - return roleMembers?.map((member) => - member && - ((memberQuery && memberQuery.trim()) - ? member.name.toLowerCase().includes(memberQuery.trim().toLowerCase()) - : true) && ( -
- - - + member && + (memberQuery && memberQuery.trim() + ? member.name.toLowerCase().includes(memberQuery.trim().toLowerCase()) + : true) && ( +
+ + + + + + {member.name} + + } + secondary={ + + {member.title} + + } + /> +
onRemove(member)}> + +
+
+ - - - {member.name} - - } - secondary={ - - {member.title} - - } - /> -
onRemove(member)} - > -
- - -
- ) - ) || null; + ) + ) || null + ); }; export default RoleUserCards; diff --git a/web-ui/src/components/admin/roles/Roles.css b/web-ui/src/components/admin/roles/Roles.css index 57beadb291..61ee69ba5b 100644 --- a/web-ui/src/components/admin/roles/Roles.css +++ b/web-ui/src/components/admin/roles/Roles.css @@ -148,7 +148,6 @@ } @media screen and (max-width: 600px) { - .roles-content .roles .roles-top .roles-top-search-fields { flex-direction: column; } @@ -159,9 +158,12 @@ margin-right: 0; } - .roles-content .roles .roles-top .roles-top-search-fields .member-role-search { + .roles-content + .roles + .roles-top + .roles-top-search-fields + .member-role-search { width: 300px; margin-bottom: 1rem; } - -} \ No newline at end of file +} diff --git a/web-ui/src/components/admin/roles/Roles.jsx b/web-ui/src/components/admin/roles/Roles.jsx index 0279fb0ca0..b7872c7a56 100644 --- a/web-ui/src/components/admin/roles/Roles.jsx +++ b/web-ui/src/components/admin/roles/Roles.jsx @@ -1,18 +1,19 @@ -import React, {useContext, useEffect, useState} from "react"; +import React, { useContext, useEffect, useState } from 'react'; -import {AppContext} from "../../../context/AppContext"; +import { AppContext } from '../../../context/AppContext'; import { SET_ROLES, SET_USER_ROLES, - UPDATE_TOAST, -} from "../../../context/actions"; + UPDATE_TOAST +} from '../../../context/actions'; import { addUserToRole, addNewRole, - removeUserFromRole, updateRole, -} from "../../../api/roles"; + removeUserFromRole, + updateRole +} from '../../../api/roles'; -import RoleUserCards from "./RoleUserCards"; +import RoleUserCards from './RoleUserCards'; import { Button, @@ -35,28 +36,28 @@ import { ListItemText, FormHelperText, Divider -} from "@mui/material"; -import PersonAddIcon from "@mui/icons-material/PersonAdd"; -import SearchIcon from "@mui/icons-material/Search"; -import AddIcon from "@mui/icons-material/Add"; +} from '@mui/material'; +import PersonAddIcon from '@mui/icons-material/PersonAdd'; +import SearchIcon from '@mui/icons-material/Search'; +import AddIcon from '@mui/icons-material/Add'; -import {isArrayPresent} from './../../../helpers/checks'; +import { isArrayPresent } from './../../../helpers/checks'; -import "./Roles.css"; -import EditIcon from "@mui/icons-material/Edit"; +import './Roles.css'; +import EditIcon from '@mui/icons-material/Edit'; const Roles = () => { - const {state, dispatch} = useContext(AppContext); - const {csrf, memberProfiles, roles, userRoles} = state; + const { state, dispatch } = useContext(AppContext); + const { csrf, memberProfiles, roles, userRoles } = state; const [showAddUser, setShowAddUser] = useState(false); const [showEditRole, setShowEditRole] = useState(false); const [editedRole, setEditedRole] = useState(null); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [selectedMember, setSelectedMember] = useState({}); const [selectedRoles, setSelectedRoles] = useState([]); const [roleToMemberMap, setRoleToMemberMap] = useState({}); - const [currentRole, setCurrentRole] = useState(""); + const [currentRole, setCurrentRole] = useState(''); memberProfiles?.sort((a, b) => a.name.localeCompare(b.name)); @@ -76,52 +77,61 @@ const Roles = () => { const newRoleToMemberMap = {}; for (const userRole of userRoles || []) { - const role = roles.find((role) => role.id === userRole?.memberRoleId?.roleId); + const role = roles.find( + role => role.id === userRole?.memberRoleId?.roleId + ); if (role) { let memberList = newRoleToMemberMap[role.role]; if (!memberList) { memberList = newRoleToMemberMap[role.role] = []; } if (memberMap[userRole?.memberRoleId?.memberId] !== undefined) { - memberList.push({...memberMap[userRole?.memberRoleId?.memberId], roleId: role.id}); + memberList.push({ + ...memberMap[userRole?.memberRoleId?.memberId], + roleId: role.id + }); } } } setRoleToMemberMap(newRoleToMemberMap); }, [userRoles, memberProfiles, roles]); - const getRoleStats = (role) => { + const getRoleStats = role => { let members = roleToMemberMap[role]; return isArrayPresent(members) ? members.length : 0; - } + }; const removeFromRole = async (member, role) => { const members = roleToMemberMap[role]; - const {roleId} = members.find((m) => member.id === m.id); + const { roleId } = members.find(m => member.id === m.id); let res = await removeUserFromRole(roleId, member.id, csrf); let data = res.payload && res.payload.status === 200 && !res.error ? res.payload : null; if (data) { -// TODO: Remove role from map.... - const filtered = userRoles.filter((userRole) => userRole?.memberRoleId?.roleId !== roleId || userRole?.memberRoleId?.memberId !== member.id); + // TODO: Remove role from map.... + const filtered = userRoles.filter( + userRole => + userRole?.memberRoleId?.roleId !== roleId || + userRole?.memberRoleId?.memberId !== member.id + ); dispatch({ type: SET_USER_ROLES, - payload: filtered, + payload: filtered }); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `${member.name} removed from ${role}s`, - }, + severity: 'success', + toast: `${member.name} removed from ${role}s` + } }); } }; - const addToRole = async (member) => { - const role = roles.find((role) => role.role === currentRole.role); + const addToRole = async member => { + const role = roles.find(role => role.role === currentRole.role); let res = await addUserToRole(role.id, member.id, csrf); let data = res.payload && res.payload.data && !res.error ? res.payload.data : null; @@ -129,36 +139,41 @@ const Roles = () => { setShowAddUser(false); dispatch({ type: SET_USER_ROLES, - payload: [...userRoles, data], + payload: [...userRoles, data] }); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `${member.name} added to ${currentRole.role}s`, - }, + severity: 'success', + toast: `${member.name} added to ${currentRole.role}s` + } }); } setSelectedMember({}); }; - const saveRole = async (role) => { - let res = role.id ? await updateRole(role, csrf) : await addNewRole(role, csrf); + const saveRole = async role => { + let res = role.id + ? await updateRole(role, csrf) + : await addNewRole(role, csrf); let data = res.payload && res.payload.data && !res.error ? res.payload.data : null; if (data) { setShowEditRole(false); - const updatedRoles = [...roles.filter((role) => role?.id !== data.id), data]; + const updatedRoles = [ + ...roles.filter(role => role?.id !== data.id), + data + ]; dispatch({ type: SET_ROLES, - payload: updatedRoles, + payload: updatedRoles }); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `Role Updated: ${role.role}`, - }, + severity: 'success', + toast: `Role Updated: ${role.role}` + } }); } }; @@ -171,13 +186,13 @@ const Roles = () => { setShowEditRole(false); }; - const setRoleName = (event) => { - setEditedRole({...editedRole, role: event?.target?.value}); - } + const setRoleName = event => { + setEditedRole({ ...editedRole, role: event?.target?.value }); + }; - const setRoleDescription = (event) => { - setEditedRole({...editedRole, description: event?.target?.value}); - } + const setRoleDescription = event => { + setEditedRole({ ...editedRole, description: event?.target?.value }); + }; return (
@@ -191,17 +206,21 @@ const Roles = () => { labelId="roles-select-label" multiple value={selectedRoles} - onChange={(event) => { + onChange={event => { const value = event.target.value; - setSelectedRoles(typeof value === "string" ? value.split(",") : value) + setSelectedRoles( + typeof value === 'string' ? value.split(',') : value + ); }} - input={} - renderValue={(selected) => selected.join(", ")} + input={} + renderValue={selected => selected.join(', ')} > - {roles?.map((roleObj) => ( + {roles?.map(roleObj => ( - -1}/> - + -1} + /> + ))} @@ -212,11 +231,15 @@ const Roles = () => { label="Search members" placeholder="Member Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} InputProps={{ - endAdornment: + endAdornment: ( + + + + ) }} />
@@ -225,7 +248,7 @@ const Roles = () => {
- {roles?.map((roleObj) => + {roles?.map(roleObj => selectedRoles.includes(roleObj.role) ? ( - +
- +
{roleObj.role} - - {roleObj.description || ""} + + {roleObj.description || ''} - + {getRoleStats(roleObj.role)} Users
@@ -296,7 +324,7 @@ const Roles = () => { setCurrentRole(roleObj); }} > - +
- + removeFromRole(member, roleObj.role)} + onRemove={member => + removeFromRole(member, roleObj.role) + } memberQuery={searchText} />
@@ -328,7 +358,7 @@ const Roles = () => { label="Role Name" placeholder="Set new role name" onChange={setRoleName} - value={editedRole?.role || ""} + value={editedRole?.role || ''} variant="outlined" /> { label="Role Description" placeholder="Set new role description" onChange={setRoleDescription} - value={editedRole?.description || ""} + value={editedRole?.description || ''} variant="outlined" /> -
diff --git a/web-ui/src/components/admin/roles/Roles.test.jsx b/web-ui/src/components/admin/roles/Roles.test.jsx index 041fc274d1..a20fbd7cbc 100644 --- a/web-ui/src/components/admin/roles/Roles.test.jsx +++ b/web-ui/src/components/admin/roles/Roles.test.jsx @@ -1,22 +1,22 @@ -import React from "react"; -import Roles from "./Roles"; -import { AppContextProvider } from "../../../context/AppContext"; +import React from 'react'; +import Roles from './Roles'; +import { AppContextProvider } from '../../../context/AppContext'; const initialState = { state: { memberProfiles: [ - { id: 1, name: "Señior Test" }, - { id: 2, name: "Señora Test" }, - { id: 3, name: "Herr Test" }, + { id: 1, name: 'Señior Test' }, + { id: 2, name: 'Señora Test' }, + { id: 3, name: 'Herr Test' } ], roles: [ - { id: 1, role: "ADMIN", memberid: 1 }, - { id: 2, role: "PDL", memberid: 2 }, - ], - }, + { id: 1, role: 'ADMIN', memberid: 1 }, + { id: 2, role: 'PDL', memberid: 2 } + ] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/admin/users/Users.jsx b/web-ui/src/components/admin/users/Users.jsx index 8c184622a2..006d9801ca 100644 --- a/web-ui/src/components/admin/users/Users.jsx +++ b/web-ui/src/components/admin/users/Users.jsx @@ -1,20 +1,20 @@ -import React, { useContext, useState} from "react"; +import React, { useContext, useState } from 'react'; import { styled } from '@mui/material/styles'; -import AdminMemberCard from "../../member-directory/AdminMemberCard"; -import MemberModal from "../../member-directory/MemberModal"; -import { createMember } from "../../../api/member"; -import { AppContext } from "../../../context/AppContext"; -import { UPDATE_MEMBER_PROFILES } from "../../../context/actions"; +import AdminMemberCard from '../../member-directory/AdminMemberCard'; +import MemberModal from '../../member-directory/MemberModal'; +import { createMember } from '../../../api/member'; +import { AppContext } from '../../../context/AppContext'; +import { UPDATE_MEMBER_PROFILES } from '../../../context/actions'; import { selectNormalizedMembers, - selectNormalizedMembersAdmin, -} from "../../../context/selectors"; + selectNormalizedMembersAdmin +} from '../../../context/selectors'; -import { Button, TextField, Grid } from "@mui/material"; -import PersonIcon from "@mui/icons-material/Person"; +import { Button, TextField, Grid } from '@mui/material'; +import PersonIcon from '@mui/icons-material/Person'; -import "./Users.css"; +import './Users.css'; const PREFIX = 'Users'; const classes = { @@ -33,39 +33,40 @@ const Root = styled('div')({ margin: '-12px' }, [`& .${classes.search}`]: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' }, [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' }, [`& .${classes.members}`]: { - display: "flex", - flexWrap: "wrap", - justifyContent: "space-evenly", - width: "100%", - }, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + width: '100%' + } }); const Users = () => { const { state, dispatch } = useContext(AppContext); const { csrf, memberProfiles, userProfile } = state; const [open, setOpen] = useState(false); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [includeTerminated, setIncludeTerminated] = useState(false); const handleIncludeTerminated = () => { setIncludeTerminated(!includeTerminated); }; const isAdmin = - userProfile && userProfile.role && userProfile.role.includes("ADMIN"); + userProfile && userProfile.role && userProfile.role.includes('ADMIN'); - const normalizedMembers = isAdmin && includeTerminated - ? selectNormalizedMembersAdmin(state, searchText) - : selectNormalizedMembers(state, searchText); + const normalizedMembers = + isAdmin && includeTerminated + ? selectNormalizedMembersAdmin(state, searchText) + : selectNormalizedMembers(state, searchText); - const handleOpen = () => setOpen(true) + const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); @@ -81,58 +82,60 @@ const Users = () => { return ( -
- - - { - setSearchText(e.target.value); - }} - /> - {isAdmin && ( -
- +
+ + + { + setSearchText(e.target.value); + }} + /> + {isAdmin && ( +
+ - { - if ( - member.location && - member.firstName && - member.lastName && - member.startDate && - member.title && - member.workEmail && - csrf - ) { - let res = await createMember(member, csrf); - let data = - res.payload && res.payload.data && !res.error - ? res.payload.data - : null; - if (data) { - dispatch({ - type: UPDATE_MEMBER_PROFILES, - payload: [...memberProfiles, data], - }); + { + if ( + member.location && + member.firstName && + member.lastName && + member.startDate && + member.title && + member.workEmail && + csrf + ) { + let res = await createMember(member, csrf); + let data = + res.payload && res.payload.data && !res.error + ? res.payload.data + : null; + if (data) { + dispatch({ + type: UPDATE_MEMBER_PROFILES, + payload: [...memberProfiles, data] + }); + } + handleClose(); } - handleClose(); - } - }} - /> -
- )} -
+ }} + /> +
+ )} +
- + { type="checkbox" />
- - {createMemberCards} + + {createMemberCards} + - -
+
); }; diff --git a/web-ui/src/components/admin/users/Users.test.jsx b/web-ui/src/components/admin/users/Users.test.jsx index fa3ae19d5c..14517db027 100644 --- a/web-ui/src/components/admin/users/Users.test.jsx +++ b/web-ui/src/components/admin/users/Users.test.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import Users from "./Users"; -import { AppContextProvider } from "../../../context/AppContext"; -import { createMemoryHistory } from "history"; +import React from 'react'; +import Users from './Users'; +import { AppContextProvider } from '../../../context/AppContext'; +import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; const history = createMemoryHistory(`/people`); @@ -9,41 +9,41 @@ const history = createMemoryHistory(`/people`); const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", -} + name: 'Current User', + firstName: 'Current', + lastName: 'User' +}; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { - name: "Current User", - firstName: "Current", - lastName: "User", - role: ["MEMBER"], + name: 'Current User', + firstName: 'Current', + lastName: 'User', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - memberProfile: currentUserProfile, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', + memberProfile: currentUserProfile }, checkins: [], guilds: [], teams: [], skills: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], index: 0, - memberProfiles: [currentUserProfile], + memberProfiles: [currentUserProfile] } -} +}; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - - - + + + ); }); diff --git a/web-ui/src/components/agenda/Agenda.jsx b/web-ui/src/components/agenda/Agenda.jsx index 62aca78c46..e005b9bf02 100644 --- a/web-ui/src/components/agenda/Agenda.jsx +++ b/web-ui/src/components/agenda/Agenda.jsx @@ -1,27 +1,31 @@ -import React, { useContext, useState, useEffect } from "react"; -import { useParams } from "react-router-dom"; -import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; +import React, { useContext, useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; import { getAgendaItem, deleteAgendaItem, updateAgendaItem, - createAgendaItem, -} from "../../api/agenda.js"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_TOAST } from "../../context/actions"; -import { selectCsrfToken, selectCurrentUser, selectCheckin } from "../../context/selectors"; -import { debounce } from "lodash/function"; -import DragIndicator from "@mui/icons-material/DragIndicator"; -import AdjustIcon from "@mui/icons-material/Adjust"; + createAgendaItem +} from '../../api/agenda.js'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_TOAST } from '../../context/actions'; +import { + selectCsrfToken, + selectCurrentUser, + selectCheckin +} from '../../context/selectors'; +import { debounce } from 'lodash/function'; +import DragIndicator from '@mui/icons-material/DragIndicator'; +import AdjustIcon from '@mui/icons-material/Adjust'; import Skeleton from '@mui/material/Skeleton'; -import IconButton from "@mui/material/IconButton"; -import SaveIcon from "@mui/icons-material/Done"; -import RemoveIcon from "@mui/icons-material/Remove"; +import IconButton from '@mui/material/IconButton'; +import SaveIcon from '@mui/icons-material/Done'; +import RemoveIcon from '@mui/icons-material/Remove'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; -import "./Agenda.css"; +import './Agenda.css'; const doUpdate = async (agendaItem, csrf) => { if (agendaItem && csrf) { @@ -40,7 +44,7 @@ const AgendaItems = () => { const currentCheckin = selectCheckin(state, checkinId); const [agendaItems, setAgendaItems] = useState(); - const [description, setDescription] = useState(""); + const [description, setDescription] = useState(''); const [isLoading, setIsLoading] = useState(false); const getAgendaItems = async (checkinId, csrf) => { @@ -78,12 +82,12 @@ const AgendaItems = () => { }; const getItemStyle = (isDragging, draggableStyle) => ({ - display: "flex", - background: isDragging ? "lightgreen" : undefined, - ...draggableStyle, + display: 'flex', + background: isDragging ? 'lightgreen' : undefined, + ...draggableStyle }); - const onDragEnd = (result) => { + const onDragEnd = result => { if (!result || !result.destination) { return; } @@ -104,7 +108,7 @@ const AgendaItems = () => { newPriority += 1; } - setAgendaItems((agendaItems) => { + setAgendaItems(agendaItems => { agendaItems[sourceIndex].priority = newPriority; reorder(agendaItems, sourceIndex, index); return agendaItems; @@ -115,27 +119,27 @@ const AgendaItems = () => { }; const makeAgendaItem = async () => { - if (!checkinId || !currentUserId || description === "" || !csrf) { + if (!checkinId || !currentUserId || description === '' || !csrf) { return; } let newAgendaItem = { checkinid: checkinId, createdbyid: currentUserId, - description: description, + description: description }; const res = await createAgendaItem(newAgendaItem, csrf); if (!res.error && res.payload && res.payload.data) { newAgendaItem.id = res.payload.data.id; newAgendaItem.priority = res.payload.data.priority; - setDescription(""); + setDescription(''); setAgendaItems([...agendaItems, newAgendaItem]); } }; - const killAgendaItem = (id) => { + const killAgendaItem = id => { if (csrf) { deleteItem(id, csrf); - let newItems = agendaItems.filter((agendaItem) => { + let newItems = agendaItems.filter(agendaItem => { return agendaItem.id !== id; }); setAgendaItems(newItems); @@ -147,9 +151,9 @@ const AgendaItems = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Agenda Items can only be edited by creator", - }, + severity: 'error', + toast: 'Agenda Items can only be edited by creator' + } }); return; } @@ -188,15 +192,15 @@ const AgendaItems = () => { {isLoading ? (
- - - + + +
) : ( handleDescriptionChange(index, e)} + onChange={e => handleDescriptionChange(index, e)} value={agendaItem.description} /> )} @@ -206,7 +210,8 @@ const AgendaItems = () => { aria-label="delete" className="delete-icon" onClick={() => killAgendaItem(agendaItem.id)} - size="large"> + size="large" + > @@ -220,9 +225,16 @@ const AgendaItems = () => { return ( - } title="Agenda Items" titleTypographyProps={{variant: "h5", component: "h2"}} /> + } + title="Agenda Items" + titleTypographyProps={{ variant: 'h5', component: 'h2' }} + /> - + {(provided, snapshot) => (
@@ -237,20 +249,21 @@ const AgendaItems = () => { disabled={currentCheckin?.completed} className="text-input" placeholder="Add an agenda item" - onChange={(e) => setDescription(e.target.value)} - onKeyPress={(e) => { - if (e.key === "Enter" && description !== "") { + onChange={e => setDescription(e.target.value)} + onKeyPress={e => { + if (e.key === 'Enter' && description !== '') { makeAgendaItem(); } }} - value={description ? description : ""} + value={description ? description : ''} /> makeAgendaItem()} - size="large"> + size="large" + >
diff --git a/web-ui/src/components/agenda/Agenda.test.jsx b/web-ui/src/components/agenda/Agenda.test.jsx index 068306d2e8..a191185222 100644 --- a/web-ui/src/components/agenda/Agenda.test.jsx +++ b/web-ui/src/components/agenda/Agenda.test.jsx @@ -1,37 +1,39 @@ -import React from "react"; -import Agenda from "./Agenda"; -import { AppContextProvider } from "../../context/AppContext"; -import { createMemoryHistory } from "history"; +import React from 'react'; +import Agenda from './Agenda'; +import { AppContextProvider } from '../../context/AppContext'; +import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -const mockMemberId = "912834091823"; -const mockCheckinId = "837465917381"; +const mockMemberId = '912834091823'; +const mockCheckinId = '837465917381'; const initialState = { state: { userProfile: { memberProfile: { - id: mockMemberId, - }, + id: mockMemberId + } }, checkins: [ { id: mockCheckinId, - completed: false, + completed: false } ] - }, + } }; -const history = createMemoryHistory(`/checkins/${mockMemberId}/${mockCheckinId}`); +const history = createMemoryHistory( + `/checkins/${mockMemberId}/${mockCheckinId}` +); vi.mock('react-router-dom', async () => ({ - ...await vi.importActual('react-router-dom'), // use actual for all non-hook parts + ...(await vi.importActual('react-router-dom')), // use actual for all non-hook parts useParams: () => ({ memberId: mockMemberId, - checkinId: mockCheckinId, + checkinId: mockCheckinId }), - useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }), + useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }) })); global.requestAnimationFrame = function (callback) { @@ -39,9 +41,9 @@ global.requestAnimationFrame = function (callback) { }; describe('Agenda', () => { - it("renders correctly", () => { + it('renders correctly', () => { snapshot( - + diff --git a/web-ui/src/components/annual-review-report/AnnualReviewReport.jsx b/web-ui/src/components/annual-review-report/AnnualReviewReport.jsx index 4de58ccf22..b7c40beac1 100644 --- a/web-ui/src/components/annual-review-report/AnnualReviewReport.jsx +++ b/web-ui/src/components/annual-review-report/AnnualReviewReport.jsx @@ -1,12 +1,12 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; -import { getAvatarURL } from "../../api/api.js"; -import { AppContext } from "../../context/AppContext"; -import { selectProfile } from "../../context/selectors"; -import { getFeedbackRequestsByRequestee } from "../../api/feedback.js"; -import { getFeedbackTemplateWithQuestions } from "../../api/feedbacktemplate.js"; -import { getAnswersFromRequest } from "../../api/feedbackanswer"; -import DateFnsAdapter from "@date-io/date-fns"; +import { getAvatarURL } from '../../api/api.js'; +import { AppContext } from '../../context/AppContext'; +import { selectProfile } from '../../context/selectors'; +import { getFeedbackRequestsByRequestee } from '../../api/feedback.js'; +import { getFeedbackTemplateWithQuestions } from '../../api/feedbacktemplate.js'; +import { getAnswersFromRequest } from '../../api/feedbackanswer'; +import DateFnsAdapter from '@date-io/date-fns'; import { Avatar, Card, @@ -15,9 +15,9 @@ import { Typography, List, ListItem, - Grid, -} from "@mui/material"; -import { styled } from "@mui/material/styles"; + Grid +} from '@mui/material'; +import { styled } from '@mui/material/styles'; const dateFns = new DateFnsAdapter(); @@ -31,137 +31,158 @@ const classes = { // TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. const Root = styled('div')({ - marginBottom:"1em", + marginBottom: '1em', [`& .${classes.redTypography}`]: { - color: "#FF0000", - marginRight: "1em", + color: '#FF0000', + marginRight: '1em' }, [`& .${classes.yellowTypography}`]: { - color: "#EE8C00", - marginRight: "1em", + color: '#EE8C00', + marginRight: '1em' }, [`& .${classes.greenTypography}`]: { - color: "#006400", - marginRight: "1em", + color: '#006400', + marginRight: '1em' }, [`& .${classes.darkGrayTypography}`]: { - color: "#333333", - marginRight: "1em", - }, + color: '#333333', + marginRight: '1em' + } }); -const Submitted = ({submitDate, dueDate}) => { - if (dueDate) { - let today = new Date(); - let due = new Date(dueDate); - if (!submitDate && today > due) { - return ( - Overdue - ); - } +const Submitted = ({ submitDate, dueDate }) => { + if (dueDate) { + let today = new Date(); + let due = new Date(dueDate); + if (!submitDate && today > due) { + return Overdue; } - if (submitDate) { - return ( - - - Submitted - - - {dateFns.format(new Date(submitDate.join("/")), "LLLL dd, yyyy")} - - - ); - } else - return ( - - Not Submitted + } + if (submitDate) { + return ( + + Submitted + + {dateFns.format(new Date(submitDate.join('/')), 'LLLL dd, yyyy')} - ); - }; + + ); + } else + return ( + + Not Submitted + + ); +}; -const QuestionResponse = ({fromProfile, responseText, submitDate, dueDate}) => ( - - - - - - - - - {fromProfile?.name} - - - {fromProfile?.title} - - - - - - - - {responseText} - - +const QuestionResponse = ({ + fromProfile, + responseText, + submitDate, + dueDate +}) => ( + + + + + + + + {fromProfile?.name} + + {fromProfile?.title} + + + + + + + {responseText} + ); -const findRequestById = (requests, requestId) => requests?.find((request) => request.id === requestId); +const findRequestById = (requests, requestId) => + requests?.find(request => request.id === requestId); -const QuestionResults = ({question, responses, requests}) => { +const QuestionResults = ({ question, responses, requests }) => { const { state } = useContext(AppContext); return ( {question.question} - { - responses?.map((response) => { - const request = findRequestById(requests, response.requestId); - const fromProfile = selectProfile(state, request?.recipientId) - return (); - }) - } + {responses?.map(response => { + const request = findRequestById(requests, response.requestId); + const fromProfile = selectProfile(state, request?.recipientId); + return ( + + ); + })} - ) + ); }; -const FeedbackTemplateResults = ({includeUnsubmitted, template, requests, answers, state}) => ( +const FeedbackTemplateResults = ({ + includeUnsubmitted, + template, + requests, + answers, + state +}) => (

{template?.title}

- {includeUnsubmitted && requests.filter((request) => request.status !== "submitted").map((request)=> { - const fromProfile = selectProfile(state, request?.recipientId) - const submitDate = request?.submitDate; - const dueDate = request?.dueDate; - return ( - request.status !== 'submitted') + .map(request => { + const fromProfile = selectProfile(state, request?.recipientId); + const submitDate = request?.submitDate; + const dueDate = request?.dueDate; + return ( + - - - - - - {fromProfile?.name} - - - {fromProfile?.title} - - - - - - - ); - })} - {template?.questions?.map((question) => ())} + style={{ marginBottom: '1em' }} + > + + + + + + {fromProfile?.name} + + + {fromProfile?.title} + + + + + + + ); + })} + {template?.questions?.map(question => ( + + ))}
); @@ -177,23 +198,26 @@ const AnnualReviewReport = ({ userId, includeUnsubmitted }) => { useEffect(() => { const loadRequests = async () => { - const res = await getFeedbackRequestsByRequestee(userId, null, csrf); - let feedbackRequests = res.payload && res.payload.data && !res.error ? res.payload.data : []; - if(!includeUnsubmitted) { - feedbackRequests = feedbackRequests.filter((request) => request.status === "submitted"); - } - setFeedbackRequests(feedbackRequests); - } + const res = await getFeedbackRequestsByRequestee(userId, null, csrf); + let feedbackRequests = + res.payload && res.payload.data && !res.error ? res.payload.data : []; + if (!includeUnsubmitted) { + feedbackRequests = feedbackRequests.filter( + request => request.status === 'submitted' + ); + } + setFeedbackRequests(feedbackRequests); + }; - if(csrf && userId) { + if (csrf && userId) { loadRequests(); } }, [userId, includeUnsubmitted, csrf]); useEffect(() => { const newRequestMap = {}; - for(let i = 0; i < feedbackRequests.length; i++) { - if(!newRequestMap[feedbackRequests[i].templateId]) { + for (let i = 0; i < feedbackRequests.length; i++) { + if (!newRequestMap[feedbackRequests[i].templateId]) { newRequestMap[feedbackRequests[i].templateId] = []; } newRequestMap[feedbackRequests[i].templateId].push(feedbackRequests[i]); @@ -205,36 +229,49 @@ const AnnualReviewReport = ({ userId, includeUnsubmitted }) => { useEffect(() => { const refreshAnswers = async () => { const requests = []; - feedbackRequests.forEach((feedbackRequest) => requests.push(getAnswersFromRequest(feedbackRequest.id))); + feedbackRequests.forEach(feedbackRequest => + requests.push(getAnswersFromRequest(feedbackRequest.id)) + ); const answers = await Promise.all(requests); - setAnswers(answers.reduce((answerMap, res) => { - const questionAnswers = res.payload && res.payload.data && !res.error ? res.payload.data : null; - questionAnswers?.forEach((answer) => { - answerMap[answer.questionId] = answerMap[answer.questionId] ? answerMap[answer.questionId] : []; + setAnswers( + answers.reduce((answerMap, res) => { + const questionAnswers = + res.payload && res.payload.data && !res.error + ? res.payload.data + : null; + questionAnswers?.forEach(answer => { + answerMap[answer.questionId] = answerMap[answer.questionId] + ? answerMap[answer.questionId] + : []; answerMap[answer.questionId].push(answer); - }); + }); - return answerMap; - }, {})); + return answerMap; + }, {}) + ); }; - if(csrf && feedbackRequests && feedbackRequests.length > 0) { - refreshAnswers(); + if (csrf && feedbackRequests && feedbackRequests.length > 0) { + refreshAnswers(); } }, [csrf, feedbackRequests]); useEffect(() => { - const refreshTemplates = async (templateIds) => { + const refreshTemplates = async templateIds => { const requests = []; - templateIds.forEach((templateId) => requests.push(getFeedbackTemplateWithQuestions(templateId))); + templateIds.forEach(templateId => + requests.push(getFeedbackTemplateWithQuestions(templateId)) + ); const templates = await Promise.all(requests); - setTemplatesMap(templates.reduce((templates, template) => { - templates[template.id] = template; - return templates; - }, {})); - } + setTemplatesMap( + templates.reduce((templates, template) => { + templates[template.id] = template; + return templates; + }, {}) + ); + }; const templateIds = Object.keys(templateRequestMap); - if(csrf && templateIds && templateIds.length > 0) { - refreshTemplates(templateIds); + if (csrf && templateIds && templateIds.length > 0) { + refreshTemplates(templateIds); } }, [templateRequestMap, csrf]); @@ -243,20 +280,34 @@ const AnnualReviewReport = ({ userId, includeUnsubmitted }) => { - {userProfile?.name} -
- } - subheader={ - - {userProfile?.title} + {userProfile?.name} + + } + subheader={ + + {userProfile?.title} } disableTypography - avatar={} + avatar={ + + } /> - {Object.entries(templateRequestMap).map(([templateId, feedbackRequests]) => ())} + {Object.entries(templateRequestMap).map( + ([templateId, feedbackRequests]) => ( + + + + ) + )}
diff --git a/web-ui/src/components/avatar/Avatar.css b/web-ui/src/components/avatar/Avatar.css index 5b83a6817c..919ed30252 100644 --- a/web-ui/src/components/avatar/Avatar.css +++ b/web-ui/src/components/avatar/Avatar.css @@ -1,4 +1,4 @@ .avatar { - background-color: #72c7d5; - cursor: pointer; + background-color: #72c7d5; + cursor: pointer; } diff --git a/web-ui/src/components/avatar/Avatar.jsx b/web-ui/src/components/avatar/Avatar.jsx index de00fe77e6..e6b64abb2d 100644 --- a/web-ui/src/components/avatar/Avatar.jsx +++ b/web-ui/src/components/avatar/Avatar.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import "./Avatar.css"; +import React from 'react'; +import './Avatar.css'; -import Avatar from "@mui/material/Avatar"; +import Avatar from '@mui/material/Avatar'; const AvatarComponent = ({ imageUrl, ...props }) => { return ; diff --git a/web-ui/src/components/avatar/Avatar.stories.jsx b/web-ui/src/components/avatar/Avatar.stories.jsx index 35bcba1df0..e79287756e 100644 --- a/web-ui/src/components/avatar/Avatar.stories.jsx +++ b/web-ui/src/components/avatar/Avatar.stories.jsx @@ -3,16 +3,15 @@ import Avatar from './Avatar'; import image from '../../logo.svg'; export default { - title: 'Check Ins/Avatar', - component: Avatar + title: 'Check Ins/Avatar', + component: Avatar }; -const Template = (args) => - ; +const Template = args => ; export const ProfileImage = Template.bind({}); ProfileImage.args = { - imageUrl: image + imageUrl: image }; export const NoProfileImage = Template.bind({}); -NoProfileImage.args = {}; \ No newline at end of file +NoProfileImage.args = {}; diff --git a/web-ui/src/components/avatar/Avatar.test.jsx b/web-ui/src/components/avatar/Avatar.test.jsx index 2d3d4297bd..3fa84dbba1 100644 --- a/web-ui/src/components/avatar/Avatar.test.jsx +++ b/web-ui/src/components/avatar/Avatar.test.jsx @@ -1,20 +1,20 @@ -import React from "react"; -import AvatarComponent from "./Avatar"; -import { AppContextProvider } from "../../context/AppContext"; -import renderer from "react-test-renderer"; +import React from 'react'; +import AvatarComponent from './Avatar'; +import { AppContextProvider } from '../../context/AppContext'; +import renderer from 'react-test-renderer'; const initialState = { state: { userProfile: { memberProfile: { - id: "912834091823", - }, - }, - }, + id: '912834091823' + } + } + } }; -describe("AvatarComponent", () => { - it("renders correctly", () => { +describe('AvatarComponent', () => { + it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/celebrations/Anniversaries.css b/web-ui/src/components/celebrations/Anniversaries.css index 91f0e5336c..10287832d3 100644 --- a/web-ui/src/components/celebrations/Anniversaries.css +++ b/web-ui/src/components/celebrations/Anniversaries.css @@ -2,22 +2,22 @@ body { font-family: 'Raleway', sans-serif; - background-color: #F0E2DB; + background-color: #f0e2db; font-size: 20px; transition: 1s; } -body.open{ +body.open { animation: bg-change 1s 1; background-color: #72c8d5; transition: 1s; } -@keyframes bg-change{ - 0%{ - background-color: #F0E2DB; +@keyframes bg-change { + 0% { + background-color: #f0e2db; } - 100%{ - background-color: #72c8d5; + 100% { + background-color: #72c8d5; } } .anniversaries { @@ -43,9 +43,9 @@ body.open{ transform-origin: 0% 0%; transform: translate(-50%, -50%); transition: 1s; -/* animation: box 0.5s infinite; */ + /* animation: box 0.5s infinite; */ } -.box{ +.box { transform-origin: 0% 0%; animation: box 0.5s infinite; } @@ -53,16 +53,16 @@ body.open{ 0% { transform: rotate(0deg) translate(-50%, -50%); } - 25%{ + 25% { transform: rotate(1deg) translate(-50%, -50%); } - 50%{ + 50% { transform: rotate(0deg) translate(-50%, -50%); } - 70%{ + 70% { transform: rotate(-1deg) translate(-50%, -50%); } - 100%{ + 100% { transform: rotate(0deg) translate(-50%, -50%); } } @@ -73,34 +73,42 @@ body.open{ background: #2559a7; border-radius: 5px 5px 0 0; transform: translate3d(-5%, 0, 0); - background-image: linear-gradient(to right, #2559a7 0%, #2559a7 44%, #feb672 44%, #feb672 56%, #2559a7 56%, #2559a7 100%); + background-image: linear-gradient( + to right, + #2559a7 0%, + #2559a7 44%, + #feb672 44%, + #feb672 56%, + #2559a7 56%, + #2559a7 100% + ); transition: 1s; } -.anniversary-gift-top.boxOpen{ +.anniversary-gift-top.boxOpen { animation: box-open 1s; - opacity:0; + opacity: 0; } -@keyframes box-open{ - 0%{ - top:0px; - opacity:1; +@keyframes box-open { + 0% { + top: 0px; + opacity: 1; } - 100%{ - top:-50px; - opacity:0; + 100% { + top: -50px; + opacity: 0; } } .anniversary-gift-top::before, .anniversary-gift-top::after { - content: ""; - width: 15px; - height: 15px; - border: 10px solid #feb672; - border-radius: 50% 50% 0 50%; - position: absolute; - top: 0; - left: 50%; - transform: translate3d(-100%, -100%, 0) skew(10deg, 10deg); + content: ''; + width: 15px; + height: 15px; + border: 10px solid #feb672; + border-radius: 50% 50% 0 50%; + position: absolute; + top: 0; + left: 50%; + transform: translate3d(-100%, -100%, 0) skew(10deg, 10deg); } .anniversary-gift-top::after { @@ -113,39 +121,47 @@ body.open{ top: 50%; left: 50%; margin: 0; - color: #FFFFFF; + color: #ffffff; white-space: nowrap; - transform: translate3d(-50%, -50%, 0) scale(.5); + transform: translate3d(-50%, -50%, 0) scale(0.5); transform-origin: center center; z-index: -1; - opacity:1; + opacity: 1; transition: 5s; } .anniversary-gift-box { width: 100%; height: 75%; - position:relative; - background-image: linear-gradient(to right, #2559a7 0%, #2559a7 45%, #feb672 45%, #feb672 55%, #2559a7 55%, #2559a7 100%); + position: relative; + background-image: linear-gradient( + to right, + #2559a7 0%, + #2559a7 45%, + #feb672 45%, + #feb672 55%, + #2559a7 55%, + #2559a7 100% + ); border-radius: 0 0 5px 5px; transition: 1s; } -.anniversary-gift-box.boxDown{ - animation: box-down 1s; - opacity:0; +.anniversary-gift-box.boxDown { + animation: box-down 1s; + opacity: 0; } -@keyframes box-down{ - 0%{ - top:0px; - opacity:1; +@keyframes box-down { + 0% { + top: 0px; + opacity: 1; + } + 100% { + top: 50px; + opacity: 0; } - 100%{ - top:50px; - opacity:0; - } } @media (max-width: 600px) { - .anniversaries-card { + .anniversaries-card { min-width: unset; /* margin: 0 1rem; */ } @@ -155,11 +171,11 @@ body.open{ } @media (max-width: 400px) { - .anniversaries-card { + .anniversaries-card { min-width: unset; margin: 0 1rem; } .anniversary-gift { left: 10rem; } -} \ No newline at end of file +} diff --git a/web-ui/src/components/celebrations/Anniversaries.jsx b/web-ui/src/components/celebrations/Anniversaries.jsx index f1b39b1354..a058816d54 100644 --- a/web-ui/src/components/celebrations/Anniversaries.jsx +++ b/web-ui/src/components/celebrations/Anniversaries.jsx @@ -1,43 +1,43 @@ -import React, { useContext } from "react"; -import { Link } from "react-router-dom"; -import { AppContext } from "../../context/AppContext"; +import React, { useContext } from 'react'; +import { Link } from 'react-router-dom'; +import { AppContext } from '../../context/AppContext'; -import { styled } from "@mui/material/styles"; -import { getAvatarURL } from "../../api/api.js"; +import { styled } from '@mui/material/styles'; +import { getAvatarURL } from '../../api/api.js'; import { selectMemberProfilesLoading, - selectProfile, -} from "../../context/selectors"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader"; + selectProfile +} from '../../context/selectors'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; -import { Card, CardHeader } from "@mui/material"; -import Avatar from "@mui/material/Avatar"; +import { Card, CardHeader } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; -import { Grid } from "@mui/material"; +import { Grid } from '@mui/material'; -import "./Anniversaries.css"; +import './Anniversaries.css'; -import { Typography } from "@mui/material"; +import { Typography } from '@mui/material'; -const PREFIX = "MemberSummaryCard"; +const PREFIX = 'MemberSummaryCard'; const classes = { - header: `${PREFIX}-header`, + header: `${PREFIX}-header` }; -const Root = styled("div")({ +const Root = styled('div')({ [`& .${classes.search}`]: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' }, [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' }, [`& .${classes.members}`]: { - display: "flex", - flexWrap: "wrap", - justifyContent: "space-evenly", - width: "100%", - }, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + width: '100%' + } }); const Anniversaries = ({ anniversaries }) => { @@ -48,9 +48,9 @@ const Anniversaries = ({ anniversaries }) => { const createAnniversaryCards = anniversaries.map((anniv, index) => { let user = selectProfile(state, anniv.userId); return ( - + { } subheader={ - Thank you for{" "} + Thank you for{' '} {anniv.yearsOfService.toFixed(0)} - {anniv.yearsOfService > 1 ? " years" : " year"}{" "} + {anniv.yearsOfService > 1 ? ' years' : ' year'}{' '} of service! @@ -73,7 +73,7 @@ const Anniversaries = ({ anniversaries }) => { disableTypography avatar={ } @@ -85,10 +85,10 @@ const Anniversaries = ({ anniversaries }) => { return (
-
-
-
-
+
+
+
+
@@ -101,8 +101,8 @@ const Anniversaries = ({ anniversaries }) => { )) : !loading - ? createAnniversaryCards - : null} + ? createAnniversaryCards + : null} diff --git a/web-ui/src/components/celebrations/Anniversaries.test.jsx b/web-ui/src/components/celebrations/Anniversaries.test.jsx index 1f943b4579..84dee93091 100644 --- a/web-ui/src/components/celebrations/Anniversaries.test.jsx +++ b/web-ui/src/components/celebrations/Anniversaries.test.jsx @@ -1,36 +1,34 @@ -import React from "react"; -import Anniversaries from "./Anniversaries"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import Anniversaries from './Anniversaries'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const anniversaries = [ - { - "name": "Jesse Hanner", - "anniversary": "12/20/2012", - "yearsOfService": 10.03, - "userId": "67dc3a3b-5bfa-4759-997a-fb6bac98dcf3" - }, - { - "name": "Mohit Bhatia", - "anniversary": "12/10/2016", - "yearsOfService": 6.06, - "userId": "b2d35288-7f1e-4549-aa2b-68396b162490" - }, - { - "name": "Zack Brown", - "anniversary": "12/29/2019", - "yearsOfService": 3.01, - "userId": "43ee8e79-b33d-44cd-b23c-e183894ebfef" - } - ] + { + name: 'Jesse Hanner', + anniversary: '12/20/2012', + yearsOfService: 10.03, + userId: '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3' + }, + { + name: 'Mohit Bhatia', + anniversary: '12/10/2016', + yearsOfService: 6.06, + userId: 'b2d35288-7f1e-4549-aa2b-68396b162490' + }, + { + name: 'Zack Brown', + anniversary: '12/29/2019', + yearsOfService: 3.01, + userId: '43ee8e79-b33d-44cd-b23c-e183894ebfef' + } +]; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); diff --git a/web-ui/src/components/celebrations/Birthdays.css b/web-ui/src/components/celebrations/Birthdays.css index 2582fb7a86..051d4585e1 100644 --- a/web-ui/src/components/celebrations/Birthdays.css +++ b/web-ui/src/components/celebrations/Birthdays.css @@ -1,258 +1,258 @@ @import url('https://fonts.googleapis.com/css?family=Wendy+One'); body { - font-family: "Wendy One", sans-serif; - } + font-family: 'Wendy One', sans-serif; +} + +.birthdays-container p { + text-transform: uppercase; +} + +.birthdays-container .bday-title { + display: flex; + justify-content: center; +} +.birthdays-card { + min-width: 450px; +} +.birthdays-card span { + color: #2559a7; + font-weight: bold; +} +.birthdays-container { + position: relative; +} +.balloons { + margin: 0 auto; + position: absolute; + left: 5rem; + top: -3.5rem; +} +.balloons > div { + width: 80px; + height: 100px; + background: rgba(182, 15, 97, 0.9); + border-radius: 0; + border-radius: 80% 80% 80% 80%; + margin: 0 auto; + position: absolute; + padding: 10px; + box-shadow: inset 17px 7px 10px rgba(182, 15, 97, 0.9); + -webkit-transform-origin: bottom center; +} +.balloons > div:nth-child(1) { + background: rgba(182, 15, 97, 0.9); + left: 0; + box-shadow: inset 10px 10px 10px rgba(135, 11, 72, 0.9); + -webkit-animation: balloon1 6s ease-in-out infinite; + -moz-animation: balloon1 6s ease-in-out infinite; + -o-animation: balloon1 6s ease-in-out infinite; + animation: balloon1 6s ease-in-out infinite; +} +.balloons > div:nth-child(1):before { + color: rgba(182, 15, 97, 0.9); +} +.balloons > div:nth-child(2) { + background: rgba(242, 194, 58, 0.9); + left: 8rem; + top: -1.5rem; + box-shadow: inset 10px 10px 10px rgba(192, 154, 43, 0.9); + -webkit-animation: balloon2 6s ease-in-out infinite; + -moz-animation: balloon2 6s ease-in-out infinite; + -o-animation: balloon2 6s ease-in-out infinite; + animation: balloon2 6s ease-in-out infinite; +} +.balloons > div:nth-child(2):before { + color: rgba(242, 194, 58, 0.9); +} +.balloons > div:nth-child(3) { + background: rgba(45, 181, 167, 0.9); + left: 240px; + box-shadow: inset 10px 10px 10px rgba(35, 140, 129, 0.9); + -webkit-animation: balloon4 6s ease-in-out infinite; + -moz-animation: balloon4 6s ease-in-out infinite; + -o-animation: balloon4 6s ease-in-out infinite; + animation: balloon4 6s ease-in-out infinite; +} +.balloons > div:nth-child(3):before { + color: rgba(45, 181, 167, 0.9); +} - .birthdays-container p { - text-transform: uppercase; +.balloons > div:before { + position: absolute; + bottom: -11px; + left: 32px; + content: '▲'; + font-size: 1em; +} +.balloons p { + font-size: 0.75em; + font-weight: bold; + line-height: 0.5em; + text-align: center; + color: white; + position: relative; + top: 25%; +} +.balloons:hover { + cursor: pointer; +} +/*BALLOON 1 4*/ +@-webkit-keyframes balloon1 { + 0%, + 100% { } - - .birthdays-container .bday-title { - display: flex; - justify-content: center; + 50% { + -webkit-transform: translateY(-20px) rotate(8deg); } - .birthdays-card { - min-width: 450px; +} +@-moz-keyframes balloon1 { + 0%, + 100% { + -moz-transform: translateY(0) rotate(-6deg); + } + 50% { + -moz-transform: translateY(-20px) rotate(8deg); } - .birthdays-card span { - color: #2559a7; - font-weight: bold; } - .birthdays-container { - position: relative; - } - .balloons { - margin: 0 auto; - position: absolute; - left: 5rem; - top: -3.5rem; - } - .balloons > div { - width: 80px; - height: 100px; - background: rgba(182, 15, 97, 0.9); - border-radius: 0; - border-radius: 80% 80% 80% 80%; - margin: 0 auto; - position: absolute; - padding: 10px; - box-shadow: inset 17px 7px 10px rgba(182, 15, 97, 0.9); - -webkit-transform-origin: bottom center; +@-o-keyframes balloon1 { + 0%, + 100% { + -o-transform: translateY(0) rotate(-6deg); } - .balloons > div:nth-child(1) { - background: rgba(182, 15, 97, 0.9); - left: 0; - box-shadow: inset 10px 10px 10px rgba(135, 11, 72, 0.9); - -webkit-animation: balloon1 6s ease-in-out infinite; - -moz-animation: balloon1 6s ease-in-out infinite; - -o-animation: balloon1 6s ease-in-out infinite; - animation: balloon1 6s ease-in-out infinite; + 50% { + -o-transform: translateY(-20px) rotate(8deg); } - .balloons > div:nth-child(1):before { - color: rgba(182, 15, 97, 0.9); +} +@keyframes balloon1 { + 0%, + 100% { + transform: translateY(0) rotate(-6deg); } - .balloons > div:nth-child(2) { - background: rgba(242, 194, 58, 0.9); - left: 8rem; - top: -1.5rem; - box-shadow: inset 10px 10px 10px rgba(192, 154, 43, 0.9); - -webkit-animation: balloon2 6s ease-in-out infinite; - -moz-animation: balloon2 6s ease-in-out infinite; - -o-animation: balloon2 6s ease-in-out infinite; - animation: balloon2 6s ease-in-out infinite; - } - .balloons > div:nth-child(2):before { - color: rgba(242, 194, 58, 0.9); + 50% { + transform: translateY(-20px) rotate(8deg); } - .balloons > div:nth-child(3) { - background: rgba(45, 181, 167, 0.9); - left: 240px; - box-shadow: inset 10px 10px 10px rgba(35, 140, 129, 0.9); - -webkit-animation: balloon4 6s ease-in-out infinite; - -moz-animation: balloon4 6s ease-in-out infinite; - -o-animation: balloon4 6s ease-in-out infinite; - animation: balloon4 6s ease-in-out infinite; - } - .balloons > div:nth-child(3):before { - color: rgba(45, 181, 167, 0.9); - } - - .balloons > div:before { - position: absolute; - bottom: -11px; - left: 32px; - content: "▲"; - font-size: 1em; - } - .balloons p { - font-size: .75em; - font-weight: bold; - line-height: 0.5em; - text-align: center; - color: white; - position: relative; - top: 25%; - } - .balloons:hover { - cursor: pointer; - } - /*BALLOON 1 4*/ - @-webkit-keyframes balloon1 { - 0%, - 100% { - } - 50% { - -webkit-transform: translateY(-20px) rotate(8deg); - } - } - @-moz-keyframes balloon1 { - 0%, - 100% { - -moz-transform: translateY(0) rotate(-6deg); - } - 50% { - -moz-transform: translateY(-20px) rotate(8deg); - } - } - @-o-keyframes balloon1 { - 0%, - 100% { - -o-transform: translateY(0) rotate(-6deg); - } - 50% { - -o-transform: translateY(-20px) rotate(8deg); - } - } - @keyframes balloon1 { - 0%, - 100% { - transform: translateY(0) rotate(-6deg); - } - 50% { - transform: translateY(-20px) rotate(8deg); - } - } - /* BAllOON 2 5*/ - @-webkit-keyframes balloon2 { - 0%, - 100% { - -webkit-transform: translateY(0) rotate(6deg); - } - 50% { - -webkit-transform: translateY(-30px) rotate(-8deg); - } - } - @-moz-keyframes balloon2 { - 0%, - 100% { - -moz-transform: translateY(0) rotate(6deg); - } - 50% { - -moz-transform: translateY(-30px) rotate(-8deg); - } - } - @-o-keyframes balloon2 { - 0%, - 100% { - -o-transform: translateY(0) rotate(6deg); - } - 50% { - -o-transform: translateY(-30px) rotate(-8deg); - } - } - @keyframes balloon2 { - 0%, - 100% { - transform: translateY(0) rotate(6deg); - } - 50% { - transform: translateY(-30px) rotate(-8deg); - } - } - /* BAllOON 0*/ - @-webkit-keyframes balloon3 { - 0%, - 100% { - -webkit-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -webkit-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @-moz-keyframes balloon3 { - 0%, - 100% { - -moz-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -moz-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @-o-keyframes balloon3 { - 0%, - 100% { - -o-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -o-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @keyframes balloon3 { - 0%, - 100% { - transform: translate(0, -10px) rotate(6eg); - } - 50% { - transform: translate(-20px, 30px) rotate(-8deg); - } - } - /* BAllOON 3*/ - @-webkit-keyframes balloon4 { - 0%, - 100% { - -webkit-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -webkit-transform: translate(-15px, 20px) rotate(10deg); - } - } - @-moz-keyframes balloon4 { - 0%, - 100% { - -moz-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -moz-transform: translate(-15px, 10px) rotate(10deg); - } - } - @-o-keyframes balloon4 { - 0%, - 100% { - -o-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -o-transform: translate(-15px, 10px) rotate(10deg); - } - } - @keyframes balloon4 { - 0%, - 100% { - transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - transform: translate(-15px, 10px) rotate(10deg); - } - } - @media (max-width: 1180px) { - .birthdays-container { - margin-top: 6rem; - } - } - @media (max-width: 600px) { +} +/* BAllOON 2 5*/ +@-webkit-keyframes balloon2 { + 0%, + 100% { + -webkit-transform: translateY(0) rotate(6deg); + } + 50% { + -webkit-transform: translateY(-30px) rotate(-8deg); + } +} +@-moz-keyframes balloon2 { + 0%, + 100% { + -moz-transform: translateY(0) rotate(6deg); + } + 50% { + -moz-transform: translateY(-30px) rotate(-8deg); + } +} +@-o-keyframes balloon2 { + 0%, + 100% { + -o-transform: translateY(0) rotate(6deg); + } + 50% { + -o-transform: translateY(-30px) rotate(-8deg); + } +} +@keyframes balloon2 { + 0%, + 100% { + transform: translateY(0) rotate(6deg); + } + 50% { + transform: translateY(-30px) rotate(-8deg); + } +} +/* BAllOON 0*/ +@-webkit-keyframes balloon3 { + 0%, + 100% { + -webkit-transform: translate(0, -10px) rotate(6deg); + } + 50% { + -webkit-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@-moz-keyframes balloon3 { + 0%, + 100% { + -moz-transform: translate(0, -10px) rotate(6deg); + } + 50% { + -moz-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@-o-keyframes balloon3 { + 0%, + 100% { + -o-transform: translate(0, -10px) rotate(6deg); + } + 50% { + -o-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@keyframes balloon3 { + 0%, + 100% { + transform: translate(0, -10px) rotate(6eg); + } + 50% { + transform: translate(-20px, 30px) rotate(-8deg); + } +} +/* BAllOON 3*/ +@-webkit-keyframes balloon4 { + 0%, + 100% { + -webkit-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -webkit-transform: translate(-15px, 20px) rotate(10deg); + } +} +@-moz-keyframes balloon4 { + 0%, + 100% { + -moz-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -moz-transform: translate(-15px, 10px) rotate(10deg); + } +} +@-o-keyframes balloon4 { + 0%, + 100% { + -o-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -o-transform: translate(-15px, 10px) rotate(10deg); + } +} +@keyframes balloon4 { + 0%, + 100% { + transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + transform: translate(-15px, 10px) rotate(10deg); + } +} +@media (max-width: 1180px) { + .birthdays-container { + margin-top: 6rem; + } +} +@media (max-width: 600px) { .birthdays-card { - margin: 0 1rem; - min-width: unset; + margin: 0 1rem; + min-width: unset; } .birthdays-card h5 { font-size: 1rem; @@ -263,7 +263,7 @@ body { } @media (max-width: 320px) { - .balloons > div:nth-child(1) { + .balloons > div:nth-child(1) { left: -2rem; } .balloons > div:nth-child(2) { diff --git a/web-ui/src/components/celebrations/Birthdays.jsx b/web-ui/src/components/celebrations/Birthdays.jsx index f21a14b5e6..098f645412 100644 --- a/web-ui/src/components/celebrations/Birthdays.jsx +++ b/web-ui/src/components/celebrations/Birthdays.jsx @@ -1,45 +1,45 @@ -import React, { useContext } from "react"; -import { Link } from "react-router-dom"; +import React, { useContext } from 'react'; +import { Link } from 'react-router-dom'; -import { getAvatarURL } from "../../api/api.js"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader"; +import { getAvatarURL } from '../../api/api.js'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; -import { AppContext } from "../../context/AppContext"; +import { AppContext } from '../../context/AppContext'; import { selectMemberProfilesLoading, - selectProfile, -} from "../../context/selectors"; -import { randomConfetti } from "../../context/util"; + selectProfile +} from '../../context/selectors'; +import { randomConfetti } from '../../context/util'; -import Avatar from "@mui/material/Avatar"; -import { Card, CardHeader } from "@mui/material"; -import { Grid } from "@mui/material"; -import { styled } from "@mui/material/styles"; -import { Typography } from "@mui/material"; +import Avatar from '@mui/material/Avatar'; +import { Card, CardHeader } from '@mui/material'; +import { Grid } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import { Typography } from '@mui/material'; import { formatBirthday } from "../../helpers/celebration.js"; import "./Birthdays.css"; -const PREFIX = "MemberSummaryCard"; +const PREFIX = 'MemberSummaryCard'; const classes = { - header: `${PREFIX}-header`, + header: `${PREFIX}-header` }; -const Root = styled("div")({ +const Root = styled('div')({ [`& .${classes.search}`]: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' }, [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' }, [`& .${classes.members}`]: { - display: "flex", - flexWrap: "wrap", - justifyContent: "space-evenly", - width: "100%", - }, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + width: '100%' + } }); const Birthdays = ({ birthdays, xPos = 0.75 }) => { @@ -51,17 +51,17 @@ const Birthdays = ({ birthdays, xPos = 0.75 }) => { let user = selectProfile(state, bday.userId); if (user) { return ( - + - Happy Birthday{" "} - {user.firstName + " " + user.lastName}! + Happy Birthday{' '} + {user.firstName + ' ' + user.lastName}! } subheader={ @@ -72,7 +72,7 @@ const Birthdays = ({ birthdays, xPos = 0.75 }) => { disableTypography avatar={ } @@ -110,8 +110,8 @@ const Birthdays = ({ birthdays, xPos = 0.75 }) => { )) : !loading - ? createBirthdayCards - : null} + ? createBirthdayCards + : null} diff --git a/web-ui/src/components/celebrations/Birthdays.test.jsx b/web-ui/src/components/celebrations/Birthdays.test.jsx index 413abb1c48..55c8de130a 100644 --- a/web-ui/src/components/celebrations/Birthdays.test.jsx +++ b/web-ui/src/components/celebrations/Birthdays.test.jsx @@ -23,14 +23,11 @@ const birthdays = [ ] const hideMyBirthday= false -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); diff --git a/web-ui/src/components/celebrations/DoubleCelebration.css b/web-ui/src/components/celebrations/DoubleCelebration.css index 8f1c03cc5d..a3437392db 100644 --- a/web-ui/src/components/celebrations/DoubleCelebration.css +++ b/web-ui/src/components/celebrations/DoubleCelebration.css @@ -1,17 +1,16 @@ - .double-celebration { display: flex; flex-direction: column; } .double-celebration .anniv { - margin-bottom: 10rem; + margin-bottom: 10rem; } .double-celebration .bday { - margin-top: 5rem; + margin-top: 5rem; } .double-celebration h1 { - margin: 0; + margin: 0; } diff --git a/web-ui/src/components/celebrations/DoubleCelebration.jsx b/web-ui/src/components/celebrations/DoubleCelebration.jsx index 0038973c58..80c2a8f494 100644 --- a/web-ui/src/components/celebrations/DoubleCelebration.jsx +++ b/web-ui/src/components/celebrations/DoubleCelebration.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import MyAnniversary from "./MyAnniversary"; -import MyBirthday from "./MyBirthday"; +import React from 'react'; +import MyAnniversary from './MyAnniversary'; +import MyBirthday from './MyBirthday'; -import "./DoubleCelebration.css"; +import './DoubleCelebration.css'; -const DoubleCelebration = (props) => { +const DoubleCelebration = props => { const { hideMyBirthday, hideMyAnniversary, me, myAnniversary } = props; return ( diff --git a/web-ui/src/components/celebrations/DoubleCelebration.test.jsx b/web-ui/src/components/celebrations/DoubleCelebration.test.jsx index 7c324e25d1..73541b8072 100644 --- a/web-ui/src/components/celebrations/DoubleCelebration.test.jsx +++ b/web-ui/src/components/celebrations/DoubleCelebration.test.jsx @@ -1,40 +1,40 @@ -import React from "react"; -import DoubleCelebration from "./DoubleCelebration"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import DoubleCelebration from './DoubleCelebration'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; -const hideMyAnniversary = false -const hideMyBirthday= false +const hideMyAnniversary = false; +const hideMyBirthday = false; const me = { - bioText: "Superior Engineer", - birthDate: [2022, 12, 27], - employeeId: "123123410", - firstName: "Suman", - id: "1b4f99da-ef70-4a76-9b37-8bb783b749ad", - lastName: "Maroju", - location: "St. Louis", - pdlId: "7a6a2d4e-e435-4ec9-94d8-f1ed7c779498", - startDate: [2012, 12, 29], - title: "Software Engineer", - workEmail: "marojus@objectcomputing.com" -} + bioText: 'Superior Engineer', + birthDate: [2022, 12, 27], + employeeId: '123123410', + firstName: 'Suman', + id: '1b4f99da-ef70-4a76-9b37-8bb783b749ad', + lastName: 'Maroju', + location: 'St. Louis', + pdlId: '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', + startDate: [2012, 12, 29], + title: 'Software Engineer', + workEmail: 'marojus@objectcomputing.com' +}; const myAnniversary = { - "name": "Suman Maroju", - "anniversary": "12/29/2012", - "yearsOfService": 10, - "userId": "1b4f99da-ef70-4a76-9b37-8bb783b749ad" - } + name: 'Suman Maroju', + anniversary: '12/29/2012', + yearsOfService: 10, + userId: '1b4f99da-ef70-4a76-9b37-8bb783b749ad' +}; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/celebrations/MyAnniversary.css b/web-ui/src/components/celebrations/MyAnniversary.css index b95e8cdc9b..589a4ccaf2 100644 --- a/web-ui/src/components/celebrations/MyAnniversary.css +++ b/web-ui/src/components/celebrations/MyAnniversary.css @@ -6,37 +6,37 @@ body { transition: 1s; } -.my-anniversary.open{ +.my-anniversary.open { animation: bg-change 1s 1; background-color: #72c8d5; transition: 1s; } -@keyframes bg-change{ - 0%{ - background-color: #F0E2DB; +@keyframes bg-change { + 0% { + background-color: #f0e2db; } - 100%{ - background-color: #72c8d5; + 100% { + background-color: #72c8d5; } } .hide-my-anniversary { - display: flex; - justify-content: flex-end; - font-weight: bold; - } + display: flex; + justify-content: flex-end; + font-weight: bold; +} .hide-my-anniversary:hover { - cursor: pointer; - } + cursor: pointer; +} .my-anniversary-container { - position: relative; + position: relative; } .my-anniversary h1 { - color: #2559a7; - font-weight: bolder; - position: relative; - top: 10rem; - text-align: center; - font-size: 3.5em; + color: #2559a7; + font-weight: bolder; + position: relative; + top: 10rem; + text-align: center; + font-size: 3.5em; } .my-anniversary-gift { position: absolute; @@ -50,7 +50,7 @@ body { transition: 1s; animation: box 0.5s infinite; } -.my-anniversary-gift .box{ +.my-anniversary-gift .box { transform-origin: 0% 0%; cursor: pointer; animation: box 0.5s infinite; @@ -59,16 +59,16 @@ body { 0% { transform: rotate(0deg) translate(-50%, -50%); } - 25%{ + 25% { transform: rotate(1deg) translate(-50%, -50%); } - 50%{ + 50% { transform: rotate(0deg) translate(-50%, -50%); } - 70%{ + 70% { transform: rotate(-1deg) translate(-50%, -50%); } - 100%{ + 100% { transform: rotate(0deg) translate(-50%, -50%); } } @@ -79,34 +79,42 @@ body { background: #2559a7; border-radius: 5px 5px 0 0; transform: translate3d(-5%, 0, 0); - background-image: linear-gradient(to right, #2559a7 0%, #2559a7 44%, #feb672 44%, #feb672 56%, #2559a7 56%, #2559a7 100%); + background-image: linear-gradient( + to right, + #2559a7 0%, + #2559a7 44%, + #feb672 44%, + #feb672 56%, + #2559a7 56%, + #2559a7 100% + ); transition: 1s; } -.my-anniversary-gift-top.boxOpen{ +.my-anniversary-gift-top.boxOpen { animation: box-open 1s; - opacity:0; + opacity: 0; } -@keyframes box-open{ - 0%{ - top:0px; - opacity:1; +@keyframes box-open { + 0% { + top: 0px; + opacity: 1; } - 100%{ - top:-50px; - opacity:0; + 100% { + top: -50px; + opacity: 0; } } .my-anniversary-gift-top::before, .my-anniversary-gift-top::after { - content: ""; - width: 15px; - height: 15px; - border: 10px solid #feb672; - border-radius: 50% 50% 0 50%; - position: absolute; - top: 0; - left: 50%; - transform: translate3d(-100%, -100%, 0) skew(10deg, 10deg); + content: ''; + width: 15px; + height: 15px; + border: 10px solid #feb672; + border-radius: 50% 50% 0 50%; + position: absolute; + top: 0; + left: 50%; + transform: translate3d(-100%, -100%, 0) skew(10deg, 10deg); } .my-anniversary-gift-top::after { @@ -123,7 +131,7 @@ body { transform: translate3d(-50%, 0, 0) scale(2.5); transform-origin: center center; z-index: -1; - opacity:1; + opacity: 1; transition: 3s; } .my-anniversary-gift-text.open span { @@ -134,24 +142,32 @@ body { .my-anniversary-gift-box { width: 100%; height: 75%; - position:relative; - background-image: linear-gradient(to right, #2559a7 0%, #2559a7 45%, #feb672 45%, #feb672 55%, #2559a7 55%, #2559a7 100%); + position: relative; + background-image: linear-gradient( + to right, + #2559a7 0%, + #2559a7 45%, + #feb672 45%, + #feb672 55%, + #2559a7 55%, + #2559a7 100% + ); border-radius: 0 0 5px 5px; transition: 1s; } -.my-anniversary-gift-box.boxDown{ - animation: box-down 1s; - opacity:0; +.my-anniversary-gift-box.boxDown { + animation: box-down 1s; + opacity: 0; } -@keyframes box-down{ - 0%{ - top:0px; - opacity:1; +@keyframes box-down { + 0% { + top: 0px; + opacity: 1; + } + 100% { + top: 50px; + opacity: 0; } - 100%{ - top:50px; - opacity:0; - } } @media (max-width: 800px) { @@ -182,4 +198,4 @@ body { .my-anniversary h1 { font-size: 1.25rem; } -} \ No newline at end of file +} diff --git a/web-ui/src/components/celebrations/MyAnniversary.jsx b/web-ui/src/components/celebrations/MyAnniversary.jsx index 10c268af9c..6ac97022f7 100644 --- a/web-ui/src/components/celebrations/MyAnniversary.jsx +++ b/web-ui/src/components/celebrations/MyAnniversary.jsx @@ -1,11 +1,11 @@ -import React, { useState } from "react"; +import React, { useState } from 'react'; -import "./MyAnniversary.css"; +import './MyAnniversary.css'; -const MyAnniversary = (props) => { +const MyAnniversary = props => { const { hideMyAnniversary, myAnniversary } = props; const fullName = myAnniversary[0]?.name; - const firstName = fullName?.substring(0, fullName.indexOf(" ")); + const firstName = fullName?.substring(0, fullName.indexOf(' ')); const yearsOfService = myAnniversary[0]?.yearsOfService; const [open, setOpen] = useState(false); @@ -18,31 +18,31 @@ const MyAnniversary = (props) => { return (
X
setOpen(!open)} >
- {open ? text : ""} + {open ? text : ''}
diff --git a/web-ui/src/components/celebrations/MyAnniversary.test.jsx b/web-ui/src/components/celebrations/MyAnniversary.test.jsx index 07993f3f9c..ae44737e12 100644 --- a/web-ui/src/components/celebrations/MyAnniversary.test.jsx +++ b/web-ui/src/components/celebrations/MyAnniversary.test.jsx @@ -1,23 +1,23 @@ -import React from "react"; -import MyAnniversary from "./MyAnniversary"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import MyAnniversary from './MyAnniversary'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; -const hideMyAnniversary = false +const hideMyAnniversary = false; const myAnniversary = { - "name": "Suman Maroju", - "anniversary": "12/29/2012", - "yearsOfService": 10, - "userId": "1b4f99da-ef70-4a76-9b37-8bb783b749ad" - } + name: 'Suman Maroju', + anniversary: '12/29/2012', + yearsOfService: 10, + userId: '1b4f99da-ef70-4a76-9b37-8bb783b749ad' +}; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/celebrations/MyBirthday.css b/web-ui/src/components/celebrations/MyBirthday.css index ed59d51d88..3f68741969 100644 --- a/web-ui/src/components/celebrations/MyBirthday.css +++ b/web-ui/src/components/celebrations/MyBirthday.css @@ -1,12 +1,12 @@ @import url('https://fonts.googleapis.com/css?family=Wendy+One'); body { - font-family: "Wendy One", sans-serif; - } + font-family: 'Wendy One', sans-serif; +} - .my-birthday p { - text-transform: uppercase; - } +.my-birthday p { + text-transform: uppercase; +} .hide-my-birthday { display: flex; justify-content: flex-end; @@ -16,274 +16,274 @@ body { cursor: pointer; } .my-birthday-container { - position: relative; + position: relative; } .my-birthday h1 { - color: #2559a7; - font-weight: bolder; - position: relative; - top: 12rem; - text-align: center; - font-size: 3.5em; + color: #2559a7; + font-weight: bolder; + position: relative; + top: 12rem; + text-align: center; + font-size: 3.5em; } .my-balloons { - margin: 0 auto; - position: absolute; - top: -2rem; - } - .my-balloons > div { - width: 104px; - height: 140px; - background: rgba(182, 15, 97, 0.9); - border-radius: 0; - border-radius: 80% 80% 80% 80%; - margin: 0 auto; - position: absolute; - padding: 10px; - box-shadow: inset 17px 7px 10px rgba(182, 15, 97, 0.9); - -webkit-transform-origin: bottom center; + margin: 0 auto; + position: absolute; + top: -2rem; +} +.my-balloons > div { + width: 104px; + height: 140px; + background: rgba(182, 15, 97, 0.9); + border-radius: 0; + border-radius: 80% 80% 80% 80%; + margin: 0 auto; + position: absolute; + padding: 10px; + box-shadow: inset 17px 7px 10px rgba(182, 15, 97, 0.9); + -webkit-transform-origin: bottom center; +} +.my-balloons > div:nth-child(1) { + background: rgba(182, 15, 97, 0.9); + left: 0; + top: 7rem; + box-shadow: inset 10px 10px 10px rgba(135, 11, 72, 0.9); + -webkit-animation: balloon1 6s ease-in-out infinite; + -moz-animation: balloon1 6s ease-in-out infinite; + -o-animation: balloon1 6s ease-in-out infinite; + animation: balloon1 6s ease-in-out infinite; +} +.my-balloons > div:nth-child(1):before { + color: rgba(182, 15, 97, 0.9); +} +.my-balloons > div:nth-child(2) { + background: rgba(242, 194, 58, 0.9); + left: 8rem; + top: 4rem; + box-shadow: inset 10px 10px 10px rgba(192, 154, 43, 0.9); + -webkit-animation: balloon2 6s ease-in-out infinite; + -moz-animation: balloon2 6s ease-in-out infinite; + -o-animation: balloon2 6s ease-in-out infinite; + animation: balloon2 6s ease-in-out infinite; +} +.my-balloons > div:nth-child(2):before { + color: rgba(242, 194, 58, 0.9); +} +.my-balloons > div:nth-child(3) { + background: rgba(45, 181, 167, 0.9); + left: 16rem; + box-shadow: inset 10px 10px 10px rgba(35, 140, 129, 0.9); + -webkit-animation: balloon4 6s ease-in-out infinite; + -moz-animation: balloon4 6s ease-in-out infinite; + -o-animation: balloon4 6s ease-in-out infinite; + animation: balloon4 6s ease-in-out infinite; +} +.my-balloons > div:nth-child(3):before { + color: rgba(45, 181, 167, 0.9); +} +.my-balloons > div:nth-child(4) { + background: rgba(190, 61, 244, 0.9); + left: 24rem; + top: 4rem; + box-shadow: inset 10px 10px 10px rgba(160, 31, 204, 0.9); + -webkit-animation: balloon1 5s ease-in-out infinite; + -moz-animation: balloon1 5s ease-in-out infinite; + -o-animation: balloon1 5s ease-in-out infinite; + animation: balloon1 5s ease-in-out infinite; +} +.my-balloons > div:nth-child(4):before { + color: rgba(190, 61, 244, 0.9); +} +.my-balloons > div:nth-child(5) { + background: rgba(180, 224, 67, 0.9); + left: 32rem; + top: 7rem; + box-shadow: inset 10px 10px 10px rgba(140, 179, 47, 0.9); + -webkit-animation: balloon3 5s ease-in-out infinite; + -moz-animation: balloon3 5s ease-in-out infinite; + -o-animation: balloon3 5s ease-in-out infinite; + animation: balloon3 5s ease-in-out infinite; +} +.my-balloons > div:nth-child(5):before { + color: rgba(180, 224, 67, 0.9); +} +.my-balloons > div:before { + position: absolute; + bottom: -11px; + left: 45px; + content: '▲'; + font-size: 1em; +} +.my-balloons:hover { + cursor: pointer; +} +.my-birthday-container p { + font-size: 1em; + font-weight: bold; + line-height: 0.5em; + text-align: center; + color: white; + position: relative; + top: 25%; +} +/*BALLOON 1 4*/ +@-webkit-keyframes balloon1 { + 0%, + 100% { } - .my-balloons > div:nth-child(1) { - background: rgba(182, 15, 97, 0.9); - left: 0; - top: 7rem; - box-shadow: inset 10px 10px 10px rgba(135, 11, 72, 0.9); - -webkit-animation: balloon1 6s ease-in-out infinite; - -moz-animation: balloon1 6s ease-in-out infinite; - -o-animation: balloon1 6s ease-in-out infinite; - animation: balloon1 6s ease-in-out infinite; + 50% { + -webkit-transform: translateY(-20px) rotate(8deg); } - .my-balloons > div:nth-child(1):before { - color: rgba(182, 15, 97, 0.9); +} +@-moz-keyframes balloon1 { + 0%, + 100% { + -moz-transform: translateY(0) rotate(-6deg); } - .my-balloons > div:nth-child(2) { - background: rgba(242, 194, 58, 0.9); - left: 8rem; - top: 4rem; - box-shadow: inset 10px 10px 10px rgba(192, 154, 43, 0.9); - -webkit-animation: balloon2 6s ease-in-out infinite; - -moz-animation: balloon2 6s ease-in-out infinite; - -o-animation: balloon2 6s ease-in-out infinite; - animation: balloon2 6s ease-in-out infinite; + 50% { + -moz-transform: translateY(-20px) rotate(8deg); } - .my-balloons > div:nth-child(2):before { - color: rgba(242, 194, 58, 0.9); +} +@-o-keyframes balloon1 { + 0%, + 100% { + -o-transform: translateY(0) rotate(-6deg); } - .my-balloons > div:nth-child(3) { - background: rgba(45, 181, 167, 0.9); - left: 16rem; - box-shadow: inset 10px 10px 10px rgba(35, 140, 129, 0.9); - -webkit-animation: balloon4 6s ease-in-out infinite; - -moz-animation: balloon4 6s ease-in-out infinite; - -o-animation: balloon4 6s ease-in-out infinite; - animation: balloon4 6s ease-in-out infinite; + 50% { + -o-transform: translateY(-20px) rotate(8deg); } - .my-balloons > div:nth-child(3):before { - color: rgba(45, 181, 167, 0.9); +} +@keyframes balloon1 { + 0%, + 100% { + transform: translateY(0) rotate(-6deg); } - .my-balloons > div:nth-child(4) { - background: rgba(190, 61, 244, 0.9); - left: 24rem; - top: 4rem; - box-shadow: inset 10px 10px 10px rgba(160, 31, 204, 0.9); - -webkit-animation: balloon1 5s ease-in-out infinite; - -moz-animation: balloon1 5s ease-in-out infinite; - -o-animation: balloon1 5s ease-in-out infinite; - animation: balloon1 5s ease-in-out infinite; + 50% { + transform: translateY(-20px) rotate(8deg); } - .my-balloons > div:nth-child(4):before { - color: rgba(190, 61, 244, 0.9); +} +/* BAllOON 2 5*/ +@-webkit-keyframes balloon2 { + 0%, + 100% { + -webkit-transform: translateY(0) rotate(6deg); } - .my-balloons > div:nth-child(5) { - background: rgba(180, 224, 67, 0.9); - left: 32rem; - top: 7rem; - box-shadow: inset 10px 10px 10px rgba(140, 179, 47, 0.9); - -webkit-animation: balloon3 5s ease-in-out infinite; - -moz-animation: balloon3 5s ease-in-out infinite; - -o-animation: balloon3 5s ease-in-out infinite; - animation: balloon3 5s ease-in-out infinite; + 50% { + -webkit-transform: translateY(-30px) rotate(-8deg); } - .my-balloons > div:nth-child(5):before { - color: rgba(180, 224, 67, 0.9); +} +@-moz-keyframes balloon2 { + 0%, + 100% { + -moz-transform: translateY(0) rotate(6deg); } - .my-balloons > div:before { - position: absolute; - bottom: -11px; - left: 45px; - content: "▲"; - font-size: 1em; + 50% { + -moz-transform: translateY(-30px) rotate(-8deg); } - .my-balloons:hover { - cursor: pointer; +} +@-o-keyframes balloon2 { + 0%, + 100% { + -o-transform: translateY(0) rotate(6deg); } - .my-birthday-container p { - font-size: 1em; - font-weight: bold; - line-height: 0.5em; - text-align: center; - color: white; - position: relative; - top: 25%; + 50% { + -o-transform: translateY(-30px) rotate(-8deg); + } +} +@keyframes balloon2 { + 0%, + 100% { + transform: translateY(0) rotate(6deg); + } + 50% { + transform: translateY(-30px) rotate(-8deg); + } +} +/* BAllOON 0*/ +@-webkit-keyframes balloon3 { + 0%, + 100% { + -webkit-transform: translate(0, -10px) rotate(6deg); + } + 50% { + -webkit-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@-moz-keyframes balloon3 { + 0%, + 100% { + -moz-transform: translate(0, -10px) rotate(6deg); + } + 50% { + -moz-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@-o-keyframes balloon3 { + 0%, + 100% { + -o-transform: translate(0, -10px) rotate(6deg); } - /*BALLOON 1 4*/ - @-webkit-keyframes balloon1 { - 0%, - 100% { - } - 50% { - -webkit-transform: translateY(-20px) rotate(8deg); - } - } - @-moz-keyframes balloon1 { - 0%, - 100% { - -moz-transform: translateY(0) rotate(-6deg); - } - 50% { - -moz-transform: translateY(-20px) rotate(8deg); - } - } - @-o-keyframes balloon1 { - 0%, - 100% { - -o-transform: translateY(0) rotate(-6deg); - } - 50% { - -o-transform: translateY(-20px) rotate(8deg); - } - } - @keyframes balloon1 { - 0%, - 100% { - transform: translateY(0) rotate(-6deg); - } - 50% { - transform: translateY(-20px) rotate(8deg); - } - } - /* BAllOON 2 5*/ - @-webkit-keyframes balloon2 { - 0%, - 100% { - -webkit-transform: translateY(0) rotate(6deg); - } - 50% { - -webkit-transform: translateY(-30px) rotate(-8deg); - } - } - @-moz-keyframes balloon2 { - 0%, - 100% { - -moz-transform: translateY(0) rotate(6deg); - } - 50% { - -moz-transform: translateY(-30px) rotate(-8deg); - } - } - @-o-keyframes balloon2 { - 0%, - 100% { - -o-transform: translateY(0) rotate(6deg); - } - 50% { - -o-transform: translateY(-30px) rotate(-8deg); - } - } - @keyframes balloon2 { - 0%, - 100% { - transform: translateY(0) rotate(6deg); - } - 50% { - transform: translateY(-30px) rotate(-8deg); - } - } - /* BAllOON 0*/ - @-webkit-keyframes balloon3 { - 0%, - 100% { - -webkit-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -webkit-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @-moz-keyframes balloon3 { - 0%, - 100% { - -moz-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -moz-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @-o-keyframes balloon3 { - 0%, - 100% { - -o-transform: translate(0, -10px) rotate(6deg); - } - 50% { - -o-transform: translate(-20px, 30px) rotate(-8deg); - } - } - @keyframes balloon3 { - 0%, - 100% { - transform: translate(0, -10px) rotate(6eg); - } - 50% { - transform: translate(-20px, 30px) rotate(-8deg); - } - } - /* BAllOON 3*/ - @-webkit-keyframes balloon4 { - 0%, - 100% { - -webkit-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -webkit-transform: translate(-15px, 20px) rotate(10deg); - } - } - @-moz-keyframes balloon4 { - 0%, - 100% { - -moz-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -moz-transform: translate(-15px, 10px) rotate(10deg); - } - } - @-o-keyframes balloon4 { - 0%, - 100% { - -o-transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - -o-transform: translate(-15px, 10px) rotate(10deg); - } - } - @keyframes balloon4 { - 0%, - 100% { - transform: translate(10px, -10px) rotate(-8deg); - } - 50% { - transform: translate(-15px, 10px) rotate(10deg); - } - } - @media (max-width: 800px) { + 50% { + -o-transform: translate(-20px, 30px) rotate(-8deg); + } +} +@keyframes balloon3 { + 0%, + 100% { + transform: translate(0, -10px) rotate(6eg); + } + 50% { + transform: translate(-20px, 30px) rotate(-8deg); + } +} +/* BAllOON 3*/ +@-webkit-keyframes balloon4 { + 0%, + 100% { + -webkit-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -webkit-transform: translate(-15px, 20px) rotate(10deg); + } +} +@-moz-keyframes balloon4 { + 0%, + 100% { + -moz-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -moz-transform: translate(-15px, 10px) rotate(10deg); + } +} +@-o-keyframes balloon4 { + 0%, + 100% { + -o-transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + -o-transform: translate(-15px, 10px) rotate(10deg); + } +} +@keyframes balloon4 { + 0%, + 100% { + transform: translate(10px, -10px) rotate(-8deg); + } + 50% { + transform: translate(-15px, 10px) rotate(10deg); + } +} +@media (max-width: 800px) { .my-birthday h1 { font-size: 2.5rem; } } - @media (max-width: 600px) { +@media (max-width: 600px) { .my-birthday-container { bottom: 0rem; } .my-birthday-container p { - font-size: .5rem; + font-size: 0.5rem; text-align: center; position: relative; top: 25%; @@ -294,8 +294,8 @@ body { font-size: 1.75rem; } .my-birthday-container .my-balloons > div { - width: 64px; - height: 85px; + width: 64px; + height: 85px; } .my-balloons > div:before { left: 1.65rem; @@ -325,8 +325,8 @@ body { font-size: 1.25rem; } .my-birthday-container .my-balloons > div { - width: 64px; - height: 85px; + width: 64px; + height: 85px; } .my-balloons > div:nth-child(1) { left: -1rem; @@ -343,4 +343,4 @@ body { .my-balloons > div:nth-child(5) { left: 16rem; } -} \ No newline at end of file +} diff --git a/web-ui/src/components/celebrations/MyBirthday.jsx b/web-ui/src/components/celebrations/MyBirthday.jsx index cadbbdca62..3848e2c40e 100644 --- a/web-ui/src/components/celebrations/MyBirthday.jsx +++ b/web-ui/src/components/celebrations/MyBirthday.jsx @@ -1,11 +1,11 @@ -import React from "react"; +import React from 'react'; -import { randomConfetti } from "../../context/util"; +import { randomConfetti } from '../../context/util'; -import "./MyBirthday.css"; -import "./Birthdays.css"; +import './MyBirthday.css'; +import './Birthdays.css'; -const MyBirthday = (props) => { +const MyBirthday = props => { const { me, hideMyBirthday } = props; return ( diff --git a/web-ui/src/components/celebrations/MyBirthday.test.jsx b/web-ui/src/components/celebrations/MyBirthday.test.jsx index cc21883ca6..befc29ad80 100644 --- a/web-ui/src/components/celebrations/MyBirthday.test.jsx +++ b/web-ui/src/components/celebrations/MyBirthday.test.jsx @@ -1,21 +1,19 @@ -import React from "react"; -import MyBirthday from "./MyBirthday"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import MyBirthday from './MyBirthday'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const me = { - id: "0987654321", - name: "Moi", - lastName: "Monseiur", - } + id: '0987654321', + name: 'Moi', + lastName: 'Monseiur' +}; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); diff --git a/web-ui/src/components/checkin/Checkin.css b/web-ui/src/components/checkin/Checkin.css index 0b93a8884c..39df24e7a6 100644 --- a/web-ui/src/components/checkin/Checkin.css +++ b/web-ui/src/components/checkin/Checkin.css @@ -17,7 +17,7 @@ .date-input { display: flex; align-items: center; - cursor: pointer + cursor: pointer; } .info { diff --git a/web-ui/src/components/checkin/CheckinCycle.jsx b/web-ui/src/components/checkin/CheckinCycle.jsx index ab135e401a..057f87bb2d 100644 --- a/web-ui/src/components/checkin/CheckinCycle.jsx +++ b/web-ui/src/components/checkin/CheckinCycle.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import cycle from "./checkin-cycle.png"; +import React from 'react'; +import cycle from './checkin-cycle.png'; -const CheckinCycle = ({ style = {height: "35vw", width: "35vw"} }) => ( +const CheckinCycle = ({ style = { height: '35vw', width: '35vw' } }) => (
{ - return (); - }] + decorators: [ + Story => { + return ( + + + + ); + } + ] }; -const Template = (args) => ; +const Template = args => ; export const NoDimensions = Template.bind({}); NoDimensions.args = { - style: undefined -} + style: undefined +}; export const SetDimensions = Template.bind({}); SetDimensions.args = { - style: {height: "5rem", width: "5rem"} + style: { height: '5rem', width: '5rem' } }; - diff --git a/web-ui/src/components/checkin/CheckinCycle.test.jsx b/web-ui/src/components/checkin/CheckinCycle.test.jsx index b844eee00f..f6a7dda258 100644 --- a/web-ui/src/components/checkin/CheckinCycle.test.jsx +++ b/web-ui/src/components/checkin/CheckinCycle.test.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import CheckinCycle from "./CheckinCycle"; +import React from 'react'; +import CheckinCycle from './CheckinCycle'; -const style = { backgroundColor: "red" }; -it("renders correctly", () => { +const style = { backgroundColor: 'red' }; +it('renders correctly', () => { snapshot(); }); diff --git a/web-ui/src/components/checkin/CheckinHistory.jsx b/web-ui/src/components/checkin/CheckinHistory.jsx index f3e7680545..cc3d0ee881 100644 --- a/web-ui/src/components/checkin/CheckinHistory.jsx +++ b/web-ui/src/components/checkin/CheckinHistory.jsx @@ -1,18 +1,20 @@ -import React, { useContext } from "react"; -import { useHistory, useParams } from "react-router-dom"; +import React, { useContext } from 'react'; +import { useHistory, useParams } from 'react-router-dom'; +import { UPDATE_CHECKIN } from '../../context/actions'; +import { AppContext } from '../../context/AppContext'; +import { updateCheckin } from '../../api/checkins'; import { - UPDATE_CHECKIN, -} from "../../context/actions"; -import { AppContext } from "../../context/AppContext"; -import { updateCheckin } from "../../api/checkins"; -import { selectCsrfToken, selectCheckinsForMember, selectProfile } from "../../context/selectors"; -import IconButton from "@mui/material/IconButton"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; -import { MobileDateTimePicker } from "@mui/x-date-pickers"; -import TextField from "@mui/material/TextField"; + selectCsrfToken, + selectCheckinsForMember, + selectProfile +} from '../../context/selectors'; +import IconButton from '@mui/material/IconButton'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import { MobileDateTimePicker } from '@mui/x-date-pickers'; +import TextField from '@mui/material/TextField'; -import "./Checkin.css"; +import './Checkin.css'; const CheckinsHistory = () => { const { state, dispatch } = useContext(AppContext); @@ -32,7 +34,9 @@ const CheckinsHistory = () => { // return new date unless you are running a Jest test let currentDate = null; try { - currentDate = process?.env?.VITEST_WORKER_ID ? new Date(2020, 9, 21) : new Date(); + currentDate = process?.env?.VITEST_WORKER_ID + ? new Date(2020, 9, 21) + : new Date(); } catch (e) { currentDate = new Date(); } @@ -40,9 +44,9 @@ const CheckinsHistory = () => { return currentDate; }; - const leftArrowClass = "arrow " + (index > 0 ? "enabled" : "disabled"); + const leftArrowClass = 'arrow ' + (index > 0 ? 'enabled' : 'disabled'); const rightArrowClass = - "arrow " + (index < checkins.length - 1 ? "enabled" : "disabled"); + 'arrow ' + (index < checkins.length - 1 ? 'enabled' : 'disabled'); const previousCheckin = () => { if (index > 0) { @@ -56,7 +60,7 @@ const CheckinsHistory = () => { } }; - const pickDate = async (date) => { + const pickDate = async date => { if (csrf) { const year = date.getFullYear(); const month = date.getMonth() + 1; @@ -65,52 +69,55 @@ const CheckinsHistory = () => { const minutes = date.getMinutes(); const checkin = checkins[index]; const dateArray = [year, month, day, hours, minutes, 0]; - const res = await updateCheckin({ - ...checkin, - pdlId: selectedProfile?.pdlId, - checkInDate: dateArray, - }, csrf); - const updatedCheckin = res.payload && res.payload.data && !res.error - ? res.payload.data : null; - updatedCheckin && dispatch({type: UPDATE_CHECKIN, payload: updatedCheckin}); + const res = await updateCheckin( + { + ...checkin, + pdlId: selectedProfile?.pdlId, + checkInDate: dateArray + }, + csrf + ); + const updatedCheckin = + res.payload && res.payload.data && !res.error ? res.payload.data : null; + updatedCheckin && + dispatch({ type: UPDATE_CHECKIN, payload: updatedCheckin }); } }; return ( - getCheckinDate() && ( -
- - - - - = checkins.length - 1} - aria-label="Next Check-in`" - onClick={nextCheckin} - size="large"> - - + getCheckinDate() && ( +
+ + + + + = checkins.length - 1} + aria-label="Next Check-in`" + onClick={nextCheckin} + size="large" + > + +
) ); diff --git a/web-ui/src/components/checkin/CheckinHistory.stories.jsx b/web-ui/src/components/checkin/CheckinHistory.stories.jsx index 6e79d9731f..8a0fe41f04 100644 --- a/web-ui/src/components/checkin/CheckinHistory.stories.jsx +++ b/web-ui/src/components/checkin/CheckinHistory.stories.jsx @@ -1,90 +1,79 @@ -import React, {useContext, useEffect} from 'react'; -import {AppContext, AppContextProvider, UPDATE_CHECKINS} from '../../context/AppContext'; +import React, { useContext, useEffect } from 'react'; +import { + AppContext, + AppContextProvider, + UPDATE_CHECKINS +} from '../../context/AppContext'; import CheckinHistory from './CheckinHistory'; -import { createMemoryHistory } from "history"; -import { Router } from "react-router-dom"; +import { createMemoryHistory } from 'history'; +import { Router } from 'react-router-dom'; const history = createMemoryHistory('/checkins'); export default { - title: 'Check-Ins/CheckinHistory', - component: CheckinHistory, - decorators: [(Story) => { - return (); - }] + title: 'Check-Ins/CheckinHistory', + component: CheckinHistory, + decorators: [ + Story => { + return ( + + + + + + ); + } + ] }; -const checkins = [ { - "id": "bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78", - "teamMemberId": "43ee8e79-b33d-44cd-b23c-e183894ebfef", - "pdlId": "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - "checkInDate": [ - 2020, - 9, - 29, - 11, - 32, - 29, - 40000000 - ], - "completed": true - }, - { - "id": "bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78", - "teamMemberId": "43ee8e79-b33d-44cd-b23c-e183894ebfef", - "pdlId": "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - "checkInDate": [ - 2020, - 10, - 29, - 11, - 32, - 29, - 40000000 - ], - "completed": true - }, - { - "id": "bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78", - "teamMemberId": "43ee8e79-b33d-44cd-b23c-e183894ebfef", - "pdlId": "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - "checkInDate": [ - 2020, - 11, - 29, - 11, - 32, - 29, - 40000000 - ], - "completed": false - } +const checkins = [ + { + id: 'bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78', + teamMemberId: '43ee8e79-b33d-44cd-b23c-e183894ebfef', + pdlId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + checkInDate: [2020, 9, 29, 11, 32, 29, 40000000], + completed: true + }, + { + id: 'bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78', + teamMemberId: '43ee8e79-b33d-44cd-b23c-e183894ebfef', + pdlId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + checkInDate: [2020, 10, 29, 11, 32, 29, 40000000], + completed: true + }, + { + id: 'bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78', + teamMemberId: '43ee8e79-b33d-44cd-b23c-e183894ebfef', + pdlId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + checkInDate: [2020, 11, 29, 11, 32, 29, 40000000], + completed: false + } ]; -const onlyOneCheckIn = [checkins[2]] +const onlyOneCheckIn = [checkins[2]]; -const SetCheckins = ({checkins}) => { - const { dispatch } = useContext(AppContext); - useEffect(() => { - dispatch({ type: UPDATE_CHECKINS, payload: checkins }); - }, [checkins, dispatch]); - return ""; -} +const SetCheckins = ({ checkins }) => { + const { dispatch } = useContext(AppContext); + useEffect(() => { + dispatch({ type: UPDATE_CHECKINS, payload: checkins }); + }, [checkins, dispatch]); + return ''; +}; -const Template = (args) => ( - - - - +const Template = args => ( + + + + ); export const MultipleCheckIns = Template.bind({}); MultipleCheckIns.args = { - history, - checkins + history, + checkins }; export const SingleCheckIn = Template.bind({}); SingleCheckIn.args = { - history, - checkins: onlyOneCheckIn + history, + checkins: onlyOneCheckIn }; diff --git a/web-ui/src/components/checkin/CheckinHistory.test.jsx b/web-ui/src/components/checkin/CheckinHistory.test.jsx index 433d4a45b0..70463ad9d5 100644 --- a/web-ui/src/components/checkin/CheckinHistory.test.jsx +++ b/web-ui/src/components/checkin/CheckinHistory.test.jsx @@ -1,13 +1,13 @@ -import React from "react"; -import CheckinsHistory from "./CheckinHistory"; -import { AppContextProvider } from "../../context/AppContext"; -import { Router } from "react-router-dom"; -import { createBrowserHistory } from "history"; -import { LocalizationProvider } from "@mui/x-date-pickers"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import React from 'react'; +import CheckinsHistory from './CheckinHistory'; +import { AppContextProvider } from '../../context/AppContext'; +import { Router } from 'react-router-dom'; +import { createBrowserHistory } from 'history'; +import { LocalizationProvider } from '@mui/x-date-pickers'; +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -const mockMemberId = "bf9975f8-a5b2-4551-b729-afd56b49e2cc"; -const mockCheckinId = "3a1906df-d45c-4ff5-a6f8-7dacba97ff1a"; +const mockMemberId = 'bf9975f8-a5b2-4551-b729-afd56b49e2cc'; +const mockCheckinId = '3a1906df-d45c-4ff5-a6f8-7dacba97ff1a'; const initialState = { state: { @@ -15,36 +15,36 @@ const initialState = { { id: mockCheckinId, memberId: mockMemberId, - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f28", - description: "updated string", - checkInDate: [2020, 9, 8], + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f28', + description: 'updated string', + checkInDate: [2020, 9, 8] }, { - id: "3a1906df-d45c-4ff5-a6f8-7dacba97ff1b", - memberId: "bf9975f8-a5b2-4551-b729-afd56b49e2cc", - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f29", - description: "second updated string", - checkInDate: [2020, 10, 18], - }, + id: '3a1906df-d45c-4ff5-a6f8-7dacba97ff1b', + memberId: 'bf9975f8-a5b2-4551-b729-afd56b49e2cc', + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f29', + description: 'second updated string', + checkInDate: [2020, 10, 18] + } ], userProfile: { - name: "holmes", - role: ["MEMBER"], + name: 'holmes', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, memberProfiles: [ { id: mockMemberId, - name: "holmes" + name: 'holmes' } ], - index: 0, - }, + index: 0 + } }; -describe("CheckinHistory", () => { - it("renders correctly", async () => { +describe('CheckinHistory', () => { + it('renders correctly', async () => { const customHistory = createBrowserHistory(); snapshot( diff --git a/web-ui/src/components/checkin/CheckinProfile.jsx b/web-ui/src/components/checkin/CheckinProfile.jsx index de96c00cc4..2de3b7863b 100644 --- a/web-ui/src/components/checkin/CheckinProfile.jsx +++ b/web-ui/src/components/checkin/CheckinProfile.jsx @@ -1,12 +1,12 @@ -import React, { useContext, useEffect, useState } from "react"; -import { getMember } from "../../api/member"; -import { AppContext } from "../../context/AppContext"; -import { getAvatarURL } from "../../api/api.js"; +import React, { useContext, useEffect, useState } from 'react'; +import { getMember } from '../../api/member'; +import { AppContext } from '../../context/AppContext'; +import { getAvatarURL } from '../../api/api.js'; -import Avatar from "@mui/material/Avatar"; +import Avatar from '@mui/material/Avatar'; -import "./Checkin.css"; -const displayName = "CheckinProfile"; +import './Checkin.css'; +const displayName = 'CheckinProfile'; const CheckinProfile = () => { const { state } = useContext(AppContext); @@ -14,8 +14,8 @@ const CheckinProfile = () => { const { name, pdlId, title, workEmail } = selectedProfile ? selectedProfile : userProfile && userProfile.memberProfile - ? userProfile.memberProfile - : {}; + ? userProfile.memberProfile + : {}; const [pdl, setPDL] = useState(); // Get PDL's name @@ -27,7 +27,7 @@ const CheckinProfile = () => { res.payload && res.payload.data && !res.error ? res.payload.data : undefined; - setPDL(pdlProfile ? pdlProfile.name : ""); + setPDL(pdlProfile ? pdlProfile.name : ''); } } if (csrf) { @@ -39,7 +39,7 @@ const CheckinProfile = () => {

{name}

diff --git a/web-ui/src/components/checkin/CheckinProfile.stories.jsx b/web-ui/src/components/checkin/CheckinProfile.stories.jsx index 08dd291ed5..6a43d61a8c 100644 --- a/web-ui/src/components/checkin/CheckinProfile.stories.jsx +++ b/web-ui/src/components/checkin/CheckinProfile.stories.jsx @@ -1,52 +1,63 @@ -import React, {useContext, useEffect} from 'react'; -import {AppContext, AppContextProvider, MY_PROFILE_UPDATE} from '../../context/AppContext'; +import React, { useContext, useEffect } from 'react'; +import { + AppContext, + AppContextProvider, + MY_PROFILE_UPDATE +} from '../../context/AppContext'; import CheckinProfile from './CheckinProfile'; export default { - title: 'Check-Ins/CheckinProfile', - component: CheckinProfile, - decorators: [(Story) => { - return (); - }] + title: 'Check-Ins/CheckinProfile', + component: CheckinProfile, + decorators: [ + Story => { + return ( + + + + ); + } + ] }; -const noImageProfile = { - name: "Test User", - role: "MEMBER", - memberProfile: { - pdlID: 123, - workEmail: "testuser@objectcomputing.com", - name: "Bob Jones", - title: "Software Engineer", - } +const noImageProfile = { + name: 'Test User', + role: 'MEMBER', + memberProfile: { + pdlID: 123, + workEmail: 'testuser@objectcomputing.com', + name: 'Bob Jones', + title: 'Software Engineer' + } }; -const imageProfile = { - ...noImageProfile, - imageUrl: "https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Finsertcoin%2Ffiles%2F2017%2F02%2Flego-batman1.jpg", +const imageProfile = { + ...noImageProfile, + imageUrl: + 'https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Finsertcoin%2Ffiles%2F2017%2F02%2Flego-batman1.jpg' }; -const SetProfile = ({profile}) => { - const { dispatch } = useContext(AppContext); - useEffect(() => { - dispatch({ type: MY_PROFILE_UPDATE, payload: profile }); - }, [profile, dispatch]); - return ""; -} +const SetProfile = ({ profile }) => { + const { dispatch } = useContext(AppContext); + useEffect(() => { + dispatch({ type: MY_PROFILE_UPDATE, payload: profile }); + }, [profile, dispatch]); + return ''; +}; -const Template = (args) => ( - - - - +const Template = args => ( + + + + ); export const ProfileImage = Template.bind({}); ProfileImage.args = { - profile: imageProfile + profile: imageProfile }; export const NoProfileImage = Template.bind({}); NoProfileImage.args = { - profile: noImageProfile + profile: noImageProfile }; diff --git a/web-ui/src/components/checkin/CheckinProfile.test.jsx b/web-ui/src/components/checkin/CheckinProfile.test.jsx index fdefd63100..b2457d14d0 100644 --- a/web-ui/src/components/checkin/CheckinProfile.test.jsx +++ b/web-ui/src/components/checkin/CheckinProfile.test.jsx @@ -1,23 +1,23 @@ -import React from "react"; -import CheckinProfile from "./CheckinProfile"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import CheckinProfile from './CheckinProfile'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { selectedProfile: {}, userProfile: { - name: "Senior Test", + name: 'Senior Test', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], - }, - }, + role: ['MEMBER'] + } + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/checkin/documents/CheckinDocs.css b/web-ui/src/components/checkin/documents/CheckinDocs.css index 47a3c6680e..14faf2e38f 100644 --- a/web-ui/src/components/checkin/documents/CheckinDocs.css +++ b/web-ui/src/components/checkin/documents/CheckinDocs.css @@ -8,4 +8,3 @@ min-width: 30px; padding: 0px; } - diff --git a/web-ui/src/components/checkin/documents/CheckinDocs.jsx b/web-ui/src/components/checkin/documents/CheckinDocs.jsx index 695fed7b29..5ef08d7b86 100644 --- a/web-ui/src/components/checkin/documents/CheckinDocs.jsx +++ b/web-ui/src/components/checkin/documents/CheckinDocs.jsx @@ -1,24 +1,26 @@ -import React, { useContext, useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; -import FileUploader from "./FileUploader"; +import React, { useContext, useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import FileUploader from './FileUploader'; +import { getFiles, deleteFile, uploadFile } from '../../../api/upload'; +import { AppContext } from '../../../context/AppContext'; +import { UPDATE_TOAST } from '../../../context/actions'; import { - getFiles, - deleteFile, - uploadFile, -} from "../../../api/upload"; -import { AppContext } from "../../../context/AppContext"; -import { UPDATE_TOAST } from "../../../context/actions"; -import { selectCsrfToken, selectCurrentUser, selectIsPDL, selectIsAdmin, selectCheckin } from "../../../context/selectors"; -import DescriptionIcon from "@mui/icons-material/Description"; -import IconButton from "@mui/material/IconButton"; -import DeleteIcon from "@mui/icons-material/Delete"; -import { CircularProgress } from "@mui/material"; + selectCsrfToken, + selectCurrentUser, + selectIsPDL, + selectIsAdmin, + selectCheckin +} from '../../../context/selectors'; +import DescriptionIcon from '@mui/icons-material/Description'; +import IconButton from '@mui/material/IconButton'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { CircularProgress } from '@mui/material'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; import CardActions from '@mui/material/CardActions'; -import "./CheckinDocs.css"; +import './CheckinDocs.css'; const UploadDocs = () => { const { state, dispatch } = useContext(AppContext); @@ -46,10 +48,10 @@ const UploadDocs = () => { : null; if (checkinFiles) { setFiles(checkinFiles); - checkinFiles.forEach((file) => { - setFileColors((fileColors) => ({ + checkinFiles.forEach(file => { + setFileColors(fileColors => ({ ...fileColors, - [file.name]: "green", + [file.name]: 'green' })); }); } @@ -63,16 +65,16 @@ const UploadDocs = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [checkinId, csrf]); - const handleFile = (file) => { + const handleFile = file => { if (csrf) { setFiles([...files, file]); addFile(file); } }; - const addFile = async (file) => { + const addFile = async file => { let formData = new FormData(); - formData.append("file", file); + formData.append('file', file); if (!file || files.includes(file)) { setLoading(false); return; @@ -83,19 +85,19 @@ const UploadDocs = () => { if (res.error) throw new Error(res.error); const { data, status } = res.payload; if (status !== 200 && status !== 201) { - throw new Error("status equals " + status); + throw new Error('status equals ' + status); } dispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `${data.name} was successfully uploaded`, - }, + severity: 'success', + toast: `${data.name} was successfully uploaded` + } }); - setFileColors((fileColors) => ({ ...fileColors, [file.name]: "green" })); + setFileColors(fileColors => ({ ...fileColors, [file.name]: 'green' })); setFiles([...files, data]); } catch (e) { - setFileColors((fileColors) => ({ ...fileColors, [file.name]: "red" })); + setFileColors(fileColors => ({ ...fileColors, [file.name]: 'red' })); console.log({ e }); } finally { setLoading(false); @@ -103,53 +105,62 @@ const UploadDocs = () => { }; const fileMapper = () => { - const divs = files.map((file) => { + const divs = files.map(file => { if (!file.name) { return null; } else { - let downloadUrl = "/services/files/"+file.fileId+"/download"; + let downloadUrl = '/services/files/' + file.fileId + '/download'; return (
- {file.name} + + {file.name} + { if (csrf) { await deleteFile(file.fileId, csrf); setFiles( - files.filter((e) => { + files.filter(e => { return e.name !== file.name; }) ); } }} - size="large"> + size="large" + >
); } }); - return files.length > 0 ? divs : "No files attached."; + return files.length > 0 ? divs : 'No files attached.'; }; const hiddenFileInput = React.useRef(null); return canView ? ( - - } title="Documents" titleTypographyProps={{variant: "h5", component: "h2"}} /> - -
{fileMapper()}
-
- - {loading ? ( - - ) : ( - - )} - -
- ) : ""; + + } + title="Documents" + titleTypographyProps={{ variant: 'h5', component: 'h2' }} + /> + +
{fileMapper()}
+
+ + {loading ? ( + + ) : ( + + )} + +
+ ) : ( + '' + ); }; export default UploadDocs; diff --git a/web-ui/src/components/checkin/documents/CheckinDocs.stories.jsx b/web-ui/src/components/checkin/documents/CheckinDocs.stories.jsx index 0e484ed64a..a781f5d6ef 100644 --- a/web-ui/src/components/checkin/documents/CheckinDocs.stories.jsx +++ b/web-ui/src/components/checkin/documents/CheckinDocs.stories.jsx @@ -1,81 +1,86 @@ -import React, { useContext, useEffect } from "react"; -import {AppContext, AppContextProvider, MY_PROFILE_UPDATE, UPDATE_CHECKINS} from '../../../context/AppContext'; -import CheckinDocs from "./CheckinDocs"; +import React, { useContext, useEffect } from 'react'; +import { + AppContext, + AppContextProvider, + MY_PROFILE_UPDATE, + UPDATE_CHECKINS +} from '../../../context/AppContext'; +import CheckinDocs from './CheckinDocs'; export default { - title: 'Check-Ins/CheckinDocs', - component: CheckinDocs, - decorators: [(Story) => { - return (); - }] + title: 'Check-Ins/CheckinDocs', + component: CheckinDocs, + decorators: [ + Story => { + return ( + + + + ); + } + ] }; -const memberProfile = { - name: "Test User", - role: "MEMBER", - memberProfile: { - pdlID: 123, - workEmail: "testuser@objectcomputing.com", - name: "Bob Jones", - title: "Software Engineer", - }, - imageUrl: "https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Finsertcoin%2Ffiles%2F2017%2F02%2Flego-batman1.jpg", +const memberProfile = { + name: 'Test User', + role: 'MEMBER', + memberProfile: { + pdlID: 123, + workEmail: 'testuser@objectcomputing.com', + name: 'Bob Jones', + title: 'Software Engineer' + }, + imageUrl: + 'https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fblogs-images.forbes.com%2Finsertcoin%2Ffiles%2F2017%2F02%2Flego-batman1.jpg' }; const pdlProfile = { - ...memberProfile, - role: "PDL" -} + ...memberProfile, + role: 'PDL' +}; -const SetProfile = ({profile}) => { - const { dispatch } = useContext(AppContext); - useEffect(() => { - dispatch({ type: MY_PROFILE_UPDATE, payload: profile }); - }, [profile, dispatch]); - return ""; -} +const SetProfile = ({ profile }) => { + const { dispatch } = useContext(AppContext); + useEffect(() => { + dispatch({ type: MY_PROFILE_UPDATE, payload: profile }); + }, [profile, dispatch]); + return ''; +}; -const checkins = [ { - "id": "bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78", - "teamMemberId": "43ee8e79-b33d-44cd-b23c-e183894ebfef", - "pdlId": "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - "checkInDate": [ - 2020, - 9, - 29, - 11, - 32, - 29, - 40000000 - ], - "completed": true -} +const checkins = [ + { + id: 'bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78', + teamMemberId: '43ee8e79-b33d-44cd-b23c-e183894ebfef', + pdlId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + checkInDate: [2020, 9, 29, 11, 32, 29, 40000000], + completed: true + } ]; -const SetCheckins = ({checkins}) => { - const { dispatch } = useContext(AppContext); - useEffect(() => { - dispatch({ type: UPDATE_CHECKINS, payload: checkins }); - }, [checkins, dispatch]); - return ""; -} +const SetCheckins = ({ checkins }) => { + const { dispatch } = useContext(AppContext); + useEffect(() => { + dispatch({ type: UPDATE_CHECKINS, payload: checkins }); + }, [checkins, dispatch]); + return ''; +}; -const Template = (args) => ( - - - - - +const Template = args => ( + + + + + ); export const PDLNoCurrentDocs = Template.bind({}); PDLNoCurrentDocs.args = { - profile: pdlProfile, - checkins + profile: pdlProfile, + checkins }; export const MemberDocs = Template.bind({}); MemberDocs.args = { - profile: memberProfile, - checkins -}; \ No newline at end of file + profile: memberProfile, + checkins +}; diff --git a/web-ui/src/components/checkin/documents/CheckinDocs.test.jsx b/web-ui/src/components/checkin/documents/CheckinDocs.test.jsx index e91e12da87..88bd1ac4b4 100644 --- a/web-ui/src/components/checkin/documents/CheckinDocs.test.jsx +++ b/web-ui/src/components/checkin/documents/CheckinDocs.test.jsx @@ -1,42 +1,42 @@ -import React from "react"; -import CheckinDocs from "./CheckinDocs"; -import { AppContextProvider } from "../../../context/AppContext"; -import { Router } from "react-router-dom"; -import { createBrowserHistory } from "history"; +import React from 'react'; +import CheckinDocs from './CheckinDocs'; +import { AppContextProvider } from '../../../context/AppContext'; +import { Router } from 'react-router-dom'; +import { createBrowserHistory } from 'history'; const initialState = { state: { checkins: [ { - id: "3a1906df-d45c-4ff5-a6f8-7dacba97ff1a", - checkinid: "bf9975f8-a5b2-4551-b729-afd56b49e2cc", - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f28", - description: "updated string", - checkInDate: [2020, 9, 8], + id: '3a1906df-d45c-4ff5-a6f8-7dacba97ff1a', + checkinid: 'bf9975f8-a5b2-4551-b729-afd56b49e2cc', + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f28', + description: 'updated string', + checkInDate: [2020, 9, 8] }, { - id: "3a1906df-d45c-4ff5-a6f8-7dacba97ff1b", - checkinid: "bf9975f8-a5b2-4551-b729-afd56b49e2cd", - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f29", - description: "second updated string", - checkInDate: [2020, 10, 18], - }, + id: '3a1906df-d45c-4ff5-a6f8-7dacba97ff1b', + checkinid: 'bf9975f8-a5b2-4551-b729-afd56b49e2cd', + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f29', + description: 'second updated string', + checkInDate: [2020, 10, 18] + } ], - currentCheckin: [{ id: "10-982409128354" }], + currentCheckin: [{ id: '10-982409128354' }], userProfile: { memberProfile: { - id: "130u410234", + id: '130u410234' }, - name: "holmes", - role: ["ADMIN"], + name: 'holmes', + role: ['ADMIN'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, - index: 0, - }, + index: 0 + } }; -it("renders correctly", async () => { +it('renders correctly', async () => { const customHistory = createBrowserHistory(); snapshot( diff --git a/web-ui/src/components/checkin/documents/FileUploader.jsx b/web-ui/src/components/checkin/documents/FileUploader.jsx index 3134dde85b..60f1197b7b 100644 --- a/web-ui/src/components/checkin/documents/FileUploader.jsx +++ b/web-ui/src/components/checkin/documents/FileUploader.jsx @@ -1,9 +1,9 @@ -import React, { useContext } from "react"; -import { useParams } from "react-router-dom"; -import { AppContext } from "../../../context/AppContext"; -import { selectCheckin } from "../../../context/selectors"; -import Button from "@mui/material/Button"; -import AddCircleIcon from "@mui/icons-material/AddCircle"; +import React, { useContext } from 'react'; +import { useParams } from 'react-router-dom'; +import { AppContext } from '../../../context/AppContext'; +import { selectCheckin } from '../../../context/selectors'; +import Button from '@mui/material/Button'; +import AddCircleIcon from '@mui/icons-material/AddCircle'; // Style the Button component const FileUploader = ({ fileRef, handleFile }) => { @@ -12,27 +12,24 @@ const FileUploader = ({ fileRef, handleFile }) => { const currentCheckin = selectCheckin(state, checkinId); // Programmatically click the hidden file input element when the Button component is clicked - const handleClick = (event) => { + const handleClick = event => { fileRef.current.click(); }; // Call a function (passed as a prop from the parent component) to handle the user-selected file - const handleChange = (event) => { + const handleChange = event => { const fileUploaded = event.target.files[0]; handleFile(fileUploaded); }; return ( <> - ); diff --git a/web-ui/src/components/contribution_hours/ProgressBar.jsx b/web-ui/src/components/contribution_hours/ProgressBar.jsx index 675ab15bca..dc985c79ef 100644 --- a/web-ui/src/components/contribution_hours/ProgressBar.jsx +++ b/web-ui/src/components/contribution_hours/ProgressBar.jsx @@ -1,9 +1,9 @@ -import React from "react"; +import React from 'react'; import { styled } from '@mui/material/styles'; -import PropTypes from "prop-types"; -import LinearProgress from "@mui/material/LinearProgress"; -import Typography from "@mui/material/Typography"; -import Box from "@mui/material/Box"; +import PropTypes from 'prop-types'; +import LinearProgress from '@mui/material/LinearProgress'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; const PREFIX = 'LinearBuffer'; const classes = { @@ -12,8 +12,8 @@ const classes = { const Root = styled('div')({ [`&.${classes.root}`]: { - width: "100%", - }, + width: '100%' + } }); function LinearProgressWithLabel(props) { @@ -34,20 +34,19 @@ const propTypes = { billableHours: PropTypes.number, contributionHours: PropTypes.number.isRequired, targetHours: PropTypes.number.isRequired, - ptoHours: PropTypes.number, + ptoHours: PropTypes.number }; const LinearBuffer = ({ billableHours, contributionHours = 925, targetHours = 1850, - ptoHours = 0, + ptoHours = 0 }) => { - return ( - Billable Hours: {billableHours} - Contribution Hours:{" "} - {contributionHours} - Target Hours: {targetHours} - PTO Hours:{" "} + Billable Hours: {billableHours} - Contribution Hours:{' '} + {contributionHours} - Target Hours: {targetHours} - PTO Hours:{' '} {ptoHours} diff --git a/web-ui/src/components/contribution_hours/ProgressBar.stories.jsx b/web-ui/src/components/contribution_hours/ProgressBar.stories.jsx index 9a34c86c0d..961cc9155d 100644 --- a/web-ui/src/components/contribution_hours/ProgressBar.stories.jsx +++ b/web-ui/src/components/contribution_hours/ProgressBar.stories.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import ProgressBar from "./ProgressBar"; +import React from 'react'; +import ProgressBar from './ProgressBar'; export default { - title: "Check Ins/ProgressBar", - component: ProgressBar, + title: 'Check Ins/ProgressBar', + component: ProgressBar }; -const Template = (args) => ; +const Template = args => ; export const DefaultBar = Template.bind({}); DefaultBar.args = {}; diff --git a/web-ui/src/components/contribution_hours/ProgressBar.test.jsx b/web-ui/src/components/contribution_hours/ProgressBar.test.jsx index b4acec0378..1a670069e9 100644 --- a/web-ui/src/components/contribution_hours/ProgressBar.test.jsx +++ b/web-ui/src/components/contribution_hours/ProgressBar.test.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import ProgressBar from "./ProgressBar"; -import renderer from "react-test-renderer"; +import React from 'react'; +import ProgressBar from './ProgressBar'; +import renderer from 'react-test-renderer'; -it("has billable hours", () => { +it('has billable hours', () => { snapshot(); }); -it("has no billable hours", () => { +it('has no billable hours', () => { snapshot(); }); diff --git a/web-ui/src/components/discrete_slider/DiscreteSlider.jsx b/web-ui/src/components/discrete_slider/DiscreteSlider.jsx index df351238dc..e907980211 100644 --- a/web-ui/src/components/discrete_slider/DiscreteSlider.jsx +++ b/web-ui/src/components/discrete_slider/DiscreteSlider.jsx @@ -4,117 +4,125 @@ import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import Tooltip from '@mui/material/Tooltip'; -const Root = styled('div')(({theme}) => ({ +const Root = styled('div')(({ theme }) => ({ '& .MuiSlider-markLabel': { [theme.breakpoints.down('md')]: { - fontSize: "0.525rem", + fontSize: '0.525rem' }, [theme.breakpoints.between('sm', 'lg')]: { - fontSize: "0.525rem", + fontSize: '0.525rem' }, [theme.breakpoints.between('md', 'xl')]: { - fontSize: "0.775rem", + fontSize: '0.775rem' }, [theme.breakpoints.up('lg')]: { - fontSize: "0.875rem", - }, + fontSize: '0.875rem' + } } })); -const DiscreteSlider = ({title, onChange, onChangeCommitted, inMarks, inStartPos}) => { +const DiscreteSlider = ({ + title, + onChange, + onChangeCommitted, + inMarks, + inStartPos +}) => { const defaultMarks = [ { value: 1, label: 'Interested', - tooltip: 'You have an interest in this skill and, perhaps, common knowledge or an understanding of its basic techniques and concepts.', - tooltipChildren: [ - 'Focus on learning.', - ], + tooltip: + 'You have an interest in this skill and, perhaps, common knowledge or an understanding of its basic techniques and concepts.', + tooltipChildren: ['Focus on learning.'] }, { value: 2, label: 'Novice', - tooltip: 'You have the level of experience gained in a classroom, experimental scenarios, or via other training. You are expected to need help when performing this skill.', + tooltip: + 'You have the level of experience gained in a classroom, experimental scenarios, or via other training. You are expected to need help when performing this skill.', tooltipChildren: [ 'Focus on developing through experience.', 'You understand and can discuss terminology, concepts, principles and issues related to this skill.', - 'You rely heavily on reference and resource materials to be effective with this skill.', - ], + 'You rely heavily on reference and resource materials to be effective with this skill.' + ] }, { value: 3, label: 'Intermediate', - tooltip: 'You are able to successfully complete tasks in this competency as requested. Help from an expert may be required from time to time, but you can usually perform the skill independently.', + tooltip: + 'You are able to successfully complete tasks in this competency as requested. Help from an expert may be required from time to time, but you can usually perform the skill independently.', tooltipChildren: [ 'Focus on applying and enhancing knowledge or skill.', 'You have applied this competency to situations, while occasionally needing minimal guidance to perform successfully.', - 'You understand and can discuss the application and implications of changes to processes and procedures in this area.', - ], + 'You understand and can discuss the application and implications of changes to processes and procedures in this area.' + ] }, { value: 4, label: 'Advanced', - tooltip: 'You can perform the actions associated with this skill without assistance. You are certainly recognized within your immediate organization as "a person to ask" when difficult questions arise regarding this skill.', + tooltip: + 'You can perform the actions associated with this skill without assistance. You are certainly recognized within your immediate organization as "a person to ask" when difficult questions arise regarding this skill.', tooltipChildren: [ 'Focus on broad organizational/professional issues.', 'You have consistently provided relevant ideas and perspectives on process or practice improvements as relate to this skill.', 'You are capable of coaching others in the application of this skill.', 'You participate in senior level discussions regarding this skill.', - 'You assist in the development of reference and resource materials related to this skill.', - ], + 'You assist in the development of reference and resource materials related to this skill.' + ] }, { value: 5, label: 'Expert', - tooltip: 'You are known as an expert in this area. You can provide guidance, troubleshoot and answer questions related to this skill.', + tooltip: + 'You are known as an expert in this area. You can provide guidance, troubleshoot and answer questions related to this skill.', tooltipChildren: [ 'Focus on the strategic.', 'You have demonstrated consistent excellence in applying this competency across multiple projects or organizations.', 'You are considered the “go to” person for this skill within OCI or externally.', 'You create new applications for or lead the development of reference and resource materials for this skill.', - 'You are able to explain relevant topics, issues, process elements, and trends in sufficient detail during discussions and presentations as to foster a greater understanding among internal and external colleagues.', - ], - }, + 'You are able to explain relevant topics, issues, process elements, and trends in sufficient detail during discussions and presentations as to foster a greater understanding among internal and external colleagues.' + ] + } ]; const marks = inMarks ? inMarks : defaultMarks; const formatTooltipTitle = (title, children) => { - return( + return (
-
- {title} -
+
{title}
    - { - children && children.map((child) => { - return(
  • {child}
  • ); - }) - } + {children && + children.map(child => { + return
  • {child}
  • ; + })}
- ) + ); }; - const ValueLabelComponent = (props) => { - let thisMark = marks.find((mark) => mark.value === props.value); + const ValueLabelComponent = props => { + let thisMark = marks.find(mark => mark.value === props.value); if (!thisMark) { return ''; } return ( - {props.children} + {props.children} ); }; - const startPos = inStartPos ? Number(inStartPos) : Math.ceil(marks.length/2); + const startPos = inStartPos + ? Number(inStartPos) + : Math.ceil(marks.length / 2); return (
@@ -131,7 +139,7 @@ const DiscreteSlider = ({title, onChange, onChangeCommitted, inMarks, inStartPos components={{ ValueLabel: ValueLabelComponent }} - getAriaValueText={(value) => `${value}`} + getAriaValueText={value => `${value}`} step={null} marks={marks} onChange={onChange} @@ -142,4 +150,4 @@ const DiscreteSlider = ({title, onChange, onChangeCommitted, inMarks, inStartPos ); }; -export default DiscreteSlider; \ No newline at end of file +export default DiscreteSlider; diff --git a/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx b/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx index 61b55bab6a..355c5ade79 100644 --- a/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx +++ b/web-ui/src/components/discrete_slider/DiscreteSlider.stories.jsx @@ -4,13 +4,12 @@ import DiscreteSlider from './DiscreteSlider'; export default { title: 'Check Ins/DiscreteSlider', component: DiscreteSlider -} -const Template = (args) => - ; +}; +const Template = args => ; export const DefaultSlider = Template.bind({}); DefaultSlider.args = { - title: "Some skill", + title: 'Some skill', lastUsed: undefined }; @@ -19,10 +18,10 @@ SliderWithChangeHandler.args = { onChangeCommitted: (event, value) => { window.alert(value); } -} +}; export const SliderWithLastUsed = Template.bind({}); SliderWithLastUsed.args = { - title: "Other Skill", - lastUsed: "Currently Used" -} + title: 'Other Skill', + lastUsed: 'Currently Used' +}; diff --git a/web-ui/src/components/edit_skills/EditSkillsCard.jsx b/web-ui/src/components/edit_skills/EditSkillsCard.jsx index 78d4bb883d..09a22d0f48 100644 --- a/web-ui/src/components/edit_skills/EditSkillsCard.jsx +++ b/web-ui/src/components/edit_skills/EditSkillsCard.jsx @@ -1,19 +1,19 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; import { deleteMemberSkill, getSkillMembers, - getMemberSkills, -} from "../../api/memberskill"; -import { removeSkill, updateSkill } from "../../api/skill"; -import { AppContext } from "../../context/AppContext"; -import { selectProfileMap } from "../../context/selectors"; + getMemberSkills +} from '../../api/memberskill'; +import { removeSkill, updateSkill } from '../../api/skill'; +import { AppContext } from '../../context/AppContext'; +import { selectProfileMap } from '../../context/selectors'; import { DELETE_SKILL, UPDATE_SKILL, - UPDATE_MEMBER_SKILLS, -} from "../../context/actions"; -import { getAvatarURL } from "../../api/api.js"; + UPDATE_MEMBER_SKILLS +} from '../../context/actions'; +import { getAvatarURL } from '../../api/api.js'; import { Avatar, @@ -24,10 +24,10 @@ import { CardHeader, CardContent, Modal, - TextField, -} from "@mui/material"; + TextField +} from '@mui/material'; -import "./EditSkills.css"; +import './EditSkills.css'; const EditSkillsCard = ({ skill }) => { const { state, dispatch } = useContext(AppContext); @@ -97,7 +97,7 @@ const EditSkillsCard = ({ skill }) => { //remove all memberSkills associated with this skill first await Promise.all( memberSkillsToDelete.payload.data.map( - async (member) => await deleteMemberSkill(member.id, csrf) + async member => await deleteMemberSkill(member.id, csrf) ) ); } @@ -118,7 +118,7 @@ const EditSkillsCard = ({ skill }) => { const getMembers = async () => { let res = await getSkillMembers(id, csrf); if (res && res.payload && res.payload.data) { - const memberIds = res.payload.data.map((m) => m.memberid); + const memberIds = res.payload.data.map(m => m.memberid); setMembers(memberIds); } }; @@ -127,7 +127,7 @@ const EditSkillsCard = ({ skill }) => { } }, [csrf, id]); - const chip = (position) => { + const chip = position => { return ( } @@ -136,7 +136,7 @@ const EditSkillsCard = ({ skill }) => { ); }; - const submittedBy = (members) => { + const submittedBy = members => { const [first, second, ...rest] = members; const firstProfile = selectProfileMap(state)[first]; if (second) { @@ -153,7 +153,9 @@ const EditSkillsCard = ({ skill }) => { ); } else return firstProfile ? ( -
Submitted by: {chip(firstProfile)}
+
+ Submitted by: {chip(firstProfile)} +
) : (
Submitted by: Unknown
); @@ -177,23 +179,23 @@ const EditSkillsCard = ({ skill }) => { + onChange={e => setEditedSkill({ ...editedSkill, name: e.target.value }) } - value={editedSkill ? editedSkill.name : ""} + value={editedSkill ? editedSkill.name : ''} variant="outlined" /> + onChange={e => setEditedSkill({ ...editedSkill, - description: e.target.value, + description: e.target.value }) } - value={editedSkill ? editedSkill.description : ""} + value={editedSkill ? editedSkill.description : ''} variant="outlined" /> diff --git a/web-ui/src/components/edit_skills/EditSkillsCard.test.jsx b/web-ui/src/components/edit_skills/EditSkillsCard.test.jsx index 62e73c6a19..7cf0f15592 100644 --- a/web-ui/src/components/edit_skills/EditSkillsCard.test.jsx +++ b/web-ui/src/components/edit_skills/EditSkillsCard.test.jsx @@ -1,85 +1,94 @@ -import React from "react"; -import EditSkillsCard from "./EditSkillsCard"; -import EditSkillsPage from "../../pages/EditSkillsPage"; -import { AppContextProvider } from "../../context/AppContext"; -import {http, HttpResponse} from "msw"; -import { setupServer } from "msw/node"; -import {BrowserRouter} from "react-router-dom"; +import React from 'react'; +import EditSkillsCard from './EditSkillsCard'; +import EditSkillsPage from '../../pages/EditSkillsPage'; +import { AppContextProvider } from '../../context/AppContext'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; +import { BrowserRouter } from 'react-router-dom'; import { act } from '@testing-library/react'; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", -} + name: 'Current User', + firstName: 'Current', + lastName: 'User' +}; const initialState = { state: { - csrf: "blah", + csrf: 'blah', userProfile: { - name: "Current User", - firstName: "Current", - lastName: "User", - role: ["MEMBER"], + name: 'Current User', + firstName: 'Current', + lastName: 'User', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - memberProfile: currentUserProfile, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', + memberProfile: currentUserProfile }, skills: [ - { id: "918275", name: "skill1", description: "first" }, - { id: "9183455", name: "skill2", description: "second" }, + { id: '918275', name: 'skill1', description: 'first' }, + { id: '9183455', name: 'skill2', description: 'second' } ], checkins: [], guilds: [], teams: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], index: 0, - memberProfiles: [currentUserProfile, {id:123, name:"Guild Leader"}, {id:124, name: "Other Leader"}, {id:125, name:"Guild Member"}, {id:126, name: "Other Member"}], - }, + memberProfiles: [ + currentUserProfile, + { id: 123, name: 'Guild Leader' }, + { id: 124, name: 'Other Leader' }, + { id: 125, name: 'Guild Member' }, + { id: 126, name: 'Other Member' } + ] + } }; const pendingSkill = { extraneous: false, - id: "1134511f3e-7ab7-4edf-86f5-ab0b0a0d2ca9", - name: "Le test skill", + id: '1134511f3e-7ab7-4edf-86f5-ab0b0a0d2ca9', + name: 'Le test skill', pending: false, - description: "le description", + description: 'le description' }; let open = true; const handleClose = () => (open = false); const server = setupServer( - http.get('http://localhost:8080/services/member-skills', ({request}) => { - return HttpResponse.json([{ - "id": "74422962-03ef-4957-b713-11def435db1d", - "memberid": currentUserProfile.id, - "skillid": pendingSkill.id, - "skilllevel": "3" - }]); - }), + http.get('http://localhost:8080/services/member-skills', ({ request }) => { + return HttpResponse.json([ + { + id: '74422962-03ef-4957-b713-11def435db1d', + memberid: currentUserProfile.id, + skillid: pendingSkill.id, + skilllevel: '3' + } + ]); + }) ); beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -describe("EditSkillsCard", () => { - it("renders correctly with skill", async () => { - await waitForSnapshot("skill-submitted-by", - ( +describe('EditSkillsCard', () => { + it('renders correctly with skill', async () => { + await waitForSnapshot( + 'skill-submitted-by', + - ) + ); }); - it("renders correctly", () => { + it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/edit_skills/EditSkillsModal.jsx b/web-ui/src/components/edit_skills/EditSkillsModal.jsx index aa4e74fb11..92a05b520f 100644 --- a/web-ui/src/components/edit_skills/EditSkillsModal.jsx +++ b/web-ui/src/components/edit_skills/EditSkillsModal.jsx @@ -1,20 +1,20 @@ -import React, { useContext, useEffect, useState } from "react"; -import { AppContext } from "../../context/AppContext"; +import React, { useContext, useEffect, useState } from 'react'; +import { AppContext } from '../../context/AppContext'; import { ADD_SKILL, DELETE_SKILL, - UPDATE_MEMBER_SKILLS, -} from "../../context/actions"; -import { combineSkill } from "../../api/skill"; -import { getMemberSkills } from "../../api/memberskill"; + UPDATE_MEMBER_SKILLS +} from '../../context/actions'; +import { combineSkill } from '../../api/skill'; +import { getMemberSkills } from '../../api/memberskill'; import Autocomplete from '@mui/material/Autocomplete'; -import {Checkbox, Modal, TextField} from "@mui/material"; -import { Button } from "@mui/material"; -import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; -import CheckBoxIcon from "@mui/icons-material/CheckBox"; +import { Checkbox, Modal, TextField } from '@mui/material'; +import { Button } from '@mui/material'; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import "./EditSkills.css"; +import './EditSkills.css'; const icon = ; const checkedIcon = ; @@ -24,9 +24,9 @@ const EditSkillsModal = ({ open, onClose, skillsToEdit }) => { const { csrf } = state; const [pendingSkills, setPendingSkills] = useState([]); const [combinedSkill, setCombinedSkill] = useState({ - name: "", - description: "", - skillsToCombine: [], + name: '', + description: '', + skillsToCombine: [] }); const { skillsToCombine, name } = combinedSkill; @@ -35,21 +35,21 @@ const EditSkillsModal = ({ open, onClose, skillsToEdit }) => { }, [skillsToEdit, state]); const handleSelections = (event, values) => { - let skills = values.map((skill) => { + let skills = values.map(skill => { return skill.id; }); setCombinedSkill({ ...combinedSkill, - skillsToCombine: skills, + skillsToCombine: skills }); }; const close = () => { onClose(); setCombinedSkill({ - name: "", - description: "", - skillsToCombine: "", + name: '', + description: '', + skillsToCombine: '' }); }; @@ -61,7 +61,7 @@ const EditSkillsModal = ({ open, onClose, skillsToEdit }) => { if (!data) { return; } - skillsToCombine.forEach((id) => + skillsToCombine.forEach(id => dispatch({ type: DELETE_SKILL, payload: id }) ); dispatch({ type: ADD_SKILL, payload: data }); @@ -85,7 +85,7 @@ const EditSkillsModal = ({ open, onClose, skillsToEdit }) => { multiple options={pendingSkills} disableCloseOnSelect - getOptionLabel={(option) => option.name} + getOptionLabel={option => option.name} onChange={handleSelections} renderOption={(props, option, { selected }) => (
  • @@ -99,7 +99,7 @@ const EditSkillsModal = ({ open, onClose, skillsToEdit }) => {
  • )} style={{ width: 500 }} - renderInput={(params) => ( + renderInput={params => ( { { + onChange={e => { setCombinedSkill({ ...combinedSkill, name: e.target.value }); }} - value={combinedSkill ? combinedSkill.name : ""} + value={combinedSkill ? combinedSkill.name : ''} variant="outlined" /> { + onChange={e => { setCombinedSkill({ ...combinedSkill, - description: e.target.value, + description: e.target.value }); }} - value={combinedSkill ? combinedSkill.description : ""} + value={combinedSkill ? combinedSkill.description : ''} variant="outlined" />
    diff --git a/web-ui/src/components/feedback_answer_input/FeedbackAnswerInput.jsx b/web-ui/src/components/feedback_answer_input/FeedbackAnswerInput.jsx index f685924ff6..ffb19d163d 100644 --- a/web-ui/src/components/feedback_answer_input/FeedbackAnswerInput.jsx +++ b/web-ui/src/components/feedback_answer_input/FeedbackAnswerInput.jsx @@ -1,13 +1,25 @@ -import React, {useCallback} from "react"; -import PropTypes from "prop-types"; -import TextField from "@mui/material/TextField"; -import RadioGroup from "@mui/material/RadioGroup"; -import {FormControlLabel} from "@mui/material"; -import Radio from "@mui/material/Radio"; -import Slider from "@mui/material/Slider"; +import React, { useCallback } from 'react'; +import PropTypes from 'prop-types'; +import TextField from '@mui/material/TextField'; +import RadioGroup from '@mui/material/RadioGroup'; +import { FormControlLabel } from '@mui/material'; +import Radio from '@mui/material/Radio'; +import Slider from '@mui/material/Slider'; -const agreeMarks = ["Strongly Disagree", "Disagree", "Neither Agree nor Disagree", "Agree", "Strongly Agree"]; -const frequencyMarks = ["Very Infrequently", "Infrequently", "Neither Frequently nor Infrequently", "Frequently", "Very Frequently"]; +const agreeMarks = [ + 'Strongly Disagree', + 'Disagree', + 'Neither Agree nor Disagree', + 'Agree', + 'Strongly Agree' +]; +const frequencyMarks = [ + 'Very Infrequently', + 'Infrequently', + 'Neither Frequently nor Infrequently', + 'Frequently', + 'Very Frequently' +]; const propTypes = { inputType: PropTypes.string.isRequired, @@ -16,41 +28,47 @@ const propTypes = { onAnswerChange: PropTypes.func }; -const FeedbackAnswerInput = ({ inputType, readOnly, answer, onAnswerChange }) => { +const FeedbackAnswerInput = ({ + inputType, + readOnly, + answer, + onAnswerChange +}) => { let inputField; - const handleChange = useCallback((event, value) => { - if (!onAnswerChange) return; - if (inputType === "SLIDER") { - onAnswerChange(agreeMarks[value]); - } else if (inputType === "FREQ") { - onAnswerChange(frequencyMarks[value]); - } else { - onAnswerChange(event.target.value); - } - }, [onAnswerChange, inputType]); + const handleChange = useCallback( + (event, value) => { + if (!onAnswerChange) return; + if (inputType === 'SLIDER') { + onAnswerChange(agreeMarks[value]); + } else if (inputType === 'FREQ') { + onAnswerChange(frequencyMarks[value]); + } else { + onAnswerChange(event.target.value); + } + }, + [onAnswerChange, inputType] + ); switch (inputType) { - case "TEXT": - inputField = readOnly - ? ( -
    {answer}
    - ) - : ( - - ); + case 'TEXT': + inputField = readOnly ? ( +
    +          {answer}
    +        
    + ) : ( + + ); break; - case "RADIO": + case 'RADIO': inputField = ( value={answer} onChange={handleChange} > - } label="Yes"/> - } label="No"/> + } + label="Yes" + /> + } + label="No" + /> ); break; - case "SLIDER": + case 'SLIDER': inputField = ( value={agreeMarks.findIndex(mark => mark === answer)} step={1} marks={agreeMarks.map((mark, index) => { - return { value: index, label: mark } + return { value: index, label: mark }; })} onChange={handleChange} /> ); break; - case "FREQ": + case 'FREQ': inputField = ( value={frequencyMarks.findIndex(mark => mark === answer)} step={1} marks={frequencyMarks.map((mark, index) => { - return { value: index, label: mark } + return { value: index, label: mark }; })} onChange={handleChange} /> @@ -100,8 +128,8 @@ const FeedbackAnswerInput = ({ inputType, readOnly, answer, onAnswerChange }) => console.warn(`No input rendered for invalid inputType '${inputType}'`); } return inputField; -} +}; FeedbackAnswerInput.propTypes = propTypes; -export default FeedbackAnswerInput; \ No newline at end of file +export default FeedbackAnswerInput; diff --git a/web-ui/src/components/feedback_date_selector/SelectDate.jsx b/web-ui/src/components/feedback_date_selector/SelectDate.jsx index 6805e4f965..a73e9129ae 100644 --- a/web-ui/src/components/feedback_date_selector/SelectDate.jsx +++ b/web-ui/src/components/feedback_date_selector/SelectDate.jsx @@ -1,9 +1,9 @@ -import React, {useCallback, useEffect, useRef} from "react"; +import React, { useCallback, useEffect, useRef } from 'react'; import { styled } from '@mui/material/styles'; -import DateFnsUtils from "@date-io/date-fns"; -import PropTypes from "prop-types"; -import {TextField} from "@mui/material"; -import { MobileDatePicker } from "@mui/x-date-pickers"; +import DateFnsUtils from '@date-io/date-fns'; +import PropTypes from 'prop-types'; +import { TextField } from '@mui/material'; +import { MobileDatePicker } from '@mui/x-date-pickers'; const dateUtils = new DateFnsUtils(); const PREFIX = 'SelectDate'; @@ -15,14 +15,14 @@ const classes = { const Root = styled('div')({ [`& .${classes.pickerContain}`]: { marginLeft: '2em', - marginTop:'2em', + marginTop: '2em' }, [`& .${classes.picker}`]: { marginBottom: '0.5em', marginTop: '1em', minWidth: '60%', - maxWidth: "80%", - display:'block', + maxWidth: '80%', + display: 'block' } }); @@ -32,63 +32,86 @@ const propTypes = { dueDateQuery: PropTypes.string }; -const SelectDate = ({changeQuery, sendDateQuery, dueDateQuery}) =>{ - const hasPushedInitialValues = useRef(false); - let todayDate = new Date(); - const sendDate = sendDateQuery ? dateUtils.parse(sendDateQuery.toString(), "MM/dd/yyyy", new Date()) : todayDate; - const dueDate = dueDateQuery ? dateUtils.parse(dueDateQuery?.toString(), "MM/dd/yyyy", new Date()) : null; +const SelectDate = ({ changeQuery, sendDateQuery, dueDateQuery }) => { + const hasPushedInitialValues = useRef(false); + let todayDate = new Date(); + const sendDate = sendDateQuery + ? dateUtils.parse(sendDateQuery.toString(), 'MM/dd/yyyy', new Date()) + : todayDate; + const dueDate = dueDateQuery + ? dateUtils.parse(dueDateQuery?.toString(), 'MM/dd/yyyy', new Date()) + : null; - useEffect(() => { - if (!hasPushedInitialValues.current && sendDate !== null && sendDate !== undefined && dueDate !== undefined) { - changeQuery("send", dateUtils.format(sendDate, "MM/dd/yyyy")); - if (dueDate !== null) { - changeQuery("due", dateUtils.format(dueDate, "MM/dd/yyyy")); - } - hasPushedInitialValues.current = true; + useEffect(() => { + if ( + !hasPushedInitialValues.current && + sendDate !== null && + sendDate !== undefined && + dueDate !== undefined + ) { + changeQuery('send', dateUtils.format(sendDate, 'MM/dd/yyyy')); + if (dueDate !== null) { + changeQuery('due', dateUtils.format(dueDate, 'MM/dd/yyyy')); } - }); + hasPushedInitialValues.current = true; + } + }); - const handleDueDateChange = useCallback((date) => { - const dueDate = date ? dateUtils.format(date, "MM/dd/yyyy") : null; - changeQuery("due", dueDate ? dueDate : undefined); - },[changeQuery]); + const handleDueDateChange = useCallback( + date => { + const dueDate = date ? dateUtils.format(date, 'MM/dd/yyyy') : null; + changeQuery('due', dueDate ? dueDate : undefined); + }, + [changeQuery] + ); - const handleSendDateChange = useCallback((date) => { - const sendDate = dateUtils.format(date, "MM/dd/yyyy"); - changeQuery("send", sendDate); - },[changeQuery]); + const handleSendDateChange = useCallback( + date => { + const sendDate = dateUtils.format(date, 'MM/dd/yyyy'); + changeQuery('send', sendDate); + }, + [changeQuery] + ); - return ( - -
    - } - disableToolbar - format="MM/dd/yyyy" - margin="normal" - id="set-send-date" - label="Send Date:" - value={sendDate} - minDate={dateUtils.date()} - onChange={handleSendDateChange} - /> -
    - } - disableToolbar - format="MM/dd/yyyy" - margin="normal" - id="set-due-date" - label="Due Date:" - value={dueDate} - minDate={sendDate} - minDateMessage="Due date must not be prior to the send date" - clearable={true} - onChange={handleDueDateChange} - /> -
    -
    - ); + return ( + +
    + ( + + )} + disableToolbar + format="MM/dd/yyyy" + margin="normal" + id="set-send-date" + label="Send Date:" + value={sendDate} + minDate={dateUtils.date()} + onChange={handleSendDateChange} + /> +
    + ( + + )} + disableToolbar + format="MM/dd/yyyy" + margin="normal" + id="set-due-date" + label="Due Date:" + value={dueDate} + minDate={sendDate} + minDateMessage="Due date must not be prior to the send date" + clearable={true} + onChange={handleDueDateChange} + /> +
    +
    + ); }; SelectDate.propTypes = propTypes; diff --git a/web-ui/src/components/feedback_date_selector/SelectDate.stories.jsx b/web-ui/src/components/feedback_date_selector/SelectDate.stories.jsx index 2e121600e5..7f3b26fa1e 100644 --- a/web-ui/src/components/feedback_date_selector/SelectDate.stories.jsx +++ b/web-ui/src/components/feedback_date_selector/SelectDate.stories.jsx @@ -1,25 +1,27 @@ -import React from "react"; -import SelectDate from "./SelectDate"; -import {AppContextProvider} from "../../context/AppContext"; -import { LocalizationProvider } from "@mui/x-date-pickers"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import React from 'react'; +import SelectDate from './SelectDate'; +import { AppContextProvider } from '../../context/AppContext'; +import { LocalizationProvider } from '@mui/x-date-pickers'; +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; export default { - title: "Check-Ins/SelectDate", - component: SelectDate, - args: { - changeQuery: (data1, data2) => {} - }, - decorators: [(Story) => { - return ( - - - - - - ); - }] + title: 'Check-Ins/SelectDate', + component: SelectDate, + args: { + changeQuery: (data1, data2) => {} + }, + decorators: [ + Story => { + return ( + + + + + + ); + } + ] }; -const Template = (args) => ; -export const DefaultDatePicker = Template.bind({}); \ No newline at end of file +const Template = args => ; +export const DefaultDatePicker = Template.bind({}); diff --git a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.css b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.css index 368f6f0857..2e22ef144a 100644 --- a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.css +++ b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.css @@ -1,56 +1,55 @@ .member-card { - max-height: 20rem; - width: 325px; - display: flex; - flex-direction: column; - justify-content: space-between; - cursor: pointer; - margin: 0 2em 2em 0; + max-height: 20rem; + width: 325px; + display: flex; + flex-direction: column; + justify-content: space-between; + cursor: pointer; + margin: 0 2em 2em 0; } .member-card .member-summary-avatar { - height: 5rem; - width: 5rem; - margin-right: 1.25rem; + height: 5rem; + width: 5rem; + margin-right: 1.25rem; } .member-summary-parent { - display: flex; - align-items: center; + display: flex; + align-items: center; } .member-card .large { - width: theme-spacing(10); - height: theme-spacing(10); + width: theme-spacing(10); + height: theme-spacing(10); } .member-card .info-container { - padding: 0; + padding: 0; } .member-card .split-button { - padding: 1rem; + padding: 1rem; } .member-card .MuiCardHeader-content h2 { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 225px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 225px; } .member-card .MuiCardHeader-content h3 { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 225px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 225px; } .reason { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - -} \ No newline at end of file + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; +} diff --git a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.jsx b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.jsx index 61ef8931b5..2fae3653ee 100644 --- a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.jsx +++ b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.jsx @@ -1,16 +1,16 @@ -import React, { useContext } from "react"; +import React, { useContext } from 'react'; import { styled } from '@mui/material/styles'; -import { AppContext } from "../../context/AppContext"; -import { selectProfileMap } from "../../context/selectors"; -import { getAvatarURL } from "../../api/api.js"; -import { Card, CardHeader } from "@mui/material"; -import Avatar from "@mui/material/Avatar"; -import PriorityHighIcon from "@mui/icons-material/PriorityHigh"; -import { green } from "@mui/material/colors"; -import CheckCircleIcon from "@mui/icons-material/CheckCircle"; -import Divider from "@mui/material/Divider"; -import "./FeedbackRecipientCard.css"; -import { Box, CardContent, Container, Typography } from "@mui/material"; +import { AppContext } from '../../context/AppContext'; +import { selectProfileMap } from '../../context/selectors'; +import { getAvatarURL } from '../../api/api.js'; +import { Card, CardHeader } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; +import { green } from '@mui/material/colors'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import Divider from '@mui/material/Divider'; +import './FeedbackRecipientCard.css'; +import { Box, CardContent, Container, Typography } from '@mui/material'; const PREFIX = 'FeedbackRecipientCard'; const classes = { @@ -22,50 +22,51 @@ const classes = { }; const StyledBox = styled(Box)({ - [`&.${classes.root}`]: { // currently defined but not used - minWidth: "10em", - maxWidth: "20em", - marginRight: "2em", - marginBottom: "2em", - cursor: "pointer", - "@media (max-width:767px)": { - marginTop: "1em", - height: "40%", - width: "80%", - }, + [`&.${classes.root}`]: { + // currently defined but not used + minWidth: '10em', + maxWidth: '20em', + marginRight: '2em', + marginBottom: '2em', + cursor: 'pointer', + '@media (max-width:767px)': { + marginTop: '1em', + height: '40%', + width: '80%' + } }, [`& .${classes.header}`]: { - cursor: "pointer", + cursor: 'pointer' }, - [`& .${classes.cardContent}`]: { // currently defined but not used - display: "flex", - alignItems: "center", - alignContent: "center", - flexDirection: "column", - justifyContent: "center", - textAlign: "center", + [`& .${classes.cardContent}`]: { + // currently defined but not used + display: 'flex', + alignItems: 'center', + alignContent: 'center', + flexDirection: 'column', + justifyContent: 'center', + textAlign: 'center' }, [`& .${classes.divider}`]: { - backgroundColor: "grey", - width: "90%", - marginBottom: "1em", - marginTop: "1em", + backgroundColor: 'grey', + width: '90%', + marginBottom: '1em', + marginTop: '1em' }, [`& .${classes.recommendationText}`]: { - color: "#333333", - }, + color: '#333333' + } }); const FeedbackRecipientCard = ({ recipientProfile, selected, reason = null, - onClick, + onClick }) => { const { state } = useContext(AppContext); - const supervisorProfile = selectProfileMap(state)[ - recipientProfile?.supervisorid - ]; + const supervisorProfile = + selectProfileMap(state)[recipientProfile?.supervisorid]; const pdlProfile = selectProfileMap(state)[recipientProfile?.pdlId]; return ( diff --git a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.stories.jsx b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.stories.jsx index b7b5233e31..dc796ab049 100644 --- a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.stories.jsx +++ b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.stories.jsx @@ -1,42 +1,48 @@ -import FeedbackRecipientCard from "./FeedbackRecipientCard"; -import React, {useContext, useEffect} from "react"; -import {AppContext, AppContextProvider} from "../../context/AppContext"; -import {UPDATE_MEMBER_PROFILES} from "../../context/actions"; +import FeedbackRecipientCard from './FeedbackRecipientCard'; +import React, { useContext, useEffect } from 'react'; +import { AppContext, AppContextProvider } from '../../context/AppContext'; +import { UPDATE_MEMBER_PROFILES } from '../../context/actions'; export default { title: 'FeedbackReqs/FeedbackRecipientCard', component: FeedbackRecipientCard, - decorators: [(Story) => { - return (); - }] + decorators: [ + Story => { + return ( + + + + ); + } + ] }; -const profile = { - id: "12342345678", +const profile = { + id: '12342345678', pdlID: 123, - workEmail: "kimberlinm@objectcomputing.com", - name: "Bob Jones", - title: "Software Engineer", -} + workEmail: 'kimberlinm@objectcomputing.com', + name: 'Bob Jones', + title: 'Software Engineer' +}; -const SetProfiles = ({profiles}) => { +const SetProfiles = ({ profiles }) => { const { dispatch } = useContext(AppContext); useEffect(() => { dispatch({ type: UPDATE_MEMBER_PROFILES, payload: profiles }); }, [profiles, dispatch]); - return ""; -} + return ''; +}; -const Template = (args) => ( +const Template = args => ( - + ); export const DefaultUser = Template.bind({}); DefaultUser.args = { profileId: profile.id, - reason: "Recommended for being a local opossum", - profiles:[profile] -}; \ No newline at end of file + reason: 'Recommended for being a local opossum', + profiles: [profile] +}; diff --git a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.test.jsx b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.test.jsx index 4b3796e845..08a0942384 100644 --- a/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.test.jsx +++ b/web-ui/src/components/feedback_recipient_card/FeedbackRecipientCard.test.jsx @@ -1,15 +1,14 @@ -import React from "react"; -import FeedbackRecipientCard from "./FeedbackRecipientCard"; -import {AppContextProvider} from "../../context/AppContext"; -import {BrowserRouter} from "react-router-dom"; - -it("renders the recipient card", () => { +import React from 'react'; +import FeedbackRecipientCard from './FeedbackRecipientCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; +it('renders the recipient card', () => { snapshot( - + - ); -}); \ No newline at end of file + ); +}); diff --git a/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.css b/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.css index 1d43746142..16cfb29160 100644 --- a/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.css +++ b/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.css @@ -1,41 +1,40 @@ .feedback-recipient-selector { - width: 100%; - height: 100%; - padding: 1rem 2rem 1rem 2rem; + width: 100%; + height: 100%; + padding: 1rem 2rem 1rem 2rem; } .selected-recipients-container { - width: 100%; - height: 50%; - min-height: 380px; - margin-top: 2em; - padding: 20px 0 20px 26px; - border-radius: 20px; - border: 1px dashed gray; + width: 100%; + height: 50%; + min-height: 380px; + margin-top: 2em; + padding: 20px 0 20px 26px; + border-radius: 20px; + border: 1px dashed gray; } .selectable-recipients-container { - width: 100%; - height: 50%; - min-height: 300px; - margin-top: 2em; + width: 100%; + height: 50%; + min-height: 300px; + margin-top: 2em; } .selected-recipients-container .recipient-card-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; + display: flex; + flex-direction: row; + flex-wrap: wrap; } .selectable-recipients-container .recipient-card-container { - display: flex; - flex-direction: row; - flex-wrap: wrap; + display: flex; + flex-direction: row; + flex-wrap: wrap; } -@media(min-width: 321px) and (max-width: 820px) { - .selected-recipients-container { - padding: 10px 5px 10px 5px; - } +@media (min-width: 321px) and (max-width: 820px) { + .selected-recipients-container { + padding: 10px 5px 10px 5px; + } } - diff --git a/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.jsx b/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.jsx index 862f913a7d..0cad6b71b2 100644 --- a/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.jsx +++ b/web-ui/src/components/feedback_recipient_selector/FeedbackRecipientSelector.jsx @@ -1,19 +1,19 @@ -import React, { useContext, useEffect, useState, useRef } from "react"; +import React, { useContext, useEffect, useState, useRef } from 'react'; import { styled } from '@mui/material/styles'; -import "./FeedbackRecipientSelector.css"; -import FeedbackRecipientCard from "../feedback_recipient_card/FeedbackRecipientCard"; -import { AppContext } from "../../context/AppContext"; +import './FeedbackRecipientSelector.css'; +import FeedbackRecipientCard from '../feedback_recipient_card/FeedbackRecipientCard'; +import { AppContext } from '../../context/AppContext'; import { selectProfile, selectCsrfToken, - selectNormalizedMembers, -} from "../../context/selectors"; -import { getFeedbackSuggestion } from "../../api/feedback"; -import { selectCurrentUser } from "../../context/selectors"; -import Typography from "@mui/material/Typography"; -import { TextField, Grid, InputAdornment } from "@mui/material"; -import { Search } from "@mui/icons-material"; -import PropTypes from "prop-types"; + selectNormalizedMembers +} from '../../context/selectors'; +import { getFeedbackSuggestion } from '../../api/feedback'; +import { selectCurrentUser } from '../../context/selectors'; +import Typography from '@mui/material/Typography'; +import { TextField, Grid, InputAdornment } from '@mui/material'; +import { Search } from '@mui/icons-material'; +import PropTypes from 'prop-types'; const PREFIX = 'FeedbackRecipientSelector'; const classes = { @@ -26,28 +26,28 @@ const classes = { const StyledGrid = styled(Grid)({ [`& .${classes.search}`]: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' }, [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' }, [`& .${classes.searchInputIcon}`]: { - color: "gray", + color: 'gray' }, [`& .${classes.members}`]: { - display: "flex", - flexWrap: "wrap", - justifyContent: "space-evenly", - width: "100%", - }, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + width: '100%' + } }); const propTypes = { changeQuery: PropTypes.func.isRequired, fromQuery: PropTypes.array.isRequired, - forQuery: PropTypes.string.isRequired, + forQuery: PropTypes.string.isRequired }; const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { @@ -57,7 +57,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { const { id } = userProfile; const searchTextUpdated = useRef(false); const hasRenewedFromURL = useRef(false); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [profiles, setProfiles] = useState([]); const normalizedMembers = selectNormalizedMembers(state, searchText); @@ -65,15 +65,15 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { if ( !searchTextUpdated.current && searchText.length !== 0 && - searchText !== "" && + searchText !== '' && searchText ) { if (fromQuery !== undefined) { - let selectedMembers = profiles.filter((profile) => + let selectedMembers = profiles.filter(profile => fromQuery.includes(profile.id) ); - let filteredNormalizedMembers = normalizedMembers.filter((member) => { - return !selectedMembers.some((selectedMember) => { + let filteredNormalizedMembers = normalizedMembers.filter(member => { + return !selectedMembers.some(selectedMember => { return selectedMember.id === member.id; }); }); @@ -93,11 +93,10 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { fromQuery !== undefined ) { let profileCopy = profiles; - if (typeof fromQuery === "string") { + if (typeof fromQuery === 'string') { let newProfile = { id: fromQuery }; if ( - profiles.filter((member) => member.id === newProfile.id).length === - 0 + profiles.filter(member => member.id === newProfile.id).length === 0 ) { profileCopy.push(newProfile); } @@ -105,8 +104,8 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { for (let i = 0; i < fromQuery.length; ++i) { let newProfile = { id: fromQuery[i] }; if ( - profiles.filter((member) => member.id === newProfile.id) - .length === 0 + profiles.filter(member => member.id === newProfile.id).length === + 0 ) { profileCopy.push(newProfile); } @@ -128,12 +127,12 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { return null; } - if (csrf && (searchText === "" || searchText.length === 0)) { - getSuggestions().then((res) => { + if (csrf && (searchText === '' || searchText.length === 0)) { + getSuggestions().then(res => { bindFromURL(); if (res !== undefined && res !== null) { - let filteredProfileCopy = profiles.filter((member) => { - return !res.some((suggestedMember) => { + let filteredProfileCopy = profiles.filter(member => { + return !res.some(suggestedMember => { return suggestedMember.id === member.id; }); }); @@ -144,7 +143,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { } // eslint-disable-next-line react-hooks/exhaustive-deps }, [id, csrf, searchText]); - const cardClickHandler = (id) => { + const cardClickHandler = id => { if (!Array.isArray(fromQuery)) { fromQuery = fromQuery ? [fromQuery] : []; } @@ -154,7 +153,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { fromQuery.push(id); } - changeQuery("from", fromQuery); + changeQuery('from', fromQuery); hasRenewedFromURL.current = false; }; @@ -162,11 +161,11 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { if (fromQuery) { const title = ( {fromQuery.length} recipient - {fromQuery.length === 1 ? "" : "s"} selected + {fromQuery.length === 1 ? '' : 's'} selected ); @@ -175,7 +174,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { return ( <> {title} -

    +

    Click on recipients to request feedback from them

    @@ -187,7 +186,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { <> {title}
    - {fromQuery.map((id) => ( + {fromQuery.map(id => ( { label="Search employees..." placeholder="Member Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); searchTextUpdated.current = false; }} @@ -223,7 +222,7 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => { > - ), + ) }} /> @@ -234,11 +233,11 @@ const FeedbackRecipientSelector = ({ changeQuery, fromQuery, forQuery }) => {
    {profiles .filter( - (profile) => + profile => !fromQuery || (!fromQuery.includes(profile.id) && profile.id !== forQuery) ) - .map((profile) => ( + .map(profile => ( { - it("renders the component", () => { - snapshot(); +describe('FeedbackRecipientSelector', () => { + it('renders the component', () => { + snapshot( + + + + + + ); }); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.css b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.css index 4c857a3573..7263c0f763 100644 --- a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.css +++ b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.css @@ -1,90 +1,83 @@ - .person-name { - color: black; + color: black; } .response-link { - color: rgb(42, 55, 172); - text-decoration: none; - font-size: 1rem; + color: rgb(42, 55, 172); + text-decoration: none; + font-size: 1rem; } .has-padding-top { - padding-top: 1em; + padding-top: 1em; } .response-link:hover { - background-color: lightgray ; + background-color: lightgray; } .red-text { - color: rgb(207, 120, 20); + color: rgb(207, 120, 20); } .person-divider { - min-width: 100%; - color: rgb(231, 230, 227); + min-width: 100%; + color: rgb(231, 230, 227); } .dark-gray-text { - color: rgb(85, 83, 83); + color: rgb(85, 83, 83); } .person-row { - padding-top: 1em; - padding-bottom: 1em; + padding-top: 1em; + padding-bottom: 1em; } .MuiCardHeader-action { - margin: 1em 0 0; - padding-top: 1em; + margin: 1em 0 0; + padding-top: 1em; } .no-wrap { - flex-wrap: nowrap; + flex-wrap: nowrap; } .align-center { - text-align: center; - justify-content: center; - align-self: center; - align-content: center; + text-align: center; + justify-content: center; + align-self: center; + align-content: center; } .align-end { - text-align: right; + text-align: right; } .feedback-request-card { - display: flex; - flex-direction: row; - justify-content: center; - align-self: center; - margin-top: 1em; - width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + align-self: center; + margin-top: 1em; + width: 100%; } .MuiFormControl-root { - width: 20%; - margin-right: 2em; + width: 20%; + margin-right: 2em; } .responder-name { - display: inline; + display: inline; } - @media screen and (max-width: 769px) { - - .card-info-container { - margin-left: 2.5em; - text-align:right; - } - .response-link { - font-size: 0.7rem; - } - - + .card-info-container { + margin-left: 2.5em; + text-align: right; } - - + .response-link { + font-size: 0.7rem; + } +} diff --git a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.jsx b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.jsx index 816277ecf8..4d85ff1e7f 100644 --- a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.jsx +++ b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.jsx @@ -1,23 +1,23 @@ -import React, { useCallback, useContext, useEffect, useState } from "react"; -import {styled} from '@mui/styles'; -import FeedbackRequestSubcard from "./feedback_request_subcard/FeedbackRequestSubcard"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { styled } from '@mui/styles'; +import FeedbackRequestSubcard from './feedback_request_subcard/FeedbackRequestSubcard'; import Card from '@mui/material/Card'; -import {Avatar, Typography} from '@mui/material'; +import { Avatar, Typography } from '@mui/material'; import CardContent from '@mui/material/CardContent'; import CardActions from '@mui/material/CardActions'; import Collapse from '@mui/material/Collapse'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import IconButton from '@mui/material/IconButton'; import Grid from '@mui/material/Grid'; -import {useHistory} from "react-router-dom"; -import PropTypes from "prop-types"; -import "./FeedbackRequestCard.css"; -import { selectProfile } from "../../context/selectors"; -import { AppContext } from "../../context/AppContext"; -import { getAvatarURL } from "../../api/api.js"; -import Divider from "@mui/material/Divider"; -import Button from "@mui/material/Button"; -import queryString from "query-string"; +import { useHistory } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import './FeedbackRequestCard.css'; +import { selectProfile } from '../../context/selectors'; +import { AppContext } from '../../context/AppContext'; +import { getAvatarURL } from '../../api/api.js'; +import Divider from '@mui/material/Divider'; +import Button from '@mui/material/Button'; +import queryString from 'query-string'; const PREFIX = 'FeedbackRequestCard'; const classes = { @@ -28,54 +28,54 @@ const classes = { const StyledCard = styled(Card)({ [`&.${classes.root}`]: { - color: "gray", - width: "100%", - maxHeight: "10%", - "@media (max-width:769px)": { - width: "100%", - maxWidth: "100%", - }, + color: 'gray', + width: '100%', + maxHeight: '10%', + '@media (max-width:769px)': { + width: '100%', + maxWidth: '100%' + } }, [`& .${classes.expandClose}`]: { - transform: "rotate(0deg)", - marginLeft: "auto", - transition: "transform 0.1s linear", + transform: 'rotate(0deg)', + marginLeft: 'auto', + transition: 'transform 0.1s linear' }, [`& .${classes.expandOpen}`]: { - transform: "rotate(180deg)", - transition: "transform 0.1s linear", - marginLeft: "auto", + transform: 'rotate(180deg)', + transition: 'transform 0.1s linear', + marginLeft: 'auto' }, - "& .MuiCardContent-root": { + '& .MuiCardContent-root': { paddingBottom: 0, paddingTop: 0, - "&:last-child": { + '&:last-child': { paddingBottom: 0 } }, - "& .MuiCardActions-root": { + '& .MuiCardActions-root': { padding: 0, - maxHeight: "30px" + maxHeight: '30px' }, - "& .MuiTypography-body1": { - "@media (max-width:767px)": { - fontSize: "0.7rem", + '& .MuiTypography-body1': { + '@media (max-width:767px)': { + fontSize: '0.7rem' } } }); const SortOption = { - SENT_DATE: "sent_date", - SUBMISSION_DATE: "submission_date", - RECIPIENT_NAME_ALPHABETICAL: "recipient_name_alphabetical", - RECIPIENT_NAME_REVERSE_ALPHABETICAL: "recipient_name_reverse_alphabetical", + SENT_DATE: 'sent_date', + SUBMISSION_DATE: 'submission_date', + RECIPIENT_NAME_ALPHABETICAL: 'recipient_name_alphabetical', + RECIPIENT_NAME_REVERSE_ALPHABETICAL: 'recipient_name_reverse_alphabetical' }; const DateRange = { - THREE_MONTHS: "3mo", - SIX_MONTHS: "6mo", - ONE_YEAR: "1yr", - ALL_TIME: "all", + THREE_MONTHS: '3mo', + SIX_MONTHS: '6mo', + ONE_YEAR: '1yr', + ALL_TIME: 'all' }; const propTypes = { @@ -86,14 +86,14 @@ const propTypes = { SortOption.SENT_DATE, SortOption.SUBMISSION_DATE, SortOption.RECIPIENT_NAME_ALPHABETICAL, - SortOption.RECIPIENT_NAME_REVERSE_ALPHABETICAL, + SortOption.RECIPIENT_NAME_REVERSE_ALPHABETICAL ]).isRequired, dateRange: PropTypes.oneOf([ DateRange.THREE_MONTHS, DateRange.SIX_MONTHS, DateRange.ONE_YEAR, - DateRange.ALL_TIME, - ]).isRequired, + DateRange.ALL_TIME + ]).isRequired }; const FeedbackRequestCard = ({ @@ -101,7 +101,7 @@ const FeedbackRequestCard = ({ templateName, responses, sortType, - dateRange, + dateRange }) => { const { state } = useContext(AppContext); const requesteeProfile = selectProfile(state, requesteeId); @@ -115,7 +115,7 @@ const FeedbackRequestCard = ({ }; const withinDateRange = useCallback( - (requestDate) => { + requestDate => { let oldestDate = new Date(); switch (dateRange) { case DateRange.THREE_MONTHS: @@ -134,7 +134,7 @@ const FeedbackRequestCard = ({ } if (Array.isArray(requestDate)) { - requestDate = new Date(requestDate.join("/")); + requestDate = new Date(requestDate.join('/')); // have to do for Safari } return requestDate >= oldestDate; @@ -146,16 +146,16 @@ const FeedbackRequestCard = ({ let message; switch (dateRange) { case DateRange.THREE_MONTHS: - message = "No requests in the past 3 months"; + message = 'No requests in the past 3 months'; break; case DateRange.SIX_MONTHS: - message = "No requests in the past 6 months"; + message = 'No requests in the past 6 months'; break; case DateRange.ONE_YEAR: - message = "No requests in the past year"; + message = 'No requests in the past year'; break; default: - message = "No requests"; + message = 'No requests'; } return ( @@ -163,9 +163,9 @@ const FeedbackRequestCard = ({
    {message} @@ -176,9 +176,9 @@ const FeedbackRequestCard = ({ const handleViewAllResponsesClick = () => { if (sortedResponses.length === 0) return; - const requestIds = sortedResponses.map((response) => response.id); + const requestIds = sortedResponses.map(response => response.id); const params = { - request: requestIds, + request: requestIds }; history.push(`/feedback/view/responses/?${queryString.stringify(params)}`); @@ -187,7 +187,7 @@ const FeedbackRequestCard = ({ // Sort the responses by either the send date or the submit date useEffect(() => { let responsesCopy = [...responses]; - responsesCopy = responsesCopy.filter((response) => + responsesCopy = responsesCopy.filter(response => withinDateRange(response.sendDate) ); @@ -240,7 +240,7 @@ const FeedbackRequestCard = ({ className="no-wrap" > - + @@ -259,7 +259,7 @@ const FeedbackRequestCard = ({ onClick={handleViewAllResponsesClick} disabled={ sortedResponses.length === 0 || - sortedResponses.every((o) => o.status === "pending") + sortedResponses.every(o => o.status === 'pending') } > View all responses @@ -276,14 +276,15 @@ const FeedbackRequestCard = ({ aria-expanded={expanded} aria-label="show more" className={expanded ? classes.expandOpen : classes.expandClose} - size="large"> + size="large" + > {sortedResponses && sortedResponses.length - ? sortedResponses.map((response) => { + ? sortedResponses.map(response => { return ( { - return (); - }] + decorators: [ + ViewFeedbackSelector => { + return ( + + + + + + ); + } + ] }; -const Template = (args) => ; +const Template = args => ; export const DefaultTemplate = Template.bind({}); DefaultTemplate.args = {}; @@ -18,18 +26,17 @@ export const sampleCardTemplate = Template.bind({}); sampleCardTemplate.args = { requesteeId: '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', templateName: 'Survey 1', - responses: [ { - id: "c15961e4-6e9b-42cd-8140-ece9efe2445c", - creatorId: "7a6a2d4e-e435-4ec9-94d8-f1ed7c779498", - requesteeId: "b2d35288-7f1e-4549-aa2b-68396b162490", - recipientId: "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - templateId: "97b0a312-e5dd-46f4-a600-d8be2ad925bb", - sendDate: [2020, 7, 7], - dueDate: null, - submitDate: [2020, 7, 8], - status: "submitted", - } + responses: [ + { + id: 'c15961e4-6e9b-42cd-8140-ece9efe2445c', + creatorId: '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', + requesteeId: 'b2d35288-7f1e-4549-aa2b-68396b162490', + recipientId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + templateId: '97b0a312-e5dd-46f4-a600-d8be2ad925bb', + sendDate: [2020, 7, 7], + dueDate: null, + submitDate: [2020, 7, 8], + status: 'submitted' + } ] -} - - +}; diff --git a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.test.jsx b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.test.jsx index 06414d399c..1d78434b16 100644 --- a/web-ui/src/components/feedback_request_card/FeedbackRequestCard.test.jsx +++ b/web-ui/src/components/feedback_request_card/FeedbackRequestCard.test.jsx @@ -1,9 +1,9 @@ -import React from "react"; -import { BrowserRouter } from "react-router-dom"; -import {AppContextProvider } from "../../context/AppContext"; -import FeedbackRequestCard from "./FeedbackRequestCard"; +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import { AppContextProvider } from '../../context/AppContext'; +import FeedbackRequestCard from './FeedbackRequestCard'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( @@ -12,19 +12,19 @@ it("renders correctly", () => { templateName="Sample Template" responses={[ { - id: "c15961e4-6e9b-42cd-8140-ece9efe2445c", - creatorId: "7a6a2d4e-e435-4ec9-94d8-f1ed7c779498", - requesteeId: "b2d35288-7f1e-4549-aa2b-68396b162490", - recipientId: "2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d", - templateId: "97b0a312-e5dd-46f4-a600-d8be2ad925bb", + id: 'c15961e4-6e9b-42cd-8140-ece9efe2445c', + creatorId: '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', + requesteeId: 'b2d35288-7f1e-4549-aa2b-68396b162490', + recipientId: '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', + templateId: '97b0a312-e5dd-46f4-a600-d8be2ad925bb', sendDate: [2020, 7, 7], dueDate: null, submitDate: [2020, 7, 8], - status: "submitted", - }, - ]}/> + status: 'submitted' + } + ]} + /> - ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.css b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.css index 0dfc05e046..1bb9ee5bbc 100644 --- a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.css +++ b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.css @@ -1,17 +1,17 @@ .feedback-request-enable-edits-modal { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - max-width: 700px; - padding: 0.5rem; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 700px; + padding: 0.5rem; } .cancel-feedback-request-modal { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - max-width: 700px; - padding: 0.5rem; -} \ No newline at end of file + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 700px; + padding: 0.5rem; +} diff --git a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.jsx b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.jsx index 848813d542..2c83b22761 100644 --- a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.jsx +++ b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.jsx @@ -1,27 +1,41 @@ -import React, {useContext, useCallback, useState} from "react"; -import { styled } from "@mui/material/styles"; -import PropTypes from "prop-types"; -import Grid from "@mui/material/Grid"; -import Typography from "@mui/material/Typography"; -import Divider from "@mui/material/Divider"; -import { sendReminderNotification } from "../../../api/notifications"; -import {cancelFeedbackRequest, updateFeedbackRequest} from "../../../api/feedback"; -import IconButton from "@mui/material/IconButton"; -import NotificationsActiveIcon from "@mui/icons-material/NotificationsActive"; -import TrashIcon from "@mui/icons-material/Delete"; -import { AppContext } from "../../../context/AppContext"; -import { selectCsrfToken, selectProfile } from "../../../context/selectors"; -import {Avatar, Button, Card, CardActions, CardContent, CardHeader, Modal, Menu, Tooltip, Alert} from "@mui/material"; -import { UPDATE_TOAST } from "../../../context/actions"; -import DateFnsAdapter from "@date-io/date-fns"; -import { getAvatarURL } from "../../../api/api"; -import { makeStyles } from "@mui/styles"; -import MoreIcon from "@mui/icons-material/MoreVert"; -import MenuItem from "@mui/material/MenuItem"; +import React, { useContext, useCallback, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import PropTypes from 'prop-types'; +import Grid from '@mui/material/Grid'; +import Typography from '@mui/material/Typography'; +import Divider from '@mui/material/Divider'; +import { sendReminderNotification } from '../../../api/notifications'; +import { + cancelFeedbackRequest, + updateFeedbackRequest +} from '../../../api/feedback'; +import IconButton from '@mui/material/IconButton'; +import NotificationsActiveIcon from '@mui/icons-material/NotificationsActive'; +import TrashIcon from '@mui/icons-material/Delete'; +import { AppContext } from '../../../context/AppContext'; +import { selectCsrfToken, selectProfile } from '../../../context/selectors'; +import { + Avatar, + Button, + Card, + CardActions, + CardContent, + CardHeader, + Modal, + Menu, + Tooltip, + Alert +} from '@mui/material'; +import { UPDATE_TOAST } from '../../../context/actions'; +import DateFnsAdapter from '@date-io/date-fns'; +import { getAvatarURL } from '../../../api/api'; +import { makeStyles } from '@mui/styles'; +import MoreIcon from '@mui/icons-material/MoreVert'; +import MenuItem from '@mui/material/MenuItem'; -import "./FeedbackRequestSubcard.css"; +import './FeedbackRequestSubcard.css'; -const PREFIX = "FeedbackRequestSubcard"; +const PREFIX = 'FeedbackRequestSubcard'; const classes = { redTypography: `${PREFIX}-redTypography`, yellowTypography: `${PREFIX}-yellowTypography`, @@ -31,36 +45,36 @@ const classes = { }; // TODO jss-to-styled codemod: The Fragment root was replaced by div. Change the tag if needed. -const Root = styled("div")({ +const Root = styled('div')({ [`& .${classes.redTypography}`]: { - color: "#FF0000", + color: '#FF0000' }, [`& .${classes.yellowTypography}`]: { - color: "#EE8C00", + color: '#EE8C00' }, [`& .${classes.greenTypography}`]: { - color: "#006400", + color: '#006400' }, [`& .${classes.darkGrayTypography}`]: { - color: "#333333", + color: '#333333' }, [`& .${classes.grayTypography}`]: { - color: "gray" + color: 'gray' } }); const useResponsiveStyles = makeStyles({ marginMobile: { '@media (max-width:960px)': { - marginBottom: "0.5vh", - marginTop: "2vh", - }, - }, + marginBottom: '0.5vh', + marginTop: '2vh' + } + } }); const dateFns = new DateFnsAdapter(); const propTypes = { - request: PropTypes.object.isRequired, + request: PropTypes.object.isRequired }; const FeedbackRequestSubcard = ({ request }) => { @@ -70,13 +84,13 @@ const FeedbackRequestSubcard = ({ request }) => { let { submitDate, dueDate, sendDate } = request; const recipient = selectProfile(state, request?.recipientId); submitDate = submitDate - ? dateFns.format(new Date(submitDate.join("/")), "LLLL dd, yyyy") + ? dateFns.format(new Date(submitDate.join('/')), 'LLLL dd, yyyy') : null; - sendDate = dateFns.format(new Date(sendDate.join("/")), "LLLL dd, yyyy"); + sendDate = dateFns.format(new Date(sendDate.join('/')), 'LLLL dd, yyyy'); dueDate = dueDate - ? dateFns.format(new Date(dueDate.join("/")), "LLLL dd, yyyy") - : null + ? dateFns.format(new Date(dueDate.join('/')), 'LLLL dd, yyyy') + : null; const [requestStatus, setRequestStatus] = useState(request?.status); const [requestDueDate, setRequestDueDate] = useState(dueDate); @@ -99,17 +113,17 @@ const FeedbackRequestSubcard = ({ request }) => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Notification sent!", - }, + severity: 'success', + toast: 'Notification sent!' + } }); } else { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Notification could not be sent :(", - }, + severity: 'error', + toast: 'Notification could not be sent :(' + } }); } }; @@ -118,42 +132,47 @@ const FeedbackRequestSubcard = ({ request }) => { } }, [recipientId, recipientEmail, csrf]); - const handleCancelClick = useCallback((feedbackRequest) => { - const cancelRequest = async (feedbackRequest) => { - const res = await cancelFeedbackRequest(feedbackRequest, csrf); - const cancellationResponse = - res && res.payload && res.payload.status === 200 && !res.error ? res.payload.data : null; - if (cancellationResponse) { - window.snackDispatch({ - type: UPDATE_TOAST, - payload: { - severity: "success", - toast: "Feedback request canceled", - }, - }); - } else { - window.snackDispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: - "There was an error deleting the feedback request. Please contact your administrator.", - }, + const handleCancelClick = useCallback( + feedbackRequest => { + const cancelRequest = async feedbackRequest => { + const res = await cancelFeedbackRequest(feedbackRequest, csrf); + const cancellationResponse = + res && res.payload && res.payload.status === 200 && !res.error + ? res.payload.data + : null; + if (cancellationResponse) { + window.snackDispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'success', + toast: 'Feedback request canceled' + } + }); + } else { + window.snackDispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: + 'There was an error deleting the feedback request. Please contact your administrator.' + } + }); + } + return cancellationResponse; + }; + + setCancelingRequest(false); + if (csrf) { + cancelRequest(feedbackRequest).then(res => { + if (res) { + setRequestStatus(res.status); + setRequestDueDate(res.dueDate); + } }); } - return cancellationResponse; - }; - - setCancelingRequest(false); - if (csrf) { - cancelRequest(feedbackRequest).then((res) => { - if (res) { - setRequestStatus(res.status); - setRequestDueDate(res.dueDate); - } - }); - } - }, [csrf]); + }, + [csrf] + ); const handleEnableEditsClick = useCallback(() => { setEnableEditsDialog(false); @@ -161,21 +180,23 @@ const FeedbackRequestSubcard = ({ request }) => { const enableFeedbackEdits = async () => { const requestWithEditsEnabled = { ...request, - status: "sent", + status: 'sent', submitDate: null - } + }; const res = await updateFeedbackRequest(requestWithEditsEnabled, csrf); - return res && res.payload && res.payload.data && !res.error ? res.payload.data : null; - } + return res && res.payload && res.payload.data && !res.error + ? res.payload.data + : null; + }; if (csrf) { - enableFeedbackEdits().then((res) => { + enableFeedbackEdits().then(res => { if (res) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", + severity: 'success', toast: `Enabled edits for ${recipient?.name}'s feedback` } }); @@ -183,8 +204,8 @@ const FeedbackRequestSubcard = ({ request }) => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Could not enable edits for this feedback request" + severity: 'error', + toast: 'Could not enable edits for this feedback request' } }); } @@ -209,18 +230,16 @@ const FeedbackRequestSubcard = ({ request }) => { Submitted {submitDate} ); - } else if (requestStatus === "pending") { + } else if (requestStatus === 'pending') { return ( Scheduled for send on {sendDate} ); - } else if (requestStatus === "canceled") { - return ( - - Canceled - - ); + } else if (requestStatus === 'canceled') { + return ( + Canceled + ); } else { return ( @@ -236,7 +255,7 @@ const FeedbackRequestSubcard = ({ request }) => { @@ -248,7 +267,7 @@ const FeedbackRequestSubcard = ({ request }) => { > @@ -266,39 +285,41 @@ const FeedbackRequestSubcard = ({ request }) => { Sent on {sendDate} - {requestDueDate ? `Due on ${requestDueDate}` : "No due date"} + {requestDueDate ? `Due on ${requestDueDate}` : 'No due date'} - {request && !request.submitDate && requestStatus !== "canceled" && ( - <> - - setCancelingRequest(true)} - aria-label="Cancel Request" - label="Cancel Request" - > - - - - - + + setCancelingRequest(true)} + aria-label="Cancel Request" + label="Cancel Request" + > + + + + - - - - - )} + + + + + + )} {request && request.submitDate && request.id ? ( <> - setExpandMenuAnchor(event.currentTarget)}> - + setExpandMenuAnchor(event.currentTarget)} + > + setExpandMenuAnchor(false)} anchorOrigin={{ - vertical: "bottom", - horizontal: "center" + vertical: 'bottom', + horizontal: 'center' }} transformOrigin={{ - vertical: "top", - horizontal: "center" + vertical: 'top', + horizontal: 'center' }} > - { - setExpandMenuAnchor(null); - setEnableEditsDialog(true); - }}>Enable Edits + { + setExpandMenuAnchor(null); + setEnableEditsDialog(true); + }} + > + Enable Edits + - setEnableEditsDialog(false)}> + setEnableEditsDialog(false)} + > - Enable Feedback Edits}/> + + Enable Feedback Edits + + } + /> - Are you sure you want {recipient?.name} to be able to make changes to this feedback submission? - This will allow them to edit their original responses and resubmit them. + Are you sure you want {recipient?.name} to be + able to make changes to this feedback submission? This + will allow them to edit their original responses and + resubmit them. - - {recipient?.name}'s feedback for this request will be inaccessible until they submit their answers again. + + {recipient?.name}'s feedback for this request will be + inaccessible until they submit their answers again. - - + + @@ -351,19 +400,40 @@ const FeedbackRequestSubcard = ({ request }) => { - {request && !request.submitDate && requestStatus !== "canceled" && ( - setCancelingRequest(false)}> + {request && !request.submitDate && requestStatus !== 'canceled' && ( + setCancelingRequest(false)} + > - Cancel Feedback Request}/> + + Cancel Feedback Request + + } + /> - Are you sure you want to cancel the feedback request sent to {recipient?.name} on {sendDate}? - The recipient will not be able to respond to this request once it is canceled. + Are you sure you want to cancel the feedback request sent to{' '} + {recipient?.name} on {sendDate}? The recipient + will not be able to respond to this request once it is + canceled. - - + + diff --git a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.test.jsx b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.test.jsx index eb5800f780..3681bb294d 100644 --- a/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.test.jsx +++ b/web-ui/src/components/feedback_request_card/feedback_request_subcard/FeedbackRequestSubcard.test.jsx @@ -1,29 +1,29 @@ -import { ThemeProvider } from "@mui/styles"; -import React from "react"; -import { BrowserRouter } from "react-router-dom"; -import {AppContextProvider } from "../../../context/AppContext"; -import FeedbackRequestSubcard from "./FeedbackRequestSubcard"; +import { ThemeProvider } from '@mui/styles'; +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import { AppContextProvider } from '../../../context/AppContext'; +import FeedbackRequestSubcard from './FeedbackRequestSubcard'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + - ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.css b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.css index 892ec237fd..704cec7b34 100644 --- a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.css +++ b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.css @@ -1,16 +1,15 @@ .request-confirmation { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-content: center; - align-items: center; - padding-top: 40px; - overflow-x: hidden; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-content: center; + align-items: center; + padding-top: 40px; + overflow-x: hidden; } .recipients-list { - padding-top: 10px; + padding-top: 10px; } - diff --git a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.jsx b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.jsx index e1c36898e4..3d058cff8e 100644 --- a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.jsx +++ b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.jsx @@ -1,15 +1,15 @@ -import React, { useContext } from "react"; +import React, { useContext } from 'react'; import { styled } from '@mui/material/styles'; -import Typography from "@mui/material/Typography"; +import Typography from '@mui/material/Typography'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; -import { selectProfile } from "../../context/selectors"; -import { AppContext } from "../../context/AppContext"; -import {Link, useLocation} from 'react-router-dom'; +import { selectProfile } from '../../context/selectors'; +import { AppContext } from '../../context/AppContext'; +import { Link, useLocation } from 'react-router-dom'; import queryString from 'query-string'; -import DateFnsUtils from "@date-io/date-fns"; -import "./FeedbackRequestConfirmation.css"; -import { green } from "@mui/material/colors"; -import Button from "@mui/material/Button"; +import DateFnsUtils from '@date-io/date-fns'; +import './FeedbackRequestConfirmation.css'; +import { green } from '@mui/material/colors'; +import Button from '@mui/material/Button'; const dateUtils = new DateFnsUtils(); const PREFIX = 'FeedbackRequestConfirmation'; @@ -20,16 +20,18 @@ const classes = { const Root = styled('div')({ [`& .${classes.announcement}`]: { - textAlign: "center", - ['@media (max-width:820px)']: { // eslint-disable-line no-useless-computed-key - fontSize: "x-large", - }, + textAlign: 'center', + ['@media (max-width:820px)']: { + // eslint-disable-line no-useless-computed-key + fontSize: 'x-large' + } }, [`& .${classes.checkmark}`]: { - ['@media (max-width:820px)']: { // eslint-disable-line no-useless-computed-key - width: "65%", - }, - }, + ['@media (max-width:820px)']: { + // eslint-disable-line no-useless-computed-key + width: '65%' + } + } }); let today = new Date(); @@ -43,41 +45,49 @@ const FeedbackRequestConfirmation = () => { const sendQuery = query.send?.toString(); const requestee = selectProfile(state, forQuery); let recipientInfo = getRecipientNames(); - let sendDate = dateUtils.parse(sendQuery, "MM/dd/yyyy", new Date()); + let sendDate = dateUtils.parse(sendQuery, 'MM/dd/yyyy', new Date()); function getRecipientNames() { if (fromQuery !== undefined) { - let fromArray = fromQuery.split(',') - let recipientProfiles = [] + let fromArray = fromQuery.split(','); + let recipientProfiles = []; if (fromArray.length !== 0) { for (let i = 0; i < fromArray.length; ++i) { - let element = fromArray[i] - recipientProfiles.push(element) + let element = fromArray[i]; + recipientProfiles.push(element); } - } else { - recipientProfiles.push(fromQuery) - + recipientProfiles.push(fromQuery); } return recipientProfiles; - } - } return ( - checkmark-image - Feedback request {dateUtils.isBefore(today, sendDate) ? " scheduled on: " + sendQuery : " sent"} for {requestee?.name} - Sent to: - {recipientInfo?.map((member, index) => - `${selectProfile(state, member)?.name}${index === recipientInfo.length - 1 ? "" : ', '}` + + checkmark-image + + + + Feedback request{' '} + {dateUtils.isBefore(today, sendDate) + ? ' scheduled on: ' + sendQuery + : ' sent'}{' '} + for {requestee?.name}{' '} + + + + Sent to: + {recipientInfo?.map( + (member, index) => + `${selectProfile(state, member)?.name}${index === recipientInfo.length - 1 ? '' : ', '}` )} - + ); -} +}; -export default FeedbackRequestConfirmation; \ No newline at end of file +export default FeedbackRequestConfirmation; diff --git a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.test.jsx b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.test.jsx index f0c60f73cd..f85e857e0a 100644 --- a/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.test.jsx +++ b/web-ui/src/components/feedback_request_confirmation/FeedbackRequestConfirmation.test.jsx @@ -1,15 +1,14 @@ -import React from "react"; -import { BrowserRouter } from "react-router-dom"; -import {AppContextProvider } from "../../context/AppContext"; -import FeedbackRequestConfirmation from "./FeedbackRequestConfirmation"; +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import { AppContextProvider } from '../../context/AppContext'; +import FeedbackRequestConfirmation from './FeedbackRequestConfirmation'; -it("renders the confirmation message", () => { +it('renders the confirmation message', () => { snapshot( - ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_request_confirmation/__snapshots__/FeedbackRequestConfirmation.test.jsx.snap b/web-ui/src/components/feedback_request_confirmation/__snapshots__/FeedbackRequestConfirmation.test.jsx.snap index 6dc84e0afc..76bc7061ac 100644 --- a/web-ui/src/components/feedback_request_confirmation/__snapshots__/FeedbackRequestConfirmation.test.jsx.snap +++ b/web-ui/src/components/feedback_request_confirmation/__snapshots__/FeedbackRequestConfirmation.test.jsx.snap @@ -21,9 +21,11 @@ exports[`renders the confirmation message 1`] = ` class="MuiTypography-root MuiTypography-h3 FeedbackRequestConfirmation-announcement css-gepadz-MuiTypography-root" > - Feedback request + Feedback request + sent - for + + for diff --git a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.css b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.css index 647b9cd335..46a3fed15f 100644 --- a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.css +++ b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.css @@ -1,87 +1,86 @@ .sbi-tips-page { - height: 100%; + height: 100%; } .submission-tips-header { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-gap: 10px; - align-items: center; - margin-top: 3em; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-gap: 10px; + align-items: center; + margin-top: 3em; } .submission-tips { - display: flex; - flex-direction: row; - margin: 8em 4em 0 4em; - justify-content: space-evenly; + display: flex; + flex-direction: row; + margin: 8em 4em 0 4em; + justify-content: space-evenly; } .sbi-circle { - background: #3f51b5; - color: #fff; - width: 250px; - height: 250px; - line-height: 250px; - border-radius: 50%; - font-size: 150px; - text-align: center; + background: #3f51b5; + color: #fff; + width: 250px; + height: 250px; + line-height: 250px; + border-radius: 50%; + font-size: 150px; + text-align: center; } .sbi-info { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 0 2em 0 2em; - max-width: 400px; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 0 2em 0 2em; + max-width: 400px; } .sbi-info .sbi-info-title { - margin: 20px 0 10px 0; + margin: 20px 0 10px 0; } @media (max-width: 800px) { + .header { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 10px; + align-items: center; + margin-top: 3em; + padding-left: 14px; + margin-bottom: 28px; + } - .header { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 10px; - align-items: center; - margin-top: 3em; - padding-left: 14px; - margin-bottom: 28px; - } - - .submission-tips { - display: flex; - flex-direction: column; - margin: 2em 1em 1em 1em; - } + .submission-tips { + display: flex; + flex-direction: column; + margin: 2em 1em 1em 1em; + } - .sbi-info { - display: flex; - flex-direction: row; - padding: 0; - margin-bottom: 2em; - } + .sbi-info { + display: flex; + flex-direction: row; + padding: 0; + margin-bottom: 2em; + } - .sbi-circle { - width: 80px; - height: 80px; - font-size: 30px; - line-height: 80px; - min-width: 80px; - margin-right: 20px; - } + .sbi-circle { + width: 80px; + height: 80px; + font-size: 30px; + line-height: 80px; + min-width: 80px; + margin-right: 20px; + } - .sbi-info .sbi-info-title { - font-size: 20px; - text-align: left; - } + .sbi-info .sbi-info-title { + font-size: 20px; + text-align: left; + } - .sbi-info .sbi-info-description { - font-size: 12px; - text-align: left; - } -} \ No newline at end of file + .sbi-info .sbi-info-description { + font-size: 12px; + text-align: left; + } +} diff --git a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.jsx b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.jsx index df47713923..7ea53d6edd 100644 --- a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.jsx +++ b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.jsx @@ -1,10 +1,10 @@ -import React from "react"; +import React from 'react'; import { styled } from '@mui/material/styles'; -import Typography from "@mui/material/Typography"; +import Typography from '@mui/material/Typography'; -import "./FeedbackSubmissionTips.css"; -import Button from "@mui/material/Button"; -import PropTypes from "prop-types"; +import './FeedbackSubmissionTips.css'; +import Button from '@mui/material/Button'; +import PropTypes from 'prop-types'; const PREFIX = 'FeedbackSubmissionTips'; const classes = { @@ -15,84 +15,99 @@ const classes = { const Root = styled('div')({ [`& .${classes.title}`]: { - textAlign: "center", + textAlign: 'center', gridColumn: 2, - ['@media (max-width: 800px)']: { // eslint-disable-line no-useless-computed-key - fontSize: "34px", + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key + fontSize: '34px', gridColumn: 1, - textAlign: "left", - + textAlign: 'left' } }, [`& .${classes.button}`]: { - justifySelf: "end", - marginRight: "3em", - ['@media (max-width: 800px)']: { // eslint-disable-line no-useless-computed-key - marginRight: "0", + justifySelf: 'end', + marginRight: '3em', + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key + marginRight: '0' } - }, [`& .${classes.announcement}`]: { - textAlign: "center", - marginBottom: "0px", - ['@media (max-width: 800px)']: { // eslint-disable-line no-useless-computed-key - fontSize: "20px", + textAlign: 'center', + marginBottom: '0px', + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key + fontSize: '20px' } } }); const sbiInfo = [ { - letter: "S", - title: "Situation", - description: "Describe the situation; be specific about when and where it occurred." + letter: 'S', + title: 'Situation', + description: + 'Describe the situation; be specific about when and where it occurred.' }, { - letter: "B", - title: "Behavior", - description: "Describe the observable behavior; don't assume you know what the other person was thinking." + letter: 'B', + title: 'Behavior', + description: + "Describe the observable behavior; don't assume you know what the other person was thinking." }, { - letter: "I", - title: "Impact", - description: "Describe what you thought and felt as a result of that behavior." + letter: 'I', + title: 'Impact', + description: + 'Describe what you thought and felt as a result of that behavior.' } ]; const propTypes = { onNextClick: PropTypes.func -} +}; -const FeedbackSubmissionTips = (props) => { +const FeedbackSubmissionTips = props => { return (
    - Feedback Tips + + Feedback Tips +
    - SBI is a common approach to providing constructive and fair feedback + + + SBI is a common approach to providing constructive and fair feedback{' '} + +
    - {sbiInfo.map((info) => ( + {sbiInfo.map(info => (
    {info.letter}
    - {info.title} - {info.description} + + {info.title} + + + {info.description} +
    ))}
    ); -} +}; FeedbackSubmissionTips.propTypes = propTypes; -export default FeedbackSubmissionTips; \ No newline at end of file +export default FeedbackSubmissionTips; diff --git a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.test.jsx b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.test.jsx index 5eb289f890..ff5068ea2f 100644 --- a/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.test.jsx +++ b/web-ui/src/components/feedback_submission_tips/FeedbackSubmissionTips.test.jsx @@ -1,6 +1,6 @@ -import React from "react"; -import FeedbackSubmissionTips from "./FeedbackSubmissionTips"; +import React from 'react'; +import FeedbackSubmissionTips from './FeedbackSubmissionTips'; -it("renders the feedback tips component.", () => { - snapshot(); -}); \ No newline at end of file +it('renders the feedback tips component.', () => { + snapshot(); +}); diff --git a/web-ui/src/components/feedback_submission_tips/__snapshots__/FeedbackSubmissionTips.test.jsx.snap b/web-ui/src/components/feedback_submission_tips/__snapshots__/FeedbackSubmissionTips.test.jsx.snap index 5fdc67d783..d4c0805ab6 100644 --- a/web-ui/src/components/feedback_submission_tips/__snapshots__/FeedbackSubmissionTips.test.jsx.snap +++ b/web-ui/src/components/feedback_submission_tips/__snapshots__/FeedbackSubmissionTips.test.jsx.snap @@ -34,7 +34,8 @@ exports[`renders the feedback tips component. 1`] = ` class="MuiTypography-root MuiTypography-h5 FeedbackSubmissionTips-announcement css-ag7rrr-MuiTypography-root" > - SBI is a common approach to providing constructive and fair feedback + SBI is a common approach to providing constructive and fair feedback +
    { +const FeedbackSubmitConfirmation = props => { const { state } = useContext(AppContext); const location = useLocation(); const query = queryString.parse(location?.search); @@ -34,7 +39,7 @@ const FeedbackSubmitConfirmation = (props) => { const [feedbackRequest, setFeedbackRequest] = useState(null); const feedbackRequestFetched = useRef(false); - const [requestee, setRequestee] = useState(null) + const [requestee, setRequestee] = useState(null); useEffect(() => { async function getFeedbackRequest(cookie) { @@ -44,17 +49,21 @@ const FeedbackSubmitConfirmation = (props) => { // make call to the API let res = await getFeedbackRequestById(requestQuery, cookie); - return ( - res.payload && + return res.payload && res.payload.data && res.payload.status === 200 && - !res.error) + !res.error ? res.payload.data : null; } - if (csrf && currentUserId && requestQuery && !feedbackRequestFetched.current) { - getFeedbackRequest(csrf).then((request) => { + if ( + csrf && + currentUserId && + requestQuery && + !feedbackRequestFetched.current + ) { + getFeedbackRequest(csrf).then(request => { if (request) { setFeedbackRequest(request); } @@ -68,17 +77,24 @@ const FeedbackSubmitConfirmation = (props) => { } if (feedbackRequestFetched.current) { - const requesteeProfile = selectProfile(state, feedbackRequest?.requesteeId); + const requesteeProfile = selectProfile( + state, + feedbackRequest?.requesteeId + ); setRequestee(requesteeProfile); } }, [feedbackRequest, state]); return ( - checkmark-image - Thank you for your feedback on {requestee?.name} + + checkmark-image + + + Thank you for your feedback on {requestee?.name} + ); -} +}; -export default FeedbackSubmitConfirmation; \ No newline at end of file +export default FeedbackSubmitConfirmation; diff --git a/web-ui/src/components/feedback_submit_confirmation/FeedbackSubmitConfirmation.test.jsx b/web-ui/src/components/feedback_submit_confirmation/FeedbackSubmitConfirmation.test.jsx index b07f8689ef..35212b1c52 100644 --- a/web-ui/src/components/feedback_submit_confirmation/FeedbackSubmitConfirmation.test.jsx +++ b/web-ui/src/components/feedback_submit_confirmation/FeedbackSubmitConfirmation.test.jsx @@ -1,15 +1,14 @@ -import React from "react"; -import { BrowserRouter } from "react-router-dom"; -import {AppContextProvider } from "../../context/AppContext"; -import FeedbackSubmitConfirmation from "./FeedbackSubmitConfirmation"; +import React from 'react'; +import { BrowserRouter } from 'react-router-dom'; +import { AppContextProvider } from '../../context/AppContext'; +import FeedbackSubmitConfirmation from './FeedbackSubmitConfirmation'; -it("renders the confirmation message", () => { +it('renders the confirmation message', () => { snapshot( - ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.css b/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.css index 8816496be7..800a11c0c9 100644 --- a/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.css +++ b/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.css @@ -1,34 +1,34 @@ .submit-form { - align-items: center; - display: flex; - flex-direction: column; - margin-top: 3em; - margin-left: 2em; - margin-right: 2em; + align-items: center; + display: flex; + flex-direction: column; + margin-top: 3em; + margin-left: 2em; + margin-right: 2em; } .submit-action-buttons { - width: 100%; - display: flex; - flex-direction: row; - justify-content: center; + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; } .feedback-submit-question { - width: calc(100% - 6em); - margin: .75em 0em; + width: calc(100% - 6em); + margin: 0.75em 0em; } .wrapper { - display: grid; - grid-template-columns: 2em 1fr; - align-items: center; - margin: 2em 1em 0em 1em; + display: grid; + grid-template-columns: 2em 1fr; + align-items: center; + margin: 2em 1em 0em 1em; } @media (max-width: 800px) { - .submit-form { - margin-left: 0; - margin-right: 0; - } + .submit-form { + margin-left: 0; + margin-right: 0; + } } diff --git a/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.jsx b/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.jsx index d7a6560fc9..7e1ba8b575 100644 --- a/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.jsx +++ b/web-ui/src/components/feedback_submit_form/FeedbackSubmitForm.jsx @@ -1,24 +1,24 @@ -import React, {useCallback, useContext, useEffect, useState} from "react"; -import {styled} from "@mui/material/styles"; -import Typography from "@mui/material/Typography"; -import PropTypes from "prop-types"; -import {blue} from "@mui/material/colors"; -import Button from "@mui/material/Button"; -import "./FeedbackSubmitForm.css"; -import {Alert, AlertTitle} from "@mui/material"; -import InfoIcon from "@mui/icons-material/Info"; -import {useHistory} from "react-router-dom"; -import {AppContext} from "../../context/AppContext"; -import {selectCsrfToken} from "../../context/selectors"; -import {UPDATE_TOAST} from "../../context/actions"; -import {updateAllAnswers, updateFeedbackRequest} from "../../api/feedback"; -import {getQuestionAndAnswer} from "../../api/feedbackanswer" -import DateFnsUtils from "@date-io/date-fns"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader"; -import FeedbackSubmitQuestion from "../feedback_submit_question/FeedbackSubmitQuestion"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import Typography from '@mui/material/Typography'; +import PropTypes from 'prop-types'; +import { blue } from '@mui/material/colors'; +import Button from '@mui/material/Button'; +import './FeedbackSubmitForm.css'; +import { Alert, AlertTitle } from '@mui/material'; +import InfoIcon from '@mui/icons-material/Info'; +import { useHistory } from 'react-router-dom'; +import { AppContext } from '../../context/AppContext'; +import { selectCsrfToken } from '../../context/selectors'; +import { UPDATE_TOAST } from '../../context/actions'; +import { updateAllAnswers, updateFeedbackRequest } from '../../api/feedback'; +import { getQuestionAndAnswer } from '../../api/feedbackanswer'; +import DateFnsUtils from '@date-io/date-fns'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; +import FeedbackSubmitQuestion from '../feedback_submit_question/FeedbackSubmitQuestion'; const dateUtils = new DateFnsUtils(); -const PREFIX = "FeedbackSubmitForm"; +const PREFIX = 'FeedbackSubmitForm'; const classes = { announcement: `${PREFIX}-announcement`, tip: `${PREFIX}-tip`, @@ -29,24 +29,24 @@ const classes = { const Root = styled('div')({ [`& .${classes.announcement}`]: { - textAlign: "center", + textAlign: 'center', '@media (max-width: 800px)': { - fontSize: "22px" + fontSize: '22px' } }, [`& .${classes.tip}`]: { '@media (max-width: 800px)': { - fontSize: "15px" + fontSize: '15px' } }, [`& .${classes.warning}`]: { - marginTop: "20px" + marginTop: '20px' }, [`& .${classes.button}`]: { - margin: "3em 1em 1em 1em", + margin: '3em 1em 1em 1em' }, [`& .${classes.coloredButton}`]: { - margin: "3em 1em 1em 1em", + margin: '3em 1em 1em 1em' } }); @@ -58,7 +58,7 @@ const randomTip = [ 'Explain the impact.', 'Provide a summary.', 'Recommend a solution.', - 'Be sincere.', + 'Be sincere.' ]; const tip = randomTip[Math.floor(Math.random() * randomTip.length)]; @@ -66,10 +66,15 @@ const tip = randomTip[Math.floor(Math.random() * randomTip.length)]; const propTypes = { requesteeName: PropTypes.string.isRequired, requestId: PropTypes.string.isRequired, - request: PropTypes.any.isRequired, + request: PropTypes.any.isRequired }; -const FeedbackSubmitForm = ({ requesteeName, requestId, request, reviewOnly = false }) => { +const FeedbackSubmitForm = ({ + requesteeName, + requestId, + request, + reviewOnly = false +}) => { const { state, dispatch } = useContext(AppContext); const csrf = selectCsrfToken(state); const [isLoading, setIsLoading] = useState(false); @@ -77,89 +82,97 @@ const FeedbackSubmitForm = ({ requesteeName, requestId, request, reviewOnly = fa const history = useHistory(); const [questionAnswerPairs, setQuestionAnswerPairs] = useState([]); - const handleAnswerChange = useCallback((index, newAnswer) => { - // Update local state with answer data until assigned an ID - let updatedQuestionAnswerPairs = [...questionAnswerPairs]; + const handleAnswerChange = useCallback( + (index, newAnswer) => { + // Update local state with answer data until assigned an ID + let updatedQuestionAnswerPairs = [...questionAnswerPairs]; - updatedQuestionAnswerPairs[index].answer = { - ...questionAnswerPairs[index].answer, - ...newAnswer - }; - setQuestionAnswerPairs(updatedQuestionAnswerPairs); - - }, [questionAnswerPairs]); + updatedQuestionAnswerPairs[index].answer = { + ...questionAnswerPairs[index].answer, + ...newAnswer + }; + setQuestionAnswerPairs(updatedQuestionAnswerPairs); + }, + [questionAnswerPairs] + ); async function updateRequestSubmit() { - request.status = "submitted" - request.submitDate = dateUtils.format(new Date(), "yyyy-MM-dd") + request.status = 'submitted'; + request.submitDate = dateUtils.format(new Date(), 'yyyy-MM-dd'); return await updateFeedbackRequest(request, csrf); } - async function updateAllAnswersSubmit(){ + async function updateAllAnswersSubmit() { let answers = []; for (let i = 0; i < questionAnswerPairs.length; ++i) { - if(questionAnswerPairs[i]?.answer && questionAnswerPairs[i]?.answer?.id && questionAnswerPairs[i]?.answer?.answer) { + if ( + questionAnswerPairs[i]?.answer && + questionAnswerPairs[i]?.answer?.id && + questionAnswerPairs[i]?.answer?.answer + ) { answers.push(questionAnswerPairs[i].answer); } } - return await updateAllAnswers(answers, csrf) + return await updateAllAnswers(answers, csrf); } - const onSubmitHandler =() => { - updateAllAnswersSubmit().then((res) => { - for (let i = 0; i < res.length; ++i ) { - if (res[i].error) { - dispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: res[i].error, - }, - }); - return false; + const onSubmitHandler = () => { + updateAllAnswersSubmit() + .then(res => { + for (let i = 0; i < res.length; ++i) { + if (res[i].error) { + dispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: res[i].error + } + }); + return false; + } } - } - return true; - }).then((resTwo) => { - if (resTwo === false) { - return; - } - updateRequestSubmit().then((res) => { - if (res && res.payload && res.payload.data && !res.error) { - history.push(`/feedback/submit/confirmation/?request=${requestId}`) - } else { - dispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: res.error, - }, - }); + return true; + }) + .then(resTwo => { + if (resTwo === false) { + return; } + updateRequestSubmit().then(res => { + if (res && res.payload && res.payload.data && !res.error) { + history.push(`/feedback/submit/confirmation/?request=${requestId}`); + } else { + dispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: res.error + } + }); + } + }); }); - }); - } + }; useEffect(() => { async function getAllQuestionsAndAnswers(requestId, cookie) { if (!requestId) { return; } - return await getQuestionAndAnswer(requestId, cookie) + return await getQuestionAndAnswer(requestId, cookie); } if (csrf) { setIsLoading(true); - getAllQuestionsAndAnswers(requestId, csrf).then((res) =>{ + getAllQuestionsAndAnswers(requestId, csrf).then(res => { if (res && res.payload && res.payload.data && !res.error) { - setQuestionAnswerPairs(res.payload.data) + setQuestionAnswerPairs(res.payload.data); } else { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: res.error, - }, + severity: 'error', + toast: res.error + } }); } setIsLoading(false); @@ -167,20 +180,33 @@ const FeedbackSubmitForm = ({ requesteeName, requestId, request, reviewOnly = fa } }, [requestId, csrf, dispatch]); - return isLoading ? : ( + return isLoading ? ( + + ) : ( - {isReviewing ? "Reviewing" : "Submitting"} Feedback on {requesteeName} - {!isReviewing && (
    - info-icon - Tip of the day: {tip} -
    )} - {isReviewing && - ( + + {isReviewing ? 'Reviewing' : 'Submitting'} Feedback on{' '} + {requesteeName} + + {!isReviewing && ( +
    + + info-icon + + + Tip of the day: + {tip} + +
    + )} + {isReviewing && ( + Notice! - Feedback is not anonymous, and can be seen by more than just the feedback requester. + Feedback is not anonymous, and can be seen by more than just the + feedback requester. Be mindful of your answers. - ) - } +
    + )} {questionAnswerPairs.map((questionAnswerPair, index) => ( { + onAnswerChange={newAnswer => { handleAnswerChange(index, newAnswer); }} /> ))} - {!reviewOnly && (
    - {isReviewing ? - ( + {!reviewOnly && ( +
    + {isReviewing ? ( + + + + + ) : ( - - ) : - } -
    )} + )} +
    + )}
    ); }; diff --git a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.css b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.css index 821f31de71..459e24dbc3 100644 --- a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.css +++ b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.css @@ -1,4 +1,4 @@ .feedback-submit-question { - margin-top: 2em; - margin-left: 1em; -} \ No newline at end of file + margin-top: 2em; + margin-left: 1em; +} diff --git a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.jsx b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.jsx index dbdb13269a..ce87d013de 100644 --- a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.jsx +++ b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.jsx @@ -1,21 +1,21 @@ -import React, {useCallback, useContext, useEffect, useRef} from "react"; -import PropTypes from "prop-types"; +import React, { useCallback, useContext, useEffect, useRef } from 'react'; +import PropTypes from 'prop-types'; -import Typography from "@mui/material/Typography"; +import Typography from '@mui/material/Typography'; -import "./FeedbackSubmitQuestion.css" -import {debounce} from "lodash/function"; -import {saveSingleAnswer, updateSingleAnswer} from "../../api/feedback"; -import {AppContext} from "../../context/AppContext"; -import {UPDATE_TOAST} from "../../context/actions"; -import FeedbackAnswerInput from "../feedback_answer_input/FeedbackAnswerInput"; +import './FeedbackSubmitQuestion.css'; +import { debounce } from 'lodash/function'; +import { saveSingleAnswer, updateSingleAnswer } from '../../api/feedback'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_TOAST } from '../../context/actions'; +import FeedbackAnswerInput from '../feedback_answer_input/FeedbackAnswerInput'; const propTypes = { question: PropTypes.shape({ id: PropTypes.string.isRequired, question: PropTypes.string.isRequired, questionNumber: PropTypes.number.isRequired, - inputType: PropTypes.oneOf(["TEXT", "RADIO", "SLIDER","NONE"]).isRequired + inputType: PropTypes.oneOf(['TEXT', 'RADIO', 'SLIDER', 'NONE']).isRequired }), readOnly: PropTypes.bool.isRequired, answer: PropTypes.shape({ @@ -28,8 +28,7 @@ const propTypes = { onAnswerChange: PropTypes.func }; -const FeedbackSubmitQuestion = (props) => { - +const FeedbackSubmitQuestion = props => { const { state, dispatch } = useContext(AppContext); const { csrf } = state; @@ -42,79 +41,97 @@ const FeedbackSubmitQuestion = (props) => { } }, [props.answer?.id]); - const saveAnswer = useCallback((answer) => { - savingAnswer.current = true; - saveSingleAnswer(answer, csrf).then(res => { - if (res?.payload?.data && !res.error) { - const answerWithId = { - ...answer, - id: res.payload.data.id - }; - props.onAnswerChange(answerWithId); - } else { - savingAnswer.current = false; - dispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: "Failed to save answer" - } - }); - } - }); - }, [csrf, dispatch, props]); + const saveAnswer = useCallback( + answer => { + savingAnswer.current = true; + saveSingleAnswer(answer, csrf).then(res => { + if (res?.payload?.data && !res.error) { + const answerWithId = { + ...answer, + id: res.payload.data.id + }; + props.onAnswerChange(answerWithId); + } else { + savingAnswer.current = false; + dispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: 'Failed to save answer' + } + }); + } + }); + }, + [csrf, dispatch, props] + ); const saveAnswerWithDebounce = useRef(debounce(saveAnswer, 2000)); - const handleSaveAnswer = useCallback((answerText) => { - props.onAnswerChange({ - answer: answerText - }); - - if (!savingAnswer.current) { - const newAnswer = { - answer: answerText, - questionId: props.question.id, - requestId: props.requestId - }; - - const save = saveAnswerWithDebounce.current; - save(newAnswer); - } - }, [props, savingAnswer]); - - const handleUpdateAnswer = useCallback((answerText) => { - if (props.answer && props.answer.id) { + const handleSaveAnswer = useCallback( + answerText => { props.onAnswerChange({ - id: props.answer.id, answer: answerText }); - const updatedAnswer = { - ...props.answer, - answer: answerText - }; + if (!savingAnswer.current) { + const newAnswer = { + answer: answerText, + questionId: props.question.id, + requestId: props.requestId + }; - const update = updateAnswerWithDebounce.current; - update(updatedAnswer, csrf); - } - }, [csrf, props]); + const save = saveAnswerWithDebounce.current; + save(newAnswer); + } + }, + [props, savingAnswer] + ); - const isStaticText = props?.question?.inputType?.toUpperCase() === "NONE"; + const handleUpdateAnswer = useCallback( + answerText => { + if (props.answer && props.answer.id) { + props.onAnswerChange({ + id: props.answer.id, + answer: answerText + }); + + const updatedAnswer = { + ...props.answer, + answer: answerText + }; + + const update = updateAnswerWithDebounce.current; + update(updatedAnswer, csrf); + } + }, + [csrf, props] + ); + + const isStaticText = props?.question?.inputType?.toUpperCase() === 'NONE'; return (
    - {props.question.question} + + {props.question.question} +
    ); -} +}; FeedbackSubmitQuestion.propTypes = propTypes; -export default FeedbackSubmitQuestion; \ No newline at end of file +export default FeedbackSubmitQuestion; diff --git a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.test.jsx b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.test.jsx index 4a1d1ef8bc..c46d8e72be 100644 --- a/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.test.jsx +++ b/web-ui/src/components/feedback_submit_question/FeedbackSubmitQuestion.test.jsx @@ -1,23 +1,23 @@ -import React from "react"; -import FeedbackSubmitQuestion from "./FeedbackSubmitQuestion"; -import {AppContextProvider} from "../../context/AppContext"; +import React from 'react'; +import FeedbackSubmitQuestion from './FeedbackSubmitQuestion'; +import { AppContextProvider } from '../../context/AppContext'; -it("renders the feedback submit question as text", () => { +it('renders the feedback submit question as text', () => { snapshot( { ); }); -it("renders the feedback submit question as radio buttons", () => { +it('renders the feedback submit question as radio buttons', () => { snapshot( { ); }); -it("renders the feedback submit question as a slider", () => { +it('renders the feedback submit question as a slider', () => { snapshot( ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.css b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.css index 9b85a3de9c..04c5a8ad73 100644 --- a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.css +++ b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.css @@ -26,4 +26,4 @@ .feedback-template-actions .ad-hoc-button { margin: 16px 0 0 0; } -} \ No newline at end of file +} diff --git a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.jsx b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.jsx index cf330f91fe..c455f069e7 100644 --- a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.jsx +++ b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.jsx @@ -1,34 +1,44 @@ -import React, {useState, useContext, useEffect, useCallback, useRef} from "react"; -import TemplateCard from "../template-card/TemplateCard"; -import TemplatePreviewModal from "../template-preview-modal/TemplatePreviewModal"; -import PropTypes from "prop-types"; -import {InputAdornment, TextField} from "@mui/material"; -import Button from "@mui/material/Button"; -import {Tooltip} from "@mui/material"; -import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import React, { + useState, + useContext, + useEffect, + useCallback, + useRef +} from 'react'; +import TemplateCard from '../template-card/TemplateCard'; +import TemplatePreviewModal from '../template-preview-modal/TemplatePreviewModal'; +import PropTypes from 'prop-types'; +import { InputAdornment, TextField } from '@mui/material'; +import Button from '@mui/material/Button'; +import { Tooltip } from '@mui/material'; +import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; import { createFeedbackTemplateWithQuestion, getAllFeedbackTemplates -} from "../../api/feedbacktemplate"; -import {AppContext} from "../../context/AppContext"; -import {selectCsrfToken, selectCurrentUser} from "../../context/selectors"; -import "./FeedbackTemplateSelector.css"; -import {Search} from "@mui/icons-material"; -import {UPDATE_TOAST} from "../../context/actions"; +} from '../../api/feedbacktemplate'; +import { AppContext } from '../../context/AppContext'; +import { selectCsrfToken, selectCurrentUser } from '../../context/selectors'; +import './FeedbackTemplateSelector.css'; +import { Search } from '@mui/icons-material'; +import { UPDATE_TOAST } from '../../context/actions'; const propTypes = { query: PropTypes.string, changeQuery: PropTypes.func }; -const FeedbackTemplateSelector = ({query, changeQuery}) => { +const FeedbackTemplateSelector = ({ query, changeQuery }) => { const { state, dispatch } = useContext(AppContext); const csrf = selectCsrfToken(state); const currentUser = selectCurrentUser(state); const currentUserId = currentUser?.id; const [templates, setTemplates] = useState([]); - const [preview, setPreview] = useState({open: false, selectedTemplate: {}, createAdHoc: false}); - const [searchText, setSearchText] = useState(""); + const [preview, setPreview] = useState({ + open: false, + selectedTemplate: {}, + createAdHoc: false + }); + const [searchText, setSearchText] = useState(''); const templatesFetched = useRef(false); // Gets all templates when the component mounts @@ -44,14 +54,14 @@ const FeedbackTemplateSelector = ({query, changeQuery}) => { res.payload.status === 200 && !res.error ? res.payload.data - : null + : null; if (templateList) { templatesFetched.current = true; return templateList; } - } + } if (csrf && currentUserId) { - getTemplates(csrf).then((templateList) => { + getTemplates(csrf).then(templateList => { setTemplates(templateList); }); } @@ -59,12 +69,20 @@ const FeedbackTemplateSelector = ({query, changeQuery}) => { const handlePreviewOpen = (event, selectedTemplate) => { event.stopPropagation(); - setPreview({open: true, selectedTemplate: selectedTemplate, createAdHoc: false}); - } - - const handlePreviewClose = (selectedTemplate) => { - setPreview({open: false, selectedTemplate: selectedTemplate, createAdHoc: false}); - } + setPreview({ + open: true, + selectedTemplate: selectedTemplate, + createAdHoc: false + }); + }; + + const handlePreviewClose = selectedTemplate => { + setPreview({ + open: false, + selectedTemplate: selectedTemplate, + createAdHoc: false + }); + }; const handlePreviewSubmit = async (submittedTemplate, submittedQuestion) => { if (!currentUserId || !csrf) { @@ -84,71 +102,84 @@ const FeedbackTemplateSelector = ({query, changeQuery}) => { const newTemplateQuestion = { question: submittedQuestion, questionNumber: 1, - inputType: "TEXT" - } + inputType: 'TEXT' + }; - const {templateRes, questionRes} = await createFeedbackTemplateWithQuestion(newFeedbackTemplate, newTemplateQuestion, csrf); + const { templateRes, questionRes } = + await createFeedbackTemplateWithQuestion( + newFeedbackTemplate, + newTemplateQuestion, + csrf + ); if (templateRes.error || questionRes.error) { - const errorMessage = templateRes.error ? "Failed to save ad-hoc template" : "Failed to save question for ad-hoc template"; + const errorMessage = templateRes.error + ? 'Failed to save ad-hoc template' + : 'Failed to save question for ad-hoc template'; dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", + severity: 'error', toast: errorMessage } }); } else if (templateRes.payload && templateRes.payload.data) { newFeedbackTemplate.id = templateRes.payload.data.id; setTemplates([...templates, newFeedbackTemplate]); - changeQuery("template", newFeedbackTemplate.id); + changeQuery('template', newFeedbackTemplate.id); } + } else if (submittedTemplate) { + changeQuery('template', submittedTemplate.id); } - else if (submittedTemplate) { - changeQuery("template", submittedTemplate.id); - } - - setPreview({open: false, selectedTemplate: submittedTemplate, createAdHoc: false}); - } - const onCardClick = useCallback((template) => { - if (!template || !template.id) { - return; - } - if (query === template.id) { - changeQuery("template", undefined); - } else { - changeQuery("template", template.id); - } - }, [changeQuery, query]); + setPreview({ + open: false, + selectedTemplate: submittedTemplate, + createAdHoc: false + }); + }; + + const onCardClick = useCallback( + template => { + if (!template || !template.id) { + return; + } + if (query === template.id) { + changeQuery('template', undefined); + } else { + changeQuery('template', template.id); + } + }, + [changeQuery, query] + ); const onNewAdHocClick = () => { - setPreview({open: true, selectedTemplate: {}, createAdHoc: true}); - } + setPreview({ open: true, selectedTemplate: {}, createAdHoc: true }); + }; const getFilteredTemplates = useCallback(() => { if (templates === undefined) { return null; } else if (templatesFetched.current && templates.length === 0) { - return

    No templates found

    ; + return

    No templates found

    ; } let templatesToDisplay = templates; if (searchText) { - const filtered = templates.filter((template) => - template.title?.toLowerCase().includes(searchText.toLowerCase()) || - template.description?.toLowerCase().includes(searchText.toLowerCase()) + const filtered = templates.filter( + template => + template.title?.toLowerCase().includes(searchText.toLowerCase()) || + template.description?.toLowerCase().includes(searchText.toLowerCase()) ); if (filtered.length === 0) { - return

    No matching templates

    ; + return

    No matching templates

    ; } else { templatesToDisplay = filtered; } } - - return templatesToDisplay.map((template) => ( + return templatesToDisplay.map(template => ( { isSelected={query === template.id} questions={template.questions} expanded={preview.open} - onPreviewClick={(e) => handlePreviewOpen(e, template)} - onCardClick={() => onCardClick(template)}/> - )) + onPreviewClick={e => handlePreviewOpen(e, template)} + onCardClick={() => onCardClick(template)} + /> + )); }, [query, templates, searchText, onCardClick, preview.open]); return ( - {preview.selectedTemplate && - handlePreviewSubmit(submittedTemplate, submittedQuestion)} - onClose={() => handlePreviewClose(preview.selectedTemplate)} - createAdHoc={preview.createAdHoc} - /> - } + {preview.selectedTemplate && ( + + handlePreviewSubmit(submittedTemplate, submittedQuestion) + } + onClose={() => handlePreviewClose(preview.selectedTemplate)} + createAdHoc={preview.createAdHoc} + /> + )}
    { + onChange={e => { setSearchText(e.target.value); }} InputProps={{ endAdornment: ( - - + + ) - }}/> + }} + />
    - - - + +
    -
    - {getFilteredTemplates()} -
    +
    {getFilteredTemplates()}
    ); -} +}; FeedbackTemplateSelector.propTypes = propTypes; diff --git a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.test.jsx b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.test.jsx index 08b469d0f0..573b3f16ec 100644 --- a/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.test.jsx +++ b/web-ui/src/components/feedback_template_selector/FeedbackTemplateSelector.test.jsx @@ -1,8 +1,11 @@ -import React from "react"; -import FeedbackTemplateSelector from "./FeedbackTemplateSelector"; -import {AppContextProvider} from "../../context/AppContext"; +import React from 'react'; +import FeedbackTemplateSelector from './FeedbackTemplateSelector'; +import { AppContextProvider } from '../../context/AppContext'; - -it("renders the recipient card", () => { - snapshot(); -}); \ No newline at end of file +it('renders the recipient card', () => { + snapshot( + + + + ); +}); diff --git a/web-ui/src/components/feelings/Feelings.jsx b/web-ui/src/components/feelings/Feelings.jsx index 326138dee5..c469cf8ffb 100644 --- a/web-ui/src/components/feelings/Feelings.jsx +++ b/web-ui/src/components/feelings/Feelings.jsx @@ -1,37 +1,43 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faFaceGrinBeam, faSmile, faMeh, faFrown, faFaceSadCry } from "@fortawesome/free-regular-svg-icons"; +import React from 'react'; +import PropTypes from 'prop-types'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faFaceGrinBeam, + faSmile, + faMeh, + faFrown, + faFaceSadCry +} from '@fortawesome/free-regular-svg-icons'; const propTypes = { message: PropTypes.string, - onSelect: PropTypes.func, + onSelect: PropTypes.func }; -const displayName = "Feelings"; +const displayName = 'Feelings'; const Feelings = ({ onSelect, message }) => { const inputs = [ - ["Terrible", faFaceSadCry], - ["Bad", faFrown], - ["Okay", faMeh], - ["Good", faSmile], - ["Great", faFaceGrinBeam], + ['Terrible', faFaceSadCry], + ['Bad', faFrown], + ['Okay', faMeh], + ['Good', faSmile], + ['Great', faFaceGrinBeam] ]; - const onChange = (e) => { + const onChange = e => { onSelect(e.target.value); }; return (

    {message}

    -
    +
    {inputs.map(([text, icon], i) => (
    diff --git a/web-ui/src/components/feelings/Feelings.test.jsx b/web-ui/src/components/feelings/Feelings.test.jsx index 543a8c60b8..f04efc31df 100644 --- a/web-ui/src/components/feelings/Feelings.test.jsx +++ b/web-ui/src/components/feelings/Feelings.test.jsx @@ -1,18 +1,18 @@ -import React from "react"; -import Feelings from "./Feelings"; -import { render, screen, fireEvent } from "@testing-library/react"; +import React from 'react'; +import Feelings from './Feelings'; +import { render, screen, fireEvent } from '@testing-library/react'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot(); }); -const message = "le test"; +const message = 'le test'; -it("renders message correctly", () => { +it('renders message correctly', () => { snapshot(); }); -it("calls onSelect correctly", () => { +it('calls onSelect correctly', () => { const onSelect = vi.fn(); render(); diff --git a/web-ui/src/components/feelings/__snapshots__/Feelings.test.jsx.snap b/web-ui/src/components/feelings/__snapshots__/Feelings.test.jsx.snap index 0c0da17b21..85081875c1 100644 --- a/web-ui/src/components/feelings/__snapshots__/Feelings.test.jsx.snap +++ b/web-ui/src/components/feelings/__snapshots__/Feelings.test.jsx.snap @@ -22,7 +22,7 @@ exports[`renders correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -51,7 +51,7 @@ exports[`renders correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -80,7 +80,7 @@ exports[`renders correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -109,7 +109,7 @@ exports[`renders correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -138,7 +138,7 @@ exports[`renders correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -181,7 +181,7 @@ exports[`renders message correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -210,7 +210,7 @@ exports[`renders message correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -239,7 +239,7 @@ exports[`renders message correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -268,7 +268,7 @@ exports[`renders message correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > @@ -297,7 +297,7 @@ exports[`renders message correctly 1`] = ` xmlns="http://www.w3.org/2000/svg" > diff --git a/web-ui/src/components/guides/GuideLink.css b/web-ui/src/components/guides/GuideLink.css index e6f7beab6c..5d7c337d7e 100644 --- a/web-ui/src/components/guides/GuideLink.css +++ b/web-ui/src/components/guides/GuideLink.css @@ -1,15 +1,15 @@ .guide-info { - text-align: left; - margin: 0.75rem 0.25rem; - display: flex; - flex-direction: row; - align-items: center; + text-align: left; + margin: 0.75rem 0.25rem; + display: flex; + flex-direction: row; + align-items: center; } .guide-link { - margin-left: 1rem; + margin-left: 1rem; } .guide-icon { - vertical-align: middle; -} \ No newline at end of file + vertical-align: middle; +} diff --git a/web-ui/src/components/guides/GuideLink.jsx b/web-ui/src/components/guides/GuideLink.jsx index 252c8f832c..9595be6b5c 100644 --- a/web-ui/src/components/guides/GuideLink.jsx +++ b/web-ui/src/components/guides/GuideLink.jsx @@ -1,18 +1,24 @@ -import React from "react"; +import React from 'react'; import { Link } from 'react-router-dom'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; -import "./GuideLink.css"; +import './GuideLink.css'; -const GuideLink = (props) => { - const path = "/pdfs/"; +const GuideLink = props => { + const path = '/pdfs/'; const fileName = props.name; - let fullPath = path + fileName.split(" ").join("_") + ".pdf"; + let fullPath = path + fileName.split(' ').join('_') + '.pdf'; return ( - - - - + + + + ); }; diff --git a/web-ui/src/components/guides/GuideLink.test.jsx b/web-ui/src/components/guides/GuideLink.test.jsx index b9be51d876..ba853cb0c9 100644 --- a/web-ui/src/components/guides/GuideLink.test.jsx +++ b/web-ui/src/components/guides/GuideLink.test.jsx @@ -1,7 +1,11 @@ -import React from "react"; -import GuideLink from "./GuideLink"; +import React from 'react'; +import GuideLink from './GuideLink'; import { MemoryRouter } from 'react-router-dom'; -it("renders correctly", () => { - snapshot(); +it('renders correctly', () => { + snapshot( + + + + ); }); diff --git a/web-ui/src/components/guides/GuidesPanel.css b/web-ui/src/components/guides/GuidesPanel.css index 9c4b3f5c34..9bb426e22a 100644 --- a/web-ui/src/components/guides/GuidesPanel.css +++ b/web-ui/src/components/guides/GuidesPanel.css @@ -1,7 +1,6 @@ .guide-container { - width: fit-content; - height: fit-content; - border: solid 3px black; - margin-top: 1rem; - } - \ No newline at end of file + width: fit-content; + height: fit-content; + border: solid 3px black; + margin-top: 1rem; +} diff --git a/web-ui/src/components/guides/GuidesPanel.jsx b/web-ui/src/components/guides/GuidesPanel.jsx index c328468845..e653daf572 100644 --- a/web-ui/src/components/guides/GuidesPanel.jsx +++ b/web-ui/src/components/guides/GuidesPanel.jsx @@ -1,36 +1,35 @@ -import React from "react"; +import React from 'react'; import PdfIcon from '@mui/icons-material/PictureAsPdf'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import List from '@mui/material/List'; -import "./GuidesPanel.css"; -import GuideLink from "./GuideLink"; +import './GuidesPanel.css'; +import GuideLink from './GuideLink'; const GuidesPanel = () => { - const teamMemberPDFs = [ { - name: "Expectations Discussion Guide for Team Members", + name: 'Expectations Discussion Guide for Team Members' }, { - name: "Expectations Worksheet", + name: 'Expectations Worksheet' }, { - name: "Feedback Discussion Guide for Team Members", + name: 'Feedback Discussion Guide for Team Members' }, { - name: "Development Discussion Guide for Team Members", + name: 'Development Discussion Guide for Team Members' }, { - name: "Individual Development Plan", - }, + name: 'Individual Development Plan' + } ]; return ( } title="Team Member Resources" /> - {teamMemberPDFs.map((memberPDF) => ( + {teamMemberPDFs.map(memberPDF => ( ))} diff --git a/web-ui/src/components/guides/GuidesPanel.test.jsx b/web-ui/src/components/guides/GuidesPanel.test.jsx index cc0287e307..2dc2abd8ef 100644 --- a/web-ui/src/components/guides/GuidesPanel.test.jsx +++ b/web-ui/src/components/guides/GuidesPanel.test.jsx @@ -1,7 +1,11 @@ -import React from "react"; +import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import GuidesPanel from "./GuidesPanel"; +import GuidesPanel from './GuidesPanel'; -it("renders correctly", () => { - snapshot(); +it('renders correctly', () => { + snapshot( + + + + ); }); diff --git a/web-ui/src/components/guides/PDLGuidesPanel.jsx b/web-ui/src/components/guides/PDLGuidesPanel.jsx index 4f8f31b64a..26b9af3a61 100644 --- a/web-ui/src/components/guides/PDLGuidesPanel.jsx +++ b/web-ui/src/components/guides/PDLGuidesPanel.jsx @@ -1,11 +1,11 @@ -import React, { useContext } from "react"; -import { AppContext } from "../../context/AppContext"; +import React, { useContext } from 'react'; +import { AppContext } from '../../context/AppContext'; import PdfIcon from '@mui/icons-material/PictureAsPdf'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import List from '@mui/material/List'; -import "./GuidesPanel.css"; -import GuideLink from "./GuideLink"; +import './GuidesPanel.css'; +import GuideLink from './GuideLink'; const PDLGuidesPanel = () => { const { state } = useContext(AppContext); @@ -14,25 +14,25 @@ const PDLGuidesPanel = () => { userProfile && userProfile.role && userProfile.role.length > 0 && - userProfile.role.includes("PDL"); + userProfile.role.includes('PDL'); const pdlPDFs = [ { - name: "Development Discussion Guide for PDLs", + name: 'Development Discussion Guide for PDLs' }, { - name: "Expectations Discussion Guide for PDLs", + name: 'Expectations Discussion Guide for PDLs' }, { - name: "Feedback Discussion Guide for PDLs", - }, + name: 'Feedback Discussion Guide for PDLs' + } ]; return isPdl ? ( } title="Development Lead Guides" /> - {pdlPDFs.map((pdlPDF) => ( + {pdlPDFs.map(pdlPDF => ( ))} diff --git a/web-ui/src/components/guides/PDLGuidesPanel.test.jsx b/web-ui/src/components/guides/PDLGuidesPanel.test.jsx index 2c8edbb388..89fce8de13 100644 --- a/web-ui/src/components/guides/PDLGuidesPanel.test.jsx +++ b/web-ui/src/components/guides/PDLGuidesPanel.test.jsx @@ -1,31 +1,31 @@ -import React from "react"; -import { AppContextProvider } from "../../context/AppContext"; -import PDLGuidesPanel from "./PDLGuidesPanel"; -import { render } from "@testing-library/react"; -import { Router } from "react-router-dom"; -import { createBrowserHistory } from "history"; +import React from 'react'; +import { AppContextProvider } from '../../context/AppContext'; +import PDLGuidesPanel from './PDLGuidesPanel'; +import { render } from '@testing-library/react'; +import { Router } from 'react-router-dom'; +import { createBrowserHistory } from 'history'; const initialState = { state: { userProfile: { - name: "holmes", - role: ["MEMBER"], + name: 'holmes', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - }, - }, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' + } + } }; const pdlState = { state: { userProfile: { ...initialState.state.userProfile, - role: ["MEMBER", "PDL"], + role: ['MEMBER', 'PDL'] } } }; -it("renders correctly", () => { +it('renders correctly', () => { const customHistory = createBrowserHistory(); snapshot( diff --git a/web-ui/src/components/guild-results/EditGuildModal.css b/web-ui/src/components/guild-results/EditGuildModal.css index e107ae9969..250500c036 100644 --- a/web-ui/src/components/guild-results/EditGuildModal.css +++ b/web-ui/src/components/guild-results/EditGuildModal.css @@ -1,37 +1,37 @@ .EditGuildModal { - position: absolute; - min-width: 400px; - max-width: 600px; - background-color: #FFF; - top: 50%; - left: 50%; - padding: .5rem; - transform: translate(-50%, -50%); - border: 2px solid #FFF; + position: absolute; + min-width: 400px; + max-width: 600px; + background-color: #fff; + top: 50%; + left: 50%; + padding: 0.5rem; + transform: translate(-50%, -50%); + border: 2px solid #fff; } .EditGuildModal h2 { - margin-block-end: 0rem; - margin-left: .5rem; + margin-block-end: 0rem; + margin-left: 0.5rem; } .EditGuildModal-actions { - margin-top: 1rem; - width: calc(100% - 1rem); - display: flex; - flex-direction: row; - justify-content: flex-end; + margin-top: 1rem; + width: calc(100% - 1rem); + display: flex; + flex-direction: row; + justify-content: flex-end; } .EditGuildModal .MuiTextField-root.fullWidth { - width: calc(100% - 1rem); + width: calc(100% - 1rem); } .EditGuildModal .MuiTextField-root.halfWidth { - width: calc(50% - .5rem); + width: calc(50% - 0.5rem); } .EditGuildModal .MuiTextField-root { - margin: .5rem; - width: 25ch; - } \ No newline at end of file + margin: 0.5rem; + width: 25ch; +} diff --git a/web-ui/src/components/guild-results/EditGuildModal.jsx b/web-ui/src/components/guild-results/EditGuildModal.jsx index 4879a08200..7eb1860b6d 100644 --- a/web-ui/src/components/guild-results/EditGuildModal.jsx +++ b/web-ui/src/components/guild-results/EditGuildModal.jsx @@ -1,14 +1,14 @@ -import React, { useContext, useState, useEffect, useCallback } from "react"; +import React, { useContext, useState, useEffect, useCallback } from 'react'; -import { AppContext } from "../../context/AppContext"; +import { AppContext } from '../../context/AppContext'; import { selectCurrentUser, - selectCurrentMembers, -} from "../../context/selectors"; + selectCurrentMembers +} from '../../context/selectors'; -import { Button, Modal, TextField } from "@mui/material"; +import { Button, Modal, TextField } from '@mui/material'; import Autocomplete from '@mui/material/Autocomplete'; -import "./EditGuildModal.css"; +import './EditGuildModal.css'; const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { const { state } = useContext(AppContext); @@ -19,8 +19,8 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { const guildMembers = guild?.guildMembers; const findExistingMember = useCallback( - (member) => - guildMembers?.find((current) => current.memberId === member.memberId), + member => + guildMembers?.find(current => current.memberId === member.memberId), [guildMembers] ); @@ -33,7 +33,7 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { currentUser?.id && (editedGuild.guildMembers === undefined || editedGuild.guildMembers.length === 0 || - editedGuild.guildMembers.filter((member) => member.lead === true) + editedGuild.guildMembers.filter(member => member.lead === true) .length === 0) ) { setGuild({ @@ -41,7 +41,7 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { guildMembers: [ ...new Set( editedGuild?.guildMembers?.filter( - (member) => + member => member.lead === false && member.memberId !== currentUser.id ) ), @@ -50,9 +50,9 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { name: `${currentUser.firstName} ${currentUser.lastName}`, memberId: currentUser.id, guildId: editedGuild.id, - lead: true, - }, - ], + lead: true + } + ] }); } }, [editedGuild, currentUser, findExistingMember]); @@ -60,82 +60,83 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { useEffect(() => { if (!editedGuild || !editedGuild.guildMembers || !currentMembers) return; let guildMemberNames = editedGuild.guildMembers.map( - (guildMember) => guildMember.name + guildMember => guildMember.name ); setGuildMemberOptions( - currentMembers.filter((member) => !guildMemberNames.includes(member.name)) + currentMembers.filter(member => !guildMemberNames.includes(member.name)) ); }, [currentMembers, editedGuild]); const onLeadsChange = (event, newValue) => { let extantMembers = editedGuild && editedGuild.guildMembers - ? editedGuild.guildMembers.filter((guildMember) => !guildMember.lead) + ? editedGuild.guildMembers.filter(guildMember => !guildMember.lead) : []; - newValue = newValue.map((newLead) => ({ + newValue = newValue.map(newLead => ({ id: newLead.memberId ? newLead.id : undefined, name: newLead.name, memberId: newLead.memberId ? newLead.memberId : newLead.id, guildId: editedGuild.id, - lead: true, + lead: true })); - newValue.forEach((newLead) => { + newValue.forEach(newLead => { extantMembers = extantMembers.filter( - (member) => member.memberId !== newLead.memberId + member => member.memberId !== newLead.memberId ); }); extantMembers = [...new Set(extantMembers)]; newValue = [...new Set(newValue)]; setGuild({ ...editedGuild, - guildMembers: [...extantMembers, ...newValue].map((member) => { + guildMembers: [...extantMembers, ...newValue].map(member => { const existing = findExistingMember(member); if (existing) { return { ...member, id: existing.id }; } else { return member; } - }), + }) }); }; const onGuildMembersChange = (event, newValue) => { let extantLeads = editedGuild && editedGuild.guildMembers - ? editedGuild.guildMembers.filter((guildMember) => guildMember.lead) + ? editedGuild.guildMembers.filter(guildMember => guildMember.lead) : []; - newValue = newValue.map((newMember) => ({ + newValue = newValue.map(newMember => ({ id: newMember.memberId ? newMember.id : undefined, name: newMember.name, memberId: newMember.memberId ? newMember.memberId : newMember.id, guildId: editedGuild.id, - lead: false, + lead: false })); - newValue.forEach((newMember) => { + newValue.forEach(newMember => { extantLeads = extantLeads.filter( - (lead) => lead.memberId !== newMember.memberId + lead => lead.memberId !== newMember.memberId ); }); extantLeads = [...new Set(extantLeads)]; newValue = [...new Set(newValue)]; setGuild({ ...editedGuild, - guildMembers: [...extantLeads, ...newValue].map((member) => { + guildMembers: [...extantLeads, ...newValue].map(member => { const existing = findExistingMember(member); if (existing) { return { ...member, id: existing.id }; } else { return member; } - }), + }) }); }; - const readyToEdit = (guild) => { + const readyToEdit = guild => { let numLeads = 0; if (guild && guild.guildMembers) { - numLeads = guild.guildMembers.filter((guildMember) => guildMember.lead) - .length; + numLeads = guild.guildMembers.filter( + guildMember => guildMember.lead + ).length; } return guild.name && numLeads > 0; }; @@ -155,16 +156,16 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { required className="halfWidth" placeholder="Awesome Guild" - value={editedGuild.name ? editedGuild.name : ""} - onChange={(e) => setGuild({ ...editedGuild, name: e.target.value })} + value={editedGuild.name ? editedGuild.name : ''} + onChange={e => setGuild({ ...editedGuild, name: e.target.value })} /> + value={editedGuild.description ? editedGuild.description : ''} + onChange={e => setGuild({ ...editedGuild, description: e.target.value }) } /> @@ -173,10 +174,8 @@ const EditGuildModal = ({ guild = {}, open, onSave, onClose, headerText }) => { label="Link to Compass Page" className="fullWidth" placeholder="https://www.compass.objectcomputing.com/guilds/..." - value={editedGuild.link ? editedGuild.link: ""} - onChange={(e) => - setGuild({ ...editedGuild, link: e.target.value }) - } + value={editedGuild.link ? editedGuild.link : ''} + onChange={e => setGuild({ ...editedGuild, link: e.target.value })} /> { required value={ editedGuild.guildMembers - ? editedGuild.guildMembers.filter( - (guildMember) => guildMember.lead - ) + ? editedGuild.guildMembers.filter(guildMember => guildMember.lead) : [] } onChange={onLeadsChange} - getOptionLabel={(option) => option.name} - renderInput={(params) => ( + getOptionLabel={option => option.name} + renderInput={params => ( { value={ editedGuild.guildMembers ? editedGuild.guildMembers.filter( - (guildMember) => !guildMember.lead + guildMember => !guildMember.lead ) : [] } onChange={onGuildMembersChange} - getOptionLabel={(option) => option.name} + getOptionLabel={option => option.name} isOptionEqualToValue={(option, value) => value ? value.id === option.id : false } - renderInput={(params) => ( + renderInput={params => ( { - return HttpResponse.text("O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi"); + return HttpResponse.text('O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi'); }), http.get('http://localhost:8080/services/member-profiles/current', () => { - return HttpResponse.json({ id: "12345", name: "Test User" }); + return HttpResponse.json({ id: '12345', name: 'Test User' }); }), http.get('http://localhost:8080/services/teams/members', () => { - return HttpResponse.json([{ id: "12345", name: "Test User" }]); + return HttpResponse.json([{ id: '12345', name: 'Test User' }]); }) ); @@ -25,55 +25,73 @@ afterEach(() => server.resetHandlers()); afterAll(() => server.close()); const testGuild = { - name: "Test Guild", - description: "A guild used for testing.", - guildLeads: [{id:123, name:"Guild Leader"}, {id:124, name: "Other Leader"}], - guildMembers: [{id:125, name:"Guild Member"}, {id:126, name: "Other Member"}] + name: 'Test Guild', + description: 'A guild used for testing.', + guildLeads: [ + { id: 123, name: 'Guild Leader' }, + { id: 124, name: 'Other Leader' } + ], + guildMembers: [ + { id: 125, name: 'Guild Member' }, + { id: 126, name: 'Other Member' } + ] }; const emptyGuild = { - name: "Test Guild", - description: "A guild used for testing.", -} + name: 'Test Guild', + description: 'A guild used for testing.' +}; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", -} + name: 'Current User', + firstName: 'Current', + lastName: 'User' +}; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { - name: "Current User", - firstName: "Current", - lastName: "User", - role: ["MEMBER"], + name: 'Current User', + firstName: 'Current', + lastName: 'User', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - memberProfile: currentUserProfile, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', + memberProfile: currentUserProfile }, checkins: [], guilds: [testGuild, emptyGuild], teams: [], skills: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], index: 0, - memberProfiles: [currentUserProfile, {id:123, name:"Guild Leader"}, {id:124, name: "Other Leader"}, {id:125, name:"Guild Member"}, {id:126, name: "Other Member"}], + memberProfiles: [ + currentUserProfile, + { id: 123, name: 'Guild Leader' }, + { id: 124, name: 'Other Leader' }, + { id: 125, name: 'Guild Member' }, + { id: 126, name: 'Other Member' } + ] } -} +}; -it("Cannot save without lead", async () => { +it('Cannot save without lead', async () => { const mockOnSave = vi.fn(); render( - + ); @@ -91,4 +109,4 @@ it("Cannot save without lead", async () => { await waitFor(() => { expect(mockOnSave).toHaveBeenCalled(); }); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/guild-results/GuildResults.jsx b/web-ui/src/components/guild-results/GuildResults.jsx index 28298ee427..24c55dc01d 100644 --- a/web-ui/src/components/guild-results/GuildResults.jsx +++ b/web-ui/src/components/guild-results/GuildResults.jsx @@ -1,13 +1,13 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; import { styled } from '@mui/material/styles'; -import GuildSummaryCard from "./GuildSummaryCard"; -import { AppContext } from "../../context/AppContext"; -import GuildsActions from "./GuildsActions"; -import PropTypes from "prop-types"; -import { TextField } from "@mui/material"; -import "./GuildResults.css"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader" +import GuildSummaryCard from './GuildSummaryCard'; +import { AppContext } from '../../context/AppContext'; +import GuildsActions from './GuildsActions'; +import PropTypes from 'prop-types'; +import { TextField } from '@mui/material'; +import './GuildResults.css'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; const PREFIX = 'GuildResults'; const classes = { @@ -16,7 +16,7 @@ const classes = { const Root = styled('div')(() => ({ [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' } })); @@ -25,17 +25,17 @@ const propTypes = { PropTypes.shape({ id: PropTypes.string, name: PropTypes.string, - description: PropTypes.string, + description: PropTypes.string }) - ), + ) }; -const displayName = "GuildResults"; +const displayName = 'GuildResults'; const GuildResults = () => { const { state } = useContext(AppContext); const { guilds } = state; - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); return ( @@ -45,26 +45,26 @@ const GuildResults = () => { label="Search guilds..." placeholder="Guild Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} />
    - {guilds?.length? - guilds?.map((guild, index) => - guild.name.toLowerCase().includes(searchText.toLowerCase()) ? ( - - ) : null) - : - Array.from({length: 20}) - .map((_, index) => ) - } + {guilds?.length + ? guilds?.map((guild, index) => + guild.name.toLowerCase().includes(searchText.toLowerCase()) ? ( + + ) : null + ) + : Array.from({ length: 20 }).map((_, index) => ( + + ))}
    ); diff --git a/web-ui/src/components/guild-results/GuildResults.test.jsx b/web-ui/src/components/guild-results/GuildResults.test.jsx index bf34a0c1f8..b31216a830 100644 --- a/web-ui/src/components/guild-results/GuildResults.test.jsx +++ b/web-ui/src/components/guild-results/GuildResults.test.jsx @@ -1,36 +1,36 @@ -import React from "react"; -import GuildResults from "./GuildResults"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import GuildResults from './GuildResults'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER", "ADMIN"], + role: ['MEMBER', 'ADMIN'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, guilds: [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - }, - ], - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '' + } + ] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( @@ -38,14 +38,12 @@ it("renders correctly", () => { ); }); - - -it("renders correctly when no guilds are loaded", () => { +it('renders correctly when no guilds are loaded', () => { initialState.state.guilds = []; - + snapshot( - + ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/guild-results/GuildSummaryCard.jsx b/web-ui/src/components/guild-results/GuildSummaryCard.jsx index 14c61a9f2c..b746b863d9 100644 --- a/web-ui/src/components/guild-results/GuildSummaryCard.jsx +++ b/web-ui/src/components/guild-results/GuildSummaryCard.jsx @@ -1,11 +1,11 @@ -import React, { useContext, useState, useCallback } from "react"; +import React, { useContext, useState, useCallback } from 'react'; -import { styled } from "@mui/material/styles"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_GUILDS, UPDATE_TOAST } from "../../context/actions"; -import EditGuildModal from "./EditGuildModal"; -import { Link } from "react-router-dom"; -import { Link as StyledLink } from "@mui/material"; +import { styled } from '@mui/material/styles'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_GUILDS, UPDATE_TOAST } from '../../context/actions'; +import EditGuildModal from './EditGuildModal'; +import { Link } from 'react-router-dom'; +import { Link as StyledLink } from '@mui/material'; import { Button, @@ -18,44 +18,44 @@ import { DialogTitle, DialogContent, DialogActions, - Tooltip, -} from "@mui/material"; -import PropTypes from "prop-types"; -import { deleteGuild, updateGuild } from "../../api/guild.js"; -import SplitButton from "../split-button/SplitButton"; + Tooltip +} from '@mui/material'; +import PropTypes from 'prop-types'; +import { deleteGuild, updateGuild } from '../../api/guild.js'; +import SplitButton from '../split-button/SplitButton'; -const PREFIX = "GuildSummaryCard"; +const PREFIX = 'GuildSummaryCard'; const classes = { card: `${PREFIX}-card`, header: `${PREFIX}-header`, - title: `${PREFIX}-title`, + title: `${PREFIX}-title` }; const StyledCard = styled(Card)(() => ({ [`&.${classes.card}`]: { - width: "340px", - display: "flex", - flexDirection: "column", - justifyContent: "space-between", + width: '340px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between' }, [`& .${classes.header}`]: { - width: "100%", + width: '100%' }, [`& .${classes.title}`]: { - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - }, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + } })); const propTypes = { guild: PropTypes.shape({ id: PropTypes.string, name: PropTypes.string, - description: PropTypes.string, - }), + description: PropTypes.string + }) }; -const displayName = "GuildSummaryCard"; +const displayName = 'GuildSummaryCard'; const GuildSummaryCard = ({ guild, index }) => { const { state, dispatch } = useContext(AppContext); @@ -64,21 +64,21 @@ const GuildSummaryCard = ({ guild, index }) => { const [openDelete, setOpenDelete] = useState(false); const [tooltipIsOpen, setTooltipIsOpen] = useState(false); const isAdmin = - userProfile && userProfile.role && userProfile.role.includes("ADMIN"); + userProfile && userProfile.role && userProfile.role.includes('ADMIN'); let leads = guild.guildMembers == null ? null - : guild.guildMembers.filter((guildMember) => guildMember.lead); + : guild.guildMembers.filter(guildMember => guildMember.lead); let nonLeads = guild.guildMembers == null ? null - : guild.guildMembers.filter((guildMember) => !guildMember.lead); + : guild.guildMembers.filter(guildMember => !guildMember.lead); const isGuildLead = leads === null ? false - : leads.some((lead) => lead.memberId === userProfile.memberProfile.id); + : leads.some(lead => lead.memberId === userProfile.memberProfile.id); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); @@ -94,23 +94,23 @@ const GuildSummaryCard = ({ guild, index }) => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Guild deleted", - }, + severity: 'success', + toast: 'Guild deleted' + } }); - let newGuilds = guilds.filter((guild) => { + let newGuilds = guilds.filter(guild => { return guild.id !== guildId; }); dispatch({ type: UPDATE_GUILDS, - payload: newGuilds, + payload: newGuilds }); } } }, [guildId, csrf, dispatch, guilds]); const options = - isAdmin || isGuildLead ? ["Edit Guild", "Delete Guild"] : ["Edit Guild"]; + isAdmin || isGuildLead ? ['Edit Guild', 'Delete Guild'] : ['Edit Guild']; const handleAction = (e, index) => { if (index === 0) { @@ -126,7 +126,7 @@ const GuildSummaryCard = ({ guild, index }) => { classes={{ content: classes.header, title: classes.title, - subheader: classes.title, + subheader: classes.title }} title={guild.name} subheader={ @@ -143,13 +143,13 @@ const GuildSummaryCard = ({ guild, index }) => { } /> - {guild?.link ? - -
    - Link to Guild Homepage -
    -
    - :null} + {guild?.link ? ( + +
    + Link to Guild Homepage +
    +
    + ) : null} {guild.guildMembers == null ? ( Guild Leads: None Assigned @@ -165,8 +165,8 @@ const GuildSummaryCard = ({ guild, index }) => { key={lead.memberId} to={`/profile/${lead?.memberId}`} style={{ - textDecoration: "none", - color: "rgba(0, 0, 0, 0.87)", + textDecoration: 'none', + color: 'rgba(0, 0, 0, 0.87)' }} > {index !== leads.length - 1 ? `${lead?.name}, ` : lead?.name} @@ -181,8 +181,8 @@ const GuildSummaryCard = ({ guild, index }) => { key={member.memberId} to={`/profile/${member?.memberId}`} style={{ - textDecoration: "none", - color: "rgba(0, 0, 0, 0.87)", + textDecoration: 'none', + color: 'rgba(0, 0, 0, 0.87)' }} > {index !== nonLeads.length - 1 @@ -226,7 +226,7 @@ const GuildSummaryCard = ({ guild, index }) => { guild={guild} open={open} onClose={handleClose} - onSave={async (editedGuild) => { + onSave={async editedGuild => { let res = await updateGuild(editedGuild, csrf); let data = res.payload && res.payload.data && !res.error @@ -237,7 +237,7 @@ const GuildSummaryCard = ({ guild, index }) => { copy[index] = data; dispatch({ type: UPDATE_GUILDS, - payload: copy, + payload: copy }); } }} diff --git a/web-ui/src/components/guild-results/GuildSummaryCard.test.jsx b/web-ui/src/components/guild-results/GuildSummaryCard.test.jsx index 7a76101bea..18e058d301 100644 --- a/web-ui/src/components/guild-results/GuildSummaryCard.test.jsx +++ b/web-ui/src/components/guild-results/GuildSummaryCard.test.jsx @@ -1,78 +1,77 @@ -import React from "react"; -import GuildSummaryCard from "./GuildSummaryCard"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import GuildSummaryCard from './GuildSummaryCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const guilds = [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - guildMembers: [{memberId: "3fa4-5717-4562-b3fc-2c963f66afa9", - name: "testname", lead: true}] - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '', + guildMembers: [ + { + memberId: '3fa4-5717-4562-b3fc-2c963f66afa9', + name: 'testname', + lead: true + } + ] + } ]; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - id: "3fa4-5717-4562-b3fc-2c963f66afa9", - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + id: '3fa4-5717-4562-b3fc-2c963f66afa9', + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, - guilds, - }, + guilds + } }; -const adminState = {...initialState}; -adminState.state = {...adminState.state}; -adminState.state.userProfile = {...adminState.state.userProfile}; -adminState.state.userProfile.role = ["MEMBER", "ADMIN"]; +const adminState = { ...initialState }; +adminState.state = { ...adminState.state }; +adminState.state.userProfile = { ...adminState.state.userProfile }; +adminState.state.userProfile.role = ['MEMBER', 'ADMIN']; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); }); -it("renders correctly for ADMIN", () => { +it('renders correctly for ADMIN', () => { snapshot( - + ); }); -it("renders correctly for guild lead", () => { +it('renders correctly for guild lead', () => { snapshot( - - - - - + + + + + ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/guild-results/GuildsActions.jsx b/web-ui/src/components/guild-results/GuildsActions.jsx index 2372975501..9b85031f99 100644 --- a/web-ui/src/components/guild-results/GuildsActions.jsx +++ b/web-ui/src/components/guild-results/GuildsActions.jsx @@ -1,16 +1,16 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; -import AddGuildModal from "./EditGuildModal"; -import { createGuild } from "../../api/guild"; -import { AppContext } from "../../context/AppContext"; -import { ADD_GUILD } from "../../context/actions"; +import AddGuildModal from './EditGuildModal'; +import { createGuild } from '../../api/guild'; +import { AppContext } from '../../context/AppContext'; +import { ADD_GUILD } from '../../context/actions'; -import { Button } from "@mui/material"; -import GroupIcon from "@mui/icons-material/Group"; +import { Button } from '@mui/material'; +import GroupIcon from '@mui/icons-material/Group'; -import "./GuildResults.css"; +import './GuildResults.css'; -const displayName = "GuildsActions"; +const displayName = 'GuildsActions'; const GuildsActions = () => { const { state, dispatch } = useContext(AppContext); @@ -22,7 +22,7 @@ const GuildsActions = () => { const handleClose = () => setOpen(false); - const isAdmin = userProfile?.role?.includes("ADMIN"); + const isAdmin = userProfile?.role?.includes('ADMIN'); return (
    @@ -34,7 +34,7 @@ const GuildsActions = () => { { + onSave={async guild => { if (csrf) { let res = await createGuild(guild, csrf); let data = diff --git a/web-ui/src/components/guild-results/GuildsActions.test.jsx b/web-ui/src/components/guild-results/GuildsActions.test.jsx index 24884dbe27..844df478e8 100644 --- a/web-ui/src/components/guild-results/GuildsActions.test.jsx +++ b/web-ui/src/components/guild-results/GuildsActions.test.jsx @@ -1,39 +1,39 @@ -import React from "react"; -import GuildsActions from "./GuildsActions"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import GuildsActions from './GuildsActions'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, guilds: [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - }, - ], - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '' + } + ] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/header/Header.css b/web-ui/src/components/header/Header.css index 1d113aa0a2..db0172b501 100644 --- a/web-ui/src/components/header/Header.css +++ b/web-ui/src/components/header/Header.css @@ -1,11 +1,11 @@ -@import url("https://fonts.googleapis.com/css2?family=Shadows+Into+Light&display=swap"); +@import url('https://fonts.googleapis.com/css2?family=Shadows+Into+Light&display=swap'); .header h1 { font-size: calc(1rem + 1vw); font-weight: 500; margin-top: 5px; margin-bottom: 0px; - margin-left: .5rem; + margin-left: 0.5rem; } .header { diff --git a/web-ui/src/components/header/Header.jsx b/web-ui/src/components/header/Header.jsx index 80df979eed..9ef096ff17 100644 --- a/web-ui/src/components/header/Header.jsx +++ b/web-ui/src/components/header/Header.jsx @@ -1,5 +1,5 @@ -import React from "react"; -import "./Header.css"; +import React from 'react'; +import './Header.css'; const Header = ({ title, children }) => { return ( diff --git a/web-ui/src/components/header/Header.stories.jsx b/web-ui/src/components/header/Header.stories.jsx index 1df408f094..373df9e7b7 100644 --- a/web-ui/src/components/header/Header.stories.jsx +++ b/web-ui/src/components/header/Header.stories.jsx @@ -4,12 +4,12 @@ import Header from './Header'; export default { title: 'Check-Ins/Header', - component: Header, + component: Header }; -const Template = (args) =>
    ; +const Template = args =>
    ; export const Simple = Template.bind({}); Simple.args = { - title: 'Test Title', + title: 'Test Title' }; diff --git a/web-ui/src/components/header/Header.test.jsx b/web-ui/src/components/header/Header.test.jsx index 6d90e61ed2..afe3de22eb 100644 --- a/web-ui/src/components/header/Header.test.jsx +++ b/web-ui/src/components/header/Header.test.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import Header from "./Header"; -import renderer from "react-test-renderer"; +import React from 'react'; +import Header from './Header'; +import renderer from 'react-test-renderer'; -it("renders title", () => { +it('renders title', () => { snapshot(
    ); }); diff --git a/web-ui/src/components/kudos/Kudos.jsx b/web-ui/src/components/kudos/Kudos.jsx index b8718545e6..96b1f295c5 100644 --- a/web-ui/src/components/kudos/Kudos.jsx +++ b/web-ui/src/components/kudos/Kudos.jsx @@ -1,7 +1,7 @@ import { Box, Card, CardContent, CardHeader, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; -import React from 'react' -import AvatarComponent from '../avatar/Avatar' +import React from 'react'; +import AvatarComponent from '../avatar/Avatar'; const PREFIX = 'Kudos'; const classes = { @@ -10,30 +10,33 @@ const classes = { large: `${PREFIX}-large` }; -const StyledCard = styled(Card)(({theme}) => ({ +const StyledCard = styled(Card)(({ theme }) => ({ [`& .${classes.display}`]: { - display: "flex", - flexDirection: "column", - justifyContent: "space-around" + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-around' }, [`& .${classes.small}`]: { width: theme.spacing(6), height: theme.spacing(6), - margin: theme.spacing(1), + margin: theme.spacing(1) }, [`& .${classes.large}`]: { width: theme.spacing(8), - height: theme.spacing(8), + height: theme.spacing(8) } })); -export default function Kudos({kudosTo, kudosFrom, content}) { +export default function Kudos({ kudosTo, kudosFrom, content }) { return ( - + + } disableTypography title={ @@ -44,22 +47,23 @@ export default function Kudos({kudosTo, kudosFrom, content}) { /> - - + + {content} - - - {kudosFrom && - - + + + {kudosFrom && ( + + {`${kudosFrom.name} - ${kudosFrom.title}`} - - - } + + + )} ); } - - diff --git a/web-ui/src/components/kudos/Kudos.stories.jsx b/web-ui/src/components/kudos/Kudos.stories.jsx index 0049e1af39..af70d19934 100644 --- a/web-ui/src/components/kudos/Kudos.stories.jsx +++ b/web-ui/src/components/kudos/Kudos.stories.jsx @@ -6,31 +6,31 @@ export default { component: Kudos, title: 'Check Ins/Kudos', decorators: [ - (Kudos) => ( -
    + Kudos => ( +
    ) ] -} +}; -const Template = (args) => { +const Template = args => { return ; -} +}; const kudosData = { kudosTo: { - name: "John Doe", - imageUrl: image, + name: 'John Doe', + imageUrl: image }, - content:"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.", + content: + 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.', kudosFrom: { - name: "Jane Doe", + name: 'Jane Doe', imageUrl: image, - title: "Senior Software Engineer" + title: 'Senior Software Engineer' } -} - +}; export const KudosNonConfidential = Template.bind({}); KudosNonConfidential.args = { @@ -40,11 +40,5 @@ KudosNonConfidential.args = { export const KudosConfidential = Template.bind({}); KudosConfidential.args = { ...kudosData, - kudosFrom: undefined, + kudosFrom: undefined }; - - - - - - diff --git a/web-ui/src/components/kudos/Kudos.test.jsx b/web-ui/src/components/kudos/Kudos.test.jsx index 62b1a17764..45cf83bb93 100644 --- a/web-ui/src/components/kudos/Kudos.test.jsx +++ b/web-ui/src/components/kudos/Kudos.test.jsx @@ -1,38 +1,36 @@ -import React from "react"; +import React from 'react'; import renderer from 'react-test-renderer'; -import Kudos from "./Kudos" +import Kudos from './Kudos'; import image from '../../logo.svg'; const kudosData = { kudosTo: { - name: "John Doe", - imageUrl: image, + name: 'John Doe', + imageUrl: image }, - content:"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.", + content: + 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.', kudosFrom: { - name: "Jane Doe", + name: 'Jane Doe', imageUrl: image, - title: "Senior Software Engineer" + title: 'Senior Software Engineer' } -} +}; it("renders correctly when 'kudosFrom' prop is provided", () => { const component = renderer.create( - - ) + ); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'kudosFrom' prop is not provided", () => { const component = renderer.create( - - ) + + ); expect(component.toJSON()).toMatchSnapshot(); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/member-directory/AdminMemberCard.jsx b/web-ui/src/components/member-directory/AdminMemberCard.jsx index 0940fe8399..0aaf119364 100644 --- a/web-ui/src/components/member-directory/AdminMemberCard.jsx +++ b/web-ui/src/components/member-directory/AdminMemberCard.jsx @@ -1,22 +1,22 @@ -import React, { useContext, useState } from "react"; -import { styled } from "@mui/material/styles"; -import { Link } from "react-router-dom"; +import React, { useContext, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import { Link } from 'react-router-dom'; -import MemberModal from "./MemberModal"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_MEMBER_PROFILES } from "../../context/actions"; -import { selectProfileMap } from "../../context/selectors"; -import { getAvatarURL } from "../../api/api.js"; +import MemberModal from './MemberModal'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_MEMBER_PROFILES } from '../../context/actions'; +import { selectProfileMap } from '../../context/selectors'; +import { getAvatarURL } from '../../api/api.js'; -import { Card, CardActions, CardHeader, Tooltip } from "@mui/material"; -import Avatar from "@mui/material/Avatar"; -import PriorityHighIcon from "@mui/icons-material/PriorityHigh"; +import { Card, CardActions, CardHeader, Tooltip } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; -import "./MemberSummaryCard.css"; -import SplitButton from "../split-button/SplitButton"; +import './MemberSummaryCard.css'; +import SplitButton from '../split-button/SplitButton'; -import { updateMember, deleteMember } from "../../api/member.js"; -import { DELETE_MEMBER_PROFILE, UPDATE_TOAST } from "../../context/actions.js"; +import { updateMember, deleteMember } from '../../api/member.js'; +import { DELETE_MEMBER_PROFILE, UPDATE_TOAST } from '../../context/actions.js'; import { Box, @@ -28,25 +28,25 @@ import { DialogContent, DialogContentText, DialogTitle, - Typography, -} from "@mui/material"; + Typography +} from '@mui/material'; -const PREFIX = "AdminMemberCard"; +const PREFIX = 'AdminMemberCard'; const classes = { - header: `${PREFIX}-header`, + header: `${PREFIX}-header` }; const StyledBox = styled(Box)(() => ({ [`& .${classes.header}`]: { - cursor: "pointer", - }, + cursor: 'pointer' + } })); const AdminMemberCard = ({ member, index }) => { const { state, dispatch } = useContext(AppContext); const { memberProfiles, userProfile, csrf } = state; const isAdmin = - userProfile && userProfile.role && userProfile.role.includes("ADMIN"); + userProfile && userProfile.role && userProfile.role.includes('ADMIN'); const { location, name, @@ -54,7 +54,7 @@ const AdminMemberCard = ({ member, index }) => { title, supervisorid, pdlId, - terminationDate, + terminationDate } = member; const memberId = member?.id; const supervisorProfile = selectProfileMap(state)[supervisorid]; @@ -70,7 +70,7 @@ const AdminMemberCard = ({ member, index }) => { const handleClose = () => setOpen(false); const handleCloseDeleteConfirmation = () => setOpenDelete(false); - const options = isAdmin ? ["Edit", "Delete"] : ["Edit"]; + const options = isAdmin ? ['Edit', 'Delete'] : ['Edit']; const handleAction = (e, index) => { if (index === 0) { @@ -87,9 +87,9 @@ const AdminMemberCard = ({ member, index }) => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Member deleted", - }, + severity: 'success', + toast: 'Member deleted' + } }); } handleCloseDeleteConfirmation(); @@ -97,9 +97,9 @@ const AdminMemberCard = ({ member, index }) => { return ( - + { disableTypography avatar={ !terminationDate ? ( - + ) : ( - + setTooltipIsOpen(true)} onClose={() => setTooltipIsOpen(false)} enterTouchDelay={0} placement="top-start" - title={"This member has been terminated"} + title={'This member has been terminated'} > @@ -136,7 +136,7 @@ const AdminMemberCard = ({ member, index }) => { /> - + {
    Location: {location}
    - Supervisor:{" "} + Supervisor:{' '} {supervisorid && ( {supervisorProfile?.name} )}
    - PDL:{" "} + PDL:{' '} {pdlId && ( {pdlProfile?.name} @@ -209,7 +209,7 @@ const AdminMemberCard = ({ member, index }) => { member={member} open={open} onClose={handleClose} - onSave={async (member) => { + onSave={async member => { let res = await updateMember(member, csrf); let data = res.payload && res.payload.data && !res.error @@ -218,12 +218,12 @@ const AdminMemberCard = ({ member, index }) => { if (data) { const copy = [...memberProfiles]; const index = copy.findIndex( - (profile) => profile.id === data.id + profile => profile.id === data.id ); copy[index] = data; dispatch({ type: UPDATE_MEMBER_PROFILES, - payload: copy, + payload: copy }); handleClose(); } diff --git a/web-ui/src/components/member-directory/MemberModal.jsx b/web-ui/src/components/member-directory/MemberModal.jsx index d4b3522628..99d5cc9b6c 100644 --- a/web-ui/src/components/member-directory/MemberModal.jsx +++ b/web-ui/src/components/member-directory/MemberModal.jsx @@ -1,35 +1,35 @@ -import React, { useContext, useState } from "react"; -import { AppContext } from "../../context/AppContext"; +import React, { useContext, useState } from 'react'; +import { AppContext } from '../../context/AppContext'; import { selectOrderedPdls, selectOrderedMemberFirstName, - selectCurrentMembers, -} from "../../context/selectors"; + selectCurrentMembers +} from '../../context/selectors'; -import { Modal, TextField } from "@mui/material"; -import Autocomplete from "@mui/material/Autocomplete"; -import { DatePicker } from "@mui/x-date-pickers"; -import { format } from "date-fns"; -import { Button } from "@mui/material"; -import { UPDATE_TOAST } from "../../context/actions"; +import { Modal, TextField } from '@mui/material'; +import Autocomplete from '@mui/material/Autocomplete'; +import { DatePicker } from '@mui/x-date-pickers'; +import { format } from 'date-fns'; +import { Button } from '@mui/material'; +import { UPDATE_TOAST } from '../../context/actions'; -import "./MemberModal.css"; -import { useCallback } from "react"; +import './MemberModal.css'; +import { useCallback } from 'react'; const emptyMember = { - employeeId: "", - firstName: "", - middleName: "", - lastName: "", - suffix: "", - workEmail: "", - title: "", - location: "", + employeeId: '', + firstName: '', + middleName: '', + lastName: '', + suffix: '', + workEmail: '', + title: '', + location: '', birthDay: null, - pdlId: "", - supervisorid: "", + pdlId: '', + supervisorid: '', startDate: new Date(), - terminationDate: null, + terminationDate: null }; const MemberModal = ({ member, open, onSave, onClose }) => { @@ -37,12 +37,14 @@ const MemberModal = ({ member, open, onSave, onClose }) => { const memberProfiles = selectCurrentMembers(state); const [editedMember, setMember] = useState(member); const sortedPdls = selectOrderedPdls(state); - const [isNewMember, setIsNewMember] = useState(Object.keys(member).length===0 ? true : false); + const [isNewMember, setIsNewMember] = useState( + Object.keys(member).length === 0 ? true : false + ); const sortedMembers = selectOrderedMemberFirstName(state); const onSupervisorChange = (event, newValue) => { setMember({ ...editedMember, - supervisorid: newValue ? newValue.id : "", + supervisorid: newValue ? newValue.id : '' }); }; @@ -57,19 +59,20 @@ const MemberModal = ({ member, open, onSave, onClose }) => { const onPdlChange = (event, newValue) => { setMember({ ...editedMember, - pdlId: newValue ? newValue.id : "", + pdlId: newValue ? newValue.id : '' }); }; const validateInputs = useCallback(() => { - let regEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ // eslint-disable-line + let regEmail = + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line if (!regEmail.test(editedMember.workEmail)) { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Please enter a valid email", - }, + severity: 'error', + toast: 'Please enter a valid email' + } }); return false; } @@ -81,9 +84,9 @@ const MemberModal = ({ member, open, onSave, onClose }) => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Please enter a valid birthday", - }, + severity: 'error', + toast: 'Please enter a valid birthday' + } }); return false; } @@ -94,9 +97,9 @@ const MemberModal = ({ member, open, onSave, onClose }) => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Please enter a valid start date", - }, + severity: 'error', + toast: 'Please enter a valid start date' + } }); return false; } @@ -107,9 +110,9 @@ const MemberModal = ({ member, open, onSave, onClose }) => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Please enter a termination date that is after the start date", - }, + severity: 'error', + toast: 'Please enter a termination date that is after the start date' + } }); return false; } @@ -136,16 +139,16 @@ const MemberModal = ({ member, open, onSave, onClose }) => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", + severity: 'error', toast: - "One or more required fields are empty. Check starred input fields", - }, + 'One or more required fields are empty. Check starred input fields' + } }); } else if (required && inputsFeasible) { onSave(editedMember).then(() => { if (isNewMember.current) { setMember({ emptyMember }); - setIsNewMember(true) + setIsNewMember(true); } }); } @@ -167,8 +170,8 @@ const MemberModal = ({ member, open, onSave, onClose }) => { required className="halfWidth" placeholder="First Name" - value={editedMember.firstName ? editedMember.firstName : ""} - onChange={(e) => + value={editedMember.firstName ? editedMember.firstName : ''} + onChange={e => setMember({ ...editedMember, firstName: e.target.value }) } /> @@ -177,8 +180,8 @@ const MemberModal = ({ member, open, onSave, onClose }) => { label="Middle Name" className="halfWidth" placeholder="Middle Name" - value={editedMember.middleName ? editedMember.middleName : ""} - onChange={(e) => + value={editedMember.middleName ? editedMember.middleName : ''} + onChange={e => setMember({ ...editedMember, middleName: e.target.value }) } /> @@ -188,8 +191,8 @@ const MemberModal = ({ member, open, onSave, onClose }) => { required className="halfWidth" placeholder="Last Name" - value={editedMember.lastName ? editedMember.lastName : ""} - onChange={(e) => + value={editedMember.lastName ? editedMember.lastName : ''} + onChange={e => setMember({ ...editedMember, lastName: e.target.value }) } /> @@ -198,10 +201,8 @@ const MemberModal = ({ member, open, onSave, onClose }) => { label="Suffix" className="halfWidth" placeholder="Suffix" - value={editedMember.suffix ? editedMember.suffix : ""} - onChange={(e) => - setMember({ ...editedMember, suffix: e.target.value }) - } + value={editedMember.suffix ? editedMember.suffix : ''} + onChange={e => setMember({ ...editedMember, suffix: e.target.value })} /> { required className="halfWidth" placeholder="Company Email" - value={editedMember.workEmail ? editedMember.workEmail : ""} - onChange={(e) => + value={editedMember.workEmail ? editedMember.workEmail : ''} + onChange={e => setMember({ ...editedMember, workEmail: e.target.value }) } /> @@ -220,10 +221,8 @@ const MemberModal = ({ member, open, onSave, onClose }) => { required className="halfWidth" placeholder="Official Title" - value={editedMember.title ? editedMember.title : ""} - onChange={(e) => - setMember({ ...editedMember, title: e.target.value }) - } + value={editedMember.title ? editedMember.title : ''} + onChange={e => setMember({ ...editedMember, title: e.target.value })} /> { required className="halfWidth" placeholder="Physical Location" - value={editedMember.location ? editedMember.location : ""} - onChange={(e) => + value={editedMember.location ? editedMember.location : ''} + onChange={e => setMember({ ...editedMember, location: e.target.value }) } /> { format="MM/dd/yyyy" value={birthDay} openTo="year" - onChange={(date) => { + onChange={date => { setMember({ ...editedMember, birthDay: date }); }} KeyboardButtonProps={{ - "aria-label": "Change Date", + 'aria-label': 'Change Date' }} /> { required className="halfWidth" placeholder="Employee Identifier" - value={editedMember.employeeId ? editedMember.employeeId : ""} - onChange={(e) => + value={editedMember.employeeId ? editedMember.employeeId : ''} + onChange={e => setMember({ ...editedMember, employeeId: e.target.value }) } /> @@ -267,12 +266,12 @@ const MemberModal = ({ member, open, onSave, onClose }) => { options={sortedPdls} value={ (sortedPdls && - sortedPdls.find((pdl) => pdl?.id === editedMember.pdlId)) || - "" + sortedPdls.find(pdl => pdl?.id === editedMember.pdlId)) || + '' } onChange={onPdlChange} - getOptionLabel={(option) => option.name || ""} - renderInput={(params) => ( + getOptionLabel={option => option.name || ''} + renderInput={params => ( { )} /> - memberProfile.id === editedMember.supervisorid + memberProfile => memberProfile.id === editedMember.supervisorid )) || - "" + '' } onChange={onSupervisorChange} - getOptionLabel={(option) => option.name || ""} - renderInput={(params) => ( + getOptionLabel={option => option.name || ''} + renderInput={params => ( { )} /> { + onChange={e => { setMember({ ...editedMember, startDate: e }); }} KeyboardButtonProps={{ - "aria-label": "Change Date", + 'aria-label': 'Change Date' }} /> { + placeholder={format(new Date(), 'MM/dd/yyy')} + onChange={date => { setMember({ ...editedMember, terminationDate: date }); }} KeyboardButtonProps={{ - "aria-label": "Change Date", + 'aria-label': 'Change Date' }} />
    diff --git a/web-ui/src/components/member-directory/MemberModal.test.jsx b/web-ui/src/components/member-directory/MemberModal.test.jsx index 646f75f449..6006d30f21 100644 --- a/web-ui/src/components/member-directory/MemberModal.test.jsx +++ b/web-ui/src/components/member-directory/MemberModal.test.jsx @@ -1,58 +1,58 @@ -import React from "react"; -import MemberSummaryCard from "./MemberSummaryCard"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import MemberSummaryCard from './MemberSummaryCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const initialState = { state: { userProfile: { memberProfile: { - id: "912834091823", - name: "Current", - pdlId: "0987654321", - supervisorId: "9876543210", + id: '912834091823', + name: 'Current', + pdlId: '0987654321', + supervisorId: '9876543210' }, - role: ["MEMBER"], + role: ['MEMBER'] }, memberProfiles: [ { - id: "0987654321", - name: "TestName", - lastName: "Name", + id: '0987654321', + name: 'TestName', + lastName: 'Name' }, { - id: "9876543210", - name: "TestName2", - lastName: "Name2", - }, - ], - }, + id: '9876543210', + name: 'TestName2', + lastName: 'Name2' + } + ] + } }; -const onSave = (member) => { +const onSave = member => { console.log(member); }; const open = () => { - console.log("Open"); + console.log('Open'); }; const close = () => { - console.log("Closed"); + console.log('Closed'); }; const member = { - firstName: "tester", - lastName: "teserson", - id: "2o34i2j34", + firstName: 'tester', + lastName: 'teserson', + id: '2o34i2j34', startDate: [2018, 1, 10], - location: "STL", - imageURL: "url.com", - title: "engineer", - workEmail: "testerson@oci.com", + location: 'STL', + imageURL: 'url.com', + title: 'engineer', + workEmail: 'testerson@oci.com' }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/member-directory/MemberSummaryCard.css b/web-ui/src/components/member-directory/MemberSummaryCard.css index 670bc7823f..d3b25b7447 100644 --- a/web-ui/src/components/member-directory/MemberSummaryCard.css +++ b/web-ui/src/components/member-directory/MemberSummaryCard.css @@ -43,4 +43,4 @@ text-overflow: ellipsis; white-space: nowrap; width: 225px; -} \ No newline at end of file +} diff --git a/web-ui/src/components/member-directory/MemberSummaryCard.jsx b/web-ui/src/components/member-directory/MemberSummaryCard.jsx index bb28ebc7b0..af36664f3b 100644 --- a/web-ui/src/components/member-directory/MemberSummaryCard.jsx +++ b/web-ui/src/components/member-directory/MemberSummaryCard.jsx @@ -1,18 +1,24 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; import { styled } from '@mui/material/styles'; -import { Link } from "react-router-dom"; +import { Link } from 'react-router-dom'; -import { AppContext } from "../../context/AppContext"; -import { selectIsAdmin, selectProfileMap } from "../../context/selectors"; -import { getAvatarURL } from "../../api/api.js"; +import { AppContext } from '../../context/AppContext'; +import { selectIsAdmin, selectProfileMap } from '../../context/selectors'; +import { getAvatarURL } from '../../api/api.js'; -import { Card, CardHeader } from "@mui/material"; -import Avatar from "@mui/material/Avatar"; -import PriorityHighIcon from "@mui/icons-material/PriorityHigh"; +import { Card, CardHeader } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; -import "./MemberSummaryCard.css"; +import './MemberSummaryCard.css'; -import { Box, CardContent, Container, Tooltip, Typography } from "@mui/material"; +import { + Box, + CardContent, + Container, + Tooltip, + Typography +} from '@mui/material'; const PREFIX = 'MemberSummaryCard'; const classes = { header: `${PREFIX}-header` @@ -20,7 +26,7 @@ const classes = { const StyledBox = styled(Box)(() => ({ [`& .${classes.header}`]: { - cursor: "pointer", + cursor: 'pointer' } })); @@ -34,7 +40,7 @@ const MemberSummaryCard = ({ member }) => { title, supervisorid, pdlId, - terminationDate, + terminationDate } = member; const supervisorProfile = selectProfileMap(state)[supervisorid]; const pdlProfile = selectProfileMap(state)[pdlId]; @@ -42,9 +48,9 @@ const MemberSummaryCard = ({ member }) => { return ( - + { disableTypography avatar={ isAdmin && terminationDate ? ( - + setTooltipIsOpen(true)} onClose={() => setTooltipIsOpen(false)} enterTouchDelay={0} placement="top-start" - title={"This member has been terminated"} + title={'This member has been terminated'} > ) : ( - + ) } /> - + {
    Location: {location}
    - Supervisor: {supervisorid && - - {supervisorProfile?.name} - } + Supervisor:{' '} + {supervisorid && ( + + {supervisorProfile?.name} + + )} +
    + PDL:{' '} + {pdlId && ( + + {pdlProfile?.name} + + )}
    - PDL: {pdlId && - - {pdlProfile?.name} - - - } -
    diff --git a/web-ui/src/components/member-directory/MemberSummaryCard.test.jsx b/web-ui/src/components/member-directory/MemberSummaryCard.test.jsx index 34267c6a7b..93a73623cf 100644 --- a/web-ui/src/components/member-directory/MemberSummaryCard.test.jsx +++ b/web-ui/src/components/member-directory/MemberSummaryCard.test.jsx @@ -1,50 +1,50 @@ -import React from "react"; -import MemberSummaryCard from "./MemberSummaryCard"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import MemberSummaryCard from './MemberSummaryCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const initialState = { state: { userProfile: { memberProfile: { - id: "912834091823", - name: "Current", - pdlId: "0987654321", - supervisorId: "9876543210", + id: '912834091823', + name: 'Current', + pdlId: '0987654321', + supervisorId: '9876543210' }, - role: ["MEMBER"], + role: ['MEMBER'] }, memberProfiles: [ { - id: "0987654321", - name: "TestName", - lastName: "Name", + id: '0987654321', + name: 'TestName', + lastName: 'Name' }, { - id: "9876543210", - name: "TestName2", - lastName: "Name2", - }, - ], - }, + id: '9876543210', + name: 'TestName2', + lastName: 'Name2' + } + ] + } }; const member = { - name: "testerson", - id: "2o34i2j34", + name: 'testerson', + id: '2o34i2j34', startDate: [2018, 1, 10], - location: "STL", - imageURL: "url.com", - title: "engineer", - workEmail: "testerson@oci.com", + location: 'STL', + imageURL: 'url.com', + title: 'engineer', + workEmail: 'testerson@oci.com' }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); }); diff --git a/web-ui/src/components/member-directory/__snapshots__/MemberModal.test.jsx.snap b/web-ui/src/components/member-directory/__snapshots__/MemberModal.test.jsx.snap index ccc107519b..05d1b9d2f2 100644 --- a/web-ui/src/components/member-directory/__snapshots__/MemberModal.test.jsx.snap +++ b/web-ui/src/components/member-directory/__snapshots__/MemberModal.test.jsx.snap @@ -61,9 +61,11 @@ exports[`renders correctly 1`] = ` Location: STL
    - Supervisor: + Supervisor: +
    - PDL: + PDL: +

    diff --git a/web-ui/src/components/member-directory/__snapshots__/MemberSummaryCard.test.jsx.snap b/web-ui/src/components/member-directory/__snapshots__/MemberSummaryCard.test.jsx.snap index bbc8c6915c..38dc0f304e 100644 --- a/web-ui/src/components/member-directory/__snapshots__/MemberSummaryCard.test.jsx.snap +++ b/web-ui/src/components/member-directory/__snapshots__/MemberSummaryCard.test.jsx.snap @@ -63,9 +63,11 @@ exports[`renders correctly 1`] = ` Location: STL
    - Supervisor: + Supervisor: +
    - PDL: + PDL: +

    diff --git a/web-ui/src/components/member_selector/MemberSelector.css b/web-ui/src/components/member_selector/MemberSelector.css index b0704f1832..27080dd161 100644 --- a/web-ui/src/components/member_selector/MemberSelector.css +++ b/web-ui/src/components/member_selector/MemberSelector.css @@ -1,33 +1,33 @@ /* Workaround for bleeding style applied to MuiCardHeader-action */ .member-selector-card .MuiCardHeader-action { - padding: 0; + padding: 0; } .member-selector-card .MuiCardHeader-avatar { - margin-right: 8px; + margin-right: 8px; } .member-selector-card .member-selector-card-title-container { - display: flex; - flex-direction: row; - align-items: center; - gap: 0.5rem; + display: flex; + flex-direction: row; + align-items: center; + gap: 0.5rem; } .member-selector-card .member-selector-card-title { - font-size: 1.5em; + font-size: 1.5em; } .member-selector-card .member-selector-card-count { - font-size: 1.25em; + font-size: 1.25em; } @media screen and (max-width: 600px) { - .member-selector-card .member-selector-card-title { - font-size: 1.25em; - } + .member-selector-card .member-selector-card-title { + font-size: 1.25em; + } - .member-selector-card .member-selector-card-count { - font-size: 1em; - } -} \ No newline at end of file + .member-selector-card .member-selector-card-count { + font-size: 1em; + } +} diff --git a/web-ui/src/components/member_selector/MemberSelector.jsx b/web-ui/src/components/member_selector/MemberSelector.jsx index 167ec20489..ac7a75ec0e 100644 --- a/web-ui/src/components/member_selector/MemberSelector.jsx +++ b/web-ui/src/components/member_selector/MemberSelector.jsx @@ -1,35 +1,39 @@ -import React, {useCallback, useContext, useEffect, useState} from "react"; -import PropTypes from "prop-types"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; import { Avatar, Card, - CardHeader, Collapse, + CardHeader, + Collapse, Divider, IconButton, List, ListItem, - ListItemAvatar, ListItemIcon, - ListItemText, Menu, MenuItem, + ListItemAvatar, + ListItemIcon, + ListItemText, + Menu, + MenuItem, Tooltip, Typography -} from "@mui/material"; -import AddIcon from "@mui/icons-material/Add"; -import RemoveIcon from "@mui/icons-material/Remove"; -import ExpandLessIcon from "@mui/icons-material/ExpandLess"; -import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; -import HighlightOffIcon from "@mui/icons-material/HighlightOff"; -import MoreVertIcon from "@mui/icons-material/MoreVert"; -import {getAvatarURL} from "../../api/api"; - -import MemberSelectorDialog from "./member_selector_dialog/MemberSelectorDialog"; -import DownloadIcon from "@mui/icons-material/FileDownload"; -import {reportSelectedMembersCsv} from "../../api/member.js"; -import {AppContext} from "../../context/AppContext.jsx"; -import {selectCsrfToken} from "../../context/selectors.js"; -import fileDownload from "js-file-download"; -import {UPDATE_TOAST} from "../../context/actions.js"; - -import "./MemberSelector.css"; +} from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import RemoveIcon from '@mui/icons-material/Remove'; +import ExpandLessIcon from '@mui/icons-material/ExpandLess'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import HighlightOffIcon from '@mui/icons-material/HighlightOff'; +import MoreVertIcon from '@mui/icons-material/MoreVert'; +import { getAvatarURL } from '../../api/api'; + +import MemberSelectorDialog from './member_selector_dialog/MemberSelectorDialog'; +import DownloadIcon from '@mui/icons-material/FileDownload'; +import { reportSelectedMembersCsv } from '../../api/member.js'; +import { AppContext } from '../../context/AppContext.jsx'; +import { selectCsrfToken } from '../../context/selectors.js'; +import fileDownload from 'js-file-download'; +import { UPDATE_TOAST } from '../../context/actions.js'; + +import './MemberSelector.css'; const propTypes = { /** The members that are currently selected. Use to make this a controlled component. */ @@ -52,13 +56,25 @@ const propTypes = { style: PropTypes.object }; -const MemberSelector = ({selected, onChange, title = "Selected Members", outlined = false, exportable = false, listHeight = 400, disabled = false, className, style }) => { +const MemberSelector = ({ + selected, + onChange, + title = 'Selected Members', + outlined = false, + exportable = false, + listHeight = 400, + disabled = false, + className, + style +}) => { const isControlled = !!selected && Array.isArray(selected); const { state, dispatch } = useContext(AppContext); const csrf = selectCsrfToken(state); - const [selectedMembers, setSelectedMembers] = useState(isControlled ? selected : []); + const [selectedMembers, setSelectedMembers] = useState( + isControlled ? selected : [] + ); const [dialogOpen, setDialogOpen] = useState(false); const [expanded, setExpanded] = useState(true); const [menuAnchor, setMenuAnchor] = useState(null); @@ -77,18 +93,26 @@ const MemberSelector = ({selected, onChange, title = "Selected Members", outline } }, [disabled]); - const addMembers = useCallback((membersToAdd) => { - const selected = [...selectedMembers, ...membersToAdd]; - setSelectedMembers(selected); - setDialogOpen(false); - }, [selectedMembers]); + const addMembers = useCallback( + membersToAdd => { + const selected = [...selectedMembers, ...membersToAdd]; + setSelectedMembers(selected); + setDialogOpen(false); + }, + [selectedMembers] + ); - const removeMember = useCallback((member) => { - const selected = [...selectedMembers] - const indexToRemove = selected.findIndex(selectedMember => selectedMember.id === member.id); - selected.splice(indexToRemove, 1); - setSelectedMembers(selected); - }, [selectedMembers]); + const removeMember = useCallback( + member => { + const selected = [...selectedMembers]; + const indexToRemove = selected.findIndex( + selectedMember => selectedMember.id === member.id + ); + selected.splice(indexToRemove, 1); + setSelectedMembers(selected); + }, + [selectedMembers] + ); const downloadMemberCsv = useCallback(() => { if (!exportable) { @@ -98,20 +122,20 @@ const MemberSelector = ({selected, onChange, title = "Selected Members", outline const memberIds = selectedMembers.map(member => member.id); reportSelectedMembersCsv(memberIds, csrf).then(res => { if (res && !res.error) { - fileDownload(res.payload.data, "members.csv"); + fileDownload(res.payload.data, 'members.csv'); dispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Member export has been saved" + severity: 'success', + toast: 'Member export has been saved' } }); } else { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to export members to CSV" + severity: 'error', + toast: 'Failed to export members to CSV' } }); } @@ -125,75 +149,95 @@ const MemberSelector = ({selected, onChange, title = "Selected Members", outline return ( <> + variant={outlined ? 'outlined' : 'elevation'} + className={'member-selector-card' + (className ? ` ${className}` : '')} + style={style} + > setExpanded(!expanded)}> - {expanded ? : } + {expanded ? : } } title={
    - {title} - ({selectedMembers.length}) + + {title} + + + ({selectedMembers.length}) +
    } action={ - <> - + <> + + setDialogOpen(true)} + disabled={disabled} + > + + + setDialogOpen(true)} - disabled={disabled} + style={{ margin: '4px 8px 0 0' }} + onClick={event => setMenuAnchor(event.currentTarget)} > - + - - setMenuAnchor(event.currentTarget)}> - - - setMenuAnchor(null)} - > - { - setMenuAnchor(null); - clearMembers(); - }} - disabled={disabled || !selectedMembers.length} + setMenuAnchor(null)} > - - - - Remove all - - {exportable && { setMenuAnchor(null); - downloadMemberCsv(); + clearMembers(); }} - disabled={!selectedMembers.length} + disabled={disabled || !selectedMembers.length} > - + - Download + Remove all - } - - + {exportable && ( + { + setMenuAnchor(null); + downloadMemberCsv(); + }} + disabled={!selectedMembers.length} + > + + + + Download + + )} + + } /> - - - {selectedMembers.length - ? (selectedMembers.map(member => + + + {selectedMembers.length ? ( + selectedMembers.map(member => ( removeMember(member)} disabled={disabled} > - + } > - + {member.name}} - secondary={{member.title}} + primary={ + {member.name} + } + secondary={ + + {member.title} + + } /> )) - : ( - No members selected - ) - } + ) : ( + + + No members selected + + + )}
    @@ -228,7 +281,7 @@ const MemberSelector = ({selected, onChange, title = "Selected Members", outline open={dialogOpen} selectedMembers={selectedMembers} onClose={() => setDialogOpen(false)} - onSubmit={(membersToAdd) => addMembers(membersToAdd)} + onSubmit={membersToAdd => addMembers(membersToAdd)} /> ); @@ -236,4 +289,4 @@ const MemberSelector = ({selected, onChange, title = "Selected Members", outline MemberSelector.propTypes = propTypes; -export default MemberSelector; \ No newline at end of file +export default MemberSelector; diff --git a/web-ui/src/components/member_selector/MemberSelector.test.jsx b/web-ui/src/components/member_selector/MemberSelector.test.jsx index 0861f71967..2febabbc67 100644 --- a/web-ui/src/components/member_selector/MemberSelector.test.jsx +++ b/web-ui/src/components/member_selector/MemberSelector.test.jsx @@ -1,45 +1,43 @@ -import React from "react"; -import { AppContextProvider } from "../../context/AppContext"; -import MemberSelector from "./MemberSelector"; +import React from 'react'; +import { AppContextProvider } from '../../context/AppContext'; +import MemberSelector from './MemberSelector'; const initialState = { state: { userProfile: { memberProfile: { - id: "912834091823", - name: "Current", - pdlId: "0987654321", - supervisorId: "9876543210", + id: '912834091823', + name: 'Current', + pdlId: '0987654321', + supervisorId: '9876543210' }, - role: ["MEMBER"], + role: ['MEMBER'] }, memberProfiles: [ { - id: "0987654321", - name: "TestName", - lastName: "Name", + id: '0987654321', + name: 'TestName', + lastName: 'Name' }, { - id: "9876543210", - name: "TestName2", - lastName: "Name2", - }, - ], - }, + id: '9876543210', + name: 'TestName2', + lastName: 'Name2' + } + ] + } }; -describe("MemberSelector", () => { - it("renders correctly with default props", () => { +describe('MemberSelector', () => { + it('renders correctly with default props', () => { snapshot( - + ); }); - it("renders correctly as a controlled component", () => { + it('renders correctly as a controlled component', () => { snapshot( { exportable listHeight={300} className="test-class" - style={{ margin: "10px" }} + style={{ margin: '10px' }} /> ); }); - it("renders correctly when disabled", () => { + it('renders correctly when disabled', () => { snapshot( ( - + )); const FilterType = Object.freeze({ - GUILD: "Guild", - TEAM: "Team", - TITLE: "Title", - LOCATION: "Location", - ROLE: "Role", - SKILL: "Skill", - MANAGER: "Manager", + GUILD: 'Guild', + TEAM: 'Team', + TITLE: 'Title', + LOCATION: 'Location', + ROLE: 'Role', + SKILL: 'Skill', + MANAGER: 'Manager' }); const propTypes = { @@ -70,8 +79,8 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { // Contains set of ids of checked members for instant add/remove operations const [checked, setChecked] = useState(new Set()); - const [nameQuery, setNameQuery] = useState(""); - const [filterType, setFilterType] = useState(FilterType.TEAM) + const [nameQuery, setNameQuery] = useState(''); + const [filterType, setFilterType] = useState(FilterType.TEAM); const [filterOptions, setFilterOptions] = useState(null); const [filter, setFilter] = useState(null); const [filteredMembers, setFilteredMembers] = useState([]); @@ -89,7 +98,7 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { if (!open) { // Reset all state except for the chosen filter type and its corresponding options setChecked(new Set()); - setNameQuery(""); + setNameQuery(''); setFilter(null); setFilteredMembers([]); setDirectReportsOnly(false); @@ -105,14 +114,14 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { const teams = selectTeams(state); return { options: teams, - label: (team) => team.name, + label: team => team.name, equals: (team1, team2) => team1.id === team2.id }; case FilterType.GUILD: const guilds = selectGuilds(state); return { options: guilds, - label: (guild) => guild.name, + label: guild => guild.name, equals: (guild1, guild2) => guild1.id === guild2.id }; case FilterType.TITLE: @@ -123,7 +132,7 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { titles = [...new Set(titles)]; return { options: titles, - label: (title) => title, + label: title => title, equals: (title1, title2) => title1 === title2 }; case FilterType.LOCATION: @@ -133,56 +142,61 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { locations = [...new Set(locations)]; return { options: locations, - label: (location) => location, + label: location => location, equals: (location1, location2) => location1 === location2 }; case FilterType.ROLE: const roles = selectRoles(state); return { options: roles, - label: (role) => role.role, + label: role => role.role, equals: (role1, role2) => role1.id === role2.id }; case FilterType.SKILL: let skills = selectSkills(state); return { options: skills, - label: (skill) => skill.name, + label: skill => skill.name, equals: (skill1, skill2) => skill1.id === skill2.id }; case FilterType.MANAGER: const supervisors = selectSupervisors(state); return { options: supervisors, - label: (supervisor) => supervisor.name, - equals: (supervisor1, supervisor2) => supervisor1.id === supervisor2.id + label: supervisor => supervisor.name, + equals: (supervisor1, supervisor2) => + supervisor1.id === supervisor2.id }; default: - console.warn(`Cannot get options for FilterType ${filterType}; no implementation provided`); + console.warn( + `Cannot get options for FilterType ${filterType}; no implementation provided` + ); return null; } - } + }; setFilterOptions(getFilterOptions()); - }, [filterType, members, state]); - const showError = useCallback((message) => { - dispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: message - } - }); - }, [dispatch]); + const showError = useCallback( + message => { + dispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: message + } + }); + }, + [dispatch] + ); // Filters the list of members based on the selected filter type and filter useEffect(() => { const getFilteredMembers = async () => { // Exclude members that are already selected - let filteredMemberList = members.filter(member => - !selectedMembers.includes(member) + let filteredMemberList = members.filter( + member => !selectedMembers.includes(member) ); // If a filter is selected, use it to filter the list of selectable members @@ -194,8 +208,12 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { if (!teamRes.error) { const teamMembers = teamRes.payload.data; // Collect team member ids into a set for instant lookup when filtering - const memberIdsForTeam = new Set(teamMembers.map(teamMember => teamMember.memberId)); - filteredMemberList = filteredMemberList.filter(member => memberIdsForTeam.has(member.id)); + const memberIdsForTeam = new Set( + teamMembers.map(teamMember => teamMember.memberId) + ); + filteredMemberList = filteredMemberList.filter(member => + memberIdsForTeam.has(member.id) + ); break; } else { showError(`Could not retrieve members for team ${filter.name}`); @@ -207,22 +225,32 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { if (!guildRes.error) { const guildMembers = guildRes.payload.data; // Collect guild member ids into a set for instant lookup when filtering - const memberIdsForGuild = new Set(guildMembers.map(guildMember => guildMember.memberId)); - filteredMemberList = filteredMemberList.filter(member => memberIdsForGuild.has(member.id)); + const memberIdsForGuild = new Set( + guildMembers.map(guildMember => guildMember.memberId) + ); + filteredMemberList = filteredMemberList.filter(member => + memberIdsForGuild.has(member.id) + ); } else { showError(`Could not retrieve members for guild ${filter.name}`); } break; case FilterType.TITLE: - filteredMemberList = filteredMemberList.filter(member => member.title === filter); + filteredMemberList = filteredMemberList.filter( + member => member.title === filter + ); break; case FilterType.LOCATION: - filteredMemberList = filteredMemberList.filter(member => member.location === filter); + filteredMemberList = filteredMemberList.filter( + member => member.location === filter + ); break; case FilterType.ROLE: const mappedUserRoles = selectMappedUserRoles(state); - filteredMemberList = filteredMemberList.filter(member => - member.id in mappedUserRoles && mappedUserRoles[member.id].has(filter.role) + filteredMemberList = filteredMemberList.filter( + member => + member.id in mappedUserRoles && + mappedUserRoles[member.id].has(filter.role) ); break; case FilterType.SKILL: @@ -231,8 +259,12 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { if (!skillRes.error) { const memberSkills = skillRes.payload.data; // Collect member skill ids into a set for instant lookup when filtering - const memberIdsForSkill = new Set(memberSkills.map(memberSkill => memberSkill.memberid)); - filteredMemberList = filteredMemberList.filter(member => memberIdsForSkill.has(member.id)); + const memberIdsForSkill = new Set( + memberSkills.map(memberSkill => memberSkill.memberid) + ); + filteredMemberList = filteredMemberList.filter(member => + memberIdsForSkill.has(member.id) + ); } else { showError(`Could not retrieve members with skill ${filter.name}`); } @@ -244,23 +276,39 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { ? selectTeamMembersBySupervisorId(state, managerId) : selectSubordinates(state, managerId); // Collect subordinate ids into a set for instant lookup when filtering - const subordinateIds = new Set(subordinates.map(member => member.id)); - filteredMemberList = filteredMemberList.filter(member => subordinateIds.has(member.id)); + const subordinateIds = new Set( + subordinates.map(member => member.id) + ); + filteredMemberList = filteredMemberList.filter(member => + subordinateIds.has(member.id) + ); break; default: - console.warn(`Cannot filter members based on FilterType ${filterType}; no implementation provided`); + console.warn( + `Cannot filter members based on FilterType ${filterType}; no implementation provided` + ); } } return filteredMemberList; - } + }; if (open) { getFilteredMembers().then(filtered => { setFilteredMembers(filtered); }); } - }, [state, csrf, members, filterType, filter, selectedMembers, showError, directReportsOnly, open]); + }, [ + state, + csrf, + members, + filterType, + filter, + selectedMembers, + showError, + directReportsOnly, + open + ]); useEffect(() => { let selectable = [...filteredMembers]; @@ -276,29 +324,35 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { setSelectableMembers(selectable); }, [nameQuery, filteredMembers]); - const handleCheckboxToggle = useCallback((member) => { - const newChecked = new Set(checked); - if (checked.has(member.id)) { - newChecked.delete(member.id); - } else { - newChecked.add(member.id); - } - setChecked(newChecked); - }, [checked]); - - const handleToggleAll = useCallback((toggle) => { - const newChecked = new Set(checked); - if (toggle) { - selectableMembers.forEach(member => { - newChecked.add(member.id); - }); - } else { - selectableMembers.forEach(member => { + const handleCheckboxToggle = useCallback( + member => { + const newChecked = new Set(checked); + if (checked.has(member.id)) { newChecked.delete(member.id); - }); - } - setChecked(newChecked); - }, [checked, selectableMembers]); + } else { + newChecked.add(member.id); + } + setChecked(newChecked); + }, + [checked] + ); + + const handleToggleAll = useCallback( + toggle => { + const newChecked = new Set(checked); + if (toggle) { + selectableMembers.forEach(member => { + newChecked.add(member.id); + }); + } else { + selectableMembers.forEach(member => { + newChecked.delete(member.id); + }); + } + setChecked(newChecked); + }, + [checked, selectableMembers] + ); const visibleChecked = useCallback(() => { // Find only the checked members that are currently visible @@ -316,16 +370,21 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { - +
    - Select Members - {checked.size} selected + + Select Members + + + {checked.size} selected +
    @@ -339,14 +398,18 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { placeholder="Search by member name" variant="outlined" value={nameQuery} - onChange={(event) => setNameQuery(event.target.value)} + onChange={event => setNameQuery(event.target.value)} InputProps={{ - endAdornment: + endAdornment: ( + + + + ) }} /> ( + renderInput={params => ( { disablePortal disabled={!filterOptions} options={filterOptions ? filterOptions.options : []} - getOptionLabel={filterOptions ? filterOptions.label : () => ""} - isOptionEqualToValue={filterOptions ? filterOptions.equals : () => false} + getOptionLabel={filterOptions ? filterOptions.label : () => ''} + isOptionEqualToValue={ + filterOptions ? filterOptions.equals : () => false + } value={filter} onChange={(_, value) => setFilter(value)} /> @@ -368,37 +433,49 @@ const MemberSelectorDialog = ({ open, selectedMembers, onClose, onSubmit }) => { labelId="member-filter-label" label="Filter by" value={filterType} - onChange={(event) => { + onChange={event => { setFilter(null); setFilterType(event.target.value); }} > - {Object.values(FilterType).map((name) => - {name} - )} + {Object.values(FilterType).map(name => ( + + {name} + + ))} - {filterType === FilterType.MANAGER && + {filterType === FilterType.MANAGER && ( setDirectReportsOnly(event.target.checked)} - />} + control={ + + setDirectReportsOnly(event.target.checked) + } + /> + } label="Direct reports only" /> - } + )}
    handleToggleAll(event.target.checked)} - checked={selectableMembers.length > 0 && visibleChecked().length === selectableMembers.length} - indeterminate={visibleChecked().length > 0 && visibleChecked().length !== selectableMembers.length} + onChange={event => handleToggleAll(event.target.checked)} + checked={ + selectableMembers.length > 0 && + visibleChecked().length === selectableMembers.length + } + indeterminate={ + visibleChecked().length > 0 && + visibleChecked().length !== selectableMembers.length + } disabled={selectableMembers.length === 0} /> - - + + {selectableMembers.map(member => ( { disablePadding onClick={() => handleCheckboxToggle(member)} secondaryAction={ - + } > - + {member.name}} - secondary={{member.title}} + primary={ + {member.name} + } + secondary={ + + {member.title} + + } /> ))} - + ); -} +}; MemberSelectorDialog.propTypes = propTypes; -export default MemberSelectorDialog; \ No newline at end of file +export default MemberSelectorDialog; diff --git a/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.spec.jsx b/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.spec.jsx index 8f26c285ea..7a6f2d1621 100644 --- a/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.spec.jsx +++ b/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.spec.jsx @@ -1,65 +1,62 @@ -import React from "react"; -import {render, screen, within} from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import {AppContextProvider} from "../../../context/AppContext.jsx"; -import MemberSelectorDialog from "./MemberSelectorDialog.jsx"; -import {setupServer} from "msw/node"; -import {http, HttpResponse} from "msw"; +import React from 'react'; +import { render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { AppContextProvider } from '../../../context/AppContext.jsx'; +import MemberSelectorDialog from './MemberSelectorDialog.jsx'; +import { setupServer } from 'msw/node'; +import { http, HttpResponse } from 'msw'; const managerProfile = { - name: "Jane Doe", - id: "3p45j3k45", + name: 'Jane Doe', + id: '3p45j3k45', startDate: [2017, 2, 11], - location: "STL", - title: "Manager", - workEmail: "janedoe@objectcomputing.com", + location: 'STL', + title: 'Manager', + workEmail: 'janedoe@objectcomputing.com' }; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", + name: 'Current User', + firstName: 'Current', + lastName: 'User', supervisorid: managerProfile.id }; const memberProfile = { - name: "Bob Jones", - id: "2o34i2j34", + name: 'Bob Jones', + id: '2o34i2j34', startDate: [2018, 1, 10], - location: "STL", - title: "Engineer", - workEmail: "bobjones@objectcomputing.com", + location: 'STL', + title: 'Engineer', + workEmail: 'bobjones@objectcomputing.com', supervisorid: currentUserProfile.id }; const testGuild = { id: 111, - name: "Test Guild", - description: "A guild used for testing.", - guildLeads: [{id: 124, name: managerProfile.name}], + name: 'Test Guild', + description: 'A guild used for testing.', + guildLeads: [{ id: 124, name: managerProfile.name }], guildMembers: [] }; const initialState = { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { name: currentUserProfile.name, firstName: currentUserProfile.firstName, lastName: currentUserProfile.lastName, - role: ["MEMBER"], - imageUrl: "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + role: ['MEMBER'], + imageUrl: + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', memberProfile: currentUserProfile }, - memberProfiles: [ - currentUserProfile, - memberProfile, - managerProfile - ], + memberProfiles: [currentUserProfile, memberProfile, managerProfile], skills: [ - { id: "918275", name: "skill1", description: "first" }, - { id: "9183455", name: "skill2", description: "second" }, + { id: '918275', name: 'skill1', description: 'first' }, + { id: '9183455', name: 'skill2', description: 'second' } ], checkins: [], guilds: [testGuild], @@ -67,12 +64,16 @@ const initialState = { roles: [], userRoles: [], memberSkills: [], - index: 0, + index: 0 }; const server = setupServer( - http.get(`http://localhost:8080/services/guilds/members?guildId=${testGuild.id}`, () => - HttpResponse.json([{memberId: managerProfile.id, guildId: testGuild.id}]) + http.get( + `http://localhost:8080/services/guilds/members?guildId=${testGuild.id}`, + () => + HttpResponse.json([ + { memberId: managerProfile.id, guildId: testGuild.id } + ]) ) ); @@ -80,8 +81,7 @@ beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -describe("MemberSelectorDialog", () => { - +describe('MemberSelectorDialog', () => { beforeEach(async () => { render( @@ -95,92 +95,107 @@ describe("MemberSelectorDialog", () => { ); // Wait for the dialog to be visible - await screen.findByRole("heading", {name: "Select Members"}); + await screen.findByRole('heading', { name: 'Select Members' }); }); - it("Populates the list of members by default", async () => { - const memberList = await screen.findAllByRole("listitem", {}); + it('Populates the list of members by default', async () => { + const memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(initialState.memberProfiles.length); }); - it("Filters the list of members by name", async () => { - let memberList = await screen.findAllByRole("listitem", {}); + it('Filters the list of members by name', async () => { + let memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(initialState.memberProfiles.length); - const nameField = await screen.findByRole("textbox", { name: /name/i }); - expect(nameField).toHaveValue(""); + const nameField = await screen.findByRole('textbox', { name: /name/i }); + expect(nameField).toHaveValue(''); - await userEvent.type(nameField, "bob"); - expect(nameField).toHaveValue("bob"); - memberList = await screen.findAllByRole("listitem", {}); + await userEvent.type(nameField, 'bob'); + expect(nameField).toHaveValue('bob'); + memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(1); within(memberList[0]).getByText(memberProfile.name, {}); }); - it("Filters the list of members by guild", async () => { - let memberList = await screen.findAllByRole("listitem", {}); + it('Filters the list of members by guild', async () => { + let memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(initialState.memberProfiles.length); - const filterField = await screen.findByRole("combobox", { name: /filter members/i }); - let filterTypeField = await screen.findByRole("combobox", { name: /filter by/i }); - expect(filterField.innerHTML).toBe(""); - expect(filterTypeField.innerHTML).toBe("Team"); + const filterField = await screen.findByRole('combobox', { + name: /filter members/i + }); + let filterTypeField = await screen.findByRole('combobox', { + name: /filter by/i + }); + expect(filterField.innerHTML).toBe(''); + expect(filterTypeField.innerHTML).toBe('Team'); // Set the filter type to guild await userEvent.click(filterTypeField); - let optionToSelect = await screen.findByRole("option", { name: /guild/i }); + let optionToSelect = await screen.findByRole('option', { name: /guild/i }); await userEvent.click(optionToSelect); - expect(filterTypeField.innerHTML).toBe("Guild"); + expect(filterTypeField.innerHTML).toBe('Guild'); // Select a guild to use as the filter await userEvent.click(filterField); - optionToSelect = await screen.findByRole("option", { name: testGuild.name }); + optionToSelect = await screen.findByRole('option', { + name: testGuild.name + }); await userEvent.click(optionToSelect); expect(filterField.value).toBe(testGuild.name); // Only members in the guild should be visible - memberList = await screen.findAllByRole("listitem", {}); + memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(1); within(memberList[0]).getByText(managerProfile.name, {}); }); - it("Filters the list of members by manager (with indirect reports)", async () => { - let memberList = await screen.findAllByRole("listitem", {}); + it('Filters the list of members by manager (with indirect reports)', async () => { + let memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(initialState.memberProfiles.length); - const filterField = await screen.findByRole("combobox", { name: /filter members/i }); - let filterTypeField = await screen.findByRole("combobox", { name: /filter by/i }); - expect(filterField.innerHTML).toBe(""); - expect(filterTypeField.innerHTML).toBe("Team"); + const filterField = await screen.findByRole('combobox', { + name: /filter members/i + }); + let filterTypeField = await screen.findByRole('combobox', { + name: /filter by/i + }); + expect(filterField.innerHTML).toBe(''); + expect(filterTypeField.innerHTML).toBe('Team'); // Set filter type to manager await userEvent.click(filterTypeField); - let optionToSelect = await screen.findByRole("option", { name: /manager/i }); + let optionToSelect = await screen.findByRole('option', { + name: /manager/i + }); await userEvent.click(optionToSelect); - expect(filterTypeField.innerHTML).toBe("Manager"); + expect(filterTypeField.innerHTML).toBe('Manager'); // Select a manager to use as the filter await userEvent.click(filterField); - optionToSelect = await screen.findByRole("option", { name: managerProfile.name }); + optionToSelect = await screen.findByRole('option', { + name: managerProfile.name + }); await userEvent.click(optionToSelect); expect(filterField.value).toBe(managerProfile.name); // All subordinates of the selected manager should be visible - memberList = await screen.findAllByRole("listitem", {}); + memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(2); screen.getByText(memberProfile.name, {}); screen.getByText(currentUserProfile.name, {}); // Change the checkbox to only show direct reports - const checkbox = await screen.findByRole("checkbox", { name: /direct reports only/i }); + const checkbox = await screen.findByRole('checkbox', { + name: /direct reports only/i + }); expect(checkbox).not.toBeChecked(); await userEvent.click(checkbox); expect(checkbox).toBeChecked(); // Only direct reports should be visible - memberList = await screen.findAllByRole("listitem", {}); + memberList = await screen.findAllByRole('listitem', {}); expect(memberList).toHaveLength(1); screen.getByText(currentUserProfile.name, {}); }); - -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.test.jsx b/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.test.jsx index 33cd66d9e2..44caecfea8 100644 --- a/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.test.jsx +++ b/web-ui/src/components/member_selector/member_selector_dialog/MemberSelectorDialog.test.jsx @@ -1,49 +1,50 @@ -import React from "react"; -import MemberSelectorDialog from "./MemberSelectorDialog"; -import {AppContextProvider} from "../../../context/AppContext"; -import {render, screen} from "@testing-library/react"; +import React from 'react'; +import MemberSelectorDialog from './MemberSelectorDialog'; +import { AppContextProvider } from '../../../context/AppContext'; +import { render, screen } from '@testing-library/react'; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", + name: 'Current User', + firstName: 'Current', + lastName: 'User' }; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { name: currentUserProfile.name, firstName: currentUserProfile.firstName, lastName: currentUserProfile.lastName, - role: ["MEMBER"], - imageUrl: "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + role: ['MEMBER'], + imageUrl: + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', memberProfile: currentUserProfile }, memberProfiles: [ currentUserProfile, { - name: "Bob Jones", - id: "2o34i2j34", + name: 'Bob Jones', + id: '2o34i2j34', startDate: [2018, 1, 10], - location: "STL", - title: "Engineer", - workEmail: "bobjones@objectcomputing.com", + location: 'STL', + title: 'Engineer', + workEmail: 'bobjones@objectcomputing.com' }, { - name: "Jane Doe", - id: "3p45j3k45", + name: 'Jane Doe', + id: '3p45j3k45', startDate: [2017, 2, 11], - location: "STL", - title: "Manager", - workEmail: "janedoe@objectcomputing.com", + location: 'STL', + title: 'Manager', + workEmail: 'janedoe@objectcomputing.com' } ], skills: [ - { id: "918275", name: "skill1", description: "first" }, - { id: "9183455", name: "skill2", description: "second" }, + { id: '918275', name: 'skill1', description: 'first' }, + { id: '9183455', name: 'skill2', description: 'second' } ], checkins: [], guilds: [], @@ -51,13 +52,12 @@ const initialState = { roles: [], userRoles: [], memberSkills: [], - index: 0, - }, + index: 0 + } }; -describe("MemberSelectorDialog", () => { - - it("renders correctly", async () => { +describe('MemberSelectorDialog', () => { + it('renders correctly', async () => { const component = ( { ); const rendered = render(component); - await screen.findByRole("dialog", {}); + await screen.findByRole('dialog', {}); expect(rendered.baseElement).toMatchSnapshot(); }); }); diff --git a/web-ui/src/components/member_skill_radar/MemberSkillRadar.jsx b/web-ui/src/components/member_skill_radar/MemberSkillRadar.jsx index b418d80788..a830c87bb5 100644 --- a/web-ui/src/components/member_skill_radar/MemberSkillRadar.jsx +++ b/web-ui/src/components/member_skill_radar/MemberSkillRadar.jsx @@ -1,5 +1,5 @@ -import React, {useEffect, useState} from "react"; -import PropTypes from "prop-types"; +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; import { Legend, @@ -10,33 +10,36 @@ import { RadarChart, ResponsiveContainer, Tooltip -} from "recharts"; -import {RADAR_COLORS} from "./RadarColors.jsx"; +} from 'recharts'; +import { RADAR_COLORS } from './RadarColors.jsx'; const propTypes = { - data: PropTypes.arrayOf(PropTypes.shape({ - skill: PropTypes.string.isRequired - })), + data: PropTypes.arrayOf( + PropTypes.shape({ + skill: PropTypes.string.isRequired + }) + ), members: PropTypes.arrayOf(PropTypes.object).isRequired }; const MemberSkillRadar = ({ data, members }) => { - - const [colors, setColors] = useState({}); // Maps member id to corresponding radar color - const [colorOptions, setColorOptions] = useState(RADAR_COLORS); // List of predefined colors to choose from + const [colors, setColors] = useState({}); // Maps member id to corresponding radar color + const [colorOptions, setColorOptions] = useState(RADAR_COLORS); // List of predefined colors to choose from useEffect(() => { - const updatedColors = {...colors}; + const updatedColors = { ...colors }; const updatedColorOptions = [...colorOptions]; - members.forEach((member) => { + members.forEach(member => { // Only get a new color if the member doesn't have one already if (!(member.name in colors)) { // Use predefined colors until all those colors have been used if (updatedColorOptions.length > 0) { // Choose a random color from the list - const colorIndex = Math.floor(Math.random() * updatedColorOptions.length); + const colorIndex = Math.floor( + Math.random() * updatedColorOptions.length + ); updatedColors[member.name] = updatedColorOptions[colorIndex]; - updatedColorOptions.splice(colorIndex, 1); // Prevent using this color again + updatedColorOptions.splice(colorIndex, 1); // Prevent using this color again } else { // Generate a random color using HSL const hue = Math.random() * 360; @@ -51,11 +54,11 @@ const MemberSkillRadar = ({ data, members }) => { return ( - - - - - {members?.map((member) => ( + + + + + {members?.map(member => ( { fillOpacity={0.6} /> ))} - + ); -} +}; MemberSkillRadar.propTypes = propTypes; -export default MemberSkillRadar; \ No newline at end of file +export default MemberSkillRadar; diff --git a/web-ui/src/components/member_skill_radar/RadarColors.jsx b/web-ui/src/components/member_skill_radar/RadarColors.jsx index 318a096d8c..5b1bd3b403 100644 --- a/web-ui/src/components/member_skill_radar/RadarColors.jsx +++ b/web-ui/src/components/member_skill_radar/RadarColors.jsx @@ -1,21 +1,21 @@ export const RADAR_COLORS = [ - "#e74c3c", - "#b54b43", - "#e17055", - "#00b894", - "#218f8f", - "#27ae60", - "#468057", - "#0984e3", - "#3c40c6", - "#49568c", - "#717791", - "#6c5ce7", - "#6a4e8a", - "#8e44ad", - "#442482", - "#ff7675", - "#b53471", - "#8a2f81", - "#c96bc5", -]; \ No newline at end of file + '#e74c3c', + '#b54b43', + '#e17055', + '#00b894', + '#218f8f', + '#27ae60', + '#468057', + '#0984e3', + '#3c40c6', + '#49568c', + '#717791', + '#6c5ce7', + '#6a4e8a', + '#8e44ad', + '#442482', + '#ff7675', + '#b53471', + '#8a2f81', + '#c96bc5' +]; diff --git a/web-ui/src/components/menu/Menu.css b/web-ui/src/components/menu/Menu.css index e081f84806..e37f2ab1fe 100644 --- a/web-ui/src/components/menu/Menu.css +++ b/web-ui/src/components/menu/Menu.css @@ -1,5 +1,5 @@ .checkin { - font-family: "Shadows Into Light", cursive; + font-family: 'Shadows Into Light', cursive; font-size: calc(1rem + 1vw); margin-top: 0px; padding-top: 10px; @@ -7,9 +7,9 @@ } @media print { - nav { - display: none; - } + nav { + display: none; + } } .hours-upload-modal .buttons { diff --git a/web-ui/src/components/menu/Menu.test.jsx b/web-ui/src/components/menu/Menu.test.jsx index f7ac807dc6..9aebc6746c 100644 --- a/web-ui/src/components/menu/Menu.test.jsx +++ b/web-ui/src/components/menu/Menu.test.jsx @@ -1,57 +1,57 @@ -import React from "react"; -import Menu from "./Menu"; -import { MemoryRouter } from "react-router-dom"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import Menu from './Menu'; +import { MemoryRouter } from 'react-router-dom'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], permissions: [], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - }, - }, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' + } + } }; const adminState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER", "ADMIN"], - permissions: [{permission:"CAN_VIEW_SKILLS_REPORT"}], + role: ['MEMBER', 'ADMIN'], + permissions: [{ permission: 'CAN_VIEW_SKILLS_REPORT' }], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - }, - }, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' + } + } }; const pdlState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER","PDL"], + role: ['MEMBER', 'PDL'], permissions: [], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - }, - }, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' + } + } }; describe('', () => { diff --git a/web-ui/src/components/notes/Note.jsx b/web-ui/src/components/notes/Note.jsx index 1b046571d7..a353856fbf 100644 --- a/web-ui/src/components/notes/Note.jsx +++ b/web-ui/src/components/notes/Note.jsx @@ -1,29 +1,34 @@ -import React, { useContext, useEffect, useRef, useState } from "react"; -import { useParams } from "react-router-dom"; +import React, { useContext, useEffect, useRef, useState } from 'react'; +import { useParams } from 'react-router-dom'; import { getNoteByCheckinId, createCheckinNote, - updateCheckinNote, -} from "../../api/checkins"; -import { AppContext } from "../../context/AppContext"; -import { selectCsrfToken, selectCurrentUser, selectCheckin, selectProfile } from "../../context/selectors"; -import { debounce } from "lodash/function"; + updateCheckinNote +} from '../../api/checkins'; +import { AppContext } from '../../context/AppContext'; +import { + selectCsrfToken, + selectCurrentUser, + selectCheckin, + selectProfile +} from '../../context/selectors'; +import { debounce } from 'lodash/function'; import { Editor } from '@tinymce/tinymce-react'; -import NotesIcon from "@mui/icons-material/Notes"; +import NotesIcon from '@mui/icons-material/Notes'; import Skeleton from '@mui/material/Skeleton'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; // import MarkdownNote from "../markdown-note/MarkdownNote"; -import "./Note.css"; +import './Note.css'; async function realUpdate(note, csrf) { - await updateCheckinNote(note,csrf) + await updateCheckinNote(note, csrf); } const updateNote = debounce(realUpdate, 1000); -const Notes = (props) => { +const Notes = props => { const { state } = useContext(AppContext); const { checkinId, memberId } = useParams(); const csrf = selectCsrfToken(state); @@ -36,7 +41,6 @@ const Notes = (props) => { const [note, setNote] = useState(); const [isLoading, setIsLoading] = useState(true); - useEffect(() => { async function getNotes() { setIsLoading(true); @@ -50,27 +54,31 @@ const Notes = (props) => { if (currentNote) { setNote(currentNote); } else if (currentUserId === pdlId) { - if (!noteRef.current.some((id) => id === checkinId)) { + if (!noteRef.current.some(id => id === checkinId)) { noteRef.current.push(checkinId); - res = await createCheckinNote({ - checkinid: checkinId, - createdbyid: currentUserId, - description: "", - }, csrf); - noteRef.current = noteRef.current.filter( - (id) => id !== checkinId + res = await createCheckinNote( + { + checkinid: checkinId, + createdbyid: currentUserId, + description: '' + }, + csrf ); + noteRef.current = noteRef.current.filter(id => id !== checkinId); if (res.error) throw new Error(res.error); if (res && res.payload && res.payload.data) { setNote(res.payload.data); } } } else { - res = await createCheckinNote({ - checkinid: checkinId, - createdbyid: currentUserId, - description: "", - }, csrf); + res = await createCheckinNote( + { + checkinid: checkinId, + createdbyid: currentUserId, + description: '' + }, + csrf + ); if (res.error) throw new Error(res.error); if (res && res.payload && res.payload.data) { setNote(res.payload.data); @@ -82,7 +90,7 @@ const Notes = (props) => { setIsLoading(false); } if (csrf) { - getNotes() + getNotes(); } }, [csrf, checkinId, currentUserId, pdlId]); @@ -90,51 +98,58 @@ const Notes = (props) => { if (Object.keys(note).length === 0 || !csrf || currentCheckin?.completed) { return; } - - setNote((note) => { + + setNote(note => { const newNote = { ...note, description: content }; updateNote(newNote, csrf); return newNote; }); - } + }; return ( - - } title={`Notes for ${currentMember?.name}`} titleTypographyProps={{variant: "h5", component: "h2"}} /> - - {isLoading ? ( -
    -
    - - - - -
    -
    - ) : ( - - )} - -
    -
    - ); + + } + title={`Notes for ${currentMember?.name}`} + titleTypographyProps={{ variant: 'h5', component: 'h2' }} + /> + + {isLoading ? ( +
    +
    + + + + +
    +
    + ) : ( + + )} +
    +
    + ); }; export default Notes; diff --git a/web-ui/src/components/notes/Note.test.jsx b/web-ui/src/components/notes/Note.test.jsx index b65bdebb0a..d5afa08d11 100644 --- a/web-ui/src/components/notes/Note.test.jsx +++ b/web-ui/src/components/notes/Note.test.jsx @@ -1,69 +1,68 @@ -import React from "react"; -import Notes from "./Note"; -import { AppContextProvider } from "../../context/AppContext"; -import { createMemoryHistory } from "history"; +import React from 'react'; +import Notes from './Note'; +import { AppContextProvider } from '../../context/AppContext'; +import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -const mockMemberId = "912834091823"; -const mockCheckinId = "837465917381"; +const mockMemberId = '912834091823'; +const mockCheckinId = '837465917381'; -const history = createMemoryHistory(`/checkins/${mockMemberId}/${mockCheckinId}`); +const history = createMemoryHistory( + `/checkins/${mockMemberId}/${mockCheckinId}` +); vi.mock('react-router-dom', async () => ({ - ...await vi.importActual('react-router-dom'), // use actual for all non-hook parts + ...(await vi.importActual('react-router-dom')), // use actual for all non-hook parts useParams: () => ({ memberId: mockMemberId, - checkinId: mockCheckinId, + checkinId: mockCheckinId }), - useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }), + useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }) })); - const checkin = { id: mockCheckinId, teamMemberId: mockMemberId, - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f28", - description: "updated string", + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f28', + description: 'updated string' }; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { id: mockMemberId, - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, memberProfiles: [ { - name: "holmes", + name: 'holmes', id: mockMemberId, - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' } ], - checkins: [ - checkin - ] - }, + checkins: [checkin] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - - - + + + ); }); diff --git a/web-ui/src/components/opportunity/OpportunityCard.jsx b/web-ui/src/components/opportunity/OpportunityCard.jsx index f7ecc58de6..66f7b77316 100644 --- a/web-ui/src/components/opportunity/OpportunityCard.jsx +++ b/web-ui/src/components/opportunity/OpportunityCard.jsx @@ -1,11 +1,11 @@ -import React, { useContext } from "react"; +import React, { useContext } from 'react'; -import { selectIsAdmin } from "../../context/selectors"; -import { AppContext } from "../../context/AppContext"; +import { selectIsAdmin } from '../../context/selectors'; +import { AppContext } from '../../context/AppContext'; -import { format } from "date-fns"; -import { Card, CardContent, CardHeader, Typography } from "@mui/material"; -import AssignmentIcon from "@mui/icons-material/Assignment"; +import { format } from 'date-fns'; +import { Card, CardContent, CardHeader, Typography } from '@mui/material'; +import AssignmentIcon from '@mui/icons-material/Assignment'; const OpportunityCard = ({ opportunity }) => { const { state } = useContext(AppContext); @@ -25,12 +25,12 @@ const OpportunityCard = ({ opportunity }) => { } /> - {description || ""} + {description || ''}
    {url ?
    More Information : null}
    {expiresOn - ? `Expires on ${format(new Date(expiresOn), "MM/dd/yyy")}` + ? `Expires on ${format(new Date(expiresOn), 'MM/dd/yyy')}` : null}
    {isAdmin && pending ? `Pending: ${pending}` : null} diff --git a/web-ui/src/components/opportunity/OpportunityCard.stories.jsx b/web-ui/src/components/opportunity/OpportunityCard.stories.jsx index 3e4ba7faa6..f5c287f594 100644 --- a/web-ui/src/components/opportunity/OpportunityCard.stories.jsx +++ b/web-ui/src/components/opportunity/OpportunityCard.stories.jsx @@ -1,33 +1,33 @@ -import React from "react"; -import OpportunityCard from "./OpportunityCard"; +import React from 'react'; +import OpportunityCard from './OpportunityCard'; export default { component: OpportunityCard, - title: "Check Ins/Opportunity", + title: 'Check Ins/Opportunity', decorators: [ - (OpportunityCard) => ( -
    + OpportunityCard => ( +
    - ), - ], + ) + ] }; -const Template = (args) => { +const Template = args => { return ; }; const opportunityCardData = { opportunity: { - description: "Looking for someone to spit some hot fire", - expiresOn: "01/02/2030", - name: "Hip hop artist", + description: 'Looking for someone to spit some hot fire', + expiresOn: '01/02/2030', + name: 'Hip hop artist', pending: false, - url: "www.google.com", - }, + url: 'www.google.com' + } }; export const OpportunityCards = Template.bind({}); OpportunityCards.args = { - ...opportunityCardData, + ...opportunityCardData }; diff --git a/web-ui/src/components/opportunity/OpportunityCard.test.jsx b/web-ui/src/components/opportunity/OpportunityCard.test.jsx index 0dcf114e23..ca8a65996a 100644 --- a/web-ui/src/components/opportunity/OpportunityCard.test.jsx +++ b/web-ui/src/components/opportunity/OpportunityCard.test.jsx @@ -1,17 +1,17 @@ -import React from "react"; +import React from 'react'; -import OpportunityCard from "./OpportunityCard"; +import OpportunityCard from './OpportunityCard'; -import { AppContextProvider } from "../../context/AppContext"; +import { AppContextProvider } from '../../context/AppContext'; const opportunity = { - description: "Looking for someone to spit some hot fire", - expiresOn: "01/02/2030", - name: "Hip hop artist", + description: 'Looking for someone to spit some hot fire', + expiresOn: '01/02/2030', + name: 'Hip hop artist', pending: false, - url: "www.google.com", + url: 'www.google.com' }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/personnel/Personnel.jsx b/web-ui/src/components/personnel/Personnel.jsx index a5c6009065..7d1487c521 100644 --- a/web-ui/src/components/personnel/Personnel.jsx +++ b/web-ui/src/components/personnel/Personnel.jsx @@ -1,21 +1,25 @@ -import React, { useContext, useEffect, useState } from "react"; -import {useHistory} from "react-router-dom"; -import { getMembersByPDL } from "../../api/member"; -import { getCheckinByMemberId } from "../../api/checkins"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_CHECKINS } from "../../context/actions"; -import { selectCurrentUserId, selectMostRecentCheckin, selectCsrfToken } from "../../context/selectors"; +import React, { useContext, useEffect, useState } from 'react'; +import { useHistory } from 'react-router-dom'; +import { getMembersByPDL } from '../../api/member'; +import { getCheckinByMemberId } from '../../api/checkins'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_CHECKINS } from '../../context/actions'; +import { + selectCurrentUserId, + selectMostRecentCheckin, + selectCsrfToken +} from '../../context/selectors'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; import ListItemAvatar from '@mui/material/ListItemAvatar'; -import GroupIcon from "@mui/icons-material/Group"; -import Avatar from "../avatar/Avatar" -import { getAvatarURL } from "../../api/api.js"; +import GroupIcon from '@mui/icons-material/Group'; +import Avatar from '../avatar/Avatar'; +import { getAvatarURL } from '../../api/api.js'; -import "./Personnel.css"; +import './Personnel.css'; const Personnel = () => { const { state, dispatch } = useContext(AppContext); @@ -57,7 +61,7 @@ const Personnel = () => { ? res.payload.data : null; if (data && data.length > 0 && !res.error) { - dispatch({type: UPDATE_CHECKINS, payload: data}); + dispatch({ type: UPDATE_CHECKINS, payload: data }); } } } @@ -67,20 +71,24 @@ const Personnel = () => { } }, [csrf, personnel, dispatch]); -// Create feedback request link -const createFeedbackRequestLink = (memberId) => ( - { - e.stopPropagation(); - history.push(`/feedback/request?for=${memberId}`); - }}> + // Create feedback request link + const createFeedbackRequestLink = memberId => ( + { + e.stopPropagation(); + history.push(`/feedback/request?for=${memberId}`); + }} + > Request Feedback - ); + + ); // Create entry of member and their last checkin function createEntry(person, lastCheckin, keyInput) { let key = keyInput ? keyInput : undefined; - let name = "Team Member"; - let workEmail = ""; + let name = 'Team Member'; + let workEmail = ''; if (person) { let id = person.id ? person.id : null; @@ -90,9 +98,7 @@ const createFeedbackRequestLink = (memberId) => ( } return ( - + ( }} /> - + ); } @@ -110,7 +119,9 @@ const createFeedbackRequestLink = (memberId) => ( // Create the entries for the personnel container const createPersonnelEntries = () => { if (personnel && personnel.length > 0) { - return personnel.map((person) => createEntry(person, selectMostRecentCheckin(state, person.id), null)); + return personnel.map(person => + createEntry(person, selectMostRecentCheckin(state, person.id), null) + ); } else { return []; } @@ -119,9 +130,7 @@ const createFeedbackRequestLink = (memberId) => ( return ( } title="Development Partners" /> - - {createPersonnelEntries()} - + {createPersonnelEntries()} ); }; diff --git a/web-ui/src/components/personnel/Personnel.test.jsx b/web-ui/src/components/personnel/Personnel.test.jsx index 60ef5ed32b..b6447409a7 100644 --- a/web-ui/src/components/personnel/Personnel.test.jsx +++ b/web-ui/src/components/personnel/Personnel.test.jsx @@ -1,12 +1,11 @@ import React from 'react'; import Personnel from './Personnel'; -import { AppContextProvider } from "../../context/AppContext"; +import { AppContextProvider } from '../../context/AppContext'; -it("renders correctly with null", () => { - snapshot( - - - - ); - } -); \ No newline at end of file +it('renders correctly with null', () => { + snapshot( + + + + ); +}); diff --git a/web-ui/src/components/private-note/PrivateNote.jsx b/web-ui/src/components/private-note/PrivateNote.jsx index 59feccb69a..d964c9c26f 100644 --- a/web-ui/src/components/private-note/PrivateNote.jsx +++ b/web-ui/src/components/private-note/PrivateNote.jsx @@ -1,20 +1,27 @@ -import React, { useContext, useEffect, useRef, useState } from "react"; -import { useParams } from "react-router-dom"; +import React, { useContext, useEffect, useRef, useState } from 'react'; +import { useParams } from 'react-router-dom'; import { getPrivateNoteByCheckinId, createPrivateNote, - updatePrivateNote, -} from "../../api/checkins"; -import { AppContext } from "../../context/AppContext"; -import { selectCsrfToken, selectCurrentUser, selectIsPDL, selectIsAdmin, selectCheckin, selectProfile } from "../../context/selectors"; -import { debounce } from "lodash/function"; -import { Editor } from '@tinymce/tinymce-react' -import LockIcon from "@mui/icons-material/Lock"; + updatePrivateNote +} from '../../api/checkins'; +import { AppContext } from '../../context/AppContext'; +import { + selectCsrfToken, + selectCurrentUser, + selectIsPDL, + selectIsAdmin, + selectCheckin, + selectProfile +} from '../../context/selectors'; +import { debounce } from 'lodash/function'; +import { Editor } from '@tinymce/tinymce-react'; +import LockIcon from '@mui/icons-material/Lock'; import Skeleton from '@mui/material/Skeleton'; import Card from '@mui/material/Card'; import CardHeader from '@mui/material/CardHeader'; import CardContent from '@mui/material/CardContent'; -import "./PrivateNote.css"; +import './PrivateNote.css'; async function realUpdate(note, csrf) { await updatePrivateNote(note, csrf); @@ -53,27 +60,31 @@ const PrivateNote = () => { if (currentNote) { setNote(currentNote); } else if (currentUserId === pdlId) { - if (!noteRef.current.some((id) => id === checkinId)) { + if (!noteRef.current.some(id => id === checkinId)) { noteRef.current.push(checkinId); - res = await createPrivateNote({ - checkinid: checkinId, - createdbyid: currentUserId, - description: "", - }, csrf); - noteRef.current = noteRef.current.filter( - (id) => id !== checkinId + res = await createPrivateNote( + { + checkinid: checkinId, + createdbyid: currentUserId, + description: '' + }, + csrf ); + noteRef.current = noteRef.current.filter(id => id !== checkinId); if (res.error) throw new Error(res.error); if (res && res.payload && res.payload.data) { setNote(res.payload.data); } } } else { - res = await createPrivateNote({ - checkinid: checkinId, - createdbyid: currentUserId, - description: "", - }, csrf); + res = await createPrivateNote( + { + checkinid: checkinId, + createdbyid: currentUserId, + description: '' + }, + csrf + ); if (res.error) throw new Error(res.error); if (res && res.payload && res.payload.data) { setNote(res.payload.data); @@ -93,51 +104,60 @@ const PrivateNote = () => { if (Object.keys(note).length === 0 || !csrf || currentCheckin?.completed) { return; } - - setNote((note) => { + + setNote(note => { const newNote = { ...note, description: content }; updateNote(newNote, csrf); return newNote; }); - } + }; - return canView && ( + return ( + canView && ( - } title="Private Notes" titleTypographyProps={{variant: "h5", component: "h2"}} /> + } + title="Private Notes" + titleTypographyProps={{ variant: 'h5', component: 'h2' }} + /> - {isLoading ? ( -
    -
    - - - - -
    + {isLoading ? ( +
    +
    + + + +
    - ) : ( - - )} - +
    + ) : ( + + )} - ); + ) + ); }; export default PrivateNote; diff --git a/web-ui/src/components/private-note/PrivateNote.test.jsx b/web-ui/src/components/private-note/PrivateNote.test.jsx index 69f69c9abb..6eee6cbb54 100644 --- a/web-ui/src/components/private-note/PrivateNote.test.jsx +++ b/web-ui/src/components/private-note/PrivateNote.test.jsx @@ -1,69 +1,68 @@ -import React from "react"; -import PrivateNote from "./PrivateNote"; -import { AppContextProvider } from "../../context/AppContext"; -import { createMemoryHistory } from "history"; +import React from 'react'; +import PrivateNote from './PrivateNote'; +import { AppContextProvider } from '../../context/AppContext'; +import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -const mockMemberId = "912834091823"; -const mockCheckinId = "837465917381"; +const mockMemberId = '912834091823'; +const mockCheckinId = '837465917381'; -const history = createMemoryHistory(`/checkins/${mockMemberId}/${mockCheckinId}`); +const history = createMemoryHistory( + `/checkins/${mockMemberId}/${mockCheckinId}` +); vi.mock('react-router-dom', async () => ({ - ...await vi.importActual('react-router-dom'), // use actual for all non-hook parts + ...(await vi.importActual('react-router-dom')), // use actual for all non-hook parts useParams: () => ({ memberId: mockMemberId, - checkinId: mockCheckinId, + checkinId: mockCheckinId }), - useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }), + useRouteMatch: () => ({ url: `/checkins/${mockMemberId}/${mockCheckinId}` }) })); - const checkin = { id: mockCheckinId, teamMemberId: mockMemberId, - createdbyid: "5425d835-dcd1-4d91-9540-200c06f18f28", - description: "updated string", + createdbyid: '5425d835-dcd1-4d91-9540-200c06f18f28', + description: 'updated string' }; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { id: mockMemberId, - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, memberProfiles: [ { - name: "holmes", + name: 'holmes', id: mockMemberId, - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' } ], - checkins: [ - checkin - ] - }, + checkins: [checkin] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - - - + + + ); }); diff --git a/web-ui/src/components/profile/Profile.jsx b/web-ui/src/components/profile/Profile.jsx index 65f1f17319..3bad89d0e7 100644 --- a/web-ui/src/components/profile/Profile.jsx +++ b/web-ui/src/components/profile/Profile.jsx @@ -1,10 +1,10 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; import { styled } from '@mui/material/styles'; -import { Avatar, Typography } from "@mui/material"; -import { AppContext } from "../../context/AppContext"; -import { selectProfileMap } from "../../context/selectors"; -import { getAvatarURL } from "../../api/api.js"; -import { getMember } from "../../api/member"; +import { Avatar, Typography } from '@mui/material'; +import { AppContext } from '../../context/AppContext'; +import { selectProfileMap } from '../../context/selectors'; +import { getAvatarURL } from '../../api/api.js'; +import { getMember } from '../../api/member'; const PREFIX = 'Profile'; @@ -19,36 +19,36 @@ const classes = { const Root = styled('div')(() => ({ [`& .${classes.profileInfo}`]: { - display: "flex", - flexDirection: "row", - margin: "14px", + display: 'flex', + flexDirection: 'row', + margin: '14px' }, [`& .${classes.profileImage}`]: { - marginRight: "20px", - marginTop: "10px", - marginBottom: "10px", - cursor: "pointer", - width: "160px", - height: "160px", + marginRight: '20px', + marginTop: '10px', + marginBottom: '10px', + cursor: 'pointer', + width: '160px', + height: '160px' }, [`&.${classes.flexRow}`]: { - display: "flex", - flexDirection: "row", - justifyContent: "center", - marginBottom: "16px", + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + marginBottom: '16px' }, [`& .${classes.header}`]: { - display: "flex", - flexDirection: "row", - marginBottom: "16px", - alignItems: "center", + display: 'flex', + flexDirection: 'row', + marginBottom: '16px', + alignItems: 'center' }, [`& .${classes.title}`]: { - display: "flex", - flexDirection: "column", + display: 'flex', + flexDirection: 'column' }, [`& .${classes.smallAvatar}`]: { - marginRight: "16px", + marginRight: '16px' } })); @@ -61,9 +61,9 @@ const Profile = ({ memberId, pdlId, checkinPdlId }) => { ? userProfile : {}; - const [pdl, setPDL] = useState(""); - const [checkinPdl, setCheckinPdl] = useState(""); - const [supervisor, setSupervisor] = useState(""); + const [pdl, setPDL] = useState(''); + const [checkinPdl, setCheckinPdl] = useState(''); + const [supervisor, setSupervisor] = useState(''); const areSamePdls = checkinPdl && pdl && checkinPdl === pdl; @@ -74,7 +74,7 @@ const Profile = ({ memberId, pdlId, checkinPdlId }) => { let res = await getMember(pdlId, csrf); let pdlProfile = res.payload.data && !res.error ? res.payload.data : undefined; - setPDL(pdlProfile ? pdlProfile.name : ""); + setPDL(pdlProfile ? pdlProfile.name : ''); } } if (csrf) { @@ -89,7 +89,7 @@ const Profile = ({ memberId, pdlId, checkinPdlId }) => { let res = await getMember(checkinPdlId, csrf); let checkinPdlProfile = res.payload.data && !res.error ? res.payload.data : undefined; - setCheckinPdl(checkinPdlProfile ? checkinPdlProfile.name : ""); + setCheckinPdl(checkinPdlProfile ? checkinPdlProfile.name : ''); } } if (csrf) { @@ -104,7 +104,7 @@ const Profile = ({ memberId, pdlId, checkinPdlId }) => { let res = await getMember(supervisorid, csrf); let supervisorProfile = res.payload.data && !res.error ? res.payload.data : undefined; - setSupervisor(supervisorProfile ? supervisorProfile.name : ""); + setSupervisor(supervisorProfile ? supervisorProfile.name : ''); } } if (csrf) { diff --git a/web-ui/src/components/profile/Profile.test.jsx b/web-ui/src/components/profile/Profile.test.jsx index 93ee710322..f8621be733 100644 --- a/web-ui/src/components/profile/Profile.test.jsx +++ b/web-ui/src/components/profile/Profile.test.jsx @@ -1,54 +1,54 @@ -import React from "react"; -import Profile from "./Profile"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import Profile from './Profile'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { userProfile: { memberProfile: { - id: "912834091823", - pdlId: "0987654321", - supervisorid: "9876543210" + id: '912834091823', + pdlId: '0987654321', + supervisorid: '9876543210' }, - role: ["MEMBER"], + role: ['MEMBER'] }, memberProfiles: [ - { - id: "0987654321", - name: "TestName", - lastName: "Name", - }, - { - id: "9876543210", - name: "TestName2", - lastName: "Name2", - }, + { + id: '0987654321', + name: 'TestName', + lastName: 'Name' + }, + { + id: '9876543210', + name: 'TestName2', + lastName: 'Name2' + } ], memberSkills: [ { - memberid: "912834091823", - skillId: "99999" + memberid: '912834091823', + skillId: '99999' } ], skills: [ { - id: "99999", + id: '99999' } ] - }, + } }; const member = { - name: "testerson", - id: "2o34i2j34", + name: 'testerson', + id: '2o34i2j34', startDate: [2018, 1, 10], - location: "STL", - imageURL: "url.com", - title: "engineer", - workEmail: "testerson@oci.com", + location: 'STL', + imageURL: 'url.com', + title: 'engineer', + workEmail: 'testerson@oci.com' }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/profile/Search.jsx b/web-ui/src/components/profile/Search.jsx index 961bd471a4..948a3bc276 100644 --- a/web-ui/src/components/profile/Search.jsx +++ b/web-ui/src/components/profile/Search.jsx @@ -1,26 +1,26 @@ -import React, { useContext, useState } from "react"; -import { AppContext } from "../../context/AppContext"; +import React, { useContext, useState } from 'react'; +import { AppContext } from '../../context/AppContext'; -import Fuse from "fuse.js"; +import Fuse from 'fuse.js'; -import "./Search.css"; +import './Search.css'; const Search = ({ mySkills, addSkill }) => { const { state } = useContext(AppContext); const { skills } = state; const skillsList = skills.filter(({ pending }) => !pending); - const [pattern, setPattern] = useState(""); + const [pattern, setPattern] = useState(''); const options = { includeScore: true, ignoreLocation: true, - keys: ["name"], + keys: ['name'] }; const filter = (skillList, options) => { const fuse = new Fuse(skillList, options); - return fuse.search(pattern).map((item) => { + return fuse.search(pattern).map(item => { return item.item.name; }); }; @@ -29,23 +29,22 @@ const Search = ({ mySkills, addSkill }) => { return (
    -
    +
    setPattern(e.target.value)} - onKeyPress={(e) => { + onChange={e => setPattern(e.target.value)} + onKeyPress={e => { const inMySkills = mySkills.length > 0 ? mySkills.find( - (skill) => - skill.name.toUpperCase() === pattern.toUpperCase() + skill => skill.name.toUpperCase() === pattern.toUpperCase() ) : undefined; - if (e.key === "Enter") { + if (e.key === 'Enter') { if (inMySkills) { - setPattern(""); + setPattern(''); } else { - setPattern(""); + setPattern(''); addSkill(e.target.value); } } @@ -54,14 +53,14 @@ const Search = ({ mySkills, addSkill }) => { value={pattern} >
    - {filtered.map((name) => { + {filtered.map(name => { return (

    { addSkill(name); - setPattern(""); + setPattern(''); }} > {name} diff --git a/web-ui/src/components/received_request_card/ReceivedRequestCard.jsx b/web-ui/src/components/received_request_card/ReceivedRequestCard.jsx index fad887d793..a2583decfa 100644 --- a/web-ui/src/components/received_request_card/ReceivedRequestCard.jsx +++ b/web-ui/src/components/received_request_card/ReceivedRequestCard.jsx @@ -1,14 +1,14 @@ -import React, { useContext } from "react"; -import { styled } from "@mui/material/styles"; -import { Avatar, Card, Tooltip, IconButton } from "@mui/material"; -import { getAvatarURL } from "../../api/api"; -import Typography from "@mui/material/Typography"; -import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; -import { selectProfile } from "../../context/selectors"; -import DateFnsUtils from "@date-io/date-fns"; -import { AppContext } from "../../context/AppContext"; -import { Edit as EditIcon } from "@mui/icons-material"; +import React, { useContext } from 'react'; +import { styled } from '@mui/material/styles'; +import { Avatar, Card, Tooltip, IconButton } from '@mui/material'; +import { getAvatarURL } from '../../api/api'; +import Typography from '@mui/material/Typography'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { selectProfile } from '../../context/selectors'; +import DateFnsUtils from '@date-io/date-fns'; +import { AppContext } from '../../context/AppContext'; +import { Edit as EditIcon } from '@mui/icons-material'; const dateFns = new DateFnsUtils(); const PREFIX = 'ReceivedRequestCard'; @@ -22,24 +22,24 @@ const classes = { const StyledCard = styled(Card)({ [`& .${classes.redTypography}`]: { - color: "#FF0000", + color: '#FF0000' }, [`& .${classes.yellowTypography}`]: { - color: "#EE8C00", + color: '#EE8C00' }, [`& .${classes.greenTypography}`]: { - color: "#006400", + color: '#006400' }, [`& .${classes.darkGrayTypography}`]: { - color: "#333333", + color: '#333333' }, [`& .${classes.grayTypography}`]: { - color: "gray", - }, + color: 'gray' + } }); const propTypes = { - request: PropTypes.object.isRequired, + request: PropTypes.object.isRequired }; const ReceivedRequestCard = ({ request }) => { @@ -48,18 +48,18 @@ const ReceivedRequestCard = ({ request }) => { const requestCreator = selectProfile(state, request?.creatorId); const requestee = selectProfile(state, request?.requesteeId); submitDate = submitDate - ? dateFns.format(new Date(submitDate.join("/")), "MM/dd/yyyy") + ? dateFns.format(new Date(submitDate.join('/')), 'MM/dd/yyyy') : null; dueDate = dueDate - ? dateFns.format(new Date(dueDate.join("/")), "LLLL dd, yyyy") + ? dateFns.format(new Date(dueDate.join('/')), 'LLLL dd, yyyy') : null; - sendDate = dateFns.format(new Date(sendDate.join("/")), "LLLL dd, yyyy"); + sendDate = dateFns.format(new Date(sendDate.join('/')), 'LLLL dd, yyyy'); const Submitted = () => { if (request.dueDate) { const today = new Date(); const due = new Date(request.dueDate); - if (!request.submitDate && today > due && request.status !== "canceled") { + if (!request.submitDate && today > due && request.status !== 'canceled') { return ( Overdue ); @@ -71,13 +71,11 @@ const ReceivedRequestCard = ({ request }) => { Submitted {submitDate} ); - } else if (request.status === "canceled") { + } else if (request.status === 'canceled') { return ( - - Canceled - + Canceled ); - } else if (request.status !== "pending") { + } else if (request.status !== 'pending') { return ( Not Submitted @@ -87,12 +85,12 @@ const ReceivedRequestCard = ({ request }) => { }; return ( - +

    @@ -101,25 +99,25 @@ const ReceivedRequestCard = ({ request }) => { {requestCreator?.title}
    - + requested feedback on
    {requestee?.name} {requestee?.title} @@ -132,17 +130,20 @@ const ReceivedRequestCard = ({ request }) => { Sent on {sendDate} - {request?.dueDate ? `Due on ${dueDate}` : "No due date"} + {request?.dueDate ? `Due on ${dueDate}` : 'No due date'}
    - {request && !request.submitDate && request.id && request.status !== "canceled" ? ( + {request && + !request.submitDate && + request.id && + request.status !== 'canceled' ? ( diff --git a/web-ui/src/components/reports-section/CheckinReport.jsx b/web-ui/src/components/reports-section/CheckinReport.jsx index 6cc9651975..fcbfbd3e06 100644 --- a/web-ui/src/components/reports-section/CheckinReport.jsx +++ b/web-ui/src/components/reports-section/CheckinReport.jsx @@ -1,9 +1,9 @@ -import React, { useContext } from "react"; -import { Link } from "react-router-dom"; +import React, { useContext } from 'react'; +import { Link } from 'react-router-dom'; -import { getAvatarURL } from "../../api/api.js"; -import { AppContext } from "../../context/AppContext"; -import { selectFilteredCheckinsForTeamMemberAndPDL } from "../../context/selectors"; +import { getAvatarURL } from '../../api/api.js'; +import { AppContext } from '../../context/AppContext'; +import { selectFilteredCheckinsForTeamMemberAndPDL } from '../../context/selectors'; import { Accordion, @@ -16,16 +16,16 @@ import { CardContent, Chip, Container, - Typography, -} from "@mui/material"; + Typography +} from '@mui/material'; -import "./CheckinReport.css"; +import './CheckinReport.css'; const CheckinsReport = ({ closed, pdl, planned }) => { const { state } = useContext(AppContext); const { name, id, members, workEmail } = pdl; - const getCheckinDate = (checkin) => { + const getCheckinDate = checkin => { if (!checkin || !checkin.checkInDate) return; const [year, month, day, hour, minute] = checkin.checkInDate; return new Date(year, month - 1, day, hour, minute, 0); @@ -35,22 +35,22 @@ const CheckinsReport = ({ closed, pdl, planned }) => { const now = new Date(); let checkinDate = new Date(getCheckinDate(checkin)); let dateString = new Date(getCheckinDate(checkin)).toString(); - dateString = dateString.split(" ").slice(0, 5).join(" "); + dateString = dateString.split(' ').slice(0, 5).join(' '); return (
    {dateString} now - ? "Planned" - : "Open" + ? 'Planned' + : 'Open' } />
    @@ -58,10 +58,9 @@ const CheckinsReport = ({ closed, pdl, planned }) => { ); }; const TeamMemberMap = () => { - const filtered = members && - members.filter((member) => { + members.filter(member => { const checkins = selectFilteredCheckinsForTeamMemberAndPDL( state, member.id, @@ -72,7 +71,7 @@ const CheckinsReport = ({ closed, pdl, planned }) => { return checkins && checkins.length > 0; }); if (filtered && filtered.length > 0) { - return filtered.map((member) => { + return filtered.map(member => { const checkins = selectFilteredCheckinsForTeamMemberAndPDL( state, member.id, @@ -87,13 +86,13 @@ const CheckinsReport = ({ closed, pdl, planned }) => { id="accordion-summary" > {member.name} - {checkins.map((checkin) => ( + {checkins.map(checkin => ( { @@ -41,29 +39,24 @@ const SelectUserModal = ({ userLabel, open, onSelect, onClose }) => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: - "You must select a team member.", - }, + severity: 'error', + toast: 'You must select a team member.' + } }); } else { onSelect(member); } - }, [ - onSelect, - dispatch, - member, - ]); + }, [onSelect, dispatch, member]); return ( option.name || ""} - renderInput={(params) => ( + getOptionLabel={option => option.name || ''} + renderInput={params => ( { const { state, dispatch } = useContext(AppContext); @@ -41,7 +44,7 @@ const SelfReview = ({ periodId, onBack }) => { ? res.payload.data : null; if (data) { - dispatch({ type: UPDATE_REVIEW_PERIODS, payload: data}); + dispatch({ type: UPDATE_REVIEW_PERIODS, payload: data }); } }; if (csrf) { @@ -51,24 +54,28 @@ const SelfReview = ({ periodId, onBack }) => { useEffect(() => { const createSelfReview = async () => { - if(!memberProfile?.supervisorid) { + if (!memberProfile?.supervisorid) { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "You do not have an assigned supervisor. Please contact your HR administrator.", - }, + severity: 'error', + toast: + 'You do not have an assigned supervisor. Please contact your HR administrator.' + } }); } else { - const res = await createFeedbackRequest({ - creatorId: memberProfile?.supervisorid, - requesteeId: currentUserId, - recipientId: currentUserId, - templateId: period?.selfReviewTemplateId, - reviewPeriodId: period?.id, - sendDate: dateUtils.format(new Date(), 'yyyy-MM-dd'), - status: "pending", - }, csrf); + const res = await createFeedbackRequest( + { + creatorId: memberProfile?.supervisorid, + requesteeId: currentUserId, + recipientId: currentUserId, + templateId: period?.selfReviewTemplateId, + reviewPeriodId: period?.id, + sendDate: dateUtils.format(new Date(), 'yyyy-MM-dd'), + status: 'pending' + }, + csrf + ); const data = res && res.payload && @@ -85,7 +92,11 @@ const SelfReview = ({ periodId, onBack }) => { }; const getReviewRequest = async () => { - const res = await findSelfReviewRequestsByPeriodAndTeamMember(period, currentUserId, csrf); + const res = await findSelfReviewRequestsByPeriodAndTeamMember( + period, + currentUserId, + csrf + ); const data = res && res.payload && @@ -102,14 +113,29 @@ const SelfReview = ({ periodId, onBack }) => { } }; - if (csrf && !selfReview && currentUserId && memberProfile && period && !loadingReview.current) { + if ( + csrf && + !selfReview && + currentUserId && + memberProfile && + period && + !loadingReview.current + ) { loadingReview.current = true; getReviewRequest(); } }, [csrf, period, selfReview, currentUserId, memberProfile, dispatch]); - return selfReview && selfReview.id && ( - + return ( + selfReview && + selfReview.id && ( + + ) ); }; diff --git a/web-ui/src/components/reviews/TeamMemberReview.jsx b/web-ui/src/components/reviews/TeamMemberReview.jsx index 58024a7c8f..2ecabcc2e1 100644 --- a/web-ui/src/components/reviews/TeamMemberReview.jsx +++ b/web-ui/src/components/reviews/TeamMemberReview.jsx @@ -1,55 +1,64 @@ -import React, {useContext, useState, useCallback} from "react"; +import React, { useContext, useState, useCallback } from 'react'; import { useTheme } from '@mui/material/styles'; import { styled } from '@mui/material/styles'; import SwipeableViews from 'react-swipeable-views'; import PropTypes from 'prop-types'; -import {AppContext} from "../../context/AppContext"; -import {selectCurrentUser, selectProfile} from "../../context/selectors"; +import { AppContext } from '../../context/AppContext'; +import { selectCurrentUser, selectProfile } from '../../context/selectors'; import AppBar from '@mui/material/AppBar'; -import Button from "@mui/material/Button"; +import Button from '@mui/material/Button'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Typography from '@mui/material/Typography'; -import CheckCircleIcon from "@mui/icons-material/CheckCircle"; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import HourglassEmptyIcon from '@mui/icons-material/HourglassEmpty'; import Box from '@mui/material/Box'; -import {Card, CardActions, CardContent, CardHeader, Modal} from "@mui/material"; -import FeedbackSubmitForm from "../feedback_submit_form/FeedbackSubmitForm"; -import SelectUserModal from "./SelectUserModal"; -import {cancelFeedbackRequest, updateFeedbackRequest} from "../../api/feedback"; -import { selectCsrfToken } from "../../context/selectors"; -import { UPDATE_TOAST } from "../../context/actions"; +import { + Card, + CardActions, + CardContent, + CardHeader, + Modal +} from '@mui/material'; +import FeedbackSubmitForm from '../feedback_submit_form/FeedbackSubmitForm'; +import SelectUserModal from './SelectUserModal'; +import { + cancelFeedbackRequest, + updateFeedbackRequest +} from '../../api/feedback'; +import { selectCsrfToken } from '../../context/selectors'; +import { UPDATE_TOAST } from '../../context/actions'; const propTypes = { - selfReview: PropTypes.any, - reviews: PropTypes.arrayOf(PropTypes.any), - memberProfile: PropTypes.any, - reloadReviews: PropTypes.func, + selfReview: PropTypes.any, + reviews: PropTypes.arrayOf(PropTypes.any), + memberProfile: PropTypes.any, + reloadReviews: PropTypes.func }; -const displayName = "TeamMemberReview"; +const displayName = 'TeamMemberReview'; const PREFIX = displayName; const classes = { actionButtons: `${PREFIX}-actionButtons`, buttonRow: `${PREFIX}-buttonRow`, - periodModal: `${PREFIX}-periodModal`, + periodModal: `${PREFIX}-periodModal` }; - -const Root = styled('div')(({theme}) => ({ +const Root = styled('div')(({ theme }) => ({ [`& .${classes.actionButtons}`]: { - margin: "0.5em 0 0 1em", - ['@media (max-width:820px)']: { // eslint-disable-line no-useless-computed-key - padding: "0", - }, + margin: '0.5em 0 0 1em', + ['@media (max-width:820px)']: { + // eslint-disable-line no-useless-computed-key + padding: '0' + } }, [`& .${classes.buttonRow}`]: { - display: "flex", - flexDirection: "row", - justifyContent: "space-around", - alignItems: "center", - margin: "0 0 1em 0", - }, + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + margin: '0 0 1em 0' + } })); const TabPanel = ({ children, value, index, ...other }) => { @@ -68,43 +77,60 @@ const TabPanel = ({ children, value, index, ...other }) => { )}
    ); -} +}; TabPanel.propTypes = { children: PropTypes.any, dir: PropTypes.string, index: PropTypes.number, - value: PropTypes.number, -} -TabPanel.displayName = "TabPanel"; + value: PropTypes.number +}; +TabPanel.displayName = 'TabPanel'; -const a11yProps = (index) => ({ +const a11yProps = index => ({ id: `full-width-tab-${index}`, - 'aria-controls': `full-width-tabpanel-${index}`, + 'aria-controls': `full-width-tabpanel-${index}` }); -const TeamMemberReview = ({selfReview, reviews, memberProfile, reloadReviews}) => { - const {state} = useContext(AppContext); +const TeamMemberReview = ({ + selfReview, + reviews, + memberProfile, + reloadReviews +}) => { + const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); const currentUser = selectCurrentUser(state); const theme = useTheme(); const [value, setValue] = useState(0); - const [reassignOpen, setReassignOpen] = useState(false) + const [reassignOpen, setReassignOpen] = useState(false); const [cancelOpen, setCancelOpen] = useState(false); - const handleOpenReassign = useCallback(() => setReassignOpen(true), [setReassignOpen]); - const handleCloseReassign = useCallback(() => setReassignOpen(false), [setReassignOpen]); - const handleOpenCancel = useCallback(() => setCancelOpen(true), [setCancelOpen]); - const handleCloseCancel = useCallback(() => setCancelOpen(false), [setCancelOpen]); + const handleOpenReassign = useCallback( + () => setReassignOpen(true), + [setReassignOpen] + ); + const handleCloseReassign = useCallback( + () => setReassignOpen(false), + [setReassignOpen] + ); + const handleOpenCancel = useCallback( + () => setCancelOpen(true), + [setCancelOpen] + ); + const handleCloseCancel = useCallback( + () => setCancelOpen(false), + [setCancelOpen] + ); - const review = reviews && reviews[value-1]; + const review = reviews && reviews[value - 1]; const recipient = selectProfile(state, review?.recipientId); const handleChange = (event, newValue) => { setValue(newValue); }; - const handleChangeIndex = (index) => { + const handleChangeIndex = index => { setValue(index); }; @@ -112,15 +138,17 @@ const TeamMemberReview = ({selfReview, reviews, memberProfile, reloadReviews}) = const cancelRequest = async () => { const res = await cancelFeedbackRequest(review, csrf); const cancellationResponse = - res && res.payload && res.payload.status === 200 && !res.error ? res.payload.data : null; + res && res.payload && res.payload.status === 200 && !res.error + ? res.payload.data + : null; if (!cancellationResponse) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", + severity: 'error', toast: - "There was an error cancelling the review. Please contact your administrator.", - }, + 'There was an error cancelling the review. Please contact your administrator.' + } }); } return cancellationResponse; @@ -128,154 +156,212 @@ const TeamMemberReview = ({selfReview, reviews, memberProfile, reloadReviews}) = handleCloseCancel(); if (csrf) { - cancelRequest().then((res) => { - if(res) { + cancelRequest().then(res => { + if (res) { reloadReviews(); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Review canceled", - }, + severity: 'success', + toast: 'Review canceled' + } }); } }); } }, [csrf, handleCloseCancel, review, reloadReviews]); - const handleReassign = useCallback((assignee) => { - const reassignRequest = async () => { - review.recipientId = assignee.id; - const res = await updateFeedbackRequest(review, csrf); - const updateResponse = - res && res.payload && res.payload.status === 200 && !res.error ? res.payload.data : null; - if (!updateResponse) { - window.snackDispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: - "There was an error reassigning the review. Please contact your administrator.", - }, - }); - } - return updateResponse; - }; - - handleCloseReassign(); - if (csrf) { - reassignRequest().then((res) => { - if(res) { - reloadReviews(); + const handleReassign = useCallback( + assignee => { + const reassignRequest = async () => { + review.recipientId = assignee.id; + const res = await updateFeedbackRequest(review, csrf); + const updateResponse = + res && res.payload && res.payload.status === 200 && !res.error + ? res.payload.data + : null; + if (!updateResponse) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Review reassigned", - }, + severity: 'error', + toast: + 'There was an error reassigning the review. Please contact your administrator.' + } }); } - }); - } - }, [csrf, handleCloseReassign, review, reloadReviews]); + return updateResponse; + }; + + handleCloseReassign(); + if (csrf) { + reassignRequest().then(res => { + if (res) { + reloadReviews(); + window.snackDispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'success', + toast: 'Review reassigned' + } + }); + } + }); + } + }, + [csrf, handleCloseReassign, review, reloadReviews] + ); - let selfReviewIcon = (); - if(selfReview?.status.toUpperCase() === "SUBMITTED") { - selfReviewIcon = (); + let selfReviewIcon = ; + if (selfReview?.status.toUpperCase() === 'SUBMITTED') { + selfReviewIcon = ; } return ( - - - + + + + {reviews && + reviews.map((review, index) => { + const reviewer = selectProfile(state, review?.recipientId); + let label = reviewer?.firstName + "'s Review"; + + if (reviewer?.id === currentUser?.id) { + label = 'Your Review'; + } + + let icon = ; + if (review?.status.toUpperCase() === 'SUBMITTED') { + icon = ; + } + + return ( + + ); + })} + + + - - { - reviews && reviews.map((review, index) => { + + {selfReview && selfReview.id ? ( + + ) : ( + + {memberProfile?.firstName} has not started their self-review. + + )} + + {reviews && + reviews.map((review, index) => { const reviewer = selectProfile(state, review?.recipientId); - let label = reviewer?.firstName + "'s Review"; + const requesteeName = memberProfile?.name; - if(reviewer?.id === currentUser?.id) { - label = "Your Review"; + let readOnly = true; + if ( + reviewer?.id === currentUser?.id && + 'SUBMITTED' !== review?.status?.toUpperCase() + ) { + readOnly = false; } - let icon = (); - if(review?.status.toUpperCase() === "SUBMITTED") { - icon = (); + return ( + + {review?.status.toUpperCase() !== 'SUBMITTED' && ( +
    + + +
    + )} + +
    + ); + })} +
    + + + + + Cancel Review + } - - return (); - }) - } -
    -
    - - - {(selfReview && selfReview.id) ? ( - - ) : ( - {memberProfile?.firstName} has not started their self-review. - )} - - { - reviews && reviews.map((review, index) => { - const reviewer = selectProfile(state, review?.recipientId); - const requesteeName = memberProfile?.name; - - let readOnly = true; - if(reviewer?.id === currentUser?.id && "SUBMITTED" !== review?.status?.toUpperCase()) { - readOnly = false; - } - - return ( - - { review?.status.toUpperCase() !== "SUBMITTED" && - (
    - - -
    )} - -
    - ); - }) - } -
    - - - - Cancel Review}/> - - - Are you sure you want to cancel the review sent to {recipient?.name} on {review?.sendDate}? - The recipient will not be able to respond to this request once it is canceled. - - - - - - - - -
    + /> + + + Are you sure you want to cancel the review sent to{' '} + {recipient?.name} on {review?.sendDate}? The + recipient will not be able to respond to this request once it is + canceled. + + + + + + + + +
    ); -} +}; TeamMemberReview.displayName = displayName; TeamMemberReview.propTypes = propTypes; -export default TeamMemberReview; \ No newline at end of file +export default TeamMemberReview; diff --git a/web-ui/src/components/reviews/TeamReviews.jsx b/web-ui/src/components/reviews/TeamReviews.jsx index 7169775fff..2264e92b3c 100644 --- a/web-ui/src/components/reviews/TeamReviews.jsx +++ b/web-ui/src/components/reviews/TeamReviews.jsx @@ -133,8 +133,8 @@ const TeamReviews = ({ periodId }) => { currentMembers.filter(member => member?.id !== currentUser?.id) ) : includeAll - ? setTeamMembers(subordinates) - : setTeamMembers(myTeam); + ? setTeamMembers(subordinates) + : setTeamMembers(myTeam); } }, [ isAdmin, diff --git a/web-ui/src/components/reviews/periods/ReviewPeriods.jsx b/web-ui/src/components/reviews/periods/ReviewPeriods.jsx index fbefd4412e..5e7a45e82b 100644 --- a/web-ui/src/components/reviews/periods/ReviewPeriods.jsx +++ b/web-ui/src/components/reviews/periods/ReviewPeriods.jsx @@ -367,8 +367,8 @@ const ReviewPeriods = ({ onPeriodSelected, mode }) => { return !!a.open === !!b.open ? ('' + a.name).localeCompare(b.name) : !!a.open - ? -1 - : 1; + ? -1 + : 1; }) .map(({ name, open, id }, i) => ( <> diff --git a/web-ui/src/components/search-results/SearchResults.jsx b/web-ui/src/components/search-results/SearchResults.jsx index 260902cd02..2f6403ff9d 100644 --- a/web-ui/src/components/search-results/SearchResults.jsx +++ b/web-ui/src/components/search-results/SearchResults.jsx @@ -1,8 +1,8 @@ -import React, { useContext } from "react"; +import React, { useContext } from 'react'; -import { AppContext } from "../../context/AppContext"; -import { getAvatarURL } from "../../api/api"; -import { selectProfile, selectSkill } from "../../context/selectors"; +import { AppContext } from '../../context/AppContext'; +import { getAvatarURL } from '../../api/api'; +import { selectProfile, selectSkill } from '../../context/selectors'; import { Avatar, @@ -11,48 +11,48 @@ import { Chip, List, ListItem, - Typography, -} from "@mui/material"; + Typography +} from '@mui/material'; const SearchResults = ({ searchResults }) => { const { state } = useContext(AppContext); - const getMemberProfile = (member) => selectProfile(state, member.id); + const getMemberProfile = member => selectProfile(state, member.id); - const chip = (skill) => { + const chip = skill => { let level = skill.level; let skillLevel = level.charAt(0) + level.slice(1).toLowerCase(); let mappedSkill = selectSkill(state, skill.id); - let chipLabel = mappedSkill.name + " - " + skillLevel; + let chipLabel = mappedSkill.name + ' - ' + skillLevel; return ; }; return (
    - { !searchResults ? ( + {!searchResults ? (
    ) : ( searchResults.map((member, index) => { return ( - + - {getMemberProfile(member)?.name || ""} + {getMemberProfile(member)?.name || ''} } subheader={ - {getMemberProfile(member)?.title || ""} + {getMemberProfile(member)?.title || ''} } disableTypography avatar={ } diff --git a/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.jsx b/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.jsx index a12c65ac81..0d8f079dcd 100644 --- a/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.jsx +++ b/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.jsx @@ -1,19 +1,26 @@ -import React, {useCallback, useState} from "react"; +import React, { useCallback, useState } from 'react'; import { - AppBar, Button, - Checkbox, Chip, Dialog, + AppBar, + Button, + Checkbox, + Chip, + Dialog, DialogContent, FormGroup, - IconButton, List, ListItem, ListItemButton, ListItemText, + IconButton, + List, + ListItem, + ListItemButton, + ListItemText, Slide, TextField, Toolbar, Typography -} from "@mui/material"; -import PropTypes from "prop-types"; -import {Close, Search} from "@mui/icons-material"; -import InputAdornment from "@mui/material/InputAdornment"; -import FormControlLabel from "@mui/material/FormControlLabel"; +} from '@mui/material'; +import PropTypes from 'prop-types'; +import { Close, Search } from '@mui/icons-material'; +import InputAdornment from '@mui/material/InputAdornment'; +import FormControlLabel from '@mui/material/FormControlLabel'; const Transition = React.forwardRef(function Transition(props, ref) { return ; @@ -27,8 +34,7 @@ const propTypes = { }; const SelectSkillsDialog = ({ isOpen, onClose, selectableSkills, onSave }) => { - - const [query, setQuery] = useState(""); + const [query, setQuery] = useState(''); const [showPendingSkills, setShowPendingSkills] = useState(false); const [selectedSkillIds, setSelectedSkillIds] = useState(new Set()); @@ -48,80 +54,106 @@ const SelectSkillsDialog = ({ isOpen, onClose, selectableSkills, onSave }) => { return []; }, [query, selectableSkills, showPendingSkills]); - const handleCheckboxToggle = useCallback((skill) => { - const newSelection = new Set(selectedSkillIds); - if (selectedSkillIds.has(skill.id)) { - newSelection.delete(skill.id); - } else { - newSelection.add(skill.id); - } - setSelectedSkillIds(newSelection); - }, [selectedSkillIds]); + const handleCheckboxToggle = useCallback( + skill => { + const newSelection = new Set(selectedSkillIds); + if (selectedSkillIds.has(skill.id)) { + newSelection.delete(skill.id); + } else { + newSelection.add(skill.id); + } + setSelectedSkillIds(newSelection); + }, + [selectedSkillIds] + ); return ( + TransitionComponent={Transition} + >
    - - - - Add Skills to Category - - - - - - setQuery(event.target.value)} - InputProps={{ - endAdornment: - }} - /> - setShowPendingSkills(event.target.checked)} - />} - label="Show Pending Skills"> - - - - {getFilteredSkills().map(skill => ( - handleCheckboxToggle(skill)} - disablePadding - secondaryAction={ + + + + + + + Add Skills to Category + + + + + + + setQuery(event.target.value)} + InputProps={{ + endAdornment: ( + + + + ) + }} + /> + setShowPendingSkills(event.target.checked)} /> } - > - - - {skill.pending && } - {skill.extraneous && } - - - ))} - - + label="Show Pending Skills" + > + + + {getFilteredSkills().map(skill => ( + handleCheckboxToggle(skill)} + disablePadding + secondaryAction={ + + } + > + + + {skill.pending && ( + + )} + {skill.extraneous && ( + + )} + + + ))} + +
    ); @@ -129,4 +161,4 @@ const SelectSkillsDialog = ({ isOpen, onClose, selectableSkills, onSave }) => { SelectSkillsDialog.propTypes = propTypes; -export default SelectSkillsDialog; \ No newline at end of file +export default SelectSkillsDialog; diff --git a/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.test.jsx b/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.test.jsx index 7878870cc6..d46627a86b 100644 --- a/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.test.jsx +++ b/web-ui/src/components/select-skills-dialog/SelectSkillsDialog.test.jsx @@ -1,55 +1,55 @@ -import React from "react"; -import {AppContextProvider} from "../../context/AppContext"; -import SelectSkillsDialog from "./SelectSkillsDialog"; +import React from 'react'; +import { AppContextProvider } from '../../context/AppContext'; +import SelectSkillsDialog from './SelectSkillsDialog'; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", -} + name: 'Current User', + firstName: 'Current', + lastName: 'User' +}; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { - name: "Current User", - firstName: "Current", - lastName: "User", - role: ["MEMBER"], + name: 'Current User', + firstName: 'Current', + lastName: 'User', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - memberProfile: currentUserProfile, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', + memberProfile: currentUserProfile }, checkins: [], guilds: [], teams: [], skills: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], index: 0, memberProfiles: [] } -} +}; const createPortal = vi.fn((element, target) => { return element; }); -vi.mock('react-dom', async (importOriginal) => { +vi.mock('react-dom', async importOriginal => { const mocked = { - ...await importOriginal('react-dom')(), + ...(await importOriginal('react-dom')()), createPortal }; return mocked; }); -vi.mock("@mui/material/Slider", () => { +vi.mock('@mui/material/Slider', () => { return { - default: () => (props) => { - const {onChange, 'data-testid': testId, ...rest} = props; + default: () => props => { + const { onChange, 'data-testid': testId, ...rest } = props; return ( { /> ); } - } + }; }); const skill = { - id: "skill-id", - name: "Java", - description: "A programming language", + id: 'skill-id', + name: 'Java', + description: 'A programming language', pending: false, extraneous: true }; -describe("SelectSkillsDialog", () => { +describe('SelectSkillsDialog', () => { afterEach(() => { createPortal.mockClear(); }); - it("renders correctly", () => { + it('renders correctly', () => { rootSnapshot( - - - + + + ); }); }); diff --git a/web-ui/src/components/sentiment_icon/SentimentIcon.css b/web-ui/src/components/sentiment_icon/SentimentIcon.css index 4232763724..4e2317f96f 100644 --- a/web-ui/src/components/sentiment_icon/SentimentIcon.css +++ b/web-ui/src/components/sentiment_icon/SentimentIcon.css @@ -12,4 +12,4 @@ .sentiment-action-buttons { margin-top: 0.5em; -} \ No newline at end of file +} diff --git a/web-ui/src/components/sentiment_icon/SentimentIcon.jsx b/web-ui/src/components/sentiment_icon/SentimentIcon.jsx index 68c05ecd80..1331cc21a9 100644 --- a/web-ui/src/components/sentiment_icon/SentimentIcon.jsx +++ b/web-ui/src/components/sentiment_icon/SentimentIcon.jsx @@ -1,81 +1,122 @@ -import React, {useState, useCallback} from "react"; -import PropTypes from "prop-types"; -import IconButton from "@mui/material/IconButton"; -import {NotInterested, SentimentSatisfied, SentimentVeryDissatisfied, SentimentVerySatisfied} from "@mui/icons-material"; -import {Popover} from "@mui/material"; -import Typography from "@mui/material/Typography"; -import Button from "@mui/material/Button"; -import "./SentimentIcon.css"; +import React, { useState, useCallback } from 'react'; +import PropTypes from 'prop-types'; +import IconButton from '@mui/material/IconButton'; +import { + NotInterested, + SentimentSatisfied, + SentimentVeryDissatisfied, + SentimentVerySatisfied +} from '@mui/icons-material'; +import { Popover } from '@mui/material'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import './SentimentIcon.css'; const sentimentThreshold = 0.4; -const negativeColor = "#e74c3c"; -const neutralColor = "#f39c12"; -const positiveColor = "#27ae60"; +const negativeColor = '#e74c3c'; +const neutralColor = '#f39c12'; +const positiveColor = '#27ae60'; const propTypes = { sentimentScore: PropTypes.number -} - -const SentimentIcon = (props) => { +}; +const SentimentIcon = props => { const [anchorElement, setAnchorElement] = useState(null); const [showSentimentPicker, setShowSentimentPicker] = useState(false); const [selectedSentiment, setSelectedSentiment] = useState(null); - const [currentSentiment, setCurrentSentiment] = useState(props.sentimentScore); + const [currentSentiment, setCurrentSentiment] = useState( + props.sentimentScore + ); // Gets the appropriate icon, button styles, and icon styles based on the sentiment score const getSentimentStyles = useCallback((sentimentScore, isSelected) => { let sentimentIcon; // HTML element representing the sentiment icon - let buttonStyle; // styles to be applied to the icon button + let buttonStyle; // styles to be applied to the icon button if (sentimentScore < -sentimentThreshold) { - sentimentIcon = ; - buttonStyle = {backgroundColor: isSelected ? negativeColor : "transparent"}; + sentimentIcon = ( + + ); + buttonStyle = { + backgroundColor: isSelected ? negativeColor : 'transparent' + }; } else if (Math.abs(sentimentScore) <= sentimentThreshold) { - sentimentIcon = ; - buttonStyle = {backgroundColor: isSelected ? neutralColor : "transparent"}; + sentimentIcon = ( + + ); + buttonStyle = { + backgroundColor: isSelected ? neutralColor : 'transparent' + }; } else { - sentimentIcon = ; - buttonStyle = {backgroundColor: isSelected ? positiveColor : "transparent"}; + sentimentIcon = ( + + ); + buttonStyle = { + backgroundColor: isSelected ? positiveColor : 'transparent' + }; } return [sentimentIcon, buttonStyle]; }, []); // Renders a sentiment button that is styled according to whether the popover is open - const getSentimentIcon = useCallback((sentimentScore) => { - const [sentimentIcon, buttonStyle] = getSentimentStyles(sentimentScore, !!anchorElement); - return ( - handlePopoverOpen(event)} - style={buttonStyle} - size="large"> - {sentimentIcon} - - ); - }, [anchorElement, getSentimentStyles]); + const getSentimentIcon = useCallback( + sentimentScore => { + const [sentimentIcon, buttonStyle] = getSentimentStyles( + sentimentScore, + !!anchorElement + ); + return ( + handlePopoverOpen(event)} + style={buttonStyle} + size="large" + > + {sentimentIcon} + + ); + }, + [anchorElement, getSentimentStyles] + ); // Renders a sentiment button that is styled according to which sentiment option is selected within the popover - const getSentimentOption = useCallback((sentimentScore) => { - const [sentimentIcon, buttonStyle] = getSentimentStyles(sentimentScore, selectedSentiment === sentimentScore); - return ( - setSelectedSentiment(sentimentScore)} - style={buttonStyle} - size="large"> - {sentimentIcon} - - ); - }, [selectedSentiment, getSentimentStyles]); + const getSentimentOption = useCallback( + sentimentScore => { + const [sentimentIcon, buttonStyle] = getSentimentStyles( + sentimentScore, + selectedSentiment === sentimentScore + ); + return ( + setSelectedSentiment(sentimentScore)} + style={buttonStyle} + size="large" + > + {sentimentIcon} + + ); + }, + [selectedSentiment, getSentimentStyles] + ); - const updateSentiment = (newSentiment) => { - if (typeof currentSentiment !== "number") return; // type check - if (selectedSentiment === null) return; // do not attempt update if no option is selected + const updateSentiment = newSentiment => { + if (typeof currentSentiment !== 'number') return; // type check + if (selectedSentiment === null) return; // do not attempt update if no option is selected // prevent saving updated sentiment if it is the same as before if ( - (newSentiment < -sentimentThreshold && currentSentiment < -sentimentThreshold) || - (Math.abs(newSentiment) < sentimentThreshold && Math.abs(currentSentiment) < sentimentThreshold) || - (newSentiment > sentimentThreshold && currentSentiment > sentimentThreshold) + (newSentiment < -sentimentThreshold && + currentSentiment < -sentimentThreshold) || + (Math.abs(newSentiment) < sentimentThreshold && + Math.abs(currentSentiment) < sentimentThreshold) || + (newSentiment > sentimentThreshold && + currentSentiment > sentimentThreshold) ) { setAnchorElement(null); return; @@ -85,22 +126,26 @@ const SentimentIcon = (props) => { // TODO: Make appropriate API call to update the sentiment setAnchorElement(null); - } + }; - const handlePopoverOpen = (event) => { + const handlePopoverOpen = event => { setShowSentimentPicker(false); setSelectedSentiment(null); setAnchorElement(event.currentTarget); - } + }; const handlePopoverClose = () => { setAnchorElement(null); - } + }; - if (props.sentimentScore === undefined || currentSentiment < -1 || 1 < currentSentiment) { + if ( + props.sentimentScore === undefined || + currentSentiment < -1 || + 1 < currentSentiment + ) { return ( - + ); } @@ -113,52 +158,66 @@ const SentimentIcon = (props) => { anchorEl={anchorElement} onClose={handlePopoverClose} anchorOrigin={{ - vertical: "bottom", - horizontal: "center" + vertical: 'bottom', + horizontal: 'center' }} transformOrigin={{ - vertical: "top", - horizontal: "center" + vertical: 'top', + horizontal: 'center' }} >
    - {!showSentimentPicker ? + {!showSentimentPicker ? ( Is this correct? - If you believe the automatic sentiment detection may have made a mistake, you may choose to change it. + + If you believe the automatic sentiment detection may have made a + mistake, you may choose to change it. +
    -
    : + + ) : ( - What is the sentiment of this response? + + What is the sentiment of this response? +
    - {[-1, 0, 1].map((possibleSentiment) => getSentimentOption(possibleSentiment))} + {[-1, 0, 1].map(possibleSentiment => + getSentimentOption(possibleSentiment) + )}
    - } + )}
    ); -} +}; SentimentIcon.propTypes = propTypes; -export default SentimentIcon; \ No newline at end of file +export default SentimentIcon; diff --git a/web-ui/src/components/sentiment_icon/SentimentIcon.stories.jsx b/web-ui/src/components/sentiment_icon/SentimentIcon.stories.jsx index 84d1626c6d..e132dc33d2 100644 --- a/web-ui/src/components/sentiment_icon/SentimentIcon.stories.jsx +++ b/web-ui/src/components/sentiment_icon/SentimentIcon.stories.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import SentimentIcon from "./SentimentIcon"; -import {AppContextProvider} from "../../context/AppContext"; +import React from 'react'; +import SentimentIcon from './SentimentIcon'; +import { AppContextProvider } from '../../context/AppContext'; export default { - title: "Check Ins/SentimentIcon", + title: 'Check Ins/SentimentIcon', component: SentimentIcon, decorators: [ - (SentimentIcon) => ( + SentimentIcon => ( - + ) ] @@ -16,11 +16,11 @@ export default { const sentimentData = { sentimentScore: 0 -} +}; -const Template = (args) => { +const Template = args => { return ; -} +}; export const DefaultTemplate = Template.bind({}); DefaultTemplate.args = { diff --git a/web-ui/src/components/sentiment_icon/SentimentIcon.test.jsx b/web-ui/src/components/sentiment_icon/SentimentIcon.test.jsx index ac2d7d2ddc..8682db56ab 100644 --- a/web-ui/src/components/sentiment_icon/SentimentIcon.test.jsx +++ b/web-ui/src/components/sentiment_icon/SentimentIcon.test.jsx @@ -1,8 +1,6 @@ -import React from "react"; -import SentimentIcon from "./SentimentIcon"; +import React from 'react'; +import SentimentIcon from './SentimentIcon'; -it("renders correctly", () => { - snapshot( - - ); -}); \ No newline at end of file +it('renders correctly', () => { + snapshot(); +}); diff --git a/web-ui/src/components/skeleton_loader/SkeletonLoader.jsx b/web-ui/src/components/skeleton_loader/SkeletonLoader.jsx index 194f927e18..689711b13c 100644 --- a/web-ui/src/components/skeleton_loader/SkeletonLoader.jsx +++ b/web-ui/src/components/skeleton_loader/SkeletonLoader.jsx @@ -1,38 +1,38 @@ -import React from "react"; -import { styled } from "@mui/material/styles"; -import Skeleton from "@mui/material/Skeleton"; -import { Card, CardHeader, CardContent, Grid, Box } from "@mui/material"; -import { makeStyles } from "@mui/styles"; +import React from 'react'; +import { styled } from '@mui/material/styles'; +import Skeleton from '@mui/material/Skeleton'; +import { Card, CardHeader, CardContent, Grid, Box } from '@mui/material'; +import { makeStyles } from '@mui/styles'; -const PREFIX = "SkeletonLoader"; +const PREFIX = 'SkeletonLoader'; const classes = { - card: `${PREFIX}-card`, + card: `${PREFIX}-card` }; const StyledCard = styled(Card)(() => ({ [`&.${classes.card}`]: { - width: "340px", - }, + width: '340px' + } })); const useStyles = makeStyles({ noTopBottomPadding: { paddingBottom: 0, - paddingTop: 0, + paddingTop: 0 }, smallMargin: { - marginLeft: "1em", + marginLeft: '1em' }, flexShrink: { - flexShrink: 1, - }, + flexShrink: 1 + } }); export default function SkeletonLoader({ type }) { const additionalClasses = useStyles(); // guild and team currently have the same return value but were given different conditionals // for clarity / in case one changes - if (type === "team") { + if (type === 'team') { return ( ); - } else if (type === "guild") { + } else if (type === 'guild') { return ( ); - } else if (type === "people") { + } else if (type === 'people') { return ( ); - } else if (type === "feedback_requests") { + } else if (type === 'feedback_requests') { return ( - + @@ -83,7 +83,7 @@ export default function SkeletonLoader({ type }) { container direction="row" alignItems="center" - justifyContent={"space-around"} + justifyContent={'space-around'} > @@ -93,13 +93,13 @@ export default function SkeletonLoader({ type }) { className={additionalClasses.smallMargin} height={30} variant="text" - width={"10vw"} + width={'10vw'} /> @@ -117,19 +117,19 @@ export default function SkeletonLoader({ type }) { height={30} sx={{ m: 0 }} variant="text" - width={"10vw"} + width={'10vw'} /> @@ -140,30 +140,30 @@ export default function SkeletonLoader({ type }) { ); - } else if (type === "received_requests") { + } else if (type === 'received_requests') { return ( ); - } else if (type === "view_feedback_responses") { + } else if (type === 'view_feedback_responses') { return ( @@ -171,12 +171,12 @@ export default function SkeletonLoader({ type }) { display="flex" alignItems="center" justifyContent="center" - width={"100%"} + width={'100%'} > diff --git a/web-ui/src/components/skeleton_loader/SkeletonLoader.stories.jsx b/web-ui/src/components/skeleton_loader/SkeletonLoader.stories.jsx index 5de18d4dd8..72e486845b 100644 --- a/web-ui/src/components/skeleton_loader/SkeletonLoader.stories.jsx +++ b/web-ui/src/components/skeleton_loader/SkeletonLoader.stories.jsx @@ -1,44 +1,41 @@ import React from 'react'; import SkeletonLoader from './SkeletonLoader'; - export default { component: SkeletonLoader, - title: 'Check Ins/SkeletonLoader', -} + title: 'Check Ins/SkeletonLoader' +}; -const Template = (args) => { +const Template = args => { return ; -} +}; export const TeamLoader = Template.bind({}); TeamLoader.args = { - type: "team", -} + type: 'team' +}; export const GuildLoader = Template.bind({}); GuildLoader.args = { - type: "guild", -} + type: 'guild' +}; export const PeopleLoader = Template.bind({}); PeopleLoader.args = { - type: "people", -} + type: 'people' +}; export const FeedbackRequestLoader = Template.bind({}); FeedbackRequestLoader.args = { - type: "feedback_requests", -} + type: 'feedback_requests' +}; export const RecievedRequestLoader = Template.bind({}); RecievedRequestLoader.args = { - type: "received_requests", -} + type: 'received_requests' +}; export const FeedbackResponsesLoader = Template.bind({}); FeedbackResponsesLoader.args = { - type: "view_feedback_responses", -} - - + type: 'view_feedback_responses' +}; diff --git a/web-ui/src/components/skeleton_loader/SkeletonLoader.test.jsx b/web-ui/src/components/skeleton_loader/SkeletonLoader.test.jsx index 7a7a74ec04..4e4817aa65 100644 --- a/web-ui/src/components/skeleton_loader/SkeletonLoader.test.jsx +++ b/web-ui/src/components/skeleton_loader/SkeletonLoader.test.jsx @@ -1,54 +1,44 @@ -import React from "react"; +import React from 'react'; import renderer from 'react-test-renderer'; -import SkeletonLoader from "./SkeletonLoader" - - - +import SkeletonLoader from './SkeletonLoader'; it("renders correctly when 'team' is passed as prop ", () => { - const component = renderer.create( - - ) + const component = renderer.create(); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'guild' is passed as prop ", () => { - const component = renderer.create( - - ) + const component = renderer.create(); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'people' is passed as prop ", () => { - const component = renderer.create( - - ) - expect(component.toJSON()).toMatchSnapshot(); + const component = renderer.create(); + expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'feedback_requests' is passed as prop ", () => { const component = renderer.create( - - ) + + ); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'feedback_requests' is passed as prop ", () => { const component = renderer.create( - - ) + + ); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'feedback_requests' is passed as prop ", () => { const component = renderer.create( - - ) + + ); expect(component.toJSON()).toMatchSnapshot(); }); it("renders correctly when 'feedback_requests' is passed as prop ", () => { const component = renderer.create( - - ) + + ); expect(component.toJSON()).toMatchSnapshot(); }); - diff --git a/web-ui/src/components/skill-category-card/SkillCategoryCard.jsx b/web-ui/src/components/skill-category-card/SkillCategoryCard.jsx index 50b88d45bb..563f3d2142 100644 --- a/web-ui/src/components/skill-category-card/SkillCategoryCard.jsx +++ b/web-ui/src/components/skill-category-card/SkillCategoryCard.jsx @@ -1,17 +1,24 @@ -import React from "react"; -import {Card, CardContent, CardHeader, Chip, IconButton, Tooltip} from "@mui/material"; -import PropTypes from "prop-types"; -import DeleteIcon from "@mui/icons-material/Delete"; -import EditIcon from "@mui/icons-material/Edit"; -import Typography from "@mui/material/Typography"; -import {Link} from "react-router-dom"; +import React from 'react'; +import { + Card, + CardContent, + CardHeader, + Chip, + IconButton, + Tooltip +} from '@mui/material'; +import PropTypes from 'prop-types'; +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; +import Typography from '@mui/material/Typography'; +import { Link } from 'react-router-dom'; const propTypes = { id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, description: PropTypes.string, skills: PropTypes.arrayOf(PropTypes.object), - onDelete: PropTypes.func, + onDelete: PropTypes.func }; const SkillCategoryCard = ({ id, name, description, skills, onDelete }) => { @@ -20,27 +27,34 @@ const SkillCategoryCard = ({ id, name, description, skills, onDelete }) => { - - - - + action={ +
    + + + + + + + + + + - - - - - - - -
    } +
    +
    + } /> - - {(skills && skills.length > 0) ? ( - skills.map((skill) => ) + + {skills && skills.length > 0 ? ( + skills.map(skill => ) ) : ( - This category contains no skills. + + This category contains no skills. + )} @@ -49,4 +63,4 @@ const SkillCategoryCard = ({ id, name, description, skills, onDelete }) => { SkillCategoryCard.propTypes = propTypes; -export default SkillCategoryCard; \ No newline at end of file +export default SkillCategoryCard; diff --git a/web-ui/src/components/skill-category-card/SkillCategoryCard.test.jsx b/web-ui/src/components/skill-category-card/SkillCategoryCard.test.jsx index 8b156a505b..8570bae87a 100644 --- a/web-ui/src/components/skill-category-card/SkillCategoryCard.test.jsx +++ b/web-ui/src/components/skill-category-card/SkillCategoryCard.test.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import SkillCategoryCard from "./SkillCategoryCard"; -import {AppContextProvider} from "../../context/AppContext"; -import {BrowserRouter} from "react-router-dom"; +import React from 'react'; +import SkillCategoryCard from './SkillCategoryCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.jsx b/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.jsx index 79e9d110d1..41797b6248 100644 --- a/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.jsx +++ b/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.jsx @@ -1,27 +1,32 @@ -import React, { useState } from "react"; -import PropTypes from "prop-types"; -import {Button, DialogActions, DialogContent, DialogTitle, TextField} from "@mui/material"; -import Dialog from "@mui/material/Dialog"; +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { + Button, + DialogActions, + DialogContent, + DialogTitle, + TextField +} from '@mui/material'; +import Dialog from '@mui/material/Dialog'; const propTypes = { isOpen: PropTypes.bool.isRequired, onClose: PropTypes.func, - onConfirm: PropTypes.func, + onConfirm: PropTypes.func }; const SkillCategoryNewDialog = ({ isOpen, onClose, onConfirm }) => { - - const [categoryName, setCategoryName] = useState(""); - const [categoryDescription, setCategoryDescription] = useState(""); + const [categoryName, setCategoryName] = useState(''); + const [categoryDescription, setCategoryDescription] = useState(''); const reset = () => { - setCategoryName(""); - setCategoryDescription(""); - } + setCategoryName(''); + setCategoryDescription(''); + }; const isDisabled = () => { return categoryName.trim().length === 0; - } + }; return ( { > New Category -
    +
    setCategoryName(event.target.value)} + onChange={event => setCategoryName(event.target.value)} /> { multiline maxRows={3} value={categoryDescription} - onChange={(event) => setCategoryDescription(event.target.value)} - style={{ marginTop: "1rem" }} + onChange={event => setCategoryDescription(event.target.value)} + style={{ marginTop: '1rem' }} />
    - - @@ -71,4 +83,4 @@ const SkillCategoryNewDialog = ({ isOpen, onClose, onConfirm }) => { SkillCategoryNewDialog.propTypes = propTypes; -export default SkillCategoryNewDialog; \ No newline at end of file +export default SkillCategoryNewDialog; diff --git a/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.test.jsx b/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.test.jsx index d026fffbfd..16f0a1d665 100644 --- a/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.test.jsx +++ b/web-ui/src/components/skill-category-new-dialog/SkillCategoryNewDialog.test.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import {AppContextProvider} from "../../context/AppContext"; -import SkillCategoryNewDialog from "./SkillCategoryNewDialog"; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppContextProvider } from '../../context/AppContext'; +import SkillCategoryNewDialog from './SkillCategoryNewDialog'; -describe("SkillCategoryNewDialog", () => { - it("renders correctly", () => { +describe('SkillCategoryNewDialog', () => { + it('renders correctly', () => { snapshot( { ); }); }); - - diff --git a/web-ui/src/components/skills/SkillSection.jsx b/web-ui/src/components/skills/SkillSection.jsx index 54754ee6e7..cd365c1a7b 100644 --- a/web-ui/src/components/skills/SkillSection.jsx +++ b/web-ui/src/components/skills/SkillSection.jsx @@ -1,26 +1,26 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; import { styled } from '@mui/material/styles'; -import "./SkillSection.css"; -import { AppContext } from "../../context/AppContext"; +import './SkillSection.css'; +import { AppContext } from '../../context/AppContext'; import { selectMySkills, selectOrderedSkills, - selectCsrfToken, -} from "../../context/selectors"; + selectCsrfToken +} from '../../context/selectors'; import { ADD_SKILL, ADD_MEMBER_SKILL, DELETE_MEMBER_SKILL, UPDATE_MEMBER_SKILLS, - UPDATE_TOAST, -} from "../../context/actions"; + UPDATE_TOAST +} from '../../context/actions'; import { createMemberSkill, deleteMemberSkill, - updateMemberSkill, -} from "../../api/memberskill.js"; -import { getSkill, createSkill } from "../../api/skill.js"; -import SkillSlider from "./SkillSlider"; + updateMemberSkill +} from '../../api/memberskill.js'; +import { getSkill, createSkill } from '../../api/skill.js'; +import SkillSlider from './SkillSlider'; import { Button, @@ -34,13 +34,11 @@ import { List, ListItem, Modal, - TextField, -} from "@mui/material"; -import Autocomplete, { - createFilterOptions, -} from '@mui/material/Autocomplete'; -import BuildIcon from "@mui/icons-material/Build"; -import Typography from "@mui/material/Typography"; + TextField +} from '@mui/material'; +import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'; +import BuildIcon from '@mui/icons-material/Build'; +import Typography from '@mui/material/Typography'; const PREFIX = 'SkillSection'; const classes = { @@ -50,8 +48,8 @@ const classes = { const Root = styled('span')(() => ({ [`& .${classes.skillRow}`]: { - justifyContent: "center", - fontWeight: "bold", + justifyContent: 'center', + fontWeight: 'bold' } })); @@ -61,7 +59,7 @@ const SkillSection = ({ userId }) => { const skills = selectOrderedSkills(state); const myMemberSkills = selectMySkills(state); const [mySkills, setMySkills] = useState([]); - const [skillToAdd, setSkillToAdd] = useState({ name: "", description: "" }); + const [skillToAdd, setSkillToAdd] = useState({ name: '', description: '' }); const [open, setOpen] = useState(false); const [openDelete, setOpenDelete] = useState(false); const [selectedSkillId, setSelectedSkillId] = useState(null); @@ -82,9 +80,9 @@ const SkillSection = ({ userId }) => { useEffect(() => { const getSkills = async () => { const skillsResults = await Promise.all( - myMemberSkills.map((mSkill) => mapMemberSkill(mSkill, csrf)) + myMemberSkills.map(mSkill => mapMemberSkill(mSkill, csrf)) ); - const currentUserSkills = skillsResults.map((result) => { + const currentUserSkills = skillsResults.map(result => { let skill = result.payload.data; skill.skilllevel = result.skilllevel; skill.lastuseddate = result.lastuseddate; @@ -98,12 +96,12 @@ const SkillSection = ({ userId }) => { } }, [csrf, myMemberSkills]); - const addSkill = async (name) => { + const addSkill = async name => { if (!csrf) { return; } const inSkillsList = skills.find( - (skill) => + skill => skill && skill.name.toUpperCase() === (name ? name.toUpperCase() : skillToAdd.name.toUpperCase()) @@ -114,7 +112,7 @@ const SkillSection = ({ userId }) => { const res = await createSkill( { ...skillToAdd, - pending: true, + pending: true }, csrf ); @@ -126,13 +124,13 @@ const SkillSection = ({ userId }) => { if (curSkill && curSkill.id && userId) { if ( Object.values(mySkills).find( - (skill) => skill.name.toUpperCase === curSkill.name.toUpperCase() + skill => skill.name.toUpperCase === curSkill.name.toUpperCase() ) ) { return; } const res = await createMemberSkill( - { skillid: curSkill.id, memberid: userId, skilllevel: 3}, + { skillid: curSkill.id, memberid: userId, skilllevel: 3 }, csrf ); const data = @@ -140,19 +138,19 @@ const SkillSection = ({ userId }) => { data && dispatch({ type: ADD_MEMBER_SKILL, payload: data }); } handleClose(); - setSkillToAdd({ name: "", description: "" }); + setSkillToAdd({ name: '', description: '' }); }; const removeSkill = async (id, csrf) => { - const mSkill = myMemberSkills.find((s) => s.skillid === id); + const mSkill = myMemberSkills.find(s => s.skillid === id); const result = await deleteMemberSkill(mSkill.id, csrf); if (result && result.payload && result.payload.status === 200) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Skill removed from profile", - }, + severity: 'success', + toast: 'Skill removed from profile' + } }); dispatch({ type: DELETE_MEMBER_SKILL, payload: id }); handleCloseDeleteConfirmation(); @@ -167,11 +165,14 @@ const SkillSection = ({ userId }) => { const handleUpdate = async (lastUsedDate, skillLevel, id) => { if (csrf && skillLevel) { - const mSkill = {...myMemberSkills.find((s) => s.skillid === id)}; + const mSkill = { ...myMemberSkills.find(s => s.skillid === id) }; mSkill.lastuseddate = lastUsedDate; mSkill.skilllevel = skillLevel; await updateMemberSkill(mSkill, csrf); - let copy = [...myMemberSkills.filter((skill) => skill.id !== mSkill.id), mSkill]; + let copy = [ + ...myMemberSkills.filter(skill => skill.id !== mSkill.id), + mSkill + ]; dispatch({ type: UPDATE_MEMBER_SKILLS, payload: copy }); } }; @@ -190,32 +191,28 @@ const SkillSection = ({ userId }) => { handleHomeEndKeys blurOnSelect options={skills - .filter( - (skill) => !mySkills.map((mSkill) => mSkill.id).includes(skill.id) - ) - .map((skill) => { + .filter(skill => !mySkills.map(mSkill => mSkill.id).includes(skill.id)) + .map(skill => { return { displayLabel: skill.name, - name: skill.name, + name: skill.name }; })} renderOption={(props, option) => ( -
  • - {option.displayLabel} -
  • +
  • {option.displayLabel}
  • )} filterOptions={(options, params) => { const filtered = filter(options, params); - if (params.inputValue !== "") { + if (params.inputValue !== '') { filtered.push({ name: params.inputValue, - displayLabel: `Add "${params.inputValue}"`, + displayLabel: `Add "${params.inputValue}"` }); } return filtered; }} - renderInput={(params) => ( + renderInput={params => ( { onChange={(event, value) => { if (value === null) return; const inSkillsList = skills.find( - (skill) => + skill => skill && skill.name.toUpperCase() === value.name.toUpperCase() ); if (!inSkillsList) { - setSkillToAdd({ name: value.name, description: "" }); + setSkillToAdd({ name: value.name, description: '' }); handleOpen(); } else { addSkill(value.name); } }} - getOptionLabel={(option) => option.displayLabel || ""} + getOptionLabel={option => option.displayLabel || ''} /> ); return ( <> -
    - - setSkillToAdd({ ...skillToAdd, name: e.target.value }) - } - /> - - setSkillToAdd({ ...skillToAdd, description: e.target.value }) - } - /> -
    - - -
    +
    + + setSkillToAdd({ ...skillToAdd, name: e.target.value }) + } + /> + + setSkillToAdd({ ...skillToAdd, description: e.target.value }) + } + /> +
    + +
    - +
    +
    - - Skills + + + Skills +
    - +
    {mySkills && - mySkills.map((memberSkill) => { - return ( - - { - handleOpenDeleteConfirmation(); - setSelectedSkillId(id); - }} - onUpdate={handleUpdate} - /> - - ); - })} + mySkills.map(memberSkill => { + return ( + + { + handleOpenDeleteConfirmation(); + setSelectedSkillId(id); + }} + onUpdate={handleUpdate} + /> + + ); + })}
    @@ -323,11 +322,15 @@ const SkillSection = ({ userId }) => { Delete Skill? - Are you sure you want to remove this skill from your profile? + Are you sure you want to remove this skill from your + profile? - - + + + + {({ TransitionProps, placement }) => ( + - - - - - {({ TransitionProps, placement }) => ( - - - - - {options.map((option, index) => { - return (!toggleOnSelect && index === 0) ? "" : ( + + + + {options.map((option, index) => { + return !toggleOnSelect && index === 0 ? ( + '' + ) : ( toggleOnSelect ? handleMenuItemClick(event, index) : handleButtonClick(event, index)} + onClick={event => + toggleOnSelect + ? handleMenuItemClick(event, index) + : handleButtonClick(event, index) + } > {option} - )})} - - - - - )} - + ); + })} + + + + + )} +
    ); -} +}; SplitButton.propTypes = propTypes; diff --git a/web-ui/src/components/split-button/SplitButton.stories.jsx b/web-ui/src/components/split-button/SplitButton.stories.jsx index 9e75ca39c6..14601e2c4c 100644 --- a/web-ui/src/components/split-button/SplitButton.stories.jsx +++ b/web-ui/src/components/split-button/SplitButton.stories.jsx @@ -2,23 +2,22 @@ import React from 'react'; import SplitButton from './SplitButton'; export default { - title: 'Check Ins/SplitButton', - component: SplitButton + title: 'Check Ins/SplitButton', + component: SplitButton }; -const Template = (args) => - ; -const options = ['One', 'Two', 'Three'] +const Template = args => ; +const options = ['One', 'Two', 'Three']; export const SplitButtonNoToggle = Template.bind({}); SplitButtonNoToggle.args = { - toggleOnSelect: false, - onClick: (e,index)=>window.alert(`You clicked ${options[index]}`), - options: options + toggleOnSelect: false, + onClick: (e, index) => window.alert(`You clicked ${options[index]}`), + options: options }; export const SplitButtonToggle = Template.bind({}); SplitButtonToggle.args = { - toggleOnSelect: true, - onClick: (e,index)=>window.alert(`You clicked ${options[index]}`), - options: options -}; \ No newline at end of file + toggleOnSelect: true, + onClick: (e, index) => window.alert(`You clicked ${options[index]}`), + options: options +}; diff --git a/web-ui/src/components/split-button/SplitButton.test.jsx b/web-ui/src/components/split-button/SplitButton.test.jsx index a4aad2942b..e54ffc8fb9 100644 --- a/web-ui/src/components/split-button/SplitButton.test.jsx +++ b/web-ui/src/components/split-button/SplitButton.test.jsx @@ -1,9 +1,7 @@ -import React from "react"; -import SplitButton from "./SplitButton"; -import renderer from "react-test-renderer"; +import React from 'react'; +import SplitButton from './SplitButton'; +import renderer from 'react-test-renderer'; -it("renders correctly", () => { - snapshot( - - ); +it('renders correctly', () => { + snapshot(); }); diff --git a/web-ui/src/components/team-member/MemberIcon.jsx b/web-ui/src/components/team-member/MemberIcon.jsx index 6f841a2171..4e7b96e33f 100644 --- a/web-ui/src/components/team-member/MemberIcon.jsx +++ b/web-ui/src/components/team-member/MemberIcon.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import "./TeamMember.css"; +import React from 'react'; +import './TeamMember.css'; -const MemberIcon = (props) => { +const MemberIcon = props => { const { profile, onSelect } = props; const { imageUrl } = profile; - let image = imageUrl ? imageUrl : "/default_profile.jpg"; + let image = imageUrl ? imageUrl : '/default_profile.jpg'; return (
    { +it('renders correctly', () => { snapshot(); }); diff --git a/web-ui/src/components/team-member/TeamMemberContainer.jsx b/web-ui/src/components/team-member/TeamMemberContainer.jsx index 1d285ceaaa..ee9c607242 100644 --- a/web-ui/src/components/team-member/TeamMemberContainer.jsx +++ b/web-ui/src/components/team-member/TeamMemberContainer.jsx @@ -1,10 +1,10 @@ -import React, { useEffect, useContext, useState } from "react"; -import MemberIcon from "./MemberIcon"; -import { AppContext } from "../../context/AppContext"; -import { getMembersByTeam, getTeamsByMember } from "../../api/team"; -import { getMember } from "../../api/member"; +import React, { useEffect, useContext, useState } from 'react'; +import MemberIcon from './MemberIcon'; +import { AppContext } from '../../context/AppContext'; +import { getMembersByTeam, getTeamsByMember } from '../../api/team'; +import { getMember } from '../../api/member'; -import "./TeamMember.css"; +import './TeamMember.css'; const TeamMemberContainer = () => { const { state } = useContext(AppContext); @@ -15,7 +15,7 @@ const TeamMemberContainer = () => { : undefined; const [selectedProfile, setSelectedProfile] = useState({ name: null, - imageUrl: null, + imageUrl: null }); const [teamMembers, setTeamMembers] = useState({}); const [teams, setTeams] = useState([]); @@ -28,7 +28,7 @@ const TeamMemberContainer = () => { pdlId, role, startDate, - workEmail, + workEmail } = selectedProfile; const [pdl, setPDL] = useState(); @@ -40,7 +40,7 @@ const TeamMemberContainer = () => { let res = await getMember(pdlId, csrf); let pdlProfile = res.payload.data && !res.error ? res.payload.data : undefined; - setPDL(pdlProfile ? pdlProfile.name : ""); + setPDL(pdlProfile ? pdlProfile.name : ''); } } if (csrf) { @@ -70,7 +70,7 @@ const TeamMemberContainer = () => { const teamMemberMap = Object.assign( {}, ...(await Promise.all( - teams.map(async (team) => { + teams.map(async team => { let res = await getMembersByTeam(team.uuid, csrf); let data = res && res.payload && res.payload.status === 200 @@ -79,7 +79,7 @@ const TeamMemberContainer = () => { if (data && !res.error) { return { [team.uuid]: await Promise.all( - data.map(async (member) => { + data.map(async member => { let res = await getMember(member.memberid, csrf); let data = res && @@ -90,7 +90,7 @@ const TeamMemberContainer = () => { : null; return data; }) - ), + ) }; } else { return { [team.uuid]: [] }; @@ -106,8 +106,8 @@ const TeamMemberContainer = () => { } }, [csrf, teams]); - let teamProfile = (profiles) => { - let team = profiles.map((profile) => { + let teamProfile = profiles => { + let team = profiles.map(profile => { return ( { }; let team = teamProfile(currentTeam); - const mapTeams = teams.map((team) => { + const mapTeams = teams.map(team => { return (
    {
    {mapTeams}
    {name && ( -
    +
    Profile
    -
    +

    {name}

    -
    -
    +
    +

    Role: {role}

    PDL: {pdl}

    Location: {location}

    - Start Date:{" "} + Start Date:{' '} {startDate && startDate.length === 3 ? new Date( startDate[0], startDate[1] - 1, startDate[2] ).toLocaleDateString() - : ""} + : ''}

    Email: {workEmail}

    Bio: {bioText}

    @@ -171,7 +171,7 @@ const TeamMemberContainer = () => {
    )} -
    +
    {team}
    diff --git a/web-ui/src/components/team-member/TeamMemberContainer.test.jsx b/web-ui/src/components/team-member/TeamMemberContainer.test.jsx index 07c21f0a51..a3c9d94c5b 100644 --- a/web-ui/src/components/team-member/TeamMemberContainer.test.jsx +++ b/web-ui/src/components/team-member/TeamMemberContainer.test.jsx @@ -1,15 +1,15 @@ -import React from "react"; -import TeamMemberContainer from "./TeamMemberContainer"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import TeamMemberContainer from './TeamMemberContainer'; +import { AppContextProvider } from '../../context/AppContext'; const testProfile = [ - { name: "holmes", image_url: "" }, - { name: "homie", image_url: "" }, + { name: 'holmes', image_url: '' }, + { name: 'homie', image_url: '' } ]; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); diff --git a/web-ui/src/components/team-member/TeamMemberSelect.jsx b/web-ui/src/components/team-member/TeamMemberSelect.jsx index fac5272671..e459ee3039 100644 --- a/web-ui/src/components/team-member/TeamMemberSelect.jsx +++ b/web-ui/src/components/team-member/TeamMemberSelect.jsx @@ -1,28 +1,28 @@ -import React, { useState } from "react"; -import Avatar from "@mui/material/Avatar"; +import React, { useState } from 'react'; +import Avatar from '@mui/material/Avatar'; -import "./TeamMemberSelect.css"; +import './TeamMemberSelect.css'; -const TeamMemberSelect = (props) => { +const TeamMemberSelect = props => { const { teamMembers, onChange, singleSelect = false } = props; const [filteredTeamMembers, setFilteredTeamMembers] = useState(teamMembers); - const filterTeamMembers = (e) => { + const filterTeamMembers = e => { let searchInput = e.target.value.toLowerCase(); - let filtered = teamMembers.filter((member) => { + let filtered = teamMembers.filter(member => { return member.name.toLowerCase().includes(searchInput); }); setFilteredTeamMembers(filtered); }; - const selectMultipleTeamMembers = (member) => { + const selectMultipleTeamMembers = member => { member.selected = !member.selected; - onChange(filteredTeamMembers.filter((m) => m.selected)); + onChange(filteredTeamMembers.filter(m => m.selected)); setFilteredTeamMembers([...filteredTeamMembers]); }; - const selectSingleTeamMember = (member) => { - filteredTeamMembers.map((m) => + const selectSingleTeamMember = member => { + filteredTeamMembers.map(m => m.name !== member.name ? (m.selected = false) : null ); member.selected = !member.selected; @@ -30,8 +30,8 @@ const TeamMemberSelect = (props) => { setFilteredTeamMembers([...filteredTeamMembers]); }; - const renderTeamMember = (member) => { - const className = "team-member" + (member.selected ? " selected" : ""); + const renderTeamMember = member => { + const className = 'team-member' + (member.selected ? ' selected' : ''); return (
    { src={ member.image_url ? member.image_url - : "../../images/default_profile.jpg" + : '../../images/default_profile.jpg' } - style={{ marginLeft: "10px" }} + style={{ marginLeft: '10px' }} />
    {member.name}
    @@ -60,7 +60,7 @@ const TeamMemberSelect = (props) => {
    filterTeamMembers(e)} + onChange={e => filterTeamMembers(e)} > {filteredTeamMembers.map(renderTeamMember)}
    diff --git a/web-ui/src/components/team-member/TeamMemberSelect.test.jsx b/web-ui/src/components/team-member/TeamMemberSelect.test.jsx index 6e696435bd..3c8ad36345 100644 --- a/web-ui/src/components/team-member/TeamMemberSelect.test.jsx +++ b/web-ui/src/components/team-member/TeamMemberSelect.test.jsx @@ -1,33 +1,33 @@ -import React from "react"; -import TeamMemberSelect from "./TeamMemberSelect"; -import { render, fireEvent, screen, act } from "@testing-library/react"; +import React from 'react'; +import TeamMemberSelect from './TeamMemberSelect'; +import { render, fireEvent, screen, act } from '@testing-library/react'; let teamMembers; -const handleMemberSelect = (members) => { - console.log("Parent Comp", members); +const handleMemberSelect = members => { + console.log('Parent Comp', members); }; beforeEach(() => { teamMembers = [ - { name: "jesse", image_url: null }, - { name: "mark", image_url: null }, - { name: "michael", image_url: null }, - { name: "mj", image_url: null }, - { name: "kobe", image_url: null }, - { name: "lebron", image_url: null }, + { name: 'jesse', image_url: null }, + { name: 'mark', image_url: null }, + { name: 'michael', image_url: null }, + { name: 'mj', image_url: null }, + { name: 'kobe', image_url: null }, + { name: 'lebron', image_url: null } ]; }); -it("renders correctly", () => { +it('renders correctly', () => { snapshot( ); }); -it("clicks single item", (done) => { - const name = "jesse"; - const handleChange = (teamMembers) => { +it('clicks single item', done => { + const name = 'jesse'; + const handleChange = teamMembers => { expect(teamMembers).toHaveLength(1); expect(teamMembers[0].name === name); }; @@ -43,10 +43,10 @@ it("clicks single item", (done) => { }); }); -it("clicks multiple items", (done) => { - const name1 = "jesse"; - const name2 = "michael"; - const handleChange = (teamMembers) => { +it('clicks multiple items', done => { + const name1 = 'jesse'; + const name2 = 'michael'; + const handleChange = teamMembers => { if (teamMembers.length === 1) { expect(teamMembers[0].name === name1); } else if (teamMembers.length === 2) { diff --git a/web-ui/src/components/team-results/EditTeamModal.css b/web-ui/src/components/team-results/EditTeamModal.css index cdc062e086..62cf9e126d 100644 --- a/web-ui/src/components/team-results/EditTeamModal.css +++ b/web-ui/src/components/team-results/EditTeamModal.css @@ -1,37 +1,37 @@ .EditTeamModal { - position: absolute; - min-width: 400px; - max-width: 600px; - background-color: #FFF; - top: 50%; - left: 50%; - padding: .5rem; - transform: translate(-50%, -50%); - border: 2px solid #FFF; + position: absolute; + min-width: 400px; + max-width: 600px; + background-color: #fff; + top: 50%; + left: 50%; + padding: 0.5rem; + transform: translate(-50%, -50%); + border: 2px solid #fff; } .EditTeamModal h2 { - margin-block-end: 0rem; - margin-left: .5rem; + margin-block-end: 0rem; + margin-left: 0.5rem; } .EditTeamModal-actions { - margin-top: 1rem; - width: calc(100% - 1rem); - display: flex; - flex-direction: row; - justify-content: flex-end; + margin-top: 1rem; + width: calc(100% - 1rem); + display: flex; + flex-direction: row; + justify-content: flex-end; } .EditTeamModal .MuiTextField-root.fullWidth { - width: calc(100% - 1rem); + width: calc(100% - 1rem); } .EditTeamModal .MuiTextField-root.halfWidth { - width: calc(50% - .5rem); + width: calc(50% - 0.5rem); } .EditTeamModal .MuiTextField-root { - margin: .5rem; - width: 25ch; - } \ No newline at end of file + margin: 0.5rem; + width: 25ch; +} diff --git a/web-ui/src/components/team-results/EditTeamModal.jsx b/web-ui/src/components/team-results/EditTeamModal.jsx index d53cd977ad..cb943c9994 100644 --- a/web-ui/src/components/team-results/EditTeamModal.jsx +++ b/web-ui/src/components/team-results/EditTeamModal.jsx @@ -1,16 +1,16 @@ -import React, { useContext, useState, useEffect, useCallback } from "react"; +import React, { useContext, useState, useEffect, useCallback } from 'react'; -import { AppContext } from "../../context/AppContext"; +import { AppContext } from '../../context/AppContext'; import { selectCurrentUser, - selectCurrentMembers, -} from "../../context/selectors"; + selectCurrentMembers +} from '../../context/selectors'; -import { Button } from "@mui/material"; -import Modal from "@mui/material/Modal"; -import TextField from "@mui/material/TextField"; +import { Button } from '@mui/material'; +import Modal from '@mui/material/Modal'; +import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import "./EditTeamModal.css"; +import './EditTeamModal.css'; const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { const { state } = useContext(AppContext); @@ -20,9 +20,13 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { const [teamMemberOptions, setTeamMemberOptions] = useState([]); const teamMembers = team?.teamMembers; - const findExistingMember = useCallback((member) => teamMembers?.find((current) => { - return current.memberId === member.memberId; - }), [teamMembers]); + const findExistingMember = useCallback( + member => + teamMembers?.find(current => { + return current.memberId === member.memberId; + }), + [teamMembers] + ); useEffect(() => { if (open && team.id !== editedTeam.id) setTeam(team); @@ -34,18 +38,23 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { (editedTeam.teamMembers === undefined || editedTeam.teamMembers === null || editedTeam.teamMembers.length === 0 || - editedTeam.teamMembers.filter(member => member.lead === true).length === 0) + editedTeam.teamMembers.filter(member => member.lead === true).length === + 0) ) { - let teamMembers = [{ - id: findExistingMember({memberId: currentUser.id})?.id, - memberId: currentUser.id, - name: `${currentUser.firstName} ${currentUser.lastName}`, - teamId: editedTeam.id, - lead: true - }]; + let teamMembers = [ + { + id: findExistingMember({ memberId: currentUser.id })?.id, + memberId: currentUser.id, + name: `${currentUser.firstName} ${currentUser.lastName}`, + teamId: editedTeam.id, + lead: true + } + ]; // Keep current members if all leads are removed if (editedTeam && editedTeam.teamMembers) { - const extantMembers = editedTeam.teamMembers.filter(member => member.lead === false); + const extantMembers = editedTeam.teamMembers.filter( + member => member.lead === false + ); teamMembers = teamMembers.concat(extantMembers); } @@ -60,19 +69,19 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { useEffect(() => { if (!editedTeam || !editedTeam.teamMembers || !currentMembers) return; let teamMemberNames = editedTeam.teamMembers.map( - (teamMember) => teamMember.name + teamMember => teamMember.name ); setTeamMemberOptions( - currentMembers.filter((member) => !teamMemberNames.includes(member.name)) + currentMembers.filter(member => !teamMemberNames.includes(member.name)) ); }, [currentMembers, editedTeam]); const onLeadsChange = (event, leads) => { let extantMembers = editedTeam && editedTeam.teamMembers - ? editedTeam.teamMembers.filter((teamMember) => !teamMember.lead) + ? editedTeam.teamMembers.filter(teamMember => !teamMember.lead) : []; - leads = leads.map((lead) => ({ + leads = leads.map(lead => ({ id: lead.memberId ? lead.id : undefined, name: lead.name, memberId: lead.memberId ? lead.memberId : lead.id, @@ -80,9 +89,9 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { lead: true })); - leads.forEach((lead) => { + leads.forEach(lead => { extantMembers = extantMembers.filter( - (member) => member.memberId !== lead.memberId + member => member.memberId !== lead.memberId ); }); @@ -91,24 +100,24 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { setTeam({ ...editedTeam, - teamMembers: [...extantMembers, ...leads].map((member) => { - const existing = findExistingMember(member) - if(existing) { - return {...member, id: existing.id} + teamMembers: [...extantMembers, ...leads].map(member => { + const existing = findExistingMember(member); + if (existing) { + return { ...member, id: existing.id }; } else { return member; } - }), + }) }); }; const onTeamMembersChange = (event, regularMembers) => { let extantLeads = editedTeam && editedTeam.teamMembers - ? editedTeam.teamMembers.filter((teamMember) => teamMember.lead) + ? editedTeam.teamMembers.filter(teamMember => teamMember.lead) : []; - regularMembers = regularMembers.map((member) => ({ + regularMembers = regularMembers.map(member => ({ id: member.memberId ? member.id : undefined, name: member.name, memberId: member.memberId ? member.memberId : member.id, @@ -116,9 +125,9 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { lead: false })); - regularMembers.forEach((teamMember) => { + regularMembers.forEach(teamMember => { extantLeads = extantLeads.filter( - (lead) => lead.memberId !== teamMember.memberId + lead => lead.memberId !== teamMember.memberId ); }); @@ -127,23 +136,21 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { setTeam({ ...editedTeam, - teamMembers: [...extantLeads, ...regularMembers].map((member) =>{ + teamMembers: [...extantLeads, ...regularMembers].map(member => { const existing = findExistingMember(member); if (existing) { - return {...member, id: existing.id}; - } - else { + return { ...member, id: existing.id }; + } else { return member; } }) }); }; - const readyToEdit = (team) => { + const readyToEdit = team => { let numLeads = 0; if (team && team.teamMembers) { - numLeads = team.teamMembers.filter((teamMember) => teamMember.lead) - .length; + numLeads = team.teamMembers.filter(teamMember => teamMember.lead).length; } return team.name && numLeads > 0; }; @@ -163,16 +170,16 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { required className="halfWidth" placeholder="Awesome Team" - value={editedTeam.name ? editedTeam.name : ""} - onChange={(e) => setTeam({ ...editedTeam, name: e.target.value })} + value={editedTeam.name ? editedTeam.name : ''} + onChange={e => setTeam({ ...editedTeam, name: e.target.value })} /> + value={editedTeam.description ? editedTeam.description : ''} + onChange={e => setTeam({ ...editedTeam, description: e.target.value }) } /> @@ -186,12 +193,12 @@ const EditTeamModal = ({ team = {}, open, onSave, onClose, headerText }) => { required value={ editedTeam.teamMembers - ? editedTeam.teamMembers.filter((teamMember) => teamMember.lead) + ? editedTeam.teamMembers.filter(teamMember => teamMember.lead) : [] } onChange={onLeadsChange} - getOptionLabel={(member) => member.name} - renderInput={(params) => ( + getOptionLabel={member => member.name} + renderInput={params => ( { options={teamMemberOptions} value={ editedTeam.teamMembers - ? editedTeam.teamMembers.filter((teamMember) => !teamMember.lead) + ? editedTeam.teamMembers.filter(teamMember => !teamMember.lead) : [] } onChange={onTeamMembersChange} - getOptionLabel={(member) => member.name} - renderInput={(params) => ( + getOptionLabel={member => member.name} + renderInput={params => ( { - return HttpResponse.text("O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi"); + return HttpResponse.text('O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi'); }), http.get('http://localhost:8080/services/member-profiles/current', () => { - return HttpResponse.json({ id: "12345", name: "Test User" }); + return HttpResponse.json({ id: '12345', name: 'Test User' }); }), http.get('http://localhost:8080/services/teams/members', () => { - return HttpResponse.json([{ id: "12345", name: "Test User" }]); + return HttpResponse.json([{ id: '12345', name: 'Test User' }]); }) ); @@ -25,100 +25,135 @@ afterEach(() => server.resetHandlers()); afterAll(() => server.close()); const testTeam = { - id: "54345", - name: "Test Team", - description: "A team used for testing.", - teamLeads: [{id:123, name:"Team Leader", lastName:"Leader"}, {id:124, name: "Other Leader", lastName:"OLeader"}], - teamMembers: [{id:125, name:"Team Member", lastName:"Member"}, {id:126, name: "Other Member", lastName:"OMember"}] + id: '54345', + name: 'Test Team', + description: 'A team used for testing.', + teamLeads: [ + { id: 123, name: 'Team Leader', lastName: 'Leader' }, + { id: 124, name: 'Other Leader', lastName: 'OLeader' } + ], + teamMembers: [ + { id: 125, name: 'Team Member', lastName: 'Member' }, + { id: 126, name: 'Other Member', lastName: 'OMember' } + ] }; const emptyTeam = { - id: "64346", - name: "Empty Team", - description: "A empty team used for testing.", -} + id: '64346', + name: 'Empty Team', + description: 'A empty team used for testing.' +}; const currentUserProfile = { id: 9876, pdlId: 8765, - name: "Current User", - firstName: "Current", - lastName: "User", -} + name: 'Current User', + firstName: 'Current', + lastName: 'User' +}; const initialState = { state: { - csrf: "O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi", + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', userProfile: { - name: "Current User", - firstName: "Current", - lastName: "User", - role: ["MEMBER"], + name: 'Current User', + firstName: 'Current', + lastName: 'User', + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", - memberProfile: currentUserProfile, + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg', + memberProfile: currentUserProfile }, checkins: [], guilds: [], teams: [testTeam, emptyTeam], skills: [], - roles:[], + roles: [], userRoles: [], memberSkills: [], index: 0, - memberProfiles: [currentUserProfile, {id:123, name:"Team Leader", lastName: "Leader"}, {id:124, name: "Other Leader", lastName: "OLeader"}, {id:125, name:"Team Member", lastName: "Member"}, {id:126, name: "Other Member", lastName: "OMember"}] + memberProfiles: [ + currentUserProfile, + { id: 123, name: 'Team Leader', lastName: 'Leader' }, + { id: 124, name: 'Other Leader', lastName: 'OLeader' }, + { id: 125, name: 'Team Member', lastName: 'Member' }, + { id: 126, name: 'Other Member', lastName: 'OMember' } + ] } -} - -describe("EditTeamModal", () => { - it("User added as lead when none exists", async () => { - const mockOnSave = vi.fn(); - - render( - - - - ); - - await waitFor(() => screen.getByText(/Edit your team/i)); - - const teamNameInput = screen.getByLabelText(/Team Name/i); - const teamDescriptionInput = screen.getByLabelText(/Description/i); - - const expectedTeam = {...emptyTeam, teamMembers: [{id:undefined, memberId:currentUserProfile.id, name: currentUserProfile.name, teamId: emptyTeam.id, lead: true}]}; - expect(teamNameInput).toHaveValue(emptyTeam.name); - expect(teamDescriptionInput).toHaveValue(emptyTeam.description); +}; - const saveBtn = screen.getByText(/Save Team/i); - // expect(saveBtn).toBeDisabled(); - await userEvent.click(saveBtn); - await waitFor(() => { - expect(mockOnSave).toHaveBeenCalledWith(expectedTeam); - }); +describe('EditTeamModal', () => { + it('User added as lead when none exists', async () => { + const mockOnSave = vi.fn(); + + render( + + + + ); + + await waitFor(() => screen.getByText(/Edit your team/i)); + + const teamNameInput = screen.getByLabelText(/Team Name/i); + const teamDescriptionInput = screen.getByLabelText(/Description/i); + + const expectedTeam = { + ...emptyTeam, + teamMembers: [ + { + id: undefined, + memberId: currentUserProfile.id, + name: currentUserProfile.name, + teamId: emptyTeam.id, + lead: true + } + ] + }; + expect(teamNameInput).toHaveValue(emptyTeam.name); + expect(teamDescriptionInput).toHaveValue(emptyTeam.description); + + const saveBtn = screen.getByText(/Save Team/i); + // expect(saveBtn).toBeDisabled(); + await userEvent.click(saveBtn); + await waitFor(() => { + expect(mockOnSave).toHaveBeenCalledWith(expectedTeam); }); - - it("Can save with lead", async () => { - const mockOnSave = vi.fn(); - - render( - - - - ); - - await waitFor(() => screen.getByText(/Edit your team/i)); - - const teamNameInput = screen.getByLabelText(/Team Name/i); - const teamDescriptionInput = screen.getByLabelText(/Description/i); - - expect(teamNameInput).toHaveValue(testTeam.name); - expect(teamDescriptionInput).toHaveValue(testTeam.description); - - const saveBtn = screen.getByText(/Save Team/i); - expect(saveBtn).toBeEnabled(); - await userEvent.click(saveBtn); - await waitFor(() => { - expect(mockOnSave).toHaveBeenCalled(); - }); + }); + + it('Can save with lead', async () => { + const mockOnSave = vi.fn(); + + render( + + + + ); + + await waitFor(() => screen.getByText(/Edit your team/i)); + + const teamNameInput = screen.getByLabelText(/Team Name/i); + const teamDescriptionInput = screen.getByLabelText(/Description/i); + + expect(teamNameInput).toHaveValue(testTeam.name); + expect(teamDescriptionInput).toHaveValue(testTeam.description); + + const saveBtn = screen.getByText(/Save Team/i); + expect(saveBtn).toBeEnabled(); + await userEvent.click(saveBtn); + await waitFor(() => { + expect(mockOnSave).toHaveBeenCalled(); }); -}); \ No newline at end of file + }); +}); diff --git a/web-ui/src/components/team-results/TeamResults.jsx b/web-ui/src/components/team-results/TeamResults.jsx index 3f041f5f86..4aaec41680 100644 --- a/web-ui/src/components/team-results/TeamResults.jsx +++ b/web-ui/src/components/team-results/TeamResults.jsx @@ -1,13 +1,16 @@ -import React, { useContext, useState} from "react"; +import React, { useContext, useState } from 'react'; import { styled } from '@mui/material/styles'; -import TeamSummaryCard from "./TeamSummaryCard"; -import { AppContext } from "../../context/AppContext"; -import { selectNormalizedTeams, selectTeamsLoading} from "../../context/selectors"; -import TeamsActions from "./TeamsActions"; -import PropTypes from "prop-types"; -import { TextField } from "@mui/material"; -import "./TeamResults.css"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader" +import TeamSummaryCard from './TeamSummaryCard'; +import { AppContext } from '../../context/AppContext'; +import { + selectNormalizedTeams, + selectTeamsLoading +} from '../../context/selectors'; +import TeamsActions from './TeamsActions'; +import PropTypes from 'prop-types'; +import { TextField } from '@mui/material'; +import './TeamResults.css'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; const PREFIX = 'TeamResults'; const classes = { @@ -16,7 +19,7 @@ const classes = { const Root = styled('div')({ [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' } }); @@ -25,30 +28,28 @@ const propTypes = { PropTypes.shape({ id: PropTypes.string, name: PropTypes.string, - description: PropTypes.string, + description: PropTypes.string }) - ), + ) }; -const displayName = "TeamResults"; +const displayName = 'TeamResults'; const TeamResults = () => { const { state } = useContext(AppContext); - const loading = selectTeamsLoading(state) - const [searchText, setSearchText] = useState(""); + const loading = selectTeamsLoading(state); + const [searchText, setSearchText] = useState(''); const teams = selectNormalizedTeams(state, searchText); -const teamCards = teams.map((team, index) => { - return ( - - ); - -}) - + const teamCards = teams.map((team, index) => { + return ( + + ); + }); return ( @@ -58,17 +59,20 @@ const teamCards = teams.map((team, index) => { label="Search teams..." placeholder="Team Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} />
    - { - loading ? Array.from({length: 20}).map((_, index) => ): - teams?.length && !loading ? teamCards : null - } + {loading + ? Array.from({ length: 20 }).map((_, index) => ( + + )) + : teams?.length && !loading + ? teamCards + : null}
    ); diff --git a/web-ui/src/components/team-results/TeamResults.test.jsx b/web-ui/src/components/team-results/TeamResults.test.jsx index 89f9858b48..88b8803a50 100644 --- a/web-ui/src/components/team-results/TeamResults.test.jsx +++ b/web-ui/src/components/team-results/TeamResults.test.jsx @@ -1,40 +1,40 @@ -import React from "react"; -import TeamResults from "./TeamResults"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import TeamResults from './TeamResults'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { loading: { teams: true, - memberProfiles: true, + memberProfiles: true }, userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER", "ADMIN"], + role: ['MEMBER', 'ADMIN'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, teams: [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - }, - ], - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '' + } + ] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( @@ -42,27 +42,26 @@ it("renders correctly", () => { ); }); - -it("renders correctly when no teams are loaded", () => { +it('renders correctly when no teams are loaded', () => { const stateWithoutTeams = { state: { loading: { teams: true, - memberProfiles: true, + memberProfiles: true }, userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER", "ADMIN"], + role: ['MEMBER', 'ADMIN'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, teams: [] - }, + } }; snapshot( diff --git a/web-ui/src/components/team-results/TeamSummaryCard.jsx b/web-ui/src/components/team-results/TeamSummaryCard.jsx index 42be1c9956..06ff4ec5c8 100644 --- a/web-ui/src/components/team-results/TeamSummaryCard.jsx +++ b/web-ui/src/components/team-results/TeamSummaryCard.jsx @@ -1,9 +1,9 @@ -import React, { useContext, useState, useCallback } from "react"; -import { styled } from "@mui/material/styles"; -import { AppContext } from "../../context/AppContext"; -import { UPDATE_TEAMS, UPDATE_TOAST } from "../../context/actions"; -import EditTeamModal from "./EditTeamModal"; -import { Link } from "react-router-dom"; +import React, { useContext, useState, useCallback } from 'react'; +import { styled } from '@mui/material/styles'; +import { AppContext } from '../../context/AppContext'; +import { UPDATE_TEAMS, UPDATE_TOAST } from '../../context/actions'; +import EditTeamModal from './EditTeamModal'; +import { Link } from 'react-router-dom'; import { Button, Card, @@ -15,45 +15,45 @@ import { DialogContent, DialogContentText, DialogTitle, - Tooltip, -} from "@mui/material"; -import PropTypes from "prop-types"; -import { deleteTeam, updateTeam } from "../../api/team.js"; -import SplitButton from "../split-button/SplitButton"; + Tooltip +} from '@mui/material'; +import PropTypes from 'prop-types'; +import { deleteTeam, updateTeam } from '../../api/team.js'; +import SplitButton from '../split-button/SplitButton'; -const PREFIX = "TeamSummaryCard"; +const PREFIX = 'TeamSummaryCard'; const classes = { card: `${PREFIX}-card`, header: `${PREFIX}-header`, - title: `${PREFIX}-title`, + title: `${PREFIX}-title` }; const StyledCard = styled(Card)({ [`&.${classes.card}`]: { - width: "340px", - display: "flex", - flexDirection: "column", - justifyContent: "space-between", + width: '340px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between' }, [`& .${classes.header}`]: { - width: "100%", + width: '100%' }, [`& .${classes.title}`]: { - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - }, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' + } }); const propTypes = { team: PropTypes.shape({ id: PropTypes.string, name: PropTypes.string, - description: PropTypes.string, - }), + description: PropTypes.string + }) }; -const displayName = "TeamSummaryCard"; +const displayName = 'TeamSummaryCard'; const TeamSummaryCard = ({ team, index }) => { const { state, dispatch } = useContext(AppContext); @@ -63,21 +63,21 @@ const TeamSummaryCard = ({ team, index }) => { const [tooltipIsOpen, setTooltipIsOpen] = useState(false); const isAdmin = - userProfile && userProfile.role && userProfile.role.includes("ADMIN"); + userProfile && userProfile.role && userProfile.role.includes('ADMIN'); let leads = team.teamMembers == null ? null - : team.teamMembers.filter((teamMember) => teamMember.lead); + : team.teamMembers.filter(teamMember => teamMember.lead); let nonLeads = team.teamMembers == null ? null - : team.teamMembers.filter((teamMember) => !teamMember.lead); + : team.teamMembers.filter(teamMember => !teamMember.lead); const isTeamLead = leads === null ? false - : leads.some((lead) => lead.memberId === userProfile.memberProfile.id); + : leads.some(lead => lead.memberId === userProfile.memberProfile.id); const handleOpen = () => setOpen(true); const handleOpenDeleteConfirmation = () => setOpenDelete(true); @@ -93,23 +93,23 @@ const TeamSummaryCard = ({ team, index }) => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Team deleted", - }, + severity: 'success', + toast: 'Team deleted' + } }); - let newTeams = teams.filter((team) => { + let newTeams = teams.filter(team => { return team.id !== teamId; }); dispatch({ type: UPDATE_TEAMS, - payload: newTeams, + payload: newTeams }); } } }, [teamId, csrf, dispatch, teams]); const options = - isAdmin || isTeamLead ? ["Edit Team", "Delete Team"] : ["Edit Team"]; + isAdmin || isTeamLead ? ['Edit Team', 'Delete Team'] : ['Edit Team']; const handleAction = (e, index) => { if (index === 0) { @@ -125,7 +125,7 @@ const TeamSummaryCard = ({ team, index }) => { classes={{ content: classes.header, title: classes.title, - subheader: classes.title, + subheader: classes.title }} title={team.name} subheader={ @@ -143,13 +143,13 @@ const TeamSummaryCard = ({ team, index }) => { /> {team.teamMembers == null ? ( - + Team Leads: None Assigned
    Team Members: None Assigned
    ) : ( - + Team Leads: {leads.map((lead, index) => { return ( @@ -157,8 +157,8 @@ const TeamSummaryCard = ({ team, index }) => { key={lead?.memberId} to={`/profile/${lead?.memberId}`} style={{ - textDecoration: "none", - color: "rgba(0, 0, 0, 0.87)", + textDecoration: 'none', + color: 'rgba(0, 0, 0, 0.87)' }} > {index !== leads.length - 1 ? `${lead?.name}, ` : lead?.name} @@ -173,8 +173,8 @@ const TeamSummaryCard = ({ team, index }) => { key={member?.memberId} to={`/profile/${member?.memberId}`} style={{ - textDecoration: "none", - color: "rgba(0, 0, 0, 0.87)", + textDecoration: 'none', + color: 'rgba(0, 0, 0, 0.87)' }} > {index !== nonLeads.length - 1 @@ -218,7 +218,7 @@ const TeamSummaryCard = ({ team, index }) => { team={team} open={open} onClose={handleClose} - onSave={async (editedTeam) => { + onSave={async editedTeam => { const res = await updateTeam(editedTeam, csrf); const data = res.payload && res.payload.data && !res.error @@ -229,7 +229,7 @@ const TeamSummaryCard = ({ team, index }) => { copy[index] = data; dispatch({ type: UPDATE_TEAMS, - payload: copy, + payload: copy }); } }} diff --git a/web-ui/src/components/team-results/TeamSummaryCard.test.jsx b/web-ui/src/components/team-results/TeamSummaryCard.test.jsx index 2ca7f592e6..8945e2957c 100644 --- a/web-ui/src/components/team-results/TeamSummaryCard.test.jsx +++ b/web-ui/src/components/team-results/TeamSummaryCard.test.jsx @@ -1,80 +1,77 @@ -import React from "react"; -import TeamSummaryCard from "./TeamSummaryCard"; -import { AppContextProvider } from "../../context/AppContext"; -import { BrowserRouter } from "react-router-dom"; +import React from 'react'; +import TeamSummaryCard from './TeamSummaryCard'; +import { AppContextProvider } from '../../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; const teams = [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - teamMembers: [{memberid: "3fa4-5717-4562-b3fc-2c963f66afa9", - name: "testname", lead: true}] - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '', + teamMembers: [ + { + memberid: '3fa4-5717-4562-b3fc-2c963f66afa9', + name: 'testname', + lead: true + } + ] + } ]; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - id: "3fa4-5717-4562-b3fc-2c963f66afa9", - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + id: '3fa4-5717-4562-b3fc-2c963f66afa9', + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, - teams, - }, + teams + } }; -const adminState = {...initialState}; -adminState.state = {...adminState.state}; -adminState.state.userProfile = {...adminState.state.userProfile}; -adminState.state.userProfile.role = ["MEMBER", "ADMIN"]; +const adminState = { ...initialState }; +adminState.state = { ...adminState.state }; +adminState.state.userProfile = { ...adminState.state.userProfile }; +adminState.state.userProfile.role = ['MEMBER', 'ADMIN']; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - + ); }); -it("renders correctly for ADMIN", () => { +it('renders correctly for ADMIN', () => { snapshot( - + - ); }); -it("renders correctly for team lead", () => { +it('renders correctly for team lead', () => { snapshot( - - - - - - + + + + + ); }); diff --git a/web-ui/src/components/team-results/TeamsActions.jsx b/web-ui/src/components/team-results/TeamsActions.jsx index 9169439b38..8b21be5650 100644 --- a/web-ui/src/components/team-results/TeamsActions.jsx +++ b/web-ui/src/components/team-results/TeamsActions.jsx @@ -1,21 +1,21 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; -import AddTeamModal from "./EditTeamModal"; -import { createTeam } from "../../api/team"; -import { AppContext } from "../../context/AppContext"; -import { ADD_TEAM } from "../../context/actions"; +import AddTeamModal from './EditTeamModal'; +import { createTeam } from '../../api/team'; +import { AppContext } from '../../context/AppContext'; +import { ADD_TEAM } from '../../context/actions'; -import { Button } from "@mui/material"; -import GroupIcon from "@mui/icons-material/Group"; +import { Button } from '@mui/material'; +import GroupIcon from '@mui/icons-material/Group'; -import "./TeamResults.css"; +import './TeamResults.css'; -const displayName = "TeamsActions"; +const displayName = 'TeamsActions'; const TeamsActions = () => { const { state, dispatch } = useContext(AppContext); const [open, setOpen] = useState(false); - + const { csrf } = state; const handleOpen = () => setOpen(true); @@ -30,7 +30,7 @@ const TeamsActions = () => { { + onSave={async team => { if (csrf) { let res = await createTeam(team, csrf); let data = @@ -43,7 +43,7 @@ const TeamsActions = () => { handleClose(); } }} - headerText='Add A New Team' + headerText="Add A New Team" />
    ); diff --git a/web-ui/src/components/team-results/TeamsActions.test.jsx b/web-ui/src/components/team-results/TeamsActions.test.jsx index aa7c09768c..ce3e7031bb 100644 --- a/web-ui/src/components/team-results/TeamsActions.test.jsx +++ b/web-ui/src/components/team-results/TeamsActions.test.jsx @@ -1,36 +1,36 @@ -import React from "react"; -import TeamsActions from "./TeamsActions"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import TeamsActions from './TeamsActions'; +import { AppContextProvider } from '../../context/AppContext'; const initialState = { state: { userProfile: { - name: "holmes", + name: 'holmes', memberProfile: { - pdlId: "", - title: "Tester", - workEmail: "test@tester.com", + pdlId: '', + title: 'Tester', + workEmail: 'test@tester.com' }, - role: ["MEMBER"], + role: ['MEMBER'], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, teams: [ { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "string", - description: "string", + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + name: 'string', + description: 'string' }, { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - }, - ], - }, + id: '3fa4-5717-4562-b3fc-2c963f66afa6', + name: 'stuff', + description: '' + } + ] + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/components/template-card/TemplateCard.css b/web-ui/src/components/template-card/TemplateCard.css index 76744beb24..b9692828ca 100644 --- a/web-ui/src/components/template-card/TemplateCard.css +++ b/web-ui/src/components/template-card/TemplateCard.css @@ -5,7 +5,7 @@ padding: 15px; margin: 20px; box-shadow: #282c34; - font-family: "Roboto", "Helvetica", "Arial", sans-serif; + font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; } .card-actions { @@ -44,7 +44,7 @@ margin: 0; } -@media(min-width: 321px) and (max-width: 820px) { +@media (min-width: 321px) and (max-width: 820px) { .feedback-template-card { width: 100%; padding: 0px; @@ -68,9 +68,4 @@ .feedback-template-card .creator { margin-top: 10px; } - } - - - - diff --git a/web-ui/src/components/template-card/TemplateCard.jsx b/web-ui/src/components/template-card/TemplateCard.jsx index 1282339cb5..da38eeaa62 100644 --- a/web-ui/src/components/template-card/TemplateCard.jsx +++ b/web-ui/src/components/template-card/TemplateCard.jsx @@ -1,119 +1,123 @@ -import "./TemplateCard.css"; -import React, {useContext, useEffect, useState} from "react"; +import './TemplateCard.css'; +import React, { useContext, useEffect, useState } from 'react'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; -import PropTypes from "prop-types"; +import PropTypes from 'prop-types'; import IconButton from '@mui/material/IconButton'; import VisibilityIcon from '@mui/icons-material/Visibility'; -import "./TemplateCard.css" +import './TemplateCard.css'; import withStyles from '@mui/styles/withStyles'; -import CheckCircleIcon from "@mui/icons-material/CheckCircle"; -import {green} from "@mui/material/colors"; -import {CardHeader} from "@mui/material"; -import {AppContext} from "../../context/AppContext"; -import {selectCsrfToken} from "../../context/selectors"; -import {getMember} from "../../api/member"; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import { green } from '@mui/material/colors'; +import { CardHeader } from '@mui/material'; +import { AppContext } from '../../context/AppContext'; +import { selectCsrfToken } from '../../context/selectors'; +import { getMember } from '../../api/member'; const cutText = (text, maxCharacters) => { - if (!text) { - text = ""; - } - let shortenedText = text; - if (text.length > maxCharacters) { - shortenedText = `${text.substring(0, maxCharacters)}...`; - } - return shortenedText; -} + if (!text) { + text = ''; + } + let shortenedText = text; + if (text.length > maxCharacters) { + shortenedText = `${text.substring(0, maxCharacters)}...`; + } + return shortenedText; +}; const templateCardHeaderStyles = ({ palette, breakpoints }) => { - const space = 8; - return { - root: { - minWidth: 256, - }, - header: { - padding: `1px ${space}px 0`, - display: 'flex', - alignItems: 'center', - flexDirection: 'row', - justifyContent: 'space-between', - maxHeight: '30px', - }, - }; + const space = 8; + return { + root: { + minWidth: 256 + }, + header: { + padding: `1px ${space}px 0`, + display: 'flex', + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'space-between', + maxHeight: '30px' + } + }; }; const TemplateCardHeader = withStyles(templateCardHeaderStyles, { - name: 'TemplateCardHeader', + name: 'TemplateCardHeader' })(({ classes, selected, allowPreview = false, onPreview }) => ( -
    -
    - {allowPreview && - - - - } - {selected && (checkmark-image)} -
    +
    +
    + {allowPreview && ( + + + + )} + {selected && ( + + checkmark-image + + )}
    +
    )); const propTypes = { - title: PropTypes.string.isRequired, - description: PropTypes.string, - creatorId: PropTypes.string.isRequired, - isAdHoc: PropTypes.bool, - onPreviewClick: PropTypes.func, - onCardClick: PropTypes.func -} - -const TemplateCard = (props) => { + title: PropTypes.string.isRequired, + description: PropTypes.string, + creatorId: PropTypes.string.isRequired, + isAdHoc: PropTypes.bool, + onPreviewClick: PropTypes.func, + onCardClick: PropTypes.func +}; - const { state } = useContext(AppContext); - const csrf = selectCsrfToken(state); - const [creatorName, setCreatorName] = useState(""); +const TemplateCard = props => { + const { state } = useContext(AppContext); + const csrf = selectCsrfToken(state); + const [creatorName, setCreatorName] = useState(''); + const handlePreviewClick = e => { + e.stopPropagation(); + props.onPreviewClick(e); + }; - const handlePreviewClick = (e) => { - e.stopPropagation(); - props.onPreviewClick(e); + // Get name of the template creator + useEffect(() => { + async function getCreatorName() { + if (props.creatorId) { + let res = await getMember(props.creatorId, csrf); + let creatorProfile = + res.payload && res.payload.data && !res.error + ? res.payload.data + : null; + setCreatorName(creatorProfile ? creatorProfile.name : ''); + } } + if (csrf) { + getCreatorName(); + } + }, [props.creatorId, csrf]); - // Get name of the template creator - useEffect(() => { - async function getCreatorName() { - if (props.creatorId) { - let res = await getMember(props.creatorId, csrf); - let creatorProfile = - res.payload && res.payload.data && !res.error - ? res.payload.data - : null - setCreatorName(creatorProfile ? creatorProfile.name : ""); - } - } - if (csrf) { - getCreatorName(); - } - }, [props.creatorId, csrf]); - - return ( - - - -
    -

    {cutText(props.title, 20)}

    -

    {cutText(props.description, 90)}

    -
    -

    Created by: {creatorName}

    -
    -
    - ); - + return ( + + + +
    +

    {cutText(props.title, 20)}

    +

    {cutText(props.description, 90)}

    +
    +

    + Created by: {creatorName} +

    +
    +
    + ); }; TemplateCard.propTypes = propTypes; -export default TemplateCard; \ No newline at end of file +export default TemplateCard; diff --git a/web-ui/src/components/template-card/TemplateCard.stories.jsx b/web-ui/src/components/template-card/TemplateCard.stories.jsx index 1e01262d4f..3b92fa02ec 100644 --- a/web-ui/src/components/template-card/TemplateCard.stories.jsx +++ b/web-ui/src/components/template-card/TemplateCard.stories.jsx @@ -1,19 +1,28 @@ -import React from "react"; -import TemplateCard from "./TemplateCard"; +import React from 'react'; +import TemplateCard from './TemplateCard'; export default { - title: "Check Ins/TemplateCard", - component: TemplateCard, + title: 'Check Ins/TemplateCard', + component: TemplateCard }; -const Template = (args) => ; +const Template = args => ; export const DefaultTemplate = Template.bind({}); DefaultTemplate.args = {}; export const PeerFeedbackTemplate = Template.bind({}); PeerFeedbackTemplate.args = { - templateName: "Peer Feedback", - description: "A simple feedback template", - creator: "Bob Jones", - questions: ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8"] + templateName: 'Peer Feedback', + description: 'A simple feedback template', + creator: 'Bob Jones', + questions: [ + 'Test 1', + 'Test 2', + 'Test 3', + 'Test 4', + 'Test 5', + 'Test 6', + 'Test 7', + 'Test 8' + ] }; diff --git a/web-ui/src/components/template-card/TemplateCard.test.jsx b/web-ui/src/components/template-card/TemplateCard.test.jsx index ead2943439..51aaf357b3 100644 --- a/web-ui/src/components/template-card/TemplateCard.test.jsx +++ b/web-ui/src/components/template-card/TemplateCard.test.jsx @@ -1,15 +1,15 @@ -import React from "react"; -import TemplateCard from "./TemplateCard"; -import { AppContextProvider } from "../../context/AppContext"; +import React from 'react'; +import TemplateCard from './TemplateCard'; +import { AppContextProvider } from '../../context/AppContext'; -it("renders correctly", () => { - snapshot( - - - - ); -}); \ No newline at end of file +it('renders correctly', () => { + snapshot( + + + + ); +}); diff --git a/web-ui/src/components/template-preview-modal/TemplatePreviewModal.css b/web-ui/src/components/template-preview-modal/TemplatePreviewModal.css index 5abe725fb4..657a8b291d 100644 --- a/web-ui/src/components/template-preview-modal/TemplatePreviewModal.css +++ b/web-ui/src/components/template-preview-modal/TemplatePreviewModal.css @@ -1,15 +1,15 @@ .ad-hoc-next-button { - background-color: white; - color: #3f51b5; - text-decoration: none; + background-color: white; + color: #3f51b5; + text-decoration: none; } .preview-modal-content { - margin: 30px; + margin: 30px; } .preview-modal-content .template-details-container { - display: flex; - flex-direction: row; - align-items: center; -} \ No newline at end of file + display: flex; + flex-direction: row; + align-items: center; +} diff --git a/web-ui/src/components/template-preview-modal/TemplatePreviewModal.jsx b/web-ui/src/components/template-preview-modal/TemplatePreviewModal.jsx index 4b84ebd0a3..649327dc5c 100644 --- a/web-ui/src/components/template-preview-modal/TemplatePreviewModal.jsx +++ b/web-ui/src/components/template-preview-modal/TemplatePreviewModal.jsx @@ -1,4 +1,4 @@ -import React, {useState, useEffect, useContext} from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { styled } from '@mui/material/styles'; import Dialog from '@mui/material/Dialog'; import AppBar from '@mui/material/AppBar'; @@ -7,19 +7,23 @@ import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import CloseIcon from '@mui/icons-material/Close'; import Slide from '@mui/material/Slide'; -import List from "@mui/material/List"; -import ListItem from "@mui/material/ListItem"; -import ListItemText from "@mui/material/ListItemText"; -import Button from "@mui/material/Button" -import "./TemplatePreviewModal.css"; -import AdHocCreationForm from "./ad_hoc_creation_form/AdHocCreationForm"; -import PropTypes from "prop-types"; -import {getQuestionsOnTemplate} from "../../api/feedbacktemplate"; -import {AppContext} from "../../context/AppContext"; -import {selectCsrfToken, selectCurrentUser, selectProfile} from "../../context/selectors"; -import {ListItemAvatar, Tooltip} from "@mui/material"; -import Avatar from "@mui/material/Avatar"; -import {Group as GroupIcon, Person as PersonIcon} from "@mui/icons-material"; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import Button from '@mui/material/Button'; +import './TemplatePreviewModal.css'; +import AdHocCreationForm from './ad_hoc_creation_form/AdHocCreationForm'; +import PropTypes from 'prop-types'; +import { getQuestionsOnTemplate } from '../../api/feedbacktemplate'; +import { AppContext } from '../../context/AppContext'; +import { + selectCsrfToken, + selectCurrentUser, + selectProfile +} from '../../context/selectors'; +import { ListItemAvatar, Tooltip } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import { Group as GroupIcon, Person as PersonIcon } from '@mui/icons-material'; const PREFIX = 'TemplatePreviewModal'; const classes = { @@ -32,23 +36,23 @@ const classes = { questionListItem: `${PREFIX}-questionListItem` }; -const StyledDialog = styled(Dialog)(({theme}) => ({ +const StyledDialog = styled(Dialog)(({ theme }) => ({ [`& .${classes.appBar}`]: { - position: 'relative', + position: 'relative' }, [`& .${classes.title}`]: { marginLeft: theme.spacing(2), - flex: 1, + flex: 1 }, [`& .${classes.questionNumber}`]: { - width: "2em", - height: "2em", - fontSize: "1em", - color: "white", + width: '2em', + height: '2em', + fontSize: '1em', + color: 'white', backgroundColor: theme.palette.primary.main }, [`& .${classes.questionListItem}`]: { - padding: "1.5em 1.5em" + padding: '1.5em 1.5em' } })); @@ -62,9 +66,15 @@ const propTypes = { onClose: PropTypes.func, template: PropTypes.object, createAdHoc: PropTypes.bool -} +}; -const TemplatePreviewModal = ({ open, onSubmit, onClose, template, createAdHoc }) => { +const TemplatePreviewModal = ({ + open, + onSubmit, + onClose, + template, + createAdHoc +}) => { const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); const currentUserId = selectCurrentUser(state)?.id; @@ -91,15 +101,14 @@ const TemplatePreviewModal = ({ open, onSubmit, onClose, template, createAdHoc } } } if (template && template.id) { - getTemplateQuestions(template.id, csrf).then((questionsList) => { + getTemplateQuestions(template.id, csrf).then(questionsList => { setTemplateQuestions(questionsList); }); } - }, [csrf, currentUserId, template]); const submitPreview = () => { - const submittedTemplate = {...template}; + const submittedTemplate = { ...template }; let submittedQuestion = null; if (createAdHoc) { submittedTemplate.title = newAdHocData.title; @@ -110,7 +119,13 @@ const TemplatePreviewModal = ({ open, onSubmit, onClose, template, createAdHoc } }; return ( - + + size="large" + > - {createAdHoc ? "New Ad-Hoc Template" : template.title} + {createAdHoc ? 'New Ad-Hoc Template' : template.title} -
    - {createAdHoc ? - setNewAdHocData(form)}/> : - - {template?.description} -
    - - Created by {creatorName} - - {template?.isPublic - ? - : - } -
    - {templateQuestions && templateQuestions.length === 0 && - - This template has no questions - - } - - {templateQuestions && templateQuestions.map((templateQuestion) => ( - - {templateQuestion?.inputType} - - } - > - - - {templateQuestion?.questionNumber} - - - - - ))} - -
    - } + {createAdHoc ? ( + setNewAdHocData(form)} /> + ) : ( + + {template?.description} +
    + + Created by {creatorName} + + {template?.isPublic ? ( + + + + ) : ( + + + + )} +
    + {templateQuestions && templateQuestions.length === 0 && ( + + This template has no questions + + )} + + {templateQuestions && + templateQuestions.map(templateQuestion => ( + + {templateQuestion?.inputType} + + } + > + + + {templateQuestion?.questionNumber} + + + + + ))} + +
    + )}
    ); -} +}; TemplatePreviewModal.propTypes = propTypes; -export default TemplatePreviewModal; \ No newline at end of file +export default TemplatePreviewModal; diff --git a/web-ui/src/components/template-preview-modal/ad_hoc_creation_form/AdHocCreationForm.jsx b/web-ui/src/components/template-preview-modal/ad_hoc_creation_form/AdHocCreationForm.jsx index 94bc1d4894..8437da6f0b 100644 --- a/web-ui/src/components/template-preview-modal/ad_hoc_creation_form/AdHocCreationForm.jsx +++ b/web-ui/src/components/template-preview-modal/ad_hoc_creation_form/AdHocCreationForm.jsx @@ -1,15 +1,14 @@ -import React, {useEffect, useState} from "react"; -import {TextField} from "@mui/material"; -import PropTypes from "prop-types"; +import React, { useEffect, useState } from 'react'; +import { TextField } from '@mui/material'; +import PropTypes from 'prop-types'; const propTypes = { onFormChange: PropTypes.func -} +}; -const AdHocCreationForm = (props) => { - - const [title, setTitle] = useState("Ad Hoc"); - const [description, setDescription] = useState(""); - const [question, setQuestion] = useState(""); +const AdHocCreationForm = props => { + const [title, setTitle] = useState('Ad Hoc'); + const [description, setDescription] = useState(''); + const [question, setQuestion] = useState(''); useEffect(() => { props.onFormChange({ @@ -28,18 +27,20 @@ const AdHocCreationForm = (props) => { margin="normal" required={true} value={title} - onChange={(event) => { + onChange={event => { setTitle(event.target.value); - }}/> + }} + /> { + onChange={event => { setDescription(event.target.value); - }}/> + }} + /> { margin="normal" required={true} value={question} - onChange={(event) => { + onChange={event => { setQuestion(event.target.value); - }}/> + }} + /> ); -} +}; AdHocCreationForm.propTypes = propTypes; -export default AdHocCreationForm; \ No newline at end of file +export default AdHocCreationForm; diff --git a/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.css b/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.css index c203c82859..6b0870be1e 100644 --- a/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.css +++ b/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.css @@ -1,51 +1,51 @@ .view-feedback-responses-page { - margin-top: 8vh; - margin-left: 3em; - margin-right: 3em; + margin-top: 8vh; + margin-left: 3em; + margin-right: 3em; } @media print { - .view-feedback-responses-page { - margin-left: 1em; - margin-right: 1em; - } + .view-feedback-responses-page { + margin-left: 1em; + margin-right: 1em; + } } .view-feedback-responses-page .responses-filter-container { - display: flex; - flex-direction: row; - align-items: flex-end; - margin-bottom: 3em; - height: 100px; + display: flex; + flex-direction: row; + align-items: flex-end; + margin-bottom: 3em; + height: 100px; } .view-feedback-responses-page .no-responses-found { - background-color: #e5e5e5; - text-align: center; - border-radius: 4px; - padding: 10px; + background-color: #e5e5e5; + text-align: center; + border-radius: 4px; + padding: 10px; } .question-responses-container { - display: flex; - flex-direction: column; - margin-bottom: 2em; + display: flex; + flex-direction: column; + margin-bottom: 2em; } .feedback-response-card { - margin-bottom: 16px; + margin-bottom: 16px; } @media screen and (max-width: 800px) { - .view-feedback-responses-page { - margin-left: 1em; - margin-right: 1em; - } + .view-feedback-responses-page { + margin-left: 1em; + margin-right: 1em; + } - .view-feedback-responses-page .responses-filter-container { - flex-direction: column; - align-items: center; - height: 200px; - margin-bottom: 2em; - } + .view-feedback-responses-page .responses-filter-container { + flex-direction: column; + align-items: center; + height: 200px; + margin-bottom: 2em; + } } diff --git a/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.jsx b/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.jsx index 57b5eec74a..24f2f7bf48 100644 --- a/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.jsx +++ b/web-ui/src/components/view_feedback_responses/ViewFeedbackResponses.jsx @@ -1,62 +1,64 @@ -import React, { useContext, useEffect, useState } from "react"; -import { styled } from "@mui/material/styles"; -import { Avatar, Checkbox, Chip, TextField, Typography } from "@mui/material"; -import "./ViewFeedbackResponses.css"; -import FeedbackResponseCard from "./feedback_response_card/FeedbackResponseCard"; -import { getQuestionsAndAnswers } from "../../api/feedbackanswer"; -import { getFeedbackRequestById } from "../../api/feedback"; -import queryString from "query-string"; -import { useLocation } from "react-router-dom"; -import { AppContext } from "../../context/AppContext"; -import { selectCsrfToken, selectProfile } from "../../context/selectors"; -import { UPDATE_TOAST } from "../../context/actions"; -import InputAdornment from "@mui/material/InputAdornment"; -import {Search as SearchIcon } from "@mui/icons-material"; -import { Autocomplete } from "@mui/material"; -import { getAvatarURL } from "../../api/api"; -import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; -import CheckBoxIcon from "@mui/icons-material/CheckBox"; -import SkeletonLoader from "../skeleton_loader/SkeletonLoader"; -import { Button } from "@mui/material"; +import React, { useContext, useEffect, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import { Avatar, Checkbox, Chip, TextField, Typography } from '@mui/material'; +import './ViewFeedbackResponses.css'; +import FeedbackResponseCard from './feedback_response_card/FeedbackResponseCard'; +import { getQuestionsAndAnswers } from '../../api/feedbackanswer'; +import { getFeedbackRequestById } from '../../api/feedback'; +import queryString from 'query-string'; +import { useLocation } from 'react-router-dom'; +import { AppContext } from '../../context/AppContext'; +import { selectCsrfToken, selectProfile } from '../../context/selectors'; +import { UPDATE_TOAST } from '../../context/actions'; +import InputAdornment from '@mui/material/InputAdornment'; +import { Search as SearchIcon } from '@mui/icons-material'; +import { Autocomplete } from '@mui/material'; +import { getAvatarURL } from '../../api/api'; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import SkeletonLoader from '../skeleton_loader/SkeletonLoader'; +import { Button } from '@mui/material'; -const PREFIX = "MuiCardContent"; +const PREFIX = 'MuiCardContent'; const classes = { root: `${PREFIX}-root`, notFoundMessage: `${PREFIX}-notFoundMessage`, popupIndicator: `${PREFIX}-popupIndicator`, searchField: `${PREFIX}-searchField`, - responderField: `${PREFIX}-responderField`, + responderField: `${PREFIX}-responderField` }; -const Root = styled("div")({ +const Root = styled('div')({ [`&.${classes.root}`]: { - ":last-child": { - paddingBottom: "16px", - }, + ':last-child': { + paddingBottom: '16px' + } }, [`& .${classes.notFoundMessage}`]: { - color: "gray", - marginTop: "3em", - textAlign: "center", + color: 'gray', + marginTop: '3em', + textAlign: 'center' }, [`& .${classes.popupIndicator}`]: { - transform: "none", + transform: 'none' }, [`& .${classes.searchField}`]: { - marginRight: "3em", - width: "350px", - ["@media (max-width: 800px)"]: {// eslint-disable-line no-useless-computed-key + marginRight: '3em', + width: '350px', + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key marginRight: 0, - width: "100%", - }, + width: '100%' + } }, [`& .${classes.responderField}`]: { - minWidth: "500px", - ["@media (max-width: 800px)"]: {// eslint-disable-line no-useless-computed-key + minWidth: '500px', + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key minWidth: 0, - width: "100%", - }, - }, + width: '100%' + } + } }); const ViewFeedbackResponses = () => { @@ -66,13 +68,11 @@ const ViewFeedbackResponses = () => { const [query, setQuery] = useState({}); const [questionsAndAnswers, setQuestionsAndAnswers] = useState([]); const [requestInfo, setRequestInfo] = useState({}); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [responderOptions, setResponderOptions] = useState([]); const [selectedResponders, setSelectedResponders] = useState([]); - const [ - filteredQuestionsAndAnswers, - setFilteredQuestionsAndAnswers, - ] = useState([]); + const [filteredQuestionsAndAnswers, setFilteredQuestionsAndAnswers] = + useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { @@ -103,20 +103,20 @@ const ViewFeedbackResponses = () => { return await getFeedbackRequestById(requestId, cookie); } - retrieveRequestInfo(query.request, csrf).then((res) => { + retrieveRequestInfo(query.request, csrf).then(res => { if (res && res.payload && res.payload.data && !res.error) { setRequestInfo(res.payload.data); } else { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to retrieve request information", - }, + severity: 'error', + toast: 'Failed to retrieve request information' + } }); } }); - retrieveQuestionsAndAnswers(query.request, csrf).then((res) => { + retrieveQuestionsAndAnswers(query.request, csrf).then(res => { if (res) { res.sort((a, b) => a.questionNumber - b.questionNumber); setQuestionsAndAnswers(res); @@ -124,9 +124,9 @@ const ViewFeedbackResponses = () => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to retrieve questions and answers", - }, + severity: 'error', + toast: 'Failed to retrieve questions and answers' + } }); } }); @@ -136,7 +136,7 @@ const ViewFeedbackResponses = () => { useEffect(() => { let allResponders = []; questionsAndAnswers.forEach(({ answers }) => { - const responders = answers.map((answer) => answer.responder); + const responders = answers.map(answer => answer.responder); allResponders.push(...responders); }); allResponders = [...new Set(allResponders)]; // Remove duplicate responders @@ -151,15 +151,17 @@ const ViewFeedbackResponses = () => { useEffect(() => { let responsesToDisplay = [...questionsAndAnswers]; - responsesToDisplay = responsesToDisplay.map((response) => { + responsesToDisplay = responsesToDisplay.map(response => { // Filter based on selected responders - let filteredAnswers = response.answers.filter((answer) => + let filteredAnswers = response.answers.filter(answer => selectedResponders.includes(answer.responder) ); if (searchText.trim()) { // Filter based on search text - filteredAnswers = filteredAnswers.filter(({ answer }) => - answer && answer.toLowerCase().includes(searchText.trim().toLowerCase()) + filteredAnswers = filteredAnswers.filter( + ({ answer }) => + answer && + answer.toLowerCase().includes(searchText.trim().toLowerCase()) ); } return { ...response, answers: filteredAnswers }; @@ -176,17 +178,17 @@ const ViewFeedbackResponses = () => { const handleReset = () => { setSelectedResponders(responderOptions); - } + }; return ( - View Feedback for{" "} - {selectProfile(state, requestInfo?.requesteeId)?.name}{" "} + View Feedback for{' '} + {selectProfile(state, requestInfo?.requesteeId)?.name}{' '}
    @@ -196,13 +198,13 @@ const ViewFeedbackResponses = () => { placeholder="Enter a keyword or phrase" helperText=" " value={searchText} - onChange={(event) => setSearchText(event.target.value)} + onChange={event => setSearchText(event.target.value)} InputProps={{ endAdornment: ( - + - ), + ) }} /> { className={classes.responderField} disableCloseOnSelect options={responderOptions} - getOptionLabel={(option) => { + getOptionLabel={option => { return selectProfile(state, option)?.name; }} value={selectedResponders} @@ -226,7 +228,7 @@ const ViewFeedbackResponses = () => { {selectProfile(state, option)?.name} )} - renderInput={(params) => ( + renderInput={params => ( { helperText={`Showing responses from ${ selectedResponders.length }/${responderOptions.length} recipient${ - responderOptions.length === 1 ? "" : "s" + responderOptions.length === 1 ? '' : 's' }`} /> )} @@ -260,10 +262,10 @@ const ViewFeedbackResponses = () => { />
    ); }; diff --git a/web-ui/src/pages/BirthdayAnniversaryReportPage.css b/web-ui/src/pages/BirthdayAnniversaryReportPage.css index aba0ef1e74..5e40155dc2 100644 --- a/web-ui/src/pages/BirthdayAnniversaryReportPage.css +++ b/web-ui/src/pages/BirthdayAnniversaryReportPage.css @@ -40,6 +40,6 @@ } .results-section { - align-items: center; - justify-content: space-between; -} \ No newline at end of file + align-items: center; + justify-content: space-between; +} diff --git a/web-ui/src/pages/CheckinsPage.css b/web-ui/src/pages/CheckinsPage.css index 1b787cfdef..cadd5e5cb5 100644 --- a/web-ui/src/pages/CheckinsPage.css +++ b/web-ui/src/pages/CheckinsPage.css @@ -1,4 +1,3 @@ - .modal-container { display: flex; flex-direction: column; diff --git a/web-ui/src/pages/CheckinsPage.jsx b/web-ui/src/pages/CheckinsPage.jsx index d70da97304..03e6816d6c 100644 --- a/web-ui/src/pages/CheckinsPage.jsx +++ b/web-ui/src/pages/CheckinsPage.jsx @@ -1,9 +1,9 @@ -import React, { useContext, useEffect, useState } from "react"; -import {styled} from '@mui/material/styles'; -import { useParams, useHistory } from "react-router-dom"; -import ActionItemsPanel from "../components/action_item/ActionItemsPanel"; -import AgendaItems from "../components/agenda/Agenda"; -import { AppContext } from "../context/AppContext"; +import React, { useContext, useEffect, useState } from 'react'; +import { styled } from '@mui/material/styles'; +import { useParams, useHistory } from 'react-router-dom'; +import ActionItemsPanel from '../components/action_item/ActionItemsPanel'; +import AgendaItems from '../components/agenda/Agenda'; +import { AppContext } from '../context/AppContext'; import { selectMostRecentCheckin, selectCurrentUser, @@ -12,23 +12,23 @@ import { selectCsrfToken, selectCheckin, selectProfile, - selectCheckinsForMember, -} from "../context/selectors"; -import { getCheckins, createNewCheckin } from "../context/thunks"; -import { UPDATE_CHECKIN, UPDATE_TOAST } from "../context/actions"; -import CheckinDocs from "../components/checkin/documents/CheckinDocs"; -import CheckinsHistory from "../components/checkin/CheckinHistory"; -import Profile from "../components/profile/Profile"; -import GuidesPanel from "../components/guides/GuidesPanel"; -import PDLGuidesPanel from "../components/guides/PDLGuidesPanel"; -import Note from "../components/notes/Note"; -import PrivateNote from "../components/private-note/PrivateNote"; -import Personnel from "../components/personnel/Personnel"; -import { Button, Grid, Modal, Tooltip } from "@mui/material"; -import CheckCircleIcon from "@mui/icons-material/CheckCircle"; - -import "./CheckinsPage.css"; -import { updateCheckin } from "../api/checkins"; + selectCheckinsForMember +} from '../context/selectors'; +import { getCheckins, createNewCheckin } from '../context/thunks'; +import { UPDATE_CHECKIN, UPDATE_TOAST } from '../context/actions'; +import CheckinDocs from '../components/checkin/documents/CheckinDocs'; +import CheckinsHistory from '../components/checkin/CheckinHistory'; +import Profile from '../components/profile/Profile'; +import GuidesPanel from '../components/guides/GuidesPanel'; +import PDLGuidesPanel from '../components/guides/PDLGuidesPanel'; +import Note from '../components/notes/Note'; +import PrivateNote from '../components/private-note/PrivateNote'; +import Personnel from '../components/personnel/Personnel'; +import { Button, Grid, Modal, Tooltip } from '@mui/material'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; + +import './CheckinsPage.css'; +import { updateCheckin } from '../api/checkins'; const PREFIX = 'CheckinsPage'; const classes = { @@ -39,17 +39,17 @@ const classes = { const Root = styled('div')(() => ({ [`&.${classes.root}`]: { - padding: '12px', + padding: '12px' }, [`& .${classes.navigate}`]: { - display: "flex", - flexDirection: "row", - justifyContent: "space-between", - alignItems: "baseline", + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'baseline' }, [`& .${classes.addButton}`]: { - height: "3em", - }, + height: '3em' + } })); const CheckinsPage = () => { @@ -68,7 +68,7 @@ const CheckinsPage = () => { state, selectedProfile ? selectedProfile.id : currentUserId ); - const hasOpenCheckins = memberCheckins.some((checkin) => !checkin.completed); + const hasOpenCheckins = memberCheckins.some(checkin => !checkin.completed); const [tooltipIsOpen, setTooltipIsOpen] = useState(false); useEffect(() => { @@ -115,9 +115,9 @@ const CheckinsPage = () => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "You must have an assigned PDL in order to create a Check In", - }, + severity: 'error', + toast: 'You must have an assigned PDL in order to create a Check In' + } }); return; } @@ -126,7 +126,7 @@ const CheckinsPage = () => { }; return ( - + { enterTouchDelay={0} placement="top-start" title={ - "This is disabled because there is already an open Check-In" + 'This is disabled because there is already an open Check-In' } >
    { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/CheckinsReportPage.jsx b/web-ui/src/pages/CheckinsReportPage.jsx index b095a56dc1..978f4c696d 100644 --- a/web-ui/src/pages/CheckinsReportPage.jsx +++ b/web-ui/src/pages/CheckinsReportPage.jsx @@ -1,27 +1,27 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; -import { AppContext } from "../context/AppContext"; -import CheckinReport from "../components/reports-section/CheckinReport"; +import { AppContext } from '../context/AppContext'; +import CheckinReport from '../components/reports-section/CheckinReport'; import { selectCheckinPDLS, - selectTeamMembersWithCheckinPDL, -} from "../context/selectors"; + selectTeamMembersWithCheckinPDL +} from '../context/selectors'; -import { TextField } from "@mui/material"; +import { TextField } from '@mui/material'; import Autocomplete from '@mui/material/Autocomplete'; -import "./CheckinsReportPage.css"; +import './CheckinsReportPage.css'; const CheckinsReportPage = () => { const { state } = useContext(AppContext); const [selectedPdls, setSelectedPdls] = useState([]); const [planned, setPlanned] = useState(false); const [closed, setClosed] = useState(false); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const pdls = selectCheckinPDLS(state, closed, planned).sort((a, b) => { - const aPieces = a.name.split(" ").slice(-1); - const bPieces = b.name.split(" ").slice(-1); + const aPieces = a.name.split(' ').slice(-1); + const bPieces = b.name.split(' ').slice(-1); return aPieces.toString().localeCompare(bPieces); }); const [filteredPdls, setFilteredPdls] = useState(pdls); @@ -29,12 +29,12 @@ const CheckinsReportPage = () => { useEffect(() => { if (!pdls) return; pdls.map( - (pdl) => (pdl.members = selectTeamMembersWithCheckinPDL(state, pdl.id)) + pdl => (pdl.members = selectTeamMembersWithCheckinPDL(state, pdl.id)) ); - let newPdlList = pdls.filter((pdl) => { + let newPdlList = pdls.filter(pdl => { pdl.members = pdl.members && - pdl.members.filter((member) => + pdl.members.filter(member => member?.name?.toLowerCase().includes(searchText.toLowerCase()) ); return pdl.members.length > 0; @@ -45,8 +45,8 @@ const CheckinsReportPage = () => { const onPdlChange = (event, newValue) => { let extantPdls = filteredPdls || []; - newValue.forEach((val) => { - extantPdls = extantPdls.filter((pdl) => pdl.id !== val.id); + newValue.forEach(val => { + extantPdls = extantPdls.filter(pdl => pdl.id !== val.id); }); extantPdls = [...new Set(extantPdls)]; newValue = [...new Set(newValue)]; @@ -76,8 +76,8 @@ const CheckinsReportPage = () => { options={pdls} value={selectedPdls || []} onChange={onPdlChange} - getOptionLabel={(option) => option.name} - renderInput={(params) => ( + getOptionLabel={option => option.name} + renderInput={params => ( { label="Select employees..." placeholder="Member Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} /> @@ -101,7 +101,7 @@ const CheckinsReportPage = () => {
    {selectedPdls.length - ? selectedPdls.map((pdl) => ( + ? selectedPdls.map(pdl => ( { planned={planned} /> )) - : filteredPdls.map((pdl) => ( + : filteredPdls.map(pdl => ( permissions.reduce((categories, permission) => { - const category = permission.category; - const existingCategory = categories.find(cat => cat.category === category); - - // If category exists, add permission to its permissions array - if (existingCategory) { - existingCategory.permissions.push(permission); - } else { - // Create a new category object and add it to categories - categories.push({ - category, - permissions: [permission], - }); - } - - return categories; -}, []); + deleteRolePermission +} from '../api/rolepermissions'; +import { getMemberRolesList } from '../api/memberroles'; +import { isArrayPresent, filterObjectByValOrKey } from '../helpers/checks'; +import { UPDATE_TOAST } from '../context/actions'; +import { AppContext } from '../context/AppContext'; +import { selectCurrentUserId } from '../context/selectors'; + +import './EditPermissionsPage.css'; + +const groupPermissionsByCategory = permissions => + permissions.reduce((categories, permission) => { + const category = permission.category; + const existingCategory = categories.find(cat => cat.category === category); + + // If category exists, add permission to its permissions array + if (existingCategory) { + existingCategory.permissions.push(permission); + } else { + // Create a new category object and add it to categories + categories.push({ + category, + permissions: [permission] + }); + } + + return categories; + }, []); const EditPermissionsPage = () => { const { state } = useContext(AppContext); const { csrf } = state; const [permissionsList, setPermissionsList] = useState([]); const [categoriesList, setCategoriesList] = useState([]); // eslint-disable-line no-unused-vars - const [adminId, setAdminId] = useState(""); - const [pdlId, setPDLId] = useState(""); - const [memberId, setMemberId] = useState(""); + const [adminId, setAdminId] = useState(''); + const [pdlId, setPDLId] = useState(''); + const [memberId, setMemberId] = useState(''); const [rolePermissionsList, setRolePermissionsList] = useState([]); const currentUserId = selectCurrentUserId(state); - const [currentUserRole, setCurrentUserRole] = useState(""); + const [currentUserRole, setCurrentUserRole] = useState(''); const [memberRoles, setMemberRoles] = useState([]); const [isAdminRole, setIsAdminRole] = useState(false); @@ -55,106 +56,106 @@ const EditPermissionsPage = () => { const [ createFeedbackRequestPermissionsId, - setCreateFeedbackRequestPermissionsId, - ] = useState(""); + setCreateFeedbackRequestPermissionsId + ] = useState(''); const [ deleteFeedbackRequestPermissionsId, - setDeleteFeedbackRequestPermissionsId, - ] = useState(""); + setDeleteFeedbackRequestPermissionsId + ] = useState(''); const [ viewFeedbackRequestPermissionsId, - setViewFeedbackRequestPermissionsId, - ] = useState(""); + setViewFeedbackRequestPermissionsId + ] = useState(''); const [viewFeedbackAnswerPermissionsId, setViewFeedbackAnswerPermissionsId] = - useState(""); + useState(''); const [createOrgMembersPermissionsId, setCreateOrgMembersPermissionsId] = - useState(""); + useState(''); const [deleteOrgMembersPermissionsId, setDeleteOrgMembersPermissionsId] = - useState(""); - const [viewRolePermissionsId, setViewRolePermissionsId] = useState(""); - const [assignRolePermissionsId, setAssignRolePermissionsId] = useState(""); - const [viewPermissionsId, setViewPermissionsId] = useState(""); - const [viewSkillsReportsId, setViewSkillsReportsId] = useState(""); - const [viewRetentionReportsId, setViewRetentionReportsId] = useState(""); - const [viewAnniversaryReportsId, setViewAnniversaryReportsId] = useState(""); - const [viewBirthdayReportsId, setViewBirthdayReportsId] = useState(""); - const [viewProfileReportsId, setViewProfileReportsId] = useState(""); - const [updateCheckinsId, setUpdateCheckinsId] = useState(""); - const [createCheckinsId, setCreateCheckinsId] = useState(""); - const [viewCheckinsId, setViewCheckinsId] = useState(""); + useState(''); + const [viewRolePermissionsId, setViewRolePermissionsId] = useState(''); + const [assignRolePermissionsId, setAssignRolePermissionsId] = useState(''); + const [viewPermissionsId, setViewPermissionsId] = useState(''); + const [viewSkillsReportsId, setViewSkillsReportsId] = useState(''); + const [viewRetentionReportsId, setViewRetentionReportsId] = useState(''); + const [viewAnniversaryReportsId, setViewAnniversaryReportsId] = useState(''); + const [viewBirthdayReportsId, setViewBirthdayReportsId] = useState(''); + const [viewProfileReportsId, setViewProfileReportsId] = useState(''); + const [updateCheckinsId, setUpdateCheckinsId] = useState(''); + const [createCheckinsId, setCreateCheckinsId] = useState(''); + const [viewCheckinsId, setViewCheckinsId] = useState(''); const [ createFeedbackRequestPermissionsAdmin, - setCreateFeedbackRequestPermissionsAdmin, + setCreateFeedbackRequestPermissionsAdmin ] = useState(false); const [ createFeedbackRequestPermissionsPDL, - setCreateFeedbackRequestPermissionsPDL, + setCreateFeedbackRequestPermissionsPDL ] = useState(false); const [ createFeedbackRequestPermissionsMember, - setCreateFeedbackRequestPermissionsMember, + setCreateFeedbackRequestPermissionsMember ] = useState(false); const [ deleteFeedbackRequestPermissionsAdmin, - setDeleteFeedbackRequestPermissionsAdmin, + setDeleteFeedbackRequestPermissionsAdmin ] = useState(false); const [ deleteFeedbackRequestPermissionsPDL, - setDeleteFeedbackRequestPermissionsPDL, + setDeleteFeedbackRequestPermissionsPDL ] = useState(false); const [ deleteFeedbackRequestPermissionsMember, - setDeleteFeedbackRequestPermissionsMember, + setDeleteFeedbackRequestPermissionsMember ] = useState(false); const [ viewFeedbackRequestPermissionsAdmin, - setViewFeedbackRequestPermissionsAdmin, + setViewFeedbackRequestPermissionsAdmin ] = useState(false); const [ viewFeedbackRequestPermissionsPDL, - setViewFeedbackRequestPermissionsPDL, + setViewFeedbackRequestPermissionsPDL ] = useState(false); const [ viewFeedbackRequestPermissionsMember, - setViewFeedbackRequestPermissionsMember, + setViewFeedbackRequestPermissionsMember ] = useState(false); const [ viewFeedbackAnswerPermissionsAdmin, - setViewFeedbackAnswerPermissionsAdmin, + setViewFeedbackAnswerPermissionsAdmin ] = useState(false); const [ viewFeedbackAnswerPermissionsPDL, - setViewFeedbackAnswerPermissionsPDL, + setViewFeedbackAnswerPermissionsPDL ] = useState(false); const [ viewFeedbackAnswerPermissionsMember, - setViewFeedbackAnswerPermissionsMember, + setViewFeedbackAnswerPermissionsMember ] = useState(false); const [ createOrgMembersPermissionsAdmin, - setCreateOrgMembersPermissionsAdmin, + setCreateOrgMembersPermissionsAdmin ] = useState(false); const [createOrgMembersPermissionsPDL, setCreateOrgMembersPermissionsPDL] = useState(false); const [ createOrgMembersPermissionsMember, - setCreateOrgMembersPermissionsMember, + setCreateOrgMembersPermissionsMember ] = useState(false); const [ deleteOrgMembersPermissionsAdmin, - setDeleteOrgMembersPermissionsAdmin, + setDeleteOrgMembersPermissionsAdmin ] = useState(false); const [deleteOrgMembersPermissionsPDL, setDeleteOrgMembersPermissionsPDL] = useState(false); const [ deleteOrgMembersPermissionsMember, - setDeleteOrgMembersPermissionsMember, + setDeleteOrgMembersPermissionsMember ] = useState(false); const [viewRolePermissionsAdmin, setViewRolePermissionsAdmin] = @@ -223,18 +224,18 @@ const EditPermissionsPage = () => { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `Permission added to Role`, - }, + severity: 'success', + toast: `Permission added to Role` + } }); } else { console.log(res?.error); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "warning", - toast: `Problem changing permission for that role`, - }, + severity: 'warning', + toast: `Problem changing permission for that role` + } }); } }; @@ -242,23 +243,23 @@ const EditPermissionsPage = () => { const deleteRolePermission = async (roleId, permissionId) => { let newSchema = { roleId: roleId, permissionId: permissionId }; let res = await deleteRolePermission(newSchema, csrf); - let data = !res.error ? "Success" : null; + let data = !res.error ? 'Success' : null; if (data) { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: `Permission removed from Role`, - }, + severity: 'success', + toast: `Permission removed from Role` + } }); } else { console.log(res?.error); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "warning", - toast: `Problem deleting permission for that role`, - }, + severity: 'warning', + toast: `Problem deleting permission for that role` + } }); } }; @@ -744,15 +745,15 @@ const EditPermissionsPage = () => { useEffect(() => { if (isArrayPresent(rolePermissionsList)) { - let adminData = rolePermissionsList.filter((a) => a.role === "ADMIN"); + let adminData = rolePermissionsList.filter(a => a.role === 'ADMIN'); if (isArrayPresent(adminData)) { setAdminId(adminData[0].roleId); } - let pdlData = rolePermissionsList.filter((a) => a.role === "PDL"); + let pdlData = rolePermissionsList.filter(a => a.role === 'PDL'); if (isArrayPresent(pdlData)) { setPDLId(pdlData[0].roleId); } - let memberData = rolePermissionsList.filter((a) => a.role === "MEMBER"); + let memberData = rolePermissionsList.filter(a => a.role === 'MEMBER'); if (isArrayPresent(memberData)) { setMemberId(memberData[0].roleId); } @@ -760,109 +761,109 @@ const EditPermissionsPage = () => { if (isArrayPresent(permissionsList)) { let id1 = permissionsList.filter( - (a) => a.permission === "CAN_CREATE_ORGANIZATION_MEMBERS" + a => a.permission === 'CAN_CREATE_ORGANIZATION_MEMBERS' ); if (isArrayPresent(id1)) { setCreateFeedbackRequestPermissionsId(id1[0].id); } let id2 = permissionsList.filter( - (a) => a.permission === "CAN_CREATE_FEEDBACK_REQUEST" + a => a.permission === 'CAN_CREATE_FEEDBACK_REQUEST' ); if (isArrayPresent(id2)) { setCreateFeedbackRequestPermissionsId(id2[0].id); } let id3 = permissionsList.filter( - (a) => a.permission === "CAN_DELETE_FEEDBACK_REQUEST" + a => a.permission === 'CAN_DELETE_FEEDBACK_REQUEST' ); if (isArrayPresent(id3)) { setDeleteFeedbackRequestPermissionsId(id3[0].id); } let id4 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_FEEDBACK_REQUEST" + a => a.permission === 'CAN_VIEW_FEEDBACK_REQUEST' ); if (isArrayPresent(id4)) { setViewFeedbackRequestPermissionsId(id4[0].id); } let id5 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_FEEDBACK_ANSWER" + a => a.permission === 'CAN_VIEW_FEEDBACK_ANSWER' ); if (isArrayPresent(id5)) { setViewFeedbackAnswerPermissionsId(id5[0].id); } let id6 = permissionsList.filter( - (a) => a.permission === "CAN_CREATE_ORGANIZATION_MEMBERS" + a => a.permission === 'CAN_CREATE_ORGANIZATION_MEMBERS' ); if (isArrayPresent(id6)) { setCreateOrgMembersPermissionsId(id6[0].id); } let id7 = permissionsList.filter( - (a) => a.permission === "CAN_DELETE_ORGANIZATION_MEMBERS" + a => a.permission === 'CAN_DELETE_ORGANIZATION_MEMBERS' ); if (isArrayPresent(id7)) { setDeleteOrgMembersPermissionsId(id7[0].id); } let id8 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_ROLE_PERMISSIONS" + a => a.permission === 'CAN_VIEW_ROLE_PERMISSIONS' ); if (isArrayPresent(id8)) { setViewRolePermissionsId(id8[0].id); } let id9 = permissionsList.filter( - (a) => a.permission === "CAN_ASSIGN_ROLE_PERMISSIONS" + a => a.permission === 'CAN_ASSIGN_ROLE_PERMISSIONS' ); if (isArrayPresent(id9)) { setAssignRolePermissionsId(id9[0].id); } let id10 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_PERMISSIONS" + a => a.permission === 'CAN_VIEW_PERMISSIONS' ); if (isArrayPresent(id10)) { setViewPermissionsId(id10[0].id); } let id11 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_SKILLS_REPORT" + a => a.permission === 'CAN_VIEW_SKILLS_REPORT' ); if (isArrayPresent(id11)) { setViewSkillsReportsId(id11[0].id); } let id12 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_RETENTION_REPORT" + a => a.permission === 'CAN_VIEW_RETENTION_REPORT' ); if (isArrayPresent(id12)) { setViewRetentionReportsId(id12[0].id); } let id13 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_ANNIVERSARY_REPORT" + a => a.permission === 'CAN_VIEW_ANNIVERSARY_REPORT' ); if (isArrayPresent(id13)) { setViewAnniversaryReportsId(id13[0].id); } let id14 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_BIRTHDAY_REPORT" + a => a.permission === 'CAN_VIEW_BIRTHDAY_REPORT' ); if (isArrayPresent(id14)) { setViewBirthdayReportsId(id14[0].id); } let id15 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_PROFILE_REPORT" + a => a.permission === 'CAN_VIEW_PROFILE_REPORT' ); if (isArrayPresent(id15)) { setViewProfileReportsId(id15[0].id); } let id16 = permissionsList.filter( - (a) => a.permission === "CAN_UPDATE_CHECKINS" + a => a.permission === 'CAN_UPDATE_CHECKINS' ); if (isArrayPresent(id16)) { setUpdateCheckinsId(id16[0].id); } let id17 = permissionsList.filter( - (a) => a.permission === "CAN_CREATE_CHECKINS" + a => a.permission === 'CAN_CREATE_CHECKINS' ); if (isArrayPresent(id17)) { setCreateCheckinsId(id17[0].id); } let id18 = permissionsList.filter( - (a) => a.permission === "CAN_VIEW_CHECKINS" + a => a.permission === 'CAN_VIEW_CHECKINS' ); if (isArrayPresent(id18)) { setViewCheckinsId(id18[0].id); @@ -873,7 +874,7 @@ const EditPermissionsPage = () => { useEffect(() => { if (isArrayPresent(memberRoles)) { let data = memberRoles.filter( - (a) => a.memberRoleId.memberId === currentUserId + a => a.memberRoleId.memberId === currentUserId ); if (isArrayPresent(data)) { let role = filterObjectByValOrKey( @@ -886,7 +887,7 @@ const EditPermissionsPage = () => { } } - if (currentUserRole === "ADMIN") { + if (currentUserRole === 'ADMIN') { setIsAdminRole(true); } else { setIsAdminRole(false); @@ -896,8 +897,8 @@ const EditPermissionsPage = () => { useEffect(() => { let adminRole = filterObjectByValOrKey( rolePermissionsList, - "ADMIN", - "role" + 'ADMIN', + 'role' ); if (isArrayPresent(adminRole)) { setAdminPermissionsList(adminRole[0].permissions); @@ -905,7 +906,7 @@ const EditPermissionsPage = () => { }, [rolePermissionsList, adminPermissionsList]); useEffect(() => { - let pdlRole = filterObjectByValOrKey(rolePermissionsList, "PDL", "role"); + let pdlRole = filterObjectByValOrKey(rolePermissionsList, 'PDL', 'role'); if (isArrayPresent(pdlRole)) { setPDLPermissionsList(pdlRole[0].permissions); } @@ -914,8 +915,8 @@ const EditPermissionsPage = () => { useEffect(() => { let memberRole = filterObjectByValOrKey( rolePermissionsList, - "MEMBER", - "role" + 'MEMBER', + 'role' ); if (isArrayPresent(memberRole)) { setMemberPermissionsList(memberRole[0].permissions); @@ -925,89 +926,89 @@ const EditPermissionsPage = () => { useEffect(() => { setCreateFeedbackRequestPermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_CREATE_FEEDBACK_REQUEST' ) ); setDeleteFeedbackRequestPermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_DELETE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_DELETE_FEEDBACK_REQUEST' ) ); setViewFeedbackRequestPermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_REQUEST' ) ); setViewFeedbackAnswerPermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_ANSWER" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_ANSWER' ) ); setCreateOrgMembersPermissionsAdmin( adminPermissionsList.some( - (permission) => - permission.permission === "CAN_CREATE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_CREATE_ORGANIZATION_MEMBERS' ) ); setDeleteOrgMembersPermissionsAdmin( adminPermissionsList.some( - (permission) => - permission.permission === "CAN_DELETE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_DELETE_ORGANIZATION_MEMBERS' ) ); setViewRolePermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_ROLE_PERMISSIONS' ) ); setAssignRolePermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_ASSIGN_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_ASSIGN_ROLE_PERMISSIONS' ) ); setViewPermissionsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_PERMISSIONS' ) ); setViewSkillsReportsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_SKILLS_REPORT" + permission => permission.permission === 'CAN_VIEW_SKILLS_REPORT' ) ); setViewRetentionReportsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_RETENTION_REPORT" + permission => permission.permission === 'CAN_VIEW_RETENTION_REPORT' ) ); setViewAnniversaryReportsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ANNIVERSARY_REPORT" + permission => permission.permission === 'CAN_VIEW_ANNIVERSARY_REPORT' ) ); setViewBirthdayReportsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_BIRTHDAY_REPORT" + permission => permission.permission === 'CAN_VIEW_BIRTHDAY_REPORT' ) ); setViewProfileReportsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PROFILE_REPORT" + permission => permission.permission === 'CAN_VIEW_PROFILE_REPORT' ) ); setUpdateCheckinsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_UPDATE_CHECKINS" + permission => permission.permission === 'CAN_UPDATE_CHECKINS' ) ); setCreateCheckinsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_CHECKINS" + permission => permission.permission === 'CAN_CREATE_CHECKINS' ) ); setViewCheckinsAdmin( adminPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_CHECKINS" + permission => permission.permission === 'CAN_VIEW_CHECKINS' ) ); }, [adminPermissionsList]); @@ -1015,89 +1016,89 @@ const EditPermissionsPage = () => { useEffect(() => { setCreateFeedbackRequestPermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_CREATE_FEEDBACK_REQUEST' ) ); setDeleteFeedbackRequestPermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_DELETE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_DELETE_FEEDBACK_REQUEST' ) ); setViewFeedbackRequestPermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_REQUEST' ) ); setViewFeedbackAnswerPermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_ANSWER" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_ANSWER' ) ); setCreateOrgMembersPermissionsPDL( pdlPermissionsList.some( - (permission) => - permission.permission === "CAN_CREATE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_CREATE_ORGANIZATION_MEMBERS' ) ); setDeleteOrgMembersPermissionsPDL( pdlPermissionsList.some( - (permission) => - permission.permission === "CAN_DELETE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_DELETE_ORGANIZATION_MEMBERS' ) ); setViewRolePermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_ROLE_PERMISSIONS' ) ); setAssignRolePermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_ASSIGN_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_ASSIGN_ROLE_PERMISSIONS' ) ); setViewPermissionsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_PERMISSIONS' ) ); setViewSkillsReportsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_SKILLS_REPORT" + permission => permission.permission === 'CAN_VIEW_SKILLS_REPORT' ) ); setViewRetentionReportsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_RETENTION_REPORT" + permission => permission.permission === 'CAN_VIEW_RETENTION_REPORT' ) ); setViewAnniversaryReportsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ANNIVERSARY_REPORT" + permission => permission.permission === 'CAN_VIEW_ANNIVERSARY_REPORT' ) ); setViewBirthdayReportsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_BIRTHDAY_REPORT" + permission => permission.permission === 'CAN_VIEW_BIRTHDAY_REPORT' ) ); setViewProfileReportsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PROFILE_REPORT" + permission => permission.permission === 'CAN_VIEW_PROFILE_REPORT' ) ); setUpdateCheckinsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_UPDATE_CHECKINS" + permission => permission.permission === 'CAN_UPDATE_CHECKINS' ) ); setCreateCheckinsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_CHECKINS" + permission => permission.permission === 'CAN_CREATE_CHECKINS' ) ); setViewCheckinsPDL( pdlPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_CHECKINS" + permission => permission.permission === 'CAN_VIEW_CHECKINS' ) ); }, [pdlPermissionsList]); @@ -1105,89 +1106,89 @@ const EditPermissionsPage = () => { useEffect(() => { setCreateFeedbackRequestPermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_CREATE_FEEDBACK_REQUEST' ) ); setDeleteFeedbackRequestPermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_DELETE_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_DELETE_FEEDBACK_REQUEST' ) ); setViewFeedbackRequestPermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_REQUEST" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_REQUEST' ) ); setViewFeedbackAnswerPermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_FEEDBACK_ANSWER" + permission => permission.permission === 'CAN_VIEW_FEEDBACK_ANSWER' ) ); setCreateOrgMembersPermissionsMember( memberPermissionsList.some( - (permission) => - permission.permission === "CAN_CREATE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_CREATE_ORGANIZATION_MEMBERS' ) ); setDeleteOrgMembersPermissionsMember( memberPermissionsList.some( - (permission) => - permission.permission === "CAN_DELETE_ORGANIZATION_MEMBERS" + permission => + permission.permission === 'CAN_DELETE_ORGANIZATION_MEMBERS' ) ); setViewRolePermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_ROLE_PERMISSIONS' ) ); setAssignRolePermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_ASSIGN_ROLE_PERMISSIONS" + permission => permission.permission === 'CAN_ASSIGN_ROLE_PERMISSIONS' ) ); setViewPermissionsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PERMISSIONS" + permission => permission.permission === 'CAN_VIEW_PERMISSIONS' ) ); setViewSkillsReportsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_SKILLS_REPORT" + permission => permission.permission === 'CAN_VIEW_SKILLS_REPORT' ) ); setViewRetentionReportsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_RETENTION_REPORT" + permission => permission.permission === 'CAN_VIEW_RETENTION_REPORT' ) ); setViewAnniversaryReportsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_ANNIVERSARY_REPORT" + permission => permission.permission === 'CAN_VIEW_ANNIVERSARY_REPORT' ) ); setViewBirthdayReportsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_BIRTHDAY_REPORT" + permission => permission.permission === 'CAN_VIEW_BIRTHDAY_REPORT' ) ); setViewProfileReportsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_PROFILE_REPORT" + permission => permission.permission === 'CAN_VIEW_PROFILE_REPORT' ) ); setUpdateCheckinsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_UPDATE_CHECKINS" + permission => permission.permission === 'CAN_UPDATE_CHECKINS' ) ); setCreateCheckinsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_CREATE_CHECKINS" + permission => permission.permission === 'CAN_CREATE_CHECKINS' ) ); setViewCheckinsMember( memberPermissionsList.some( - (permission) => permission.permission === "CAN_VIEW_CHECKINS" + permission => permission.permission === 'CAN_VIEW_CHECKINS' ) ); }, [memberPermissionsList]); diff --git a/web-ui/src/pages/EditPermissionsPage.test.jsx b/web-ui/src/pages/EditPermissionsPage.test.jsx index d106a06de3..453fe8c746 100644 --- a/web-ui/src/pages/EditPermissionsPage.test.jsx +++ b/web-ui/src/pages/EditPermissionsPage.test.jsx @@ -1,8 +1,8 @@ -import React from "react"; -import EditPermissionsPage from "./EditPermissionsPage"; -import { AppContextProvider } from "../context/AppContext"; +import React from 'react'; +import EditPermissionsPage from './EditPermissionsPage'; +import { AppContextProvider } from '../context/AppContext'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/EditPermissionsPageRoles.jsx b/web-ui/src/pages/EditPermissionsPageRoles.jsx index 86167fa1fb..ed7cf26397 100644 --- a/web-ui/src/pages/EditPermissionsPageRoles.jsx +++ b/web-ui/src/pages/EditPermissionsPageRoles.jsx @@ -1,5 +1,5 @@ -import React from "react"; -import { Checkbox } from "@mui/material"; +import React from 'react'; +import { Checkbox } from '@mui/material'; const EditPermissionsPageRoles = ({ title, @@ -8,7 +8,7 @@ const EditPermissionsPageRoles = ({ selectPDL, pdl, selectMember, - member, + member }) => { return (
    @@ -17,7 +17,7 @@ const EditPermissionsPageRoles = ({ checked={admin} id="admin-field" onChange={selectAdmin} - inputProps={{ "aria-label": `admin checkbox ${title}` }} + inputProps={{ 'aria-label': `admin checkbox ${title}` }} /> @@ -25,7 +25,7 @@ const EditPermissionsPageRoles = ({ checked={pdl} id="pdl-field" onChange={selectPDL} - inputProps={{ "aria-label": `pdl checkbox ${title}` }} + inputProps={{ 'aria-label': `pdl checkbox ${title}` }} /> @@ -33,7 +33,7 @@ const EditPermissionsPageRoles = ({ checked={member} id="member-field" onChange={selectMember} - inputProps={{ "aria-label": `member checkbox ${title}` }} + inputProps={{ 'aria-label': `member checkbox ${title}` }} />
    diff --git a/web-ui/src/pages/EditSkillsPage.jsx b/web-ui/src/pages/EditSkillsPage.jsx index 1f3f0008d3..57d8602320 100644 --- a/web-ui/src/pages/EditSkillsPage.jsx +++ b/web-ui/src/pages/EditSkillsPage.jsx @@ -1,19 +1,19 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; -import { AppContext } from "../context/AppContext"; -import { selectOrderedSkills, selectPendingSkills } from "../context/selectors"; -import EditSkillsCard from "../components/edit_skills/EditSkillsCard"; -import EditSkillsModal from "../components/edit_skills/EditSkillsModal"; -import {Link} from "react-router-dom"; +import { AppContext } from '../context/AppContext'; +import { selectOrderedSkills, selectPendingSkills } from '../context/selectors'; +import EditSkillsCard from '../components/edit_skills/EditSkillsCard'; +import EditSkillsModal from '../components/edit_skills/EditSkillsModal'; +import { Link } from 'react-router-dom'; -import { Button, TextField } from "@mui/material"; +import { Button, TextField } from '@mui/material'; -import "./EditSkillsPage.css"; +import './EditSkillsPage.css'; const EditSkillsPage = () => { const { state } = useContext(AppContext); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [showAllSkills, setShowAllSkills] = useState(false); const [open, setOpen] = useState(false); @@ -35,7 +35,7 @@ const EditSkillsPage = () => { placeholder="Skill" fullWidth={true} value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} /> @@ -64,18 +64,18 @@ const EditSkillsPage = () => { />
    {!showAllSkills - ? pendingSkills.map((skill) => + ? pendingSkills.map(skill => skill.name.toLowerCase().includes(searchText.toLowerCase()) ? ( ) : null ) - : allSkills.map((skill) => + : allSkills.map(skill => skill.name.toLowerCase().includes(searchText.toLowerCase()) ? ( ) : null diff --git a/web-ui/src/pages/EditSkillsPage.test.jsx b/web-ui/src/pages/EditSkillsPage.test.jsx index 5aac506509..b7235f2871 100644 --- a/web-ui/src/pages/EditSkillsPage.test.jsx +++ b/web-ui/src/pages/EditSkillsPage.test.jsx @@ -1,9 +1,9 @@ -import React from "react"; -import EditSkillsPage from "./EditSkillsPage"; -import { AppContextProvider } from "../context/AppContext"; -import {BrowserRouter} from "react-router-dom"; +import React from 'react'; +import EditSkillsPage from './EditSkillsPage'; +import { AppContextProvider } from '../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/EmailPage.css b/web-ui/src/pages/EmailPage.css index b68293d7d3..0a863bd6bf 100644 --- a/web-ui/src/pages/EmailPage.css +++ b/web-ui/src/pages/EmailPage.css @@ -1,84 +1,88 @@ .email-page .stepper-button-container { - margin-top: 1rem; - text-align: right; + margin-top: 1rem; + text-align: right; } .email-page .stepper-button { - margin-left: 1rem; + margin-left: 1rem; } .email-page .current-step-content-card { - margin-top: 1rem; + margin-top: 1rem; } .email-page .email-format-container { - width: 100%; - text-align: center; + width: 100%; + text-align: center; } .email-page .email-format-container .email-format-button { - color: #313131; - border: 2px solid #313131; - text-align: center; - margin: 0.5rem 3rem; + color: #313131; + border: 2px solid #313131; + text-align: center; + margin: 0.5rem 3rem; } -.email-page .email-format-container .email-format-button .email-format-button-content { - width: 250px; - height: 250px; - padding: 1rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; +.email-page + .email-format-container + .email-format-button + .email-format-button-content { + width: 250px; + height: 250px; + padding: 1rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; } .email-page .current-step-content-card .email-subject-container { - display: flex; - flex-direction: row; - align-items: flex-start; - margin-bottom: 1rem; + display: flex; + flex-direction: row; + align-items: flex-start; + margin-bottom: 1rem; } .email-page .current-step-content-card .missing-preview-message { - background-color: #eaeaea; - border: 1px dashed gray; - color: gray; - border-radius: 4px; - text-align: center; - padding: 3rem; + background-color: #eaeaea; + border: 1px dashed gray; + color: gray; + border-radius: 4px; + text-align: center; + padding: 3rem; } .email-page .current-step-content-card .send-test-email-container { - display: flex; - flex-direction: row; - align-items: flex-start; - margin-top: 0.5rem; - margin-bottom: 2rem; + display: flex; + flex-direction: row; + align-items: flex-start; + margin-top: 0.5rem; + margin-bottom: 2rem; } .email-page .current-step-content-card .send-test-email-input { - width: 400px; + width: 400px; } .email-page .current-step-content-card .send-test-email-button { - height: 56px; - border-bottom-left-radius: 0; - border-top-left-radius: 0; + height: 56px; + border-bottom-left-radius: 0; + border-top-left-radius: 0; } -.send-email-to-all-confirmation-dialog, .change-email-format-confirmation-dialog { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - max-width: 700px; - padding:0.5rem; +.send-email-to-all-confirmation-dialog, +.change-email-format-confirmation-dialog { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 700px; + padding: 0.5rem; } .send-email-to-all-confirmation-dialog .recipient-group-container { - width: 100%; - display: flex; - justify-content: center; - padding-top: 1rem; -} \ No newline at end of file + width: 100%; + display: flex; + justify-content: center; + padding-top: 1rem; +} diff --git a/web-ui/src/pages/EmailPage.jsx b/web-ui/src/pages/EmailPage.jsx index a25584ba12..73d86c209d 100644 --- a/web-ui/src/pages/EmailPage.jsx +++ b/web-ui/src/pages/EmailPage.jsx @@ -1,6 +1,8 @@ -import React, {useContext, useEffect, useState} from "react"; +import React, { useContext, useEffect, useState } from 'react'; import { - Alert, Avatar, AvatarGroup, + Alert, + Avatar, + AvatarGroup, Button, Card, CardActions, @@ -10,36 +12,44 @@ import { Step, StepLabel, Stepper, - TextField, Tooltip, - Typography, -} from "@mui/material"; -import {styled} from "@mui/material/styles"; -import LeftArrowIcon from "@mui/icons-material/KeyboardArrowLeft"; -import RightArrowIcon from "@mui/icons-material/KeyboardArrowRight"; -import UploadFileIcon from "@mui/icons-material/UploadFile"; -import SendIcon from "@mui/icons-material/Send"; -import EditIcon from "@mui/icons-material/Edit"; -import CheckIcon from "@mui/icons-material/CheckCircle"; -import {AppContext} from "../context/AppContext"; -import mjml2html from "mjml-browser"; -import ReactHtmlParser from "react-html-parser"; -import {UPDATE_TOAST} from "../context/actions"; -import {sendEmail} from "../api/notifications"; - -import "./EmailPage.css"; -import {getAvatarURL} from "../api/api"; -import MemberSelector from "../components/member_selector/MemberSelector.jsx"; -import {selectCsrfToken} from "../context/selectors.js"; - -const Root = styled("div")({ - margin: "2rem" + TextField, + Tooltip, + Typography +} from '@mui/material'; +import { styled } from '@mui/material/styles'; +import LeftArrowIcon from '@mui/icons-material/KeyboardArrowLeft'; +import RightArrowIcon from '@mui/icons-material/KeyboardArrowRight'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; +import SendIcon from '@mui/icons-material/Send'; +import EditIcon from '@mui/icons-material/Edit'; +import CheckIcon from '@mui/icons-material/CheckCircle'; +import { AppContext } from '../context/AppContext'; +import mjml2html from 'mjml-browser'; +import ReactHtmlParser from 'react-html-parser'; +import { UPDATE_TOAST } from '../context/actions'; +import { sendEmail } from '../api/notifications'; + +import './EmailPage.css'; +import { getAvatarURL } from '../api/api'; +import MemberSelector from '../components/member_selector/MemberSelector.jsx'; +import { selectCsrfToken } from '../context/selectors.js'; + +const Root = styled('div')({ + margin: '2rem' }); -const ChooseEmailFormatStep = ({ emailFormat, onEmailFormatChange, emailContents, emailSent }) => { - - const [formatDialog, setFormatDialog] = useState({open: false, format: null}); - - const handleFormatButtonClick = (format) => { +const ChooseEmailFormatStep = ({ + emailFormat, + onEmailFormatChange, + emailContents, + emailSent +}) => { + const [formatDialog, setFormatDialog] = useState({ + open: false, + format: null + }); + + const handleFormatButtonClick = format => { // Do nothing if the same button is clicked again if (format === emailFormat) { return; @@ -47,58 +57,106 @@ const ChooseEmailFormatStep = ({ emailFormat, onEmailFormatChange, emailContents // If the user tries to change the email format after composing an email, warn with dialog if (emailFormat && emailContents.length > 0 && format !== emailFormat) { - setFormatDialog({open: true, format: format}); + setFormatDialog({ open: true, format: format }); } else { onEmailFormatChange(format); } - } + }; return ( <>
    - Change Email Format}/> + + Change Email Format + + } + /> - You are attempting to change the format of this email, but you have already written a draft in the following step. Changing the format will reset this draft. + + You are attempting to change the format of this email, but you + have already written a draft in the following step. Changing the + format will reset this draft. + - - @@ -106,41 +164,48 @@ const ChooseEmailFormatStep = ({ emailFormat, onEmailFormatChange, emailContents ); -} - -const ComposeEmailStep = ({ emailFormat, emailContents, emailSubject, onSubjectChange, onEmailContentsChange, emailSent }) => { +}; +const ComposeEmailStep = ({ + emailFormat, + emailContents, + emailSubject, + onSubjectChange, + onEmailContentsChange, + emailSent +}) => { const [emailPreview, setEmailPreview] = useState(null); - const handleFileUpload = (event) => { + const handleFileUpload = event => { if (event.target.files && event.target.files[0]) { const fileReader = new FileReader(); - fileReader.onload = (e) => { + fileReader.onload = e => { const mjmlContent = e.target.result.toString(); const { html } = mjml2html(mjmlContent); onEmailContentsChange(html); - } + }; const file = event.target.files[0]; fileReader.readAsText(file); } - } + }; useEffect(() => { - if (emailContents && emailFormat === "file") { + if (emailContents && emailFormat === 'file') { const preview = ReactHtmlParser(emailContents); setEmailPreview(preview); } }, [emailFormat, emailContents]); - if (emailFormat === "file") { + if (emailFormat === 'file') { return ( <>
    + style={{ marginRight: '1rem', marginTop: '6px' }} + > Subject: { + onChange={event => { onSubjectChange(event.target.value); }} />
    - {emailContents - ? emailPreview - : <> - Select a MJML file to render the email. The file must have a .mjml extension. + {emailContents ? ( + emailPreview + ) : ( + <> + + Select a MJML file to render the email. The file must have a .mjml + extension. +
    - } + )} ); - } else if (emailFormat === "text") { + } else if (emailFormat === 'text') { return ( <>
    + style={{ marginRight: '1rem', marginTop: '6px' }} + > Subject: { + onChange={event => { onSubjectChange(event.target.value); }} /> @@ -208,31 +279,42 @@ const ComposeEmailStep = ({ emailFormat, emailContents, emailSubject, onSubjectC maxRows={20} placeholder="Write your email here..." value={emailContents} - onChange={(event) => onEmailContentsChange(event.target.value)} + onChange={event => onEmailContentsChange(event.target.value)} /> ); } - return <> -} - -const SelectRecipientsStep = ({ testEmail, onTestEmailChange, onSendTestEmail, recipients, onRecipientsChange, emailSent }) => { + return <>; +}; +const SelectRecipientsStep = ({ + testEmail, + onTestEmailChange, + onSendTestEmail, + recipients, + onRecipientsChange, + emailSent +}) => { const [emailError, setEmailError] = useState(false); const handleSendButtonClick = () => { - let regEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}])|(([a-zA-Z\-\d]+\.)+[a-zA-Z]{2,}))$/ + let regEmail = + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}])|(([a-zA-Z\-\d]+\.)+[a-zA-Z]{2,}))$/; if (!regEmail.test(testEmail)) { setEmailError(true); } else { onSendTestEmail(testEmail); } - } + }; return ( <> - To test this email and see how it will appear in an inbox, you can send it to an email address you have access to. If you are satisfied with this email, then select recipients from the list below. + + To test this email and see how it will appear in an inbox, you can send + it to an email address you have access to. If you are satisfied with + this email, then select recipients from the list below. +
    { + helperText={emailError ? 'Invalid email address' : ''} + onChange={event => { onTestEmailChange(event.target.value); setEmailError(false); }} InputProps={{ - style: {borderTopRightRadius: 0, borderBottomRightRadius: 0} + style: { borderTopRightRadius: 0, borderBottomRightRadius: 0 } }} />
    onRecipientsChange(selectedMembers)} + onChange={selectedMembers => onRecipientsChange(selectedMembers)} title="Recipients" outlined exportable @@ -271,40 +353,45 @@ const SelectRecipientsStep = ({ testEmail, onTestEmailChange, onSendTestEmail, r /> ); -} +}; const EmailPage = () => { const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); const [currentStep, setCurrentStep] = useState(0); const [emailFormat, setEmailFormat] = useState(null); - const [emailContents, setEmailContents] = useState(""); - const [emailSubject, setEmailSubject] = useState(""); + const [emailContents, setEmailContents] = useState(''); + const [emailSubject, setEmailSubject] = useState(''); const [recipients, setRecipients] = useState([]); - const [testEmail, setTestEmail] = useState(""); + const [testEmail, setTestEmail] = useState(''); const [testEmailSent, setTestEmailSent] = useState(false); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); const [emailSent, setEmailSent] = useState(false); - const steps = ["Choose Email Format", "Compose Email", "Select Recipients"]; + const steps = ['Choose Email Format', 'Compose Email', 'Select Recipients']; useEffect(() => { window.scrollTo(0, 0); }, [currentStep]); const sendTestEmail = () => { - if (!emailSubject.trim() || !emailContents || !csrf) { return; } - sendEmail(`Test Email - ${emailSubject}`, emailContents, emailFormat === "file", [testEmail], csrf).then(res => { + sendEmail( + `Test Email - ${emailSubject}`, + emailContents, + emailFormat === 'file', + [testEmail], + csrf + ).then(res => { let toastMessage, toastStatus; if (res && res.payload && res.payload.status === 201 && !res.error) { setTestEmailSent(true); - toastStatus = "success"; + toastStatus = 'success'; toastMessage = `Sent a test email to ${testEmail}`; } else { - toastStatus = "error"; + toastStatus = 'error'; toastMessage = `Failed to send test email to ${testEmail}`; } window.snackDispatch({ @@ -315,7 +402,7 @@ const EmailPage = () => { } }); }); - } + }; const sendEmailToAllRecipients = () => { setConfirmationDialogOpen(false); @@ -324,17 +411,23 @@ const EmailPage = () => { return; } - const recipientEmails = recipients.map((member) => member.workEmail); + const recipientEmails = recipients.map(member => member.workEmail); - sendEmail(emailSubject, emailContents, emailFormat === "file", recipientEmails, csrf).then(res => { + sendEmail( + emailSubject, + emailContents, + emailFormat === 'file', + recipientEmails, + csrf + ).then(res => { let toastMessage, toastStatus; if (res && res.payload && res.payload.status === 201 && !res.error) { setEmailSent(true); - toastStatus = "success"; - toastMessage = `Sent email to ${recipients.length} member${recipients.length === 1 ? "" : "s"}`; + toastStatus = 'success'; + toastMessage = `Sent email to ${recipients.length} member${recipients.length === 1 ? '' : 's'}`; } else { - toastStatus = "error"; - toastMessage = "Failed to send email"; + toastStatus = 'error'; + toastMessage = 'Failed to send email'; } window.snackDispatch({ type: UPDATE_TOAST, @@ -344,7 +437,7 @@ const EmailPage = () => { } }); }); - } + }; const handleNextClick = () => { switch (currentStep) { @@ -358,7 +451,7 @@ const EmailPage = () => { default: console.warn(`Invalid step in stepper: ${currentStep}`); } - } + }; const nextButtonEnabled = () => { switch (currentStep) { @@ -372,9 +465,9 @@ const EmailPage = () => { console.warn(`Invalid step in stepper: ${currentStep}`); return false; } - } + }; - const stepCompleted = (step) => { + const stepCompleted = step => { if (emailSent) { return true; } @@ -391,7 +484,7 @@ const EmailPage = () => { } return false; - } + }; return ( @@ -403,14 +496,14 @@ const EmailPage = () => { ))} - + {currentStep === 0 && ( { + onEmailFormatChange={format => { setEmailFormat(format); - setEmailContents(""); + setEmailContents(''); }} emailContents={emailContents} emailSent={emailSent} @@ -420,20 +513,20 @@ const EmailPage = () => { setEmailContents(content)} + onEmailContentsChange={content => setEmailContents(content)} emailSubject={emailSubject} - onSubjectChange={(subject) => setEmailSubject(subject)} + onSubjectChange={subject => setEmailSubject(subject)} emailSent={emailSent} /> )} {currentStep === 2 && ( setTestEmail(address)} + onTestEmailChange={address => setTestEmail(address)} onSendTestEmail={sendTestEmail} recipients={recipients} emailSent={emailSent} - onRecipientsChange={(recipients) => { + onRecipientsChange={recipients => { setRecipients(recipients); }} /> @@ -444,52 +537,71 @@ const EmailPage = () => {
    - Send Email}/> + + Send Email + + } + /> - You are about to send this email to {recipients.length} member{recipients.length === 1 ? "" : "s"} in Check-Ins. Are you sure? + You are about to send this email to {recipients.length} member + {recipients.length === 1 ? '' : 's'} in Check-Ins. Are you sure?
    - {recipients.map((member) => ( + {recipients.map(member => ( - + ))}
    - {!testEmailSent && - - Caution: You have not sent a test email to check the email formatting. + {!testEmailSent && ( + + Caution: You have not sent a test email to check the email + formatting. - } + )}
    - - @@ -499,4 +611,4 @@ const EmailPage = () => { ); }; -export default EmailPage; \ No newline at end of file +export default EmailPage; diff --git a/web-ui/src/pages/ErrorBoundaryPage.css b/web-ui/src/pages/ErrorBoundaryPage.css index 063ddacdf3..6525d38ea3 100644 --- a/web-ui/src/pages/ErrorBoundaryPage.css +++ b/web-ui/src/pages/ErrorBoundaryPage.css @@ -42,7 +42,7 @@ } .error-boundary { - background-image: url("https://media.giphy.com/media/tvGOBZKNEX0ac/giphy.gif"); + background-image: url('https://media.giphy.com/media/tvGOBZKNEX0ac/giphy.gif'); background-size: cover; display: flex; justify-content: center; diff --git a/web-ui/src/pages/ErrorBoundaryPage.jsx b/web-ui/src/pages/ErrorBoundaryPage.jsx index 615f87a25b..eac988c564 100644 --- a/web-ui/src/pages/ErrorBoundaryPage.jsx +++ b/web-ui/src/pages/ErrorBoundaryPage.jsx @@ -1,60 +1,60 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; -import { AppContext } from "../context/AppContext"; -import { UPDATE_TOAST } from "../context/actions"; -import { selectCsrfToken } from "../context/selectors"; -import { newGitHubIssue } from "../api/github"; +import { AppContext } from '../context/AppContext'; +import { UPDATE_TOAST } from '../context/actions'; +import { selectCsrfToken } from '../context/selectors'; +import { newGitHubIssue } from '../api/github'; -import { Button, Modal, TextField } from "@mui/material"; +import { Button, Modal, TextField } from '@mui/material'; import { Editor } from '@tinymce/tinymce-react'; -import "./ErrorBoundaryPage.css"; -import { sanitizeQuillElements } from "../helpers/sanitizehtml"; +import './ErrorBoundaryPage.css'; +import { sanitizeQuillElements } from '../helpers/sanitizehtml'; const ErrorFallback = ({ error }) => { const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); const [open, setOpen] = useState(false); - const [title, setTitle] = useState(""); - const [body, setBody] = useState(""); - const [link, setLink] = useState(""); + const [title, setTitle] = useState(''); + const [body, setBody] = useState(''); + const [link, setLink] = useState(''); const close = () => { setOpen(false); }; const createNewGitIssue = async () => { - if (body === "" || title === "") { + if (body === '' || title === '') { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Must have a Body and a Title", - }, + severity: 'error', + toast: 'Must have a Body and a Title' + } }); return; } //Clean new issue of potentially malicious content in body //before upload to server - let sanitizeBody = sanitizeQuillElements(body) + let sanitizeBody = sanitizeQuillElements(body); let res = await newGitHubIssue(sanitizeBody, title, csrf); if (res && res.payload) { setLink(res.payload.data[0].html_url); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: !res.error ? "success" : "error", + severity: !res.error ? 'success' : 'error', toast: !res.error ? `New issue ${title} created! Gratzie 😀` - : res.error.message, - }, + : res.error.message + } }); } }; - const handleBodyChange = (content) => { + const handleBodyChange = content => { setBody(content); }; @@ -78,7 +78,7 @@ const ErrorFallback = ({ error }) => { > Create New GitHub Issue - {link !== "" && ( + {link !== '' && (

    Check out your issue here!   {link}

    @@ -92,23 +92,26 @@ const ErrorFallback = ({ error }) => { label="Title" placeholder="Issue Title" value={title} - onChange={(e) => setTitle(e.target.value)} + onChange={e => setTitle(e.target.value)} />
    -
    - - {steps.map((label) => { + + {steps.map(label => { const stepProps = {}; const labelProps = {}; return ( - {label} + + {label} + ); })}
    - {activeStep === 1 && handleQueryChange(key, value)} query={query.template} />} - {activeStep === 2 && handleQueryChange(key, value)} fromQuery={query.from ? (Array.isArray(query.from) ? query.from : [query.from]) : []} />} - {activeStep === 3 && handleQueryChange(key, value)} sendDateQuery={query.send} dueDateQuery={query.due}/>} + {activeStep === 1 && ( + handleQueryChange(key, value)} + query={query.template} + /> + )} + {activeStep === 2 && ( + handleQueryChange(key, value)} + fromQuery={ + query.from + ? Array.isArray(query.from) + ? query.from + : [query.from] + : [] + } + /> + )} + {activeStep === 3 && ( + handleQueryChange(key, value)} + sendDateQuery={query.send} + dueDateQuery={query.due} + /> + )}
    ); -} +}; export default FeedbackRequestPage; diff --git a/web-ui/src/pages/FeedbackRequestPage.test.jsx b/web-ui/src/pages/FeedbackRequestPage.test.jsx index b26cd9e3db..a4c3958249 100644 --- a/web-ui/src/pages/FeedbackRequestPage.test.jsx +++ b/web-ui/src/pages/FeedbackRequestPage.test.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import FeedbackRequestPage from "./FeedbackRequestPage"; -import {AppContextProvider} from "../context/AppContext"; -import {MemoryRouter} from "react-router-dom"; +import React from 'react'; +import FeedbackRequestPage from './FeedbackRequestPage'; +import { AppContextProvider } from '../context/AppContext'; +import { MemoryRouter } from 'react-router-dom'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( - - - - - + + + + + ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/pages/FeedbackSubmitPage.jsx b/web-ui/src/pages/FeedbackSubmitPage.jsx index 8fe327d5e3..ef70a2ef73 100644 --- a/web-ui/src/pages/FeedbackSubmitPage.jsx +++ b/web-ui/src/pages/FeedbackSubmitPage.jsx @@ -1,16 +1,20 @@ -import React, {useContext, useEffect, useRef} from "react"; +import React, { useContext, useEffect, useRef } from 'react'; import { styled } from '@mui/material/styles'; -import { useState } from 'react' -import "./FeedbackRequestPage.css"; -import FeedbackSubmissionTips from "../components/feedback_submission_tips/FeedbackSubmissionTips"; -import FeedbackSubmitForm from "../components/feedback_submit_form/FeedbackSubmitForm"; -import {useHistory, useLocation} from "react-router-dom"; -import {selectCsrfToken, selectCurrentUser, selectProfile} from "../context/selectors"; -import {AppContext} from "../context/AppContext"; -import {getFeedbackRequestById} from "../api/feedback"; -import Typography from "@mui/material/Typography"; -import {UPDATE_TOAST} from "../context/actions"; -import * as queryString from "query-string"; +import { useState } from 'react'; +import './FeedbackRequestPage.css'; +import FeedbackSubmissionTips from '../components/feedback_submission_tips/FeedbackSubmissionTips'; +import FeedbackSubmitForm from '../components/feedback_submit_form/FeedbackSubmitForm'; +import { useHistory, useLocation } from 'react-router-dom'; +import { + selectCsrfToken, + selectCurrentUser, + selectProfile +} from '../context/selectors'; +import { AppContext } from '../context/AppContext'; +import { getFeedbackRequestById } from '../api/feedback'; +import Typography from '@mui/material/Typography'; +import { UPDATE_TOAST } from '../context/actions'; +import * as queryString from 'query-string'; const PREFIX = 'FeedbackSubmitPage'; const classes = { @@ -19,12 +23,13 @@ const classes = { const Root = styled('div')({ [`& .${classes.announcement}`]: { - textAlign: "center", - marginTop: "3em", - ['@media (max-width: 800px)']: { // eslint-disable-line no-useless-computed-key - fontSize: "22px" + textAlign: 'center', + marginTop: '3em', + ['@media (max-width: 800px)']: { + // eslint-disable-line no-useless-computed-key + fontSize: '22px' } - }, + } }); const FeedbackSubmitPage = () => { @@ -41,18 +46,17 @@ const FeedbackSubmitPage = () => { const [requestSubmitted, setRequestSubmitted] = useState(false); const [requestCanceled, setRequestCanceled] = useState(false); const feedbackRequestFetched = useRef(false); - + useEffect(() => { if (!requestQuery) { - history.push("/checkins"); + history.push('/checkins'); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "No request present", - }, + severity: 'error', + toast: 'No request present' + } }); - } async function getFeedbackRequest(cookie) { if (!currentUserId || !cookie || feedbackRequestFetched.current) { @@ -61,42 +65,49 @@ const FeedbackSubmitPage = () => { // make call to the API let res = await getFeedbackRequestById(requestQuery, cookie); - return ( - res.payload && + return res.payload && res.payload.data && res.payload.status === 200 && - !res.error) + !res.error ? res.payload.data : null; } - if (csrf && currentUserId && requestQuery && !feedbackRequestFetched.current) { - getFeedbackRequest(csrf).then((request) => { + if ( + csrf && + currentUserId && + requestQuery && + !feedbackRequestFetched.current + ) { + getFeedbackRequest(csrf).then(request => { if (request) { if (request.recipientId !== currentUserId) { - history.push("/checkins"); + history.push('/checkins'); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "You are not authorized to perform this operation.", - }, + severity: 'error', + toast: 'You are not authorized to perform this operation.' + } }); - } else if (request.status.toLowerCase() === "submitted" || request.submitDate) { + } else if ( + request.status.toLowerCase() === 'submitted' || + request.submitDate + ) { setRequestSubmitted(true); - } else if (request.status.toLowerCase() === "canceled") { + } else if (request.status.toLowerCase() === 'canceled') { setRequestCanceled(true); } else { - setFeedbackRequest(request); + setFeedbackRequest(request); } } else { - history.push("/checkins"); + history.push('/checkins'); window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Can't find feedback request with that ID", - }, + severity: 'error', + toast: "Can't find feedback request with that ID" + } }); } }); @@ -109,25 +120,38 @@ const FeedbackSubmitPage = () => { } if (feedbackRequestFetched.current) { - const requesteeProfile = selectProfile(state, feedbackRequest?.requesteeId); + const requesteeProfile = selectProfile( + state, + feedbackRequest?.requesteeId + ); setRequestee(requesteeProfile); } }, [feedbackRequest, state]); return ( - {requestCanceled ? - This feedback request has been canceled. : - (requestSubmitted ? - You have already submitted this feedback form. Thank you! : - <> - {feedbackRequestFetched.current && (showTips ? - setShowTips(false)}/> : - - )} - - ) - } + {requestCanceled ? ( + + This feedback request has been canceled. + + ) : requestSubmitted ? ( + + You have already submitted this feedback form. Thank you! + + ) : ( + <> + {feedbackRequestFetched.current && + (showTips ? ( + setShowTips(false)} /> + ) : ( + + ))} + + )} ); }; diff --git a/web-ui/src/pages/GuildsPage.jsx b/web-ui/src/pages/GuildsPage.jsx index 2846d25be3..671cbb4adc 100644 --- a/web-ui/src/pages/GuildsPage.jsx +++ b/web-ui/src/pages/GuildsPage.jsx @@ -1,16 +1,16 @@ import React from 'react'; import GuildResults from '../components/guild-results/GuildResults'; -const displayName = "GuildsPage"; +const displayName = 'GuildsPage'; const GuildsPage = () => { - return ( -
    - -
    - ); + return ( +
    + +
    + ); }; GuildsPage.displayName = displayName; -export default GuildsPage; \ No newline at end of file +export default GuildsPage; diff --git a/web-ui/src/pages/GuildsPage.test.jsx b/web-ui/src/pages/GuildsPage.test.jsx index 100bd964e5..0067057e74 100644 --- a/web-ui/src/pages/GuildsPage.test.jsx +++ b/web-ui/src/pages/GuildsPage.test.jsx @@ -1,8 +1,8 @@ -import React from "react"; -import GuildsPage from "./GuildsPage"; -import { AppContextProvider } from "../context/AppContext"; +import React from 'react'; +import GuildsPage from './GuildsPage'; +import { AppContextProvider } from '../context/AppContext'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/HomePage.css b/web-ui/src/pages/HomePage.css index aee140663d..fb9f61f622 100644 --- a/web-ui/src/pages/HomePage.css +++ b/web-ui/src/pages/HomePage.css @@ -39,6 +39,6 @@ font-weight: bolder; } .double-celebrations { - padding-top: 0; + padding-top: 0; } -} \ No newline at end of file +} diff --git a/web-ui/src/pages/HomePage.jsx b/web-ui/src/pages/HomePage.jsx index 686c0b87b3..4ac2d4c04a 100644 --- a/web-ui/src/pages/HomePage.jsx +++ b/web-ui/src/pages/HomePage.jsx @@ -1,16 +1,16 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from 'react'; -import { getTodaysCelebrations } from "../api/birthdayanniversary"; -import Anniversaries from "../components/celebrations/Anniversaries"; -import Birthdays from "../components/celebrations/Birthdays"; -import DoubleCelebration from "../components/celebrations/DoubleCelebration"; -import MyAnniversary from "../components/celebrations/MyAnniversary"; -import MyBirthday from "../components/celebrations/MyBirthday"; -import { AppContext } from "../context/AppContext"; -import { selectCsrfToken, selectCurrentUser } from "../context/selectors"; -import { sortAnniversaries, sortBirthdays } from "../context/util"; +import { getTodaysCelebrations } from '../api/birthdayanniversary'; +import Anniversaries from '../components/celebrations/Anniversaries'; +import Birthdays from '../components/celebrations/Birthdays'; +import DoubleCelebration from '../components/celebrations/DoubleCelebration'; +import MyAnniversary from '../components/celebrations/MyAnniversary'; +import MyBirthday from '../components/celebrations/MyBirthday'; +import { AppContext } from '../context/AppContext'; +import { selectCsrfToken, selectCurrentUser } from '../context/selectors'; +import { sortAnniversaries, sortBirthdays } from '../context/util'; -import "./HomePage.css"; +import './HomePage.css'; export default function HomePage() { const { state } = useContext(AppContext); @@ -37,7 +37,7 @@ export default function HomePage() { : null; if (data) { if (data.anniversaries) { - let filteredAnniversaries = data.anniversaries.filter((anniv) => { + let filteredAnniversaries = data.anniversaries.filter(anniv => { let annivYear = new Date(anniv.anniversary).getFullYear(); return annivYear !== currentYear; }); @@ -55,12 +55,12 @@ export default function HomePage() { useEffect(() => { if (birthdays) { - setMyBirthday(birthdays.some((bday) => bday.userId === me.id)); + setMyBirthday(birthdays.some(bday => bday.userId === me.id)); } if (anniversaries) { - setMyAnniversary(anniversaries.some((anniv) => anniv.userId === me.id)); + setMyAnniversary(anniversaries.some(anniv => anniv.userId === me.id)); setMyAnniversaryData( - anniversaries.filter((anniv) => anniv.userId === me.id) + anniversaries.filter(anniv => anniv.userId === me.id) ); } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -88,8 +88,8 @@ export default function HomePage() { myAnniversary && showMyBirthday && showMyAnniversary - ? "double-celebrations" - : "celebrations" + ? 'double-celebrations' + : 'celebrations' } > {myBirthday && diff --git a/web-ui/src/pages/HomePage.test.jsx b/web-ui/src/pages/HomePage.test.jsx index 665ad55e35..2a585935e7 100644 --- a/web-ui/src/pages/HomePage.test.jsx +++ b/web-ui/src/pages/HomePage.test.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import HomePage from "./HomePage"; -import { AppContextProvider } from "../context/AppContext"; -import { createMemoryHistory } from "history"; -import { Router } from "react-router-dom"; +import React from 'react'; +import HomePage from './HomePage'; +import { AppContextProvider } from '../context/AppContext'; +import { createMemoryHistory } from 'history'; +import { Router } from 'react-router-dom'; -it("renders correctly", () => { - const history = createMemoryHistory("/"); +it('renders correctly', () => { + const history = createMemoryHistory('/'); snapshot( diff --git a/web-ui/src/pages/MemberProfilePage.jsx b/web-ui/src/pages/MemberProfilePage.jsx index 19d34d4fb3..542e2875a6 100644 --- a/web-ui/src/pages/MemberProfilePage.jsx +++ b/web-ui/src/pages/MemberProfilePage.jsx @@ -1,20 +1,26 @@ -import React, { useContext, useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; +import React, { useContext, useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; -import { selectCurrentUserId, selectIsAdmin, selectProfile, selectTerminatedMembers, selectSupervisorHierarchyIds } from "../context/selectors"; -import { AppContext } from "../context/AppContext"; -import { getSelectedMemberSkills } from "../api/memberskill"; -import { getTeamByMember } from "../api/team"; -import { getGuildsForMember } from "../api/guild"; -import { getAvatarURL } from "../api/api.js"; -import ProfilePage from "./ProfilePage"; -import { levelList } from "../context/util"; +import { + selectCurrentUserId, + selectIsAdmin, + selectProfile, + selectTerminatedMembers, + selectSupervisorHierarchyIds +} from '../context/selectors'; +import { AppContext } from '../context/AppContext'; +import { getSelectedMemberSkills } from '../api/memberskill'; +import { getTeamByMember } from '../api/team'; +import { getGuildsForMember } from '../api/guild'; +import { getAvatarURL } from '../api/api.js'; +import ProfilePage from './ProfilePage'; +import { levelList } from '../context/util'; import { selectOrderedPdls, - selectOrderedMemberFirstName, -} from "../context/selectors"; + selectOrderedMemberFirstName +} from '../context/selectors'; -import "./MemberProfilePage.css"; +import './MemberProfilePage.css'; import { Avatar, @@ -26,9 +32,9 @@ import { Container, Grid, Tooltip, - Typography, -} from "@mui/material"; -import { useHistory } from "react-router-dom"; + Typography +} from '@mui/material'; +import { useHistory } from 'react-router-dom'; const MemberProfilePage = () => { const { state } = useContext(AppContext); @@ -40,19 +46,24 @@ const MemberProfilePage = () => { const sortedMembers = selectOrderedMemberFirstName(state); const isAdmin = selectIsAdmin(state); const currentUserId = selectCurrentUserId(state); - const pdlInfo = sortedPdls && sortedPdls.find((pdl) => pdl?.id === selectedMember?.pdlId); - const supervisorInfo = sortedMembers && sortedMembers.find((memberProfile) => memberProfile?.id === selectedMember?.supervisorid); + const pdlInfo = + sortedPdls && sortedPdls.find(pdl => pdl?.id === selectedMember?.pdlId); + const supervisorInfo = + sortedMembers && + sortedMembers.find( + memberProfile => memberProfile?.id === selectedMember?.supervisorid + ); const supervisorChain = selectSupervisorHierarchyIds(selectedMember)(state); const currentUserIsPdl = pdlInfo?.id === currentUserId; const currentUserIsSupervisor = supervisorChain.includes(currentUserId); - const canRequestFeedback = isAdmin || currentUserIsPdl || currentUserIsSupervisor; - + const canRequestFeedback = + isAdmin || currentUserIsPdl || currentUserIsSupervisor; useEffect(() => { // in the case of a terminated member, member details will still display const member = selectProfile(state, memberId); const terminatedMember = selectTerminatedMembers(state)?.filter( - (terminatedMember) => terminatedMember.id === memberId + terminatedMember => terminatedMember.id === memberId ); if (member) { setSelectedMember(member); @@ -99,9 +110,9 @@ const MemberProfilePage = () => { let res = await getSelectedMemberSkills(memberId, csrf); let data = res.payload && res.payload.data && !res.error ? res.payload.data : []; - let memberSkills = skills.filter((skill) => { + let memberSkills = skills.filter(skill => { //filter out memberSkills and set level - return data.some((mSkill) => { + return data.some(mSkill => { if (mSkill.skillid === skill.id) { skill.skilllevel = levelList[mSkill.skilllevel || 3]; return skill; @@ -159,25 +170,44 @@ const MemberProfilePage = () => { color="textSecondary" component="div" > -

    Email: {selectedMember.workEmail || ""}

    -

    Location: {selectedMember.location || ""}

    -

    Bio: {selectedMember.bioText || ""}

    -

    {(supervisorInfo && "Supervisor: " + supervisorInfo.firstName + " " + supervisorInfo.lastName) || ("")}

    -

    {(pdlInfo && "PDL: " + pdlInfo.firstName + " " + pdlInfo.lastName) || ("")}

    +

    Email: {selectedMember.workEmail || ''}

    +

    Location: {selectedMember.location || ''}

    +

    Bio: {selectedMember.bioText || ''}

    +

    + {(supervisorInfo && + 'Supervisor: ' + + supervisorInfo.firstName + + ' ' + + supervisorInfo.lastName) || + ''} +

    +

    + {(pdlInfo && + 'PDL: ' + + pdlInfo.firstName + + ' ' + + pdlInfo.lastName) || + ''} +

    - {canRequestFeedback && - - } + + + )} )} @@ -186,7 +216,7 @@ const MemberProfilePage = () => {
    @@ -209,7 +239,7 @@ const MemberProfilePage = () => { key={skill.id} label={ skill.name + - " - " + + ' - ' + skill.skilllevel.toLowerCase() } /> @@ -220,7 +250,7 @@ const MemberProfilePage = () => { color="primary" key={skill.id} label={ - skill.name + " - " + skill.skilllevel.toLowerCase() + skill.name + ' - ' + skill.skilllevel.toLowerCase() } /> ) @@ -231,7 +261,7 @@ const MemberProfilePage = () => {
    @@ -241,7 +271,7 @@ const MemberProfilePage = () => {
    )} {teams.length > 0 && - teams.map((team) => ( + teams.map(team => ( {
    @@ -265,7 +295,7 @@ const MemberProfilePage = () => {
    )} {guilds.length > 0 && - guilds.map((guild) => ( + guilds.map(guild => ( { +it('renders correctly', () => { const history = createMemoryHistory(`/profile/1234`); snapshot( diff --git a/web-ui/src/pages/PeoplePage.jsx b/web-ui/src/pages/PeoplePage.jsx index 85afe2519b..97e5314197 100644 --- a/web-ui/src/pages/PeoplePage.jsx +++ b/web-ui/src/pages/PeoplePage.jsx @@ -1,14 +1,14 @@ -import React, { useContext, useState} from "react"; +import React, { useContext, useState } from 'react'; import { styled } from '@mui/material/styles'; -import MemberSummaryCard from "../components/member-directory/MemberSummaryCard"; -import { AppContext } from "../context/AppContext"; +import MemberSummaryCard from '../components/member-directory/MemberSummaryCard'; +import { AppContext } from '../context/AppContext'; import { selectMemberProfilesLoading, - selectNormalizedMembers, -} from "../context/selectors"; -import { TextField, Grid } from "@mui/material"; -import "./PeoplePage.css"; -import SkeletonLoader from "../components/skeleton_loader/SkeletonLoader" + selectNormalizedMembers +} from '../context/selectors'; +import { TextField, Grid } from '@mui/material'; +import './PeoplePage.css'; +import SkeletonLoader from '../components/skeleton_loader/SkeletonLoader'; const PREFIX = 'PeoplePage'; const classes = { @@ -19,26 +19,26 @@ const classes = { const Root = styled('div')({ [`& .${classes.search}`]: { - display: "flex", - justifyContent: "space-between", - alignItems: "center", + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center' }, [`& .${classes.searchInput}`]: { - width: "20em", + width: '20em' }, [`& .${classes.members}`]: { - display: "flex", - flexWrap: "wrap", - justifyContent: "space-evenly", - width: "100%", - }, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-evenly', + width: '100%' + } }); const PeoplePage = () => { const { state } = useContext(AppContext); - const loading = selectMemberProfilesLoading(state) + const loading = selectMemberProfilesLoading(state); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const normalizedMembers = selectNormalizedMembers(state, searchText); @@ -50,8 +50,7 @@ const PeoplePage = () => { member={member} /> ); - - }) + }); return ( @@ -62,14 +61,19 @@ const PeoplePage = () => { label="Select employees..." placeholder="Member Name" value={searchText} - onChange={(e) => { + onChange={e => { setSearchText(e.target.value); }} /> - {loading ? Array.from({length: 20}).map((_, index) => ): - !loading ? createMemberCards : null} + {loading + ? Array.from({ length: 20 }).map((_, index) => ( + + )) + : !loading + ? createMemberCards + : null} diff --git a/web-ui/src/pages/PeoplePage.test.jsx b/web-ui/src/pages/PeoplePage.test.jsx index ac7542c4bb..16c8581061 100644 --- a/web-ui/src/pages/PeoplePage.test.jsx +++ b/web-ui/src/pages/PeoplePage.test.jsx @@ -1,8 +1,8 @@ -import React from "react"; -import PeoplePage from "./PeoplePage"; -import { AppContextProvider } from "../context/AppContext"; +import React from 'react'; +import PeoplePage from './PeoplePage'; +import { AppContextProvider } from '../context/AppContext'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/PermissionsPage.jsx b/web-ui/src/pages/PermissionsPage.jsx index 8be201b0b7..ab2b8a6e18 100644 --- a/web-ui/src/pages/PermissionsPage.jsx +++ b/web-ui/src/pages/PermissionsPage.jsx @@ -1,49 +1,54 @@ -import React, { useEffect, useContext, useState } from "react"; +import React, { useEffect, useContext, useState } from 'react'; -import { getPermissionsList } from "../api/permissions"; +import { getPermissionsList } from '../api/permissions'; import { getRolePermissionsList, postRolePermission, - deleteRolePermission, -} from "../api/rolepermissions"; -import { Checkbox, FormControl, MenuItem, Select, InputLabel } from "@mui/material"; -import { UPDATE_TOAST } from "../context/actions"; -import { AppContext } from "../context/AppContext"; -import { selectRoles, selectHasPermissionAssignmentPermission } from "../context/selectors"; - -import "./PermissionsPage.css"; - -const groupPermissionsByCategory = (permissions) => permissions.reduce((categories, permission) => { - const category = permission.category; - const existingCategory = categories.find(cat => cat.category === category); - - // If category exists, add permission to its permissions array - if (existingCategory) { - existingCategory.permissions.push(permission); - } else { - // Create a new category object and add it to categories - categories.push({ - category, - permissions: [permission], - }); - } + deleteRolePermission +} from '../api/rolepermissions'; +import { + Checkbox, + FormControl, + MenuItem, + Select, + InputLabel +} from '@mui/material'; +import { UPDATE_TOAST } from '../context/actions'; +import { AppContext } from '../context/AppContext'; +import { + selectRoles, + selectHasPermissionAssignmentPermission +} from '../context/selectors'; - return categories.sort((a,b) => a.category.localeCompare(b.category)); -}, []); +import './PermissionsPage.css'; -const PermissionEditor = ({ - permission, - title, - enabled, - onChange -}) => { +const groupPermissionsByCategory = permissions => + permissions.reduce((categories, permission) => { + const category = permission.category; + const existingCategory = categories.find(cat => cat.category === category); + + // If category exists, add permission to its permissions array + if (existingCategory) { + existingCategory.permissions.push(permission); + } else { + // Create a new category object and add it to categories + categories.push({ + category, + permissions: [permission] + }); + } + + return categories.sort((a, b) => a.category.localeCompare(b.category)); + }, []); + +const PermissionEditor = ({ permission, title, enabled, onChange }) => { return (
    @@ -51,17 +56,19 @@ const PermissionEditor = ({ }; const isPermissionEnabled = (rolePermissions, permission) => { - return rolePermissions.some((current) => { + return rolePermissions.some(current => { return current.permission === permission.permission; }); -} +}; const EditPermissionsPage = () => { const { state } = useContext(AppContext); const { csrf } = state; const roles = selectRoles(state); const hasPermission = selectHasPermissionAssignmentPermission(state); - const [selectedRole, setSelectedRole] = useState(roles && roles.find(()=>true)); + const [selectedRole, setSelectedRole] = useState( + roles && roles.find(() => true) + ); const [categoriesList, setCategoriesList] = useState([]); const [rolePermissionsList, setRolePermissionsList] = useState([]); const [rolePermissions, setRolePermissions] = useState([]); @@ -86,7 +93,7 @@ const EditPermissionsPage = () => { }; if (csrf) { - if(rolePermissionsList.length === 0){ + if (rolePermissionsList.length === 0) { getPermissions(); } getRolePermissions(); @@ -94,38 +101,51 @@ const EditPermissionsPage = () => { }, [csrf, refresh, rolePermissionsList.length]); useEffect(() => { - if(selectedRole && rolePermissionsList) { - const rolePermissions = rolePermissionsList.find((rolePermission) => rolePermission.roleId === selectedRole.id); + if (selectedRole && rolePermissionsList) { + const rolePermissions = rolePermissionsList.find( + rolePermission => rolePermission.roleId === selectedRole.id + ); rolePermissions && setRolePermissions(rolePermissions?.permissions); } - }, [selectedRole, rolePermissionsList]); - const handleRoleChange = (event) => { - setSelectedRole(roles.find((role) => role.id === event.target.value)); + const handleRoleChange = event => { + setSelectedRole(roles.find(role => role.id === event.target.value)); }; const addPermissionForRole = async (role, permission) => { let newSchema = { roleId: role.id, permission: permission.permission }; let res = await postRolePermission(newSchema, csrf); const snackPayload = res.error - ? { severity: "warning", toast: `Problem adding ${permission.description} to ${role.role}` } - : { severity: "success", toast: `${permission.description} added to ${role.role}` }; - window.snackDispatch({ - type: UPDATE_TOAST, - payload: snackPayload, - }); + ? { + severity: 'warning', + toast: `Problem adding ${permission.description} to ${role.role}` + } + : { + severity: 'success', + toast: `${permission.description} added to ${role.role}` + }; + window.snackDispatch({ + type: UPDATE_TOAST, + payload: snackPayload + }); }; const deletePermissionForRole = async (role, permission) => { let newSchema = { roleId: role.id, permission: permission.permission }; let res = await deleteRolePermission(newSchema, csrf); const snackPayload = res.error - ? { severity: "warning", toast: `Problem deleting ${permission.description} from ${role.role}` } - : { severity: "success", toast: `${permission.description} removed from ${role.role}` }; + ? { + severity: 'warning', + toast: `Problem deleting ${permission.description} from ${role.role}` + } + : { + severity: 'success', + toast: `${permission.description} removed from ${role.role}` + }; window.snackDispatch({ type: UPDATE_TOAST, - payload: snackPayload, + payload: snackPayload }); }; @@ -141,41 +161,45 @@ const EditPermissionsPage = () => { return (
    - { hasPermission ? - ( + {hasPermission ? ( <> -
    - - Select Role - - -
    - - { selectedRole && rolePermissions && categoriesList?.map((category) => ( -
    -

    {category?.category}:

    - { category?.permissions?.map((permission)=> ( - handleChange(event, selectedRole, permission)} /> - )) - } +
    + + Select Role + +
    - )) - } + + {selectedRole && + rolePermissions && + categoriesList?.map(category => ( +
    +

    {category?.category}:

    + {category?.permissions?.map(permission => ( + + handleChange(event, selectedRole, permission) + } + /> + ))} +
    + ))} ) : (

    You do not have permission to view this page.

    diff --git a/web-ui/src/pages/PermissionsPage.test.jsx b/web-ui/src/pages/PermissionsPage.test.jsx index 1da6c2294c..165dcca136 100644 --- a/web-ui/src/pages/PermissionsPage.test.jsx +++ b/web-ui/src/pages/PermissionsPage.test.jsx @@ -1,27 +1,27 @@ -import React from "react"; -import PermissionsPage from "./PermissionsPage"; -import { AppContextProvider } from "../context/AppContext"; +import React from 'react'; +import PermissionsPage from './PermissionsPage'; +import { AppContextProvider } from '../context/AppContext'; const initialState = { state: { userProfile: { - name: "holmes", - role: ["PDL"], - permissions: [{permission: "CAN_ASSIGN_ROLE_PERMISSIONS"}], + name: 'holmes', + role: ['PDL'], + permissions: [{ permission: 'CAN_ASSIGN_ROLE_PERMISSIONS' }], imageUrl: - "https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg", + 'https://upload.wikimedia.org/wikipedia/commons/7/74/SNL_MrBill_Doll.jpg' }, memberProfiles: [ { - id: "1234-5434-8765-3458", - name: "holmes", - }, + id: '1234-5434-8765-3458', + name: 'holmes' + } ], - index: 0, - }, + index: 0 + } }; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/ProfilePage.jsx b/web-ui/src/pages/ProfilePage.jsx index c959b71c9a..588d66b1cd 100644 --- a/web-ui/src/pages/ProfilePage.jsx +++ b/web-ui/src/pages/ProfilePage.jsx @@ -1,30 +1,27 @@ -import React, { useCallback, useContext, useEffect, useState } from "react"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; -import { debounce } from "lodash/function"; -import { AppContext } from "../context/AppContext"; +import { debounce } from 'lodash/function'; +import { AppContext } from '../context/AppContext'; import { selectCurrentUser, selectMyGuilds, selectUserProfile, - selectMyTeams, -} from "../context/selectors"; -import { - UPDATE_GUILD, - UPDATE_USER_BIO, -} from "../context/actions"; -import { addGuildMember, deleteGuildMember } from "../api/guild"; -import { updateMember } from "../api/member"; -import { getEmployeeHours } from "../api/hours"; -import Profile from "../components/profile/Profile"; -import SkillSection from "../components/skills/SkillSection"; -import ProgressBar from "../components/contribution_hours/ProgressBar"; - -import { Info } from "@mui/icons-material"; -import {Card, CardContent, CardHeader, Chip, TextField} from "@mui/material"; -import GroupIcon from "@mui/icons-material/Group"; + selectMyTeams +} from '../context/selectors'; +import { UPDATE_GUILD, UPDATE_USER_BIO } from '../context/actions'; +import { addGuildMember, deleteGuildMember } from '../api/guild'; +import { updateMember } from '../api/member'; +import { getEmployeeHours } from '../api/hours'; +import Profile from '../components/profile/Profile'; +import SkillSection from '../components/skills/SkillSection'; +import ProgressBar from '../components/contribution_hours/ProgressBar'; + +import { Info } from '@mui/icons-material'; +import { Card, CardContent, CardHeader, Chip, TextField } from '@mui/material'; +import GroupIcon from '@mui/icons-material/Group'; import Autocomplete from '@mui/material/Autocomplete'; -import "./ProfilePage.css"; +import './ProfilePage.css'; const realStoreMember = (member, csrf) => updateMember(member, csrf); @@ -65,14 +62,14 @@ const ProfilePage = () => { updateBio(); }, [bioText]); - const updateProfile = (newBio) => { + const updateProfile = newBio => { dispatch({ type: UPDATE_USER_BIO, - payload: newBio, + payload: newBio }); }; - const handleBioChange = (e) => { + const handleBioChange = e => { if (!csrf) { return; } @@ -83,24 +80,24 @@ const ProfilePage = () => { }; const addOrDeleteGuildMember = useCallback( - async (newVal) => { + async newVal => { if (!csrf) { return; } - const myGuildsSet = new Set(myGuilds?.map((guild) => guild.id)); - const newValSet = new Set(newVal?.map((val) => val.id)); + const myGuildsSet = new Set(myGuilds?.map(guild => guild.id)); + const newValSet = new Set(newVal?.map(val => val.id)); const newInSet1 = new Set( - [...myGuildsSet].filter((x) => !newValSet.has(x)) + [...myGuildsSet].filter(x => !newValSet.has(x)) ); const newInSet2 = new Set( - [...newValSet].filter((x) => !myGuildsSet.has(x)) + [...newValSet].filter(x => !myGuildsSet.has(x)) ); for (const guildId of newInSet2.values()) { let res = await addGuildMember(id, false, guildId, csrf); - const match = newVal.find((guild) => guild.id === guildId); + const match = newVal.find(guild => guild.id === guildId); let data = res.payload && res.payload.data && !res.error ? res.payload.data @@ -120,17 +117,17 @@ const ProfilePage = () => { } for (const guildId of newInSet1.values()) { - const match = myGuilds.find((guild) => guild.id === guildId); + const match = myGuilds.find(guild => guild.id === guildId); if (match) { const { guildMembers } = match; const memberToDelete = guildMembers.find( - (member) => member.memberId === id + member => member.memberId === id ); let res = await deleteGuildMember(memberToDelete.id, csrf); let success = res.payload && !res.error ? true : false; if (success) { const newGuildMembers = match.guildMembers.filter( - (member) => member.memberId !== id + member => member.memberId !== id ); let newGuild = { ...match }; newGuild.guildMembers = newGuildMembers; @@ -152,7 +149,7 @@ const ProfilePage = () => { } title="Bio" - titleTypographyProps={{ variant: "h5", component: "h2" }} + titleTypographyProps={{ variant: 'h5', component: 'h2' }} /> { )}
    ) : ( - "" + '' )}
    } title="Guilds" - titleTypographyProps={{ variant: "h5", component: "h2" }} + titleTypographyProps={{ variant: 'h5', component: 'h2' }} /> option.name} + getOptionLabel={option => option.name} isOptionEqualToValue={(option, value) => value && value.id === option.id } @@ -209,7 +206,7 @@ const ProfilePage = () => { options={guilds} required value={myGuilds} - renderInput={(params) => ( + renderInput={params => ( )} /> @@ -221,12 +218,12 @@ const ProfilePage = () => { } title="Teams" - titleTypographyProps={{ variant: "h5", component: "h1" }} + titleTypographyProps={{ variant: 'h5', component: 'h1' }} />
    {myTeams.length > 0 ? ( - myTeams.map((team) => ( + myTeams.map(team => ( { - const { state } = useContext(AppContext) - const csrf = selectCsrfToken(state) - const currentUserId = selectCurrentUserId(state) + const { state } = useContext(AppContext); + const csrf = selectCsrfToken(state); + const currentUserId = selectCurrentUserId(state); - const [searchText, setSearchText] = useState('') - const [sortValue, setSortValue] = useState(SortOption.SEND_DATE_DESCENDING) - const [isLoading, setIsLoading] = useState(true) + const [searchText, setSearchText] = useState(''); + const [sortValue, setSortValue] = useState(SortOption.SEND_DATE_DESCENDING); + const [isLoading, setIsLoading] = useState(true); - const [canceledRequests, setCanceledRequests] = useState([]) - const [receivedRequests, setReceivedRequests] = useState([]) - const [submittedRequests, setSubmittedRequests] = useState([]) + const [canceledRequests, setCanceledRequests] = useState([]); + const [receivedRequests, setReceivedRequests] = useState([]); + const [submittedRequests, setSubmittedRequests] = useState([]); - const [filteredCanceledRequests, setFilteredCanceledRequests] = useState([]) - const [filteredReceivedRequests, setFilteredReceivedRequests] = useState([]) - const [filteredSubmittedRequests, setFilteredSubmittedRequests] = useState( - [] - ) + const [filteredCanceledRequests, setFilteredCanceledRequests] = useState([]); + const [filteredReceivedRequests, setFilteredReceivedRequests] = useState([]); + const [filteredSubmittedRequests, setFilteredSubmittedRequests] = useState( + [] + ); - const [canceledRequestsExpanded, setCanceledRequestsExpanded] = - useState(false) - const [receivedRequestsExpanded, setReceivedRequestsExpanded] = - useState(true) - const [submittedRequestsExpanded, setSubmittedRequestsExpanded] = - useState(false) + const [canceledRequestsExpanded, setCanceledRequestsExpanded] = + useState(false); + const [receivedRequestsExpanded, setReceivedRequestsExpanded] = + useState(true); + const [submittedRequestsExpanded, setSubmittedRequestsExpanded] = + useState(false); - useEffect(() => { - const getAllFeedbackRequests = async () => { - let res = await getFeedbackRequestsByRecipient(currentUserId, csrf) - if (res && res.payload && res.payload.data && !res.error) { - return res.payload.data - } else { - window.snackDispatch({ - type: UPDATE_TOAST, - payload: { - severity: 'error', - toast: res.error, - }, - }) - } - } + useEffect(() => { + const getAllFeedbackRequests = async () => { + let res = await getFeedbackRequestsByRecipient(currentUserId, csrf); + if (res && res.payload && res.payload.data && !res.error) { + return res.payload.data; + } else { + window.snackDispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: res.error + } + }); + } + }; - if (csrf && currentUserId) { - getAllFeedbackRequests().then((data) => { - if (data) { - setCanceledRequests( - data.filter((req) => req.status === 'canceled') - ) - setReceivedRequests( - data.filter( - (req) => - !req.submitDate && - req.status !== 'canceled' - ) - ) - setSubmittedRequests( - data.filter( - (req) => - req.submitDate && - req.submitDate.length === 3 && - req.status !== 'canceled' - ) - ) - setIsLoading(false) - } - }) + if (csrf && currentUserId) { + getAllFeedbackRequests().then(data => { + if (data) { + setCanceledRequests(data.filter(req => req.status === 'canceled')); + setReceivedRequests( + data.filter(req => !req.submitDate && req.status !== 'canceled') + ); + setSubmittedRequests( + data.filter( + req => + req.submitDate && + req.submitDate.length === 3 && + req.status !== 'canceled' + ) + ); + setIsLoading(false); } - }, [csrf, currentUserId]) - useEffect(() => { - let filteredCanceled = [...canceledRequests] - let filteredReceived = [...receivedRequests] - let filteredSubmitted = [...submittedRequests] + }); + } + }, [csrf, currentUserId]); + useEffect(() => { + let filteredCanceled = [...canceledRequests]; + let filteredReceived = [...receivedRequests]; + let filteredSubmitted = [...submittedRequests]; - // Search for intersection of multiple queries separated by commas - const queries = searchText - .split(',') - .map((search) => search.trim().toLowerCase()) + // Search for intersection of multiple queries separated by commas + const queries = searchText + .split(',') + .map(search => search.trim().toLowerCase()); - if (searchText.trim()) { - for (let query of queries) { - const setFiltered = (filteredOption) => { - return filteredOption.filter((request) => { - const creatorName = selectProfile( - state, - request.creatorId - ).name.toLowerCase() - const requesteeName = selectProfile( - state, - request.requesteeId - ).name.toLowerCase() - return ( - creatorName.includes(query) || - requesteeName.includes(query) - ) - }) - } - filteredCanceled = setFiltered(filteredCanceled) - filteredReceived = setFiltered(filteredReceived) - filteredSubmitted = setFiltered(filteredSubmitted) - } - } + if (searchText.trim()) { + for (let query of queries) { + const setFiltered = filteredOption => { + return filteredOption.filter(request => { + const creatorName = selectProfile( + state, + request.creatorId + ).name.toLowerCase(); + const requesteeName = selectProfile( + state, + request.requesteeId + ).name.toLowerCase(); + return creatorName.includes(query) || requesteeName.includes(query); + }); + }; + filteredCanceled = setFiltered(filteredCanceled); + filteredReceived = setFiltered(filteredReceived); + filteredSubmitted = setFiltered(filteredSubmitted); + } + } - // Sort according to selected sort option - let sortMethod - switch (sortValue) { - case SortOption.SEND_DATE_ASCENDING: - sortMethod = (a, b) => - new Date(a.sendDate) > new Date(b.sendDate) ? 1 : -1 - break - case SortOption.SEND_DATE_DESCENDING: - sortMethod = (a, b) => - new Date(a.sendDate) > new Date(b.sendDate) ? -1 : 1 - break - case SortOption.DUE_DATE: - sortMethod = (a, b) => { - if (a.dueDate && b.dueDate) { - return new Date(a.dueDate) > new Date(b.dueDate) - ? 1 - : -1 - } - return !a.dueDate && b.dueDate ? 1 : -1 - } - break - default: - console.warn( - `Invalid sort option ${sortValue} provided for received requests` - ) - } + // Sort according to selected sort option + let sortMethod; + switch (sortValue) { + case SortOption.SEND_DATE_ASCENDING: + sortMethod = (a, b) => + new Date(a.sendDate) > new Date(b.sendDate) ? 1 : -1; + break; + case SortOption.SEND_DATE_DESCENDING: + sortMethod = (a, b) => + new Date(a.sendDate) > new Date(b.sendDate) ? -1 : 1; + break; + case SortOption.DUE_DATE: + sortMethod = (a, b) => { + if (a.dueDate && b.dueDate) { + return new Date(a.dueDate) > new Date(b.dueDate) ? 1 : -1; + } + return !a.dueDate && b.dueDate ? 1 : -1; + }; + break; + default: + console.warn( + `Invalid sort option ${sortValue} provided for received requests` + ); + } - filteredCanceled.sort(sortMethod) - filteredReceived.sort(sortMethod) - filteredSubmitted.sort(sortMethod) + filteredCanceled.sort(sortMethod); + filteredReceived.sort(sortMethod); + filteredSubmitted.sort(sortMethod); - setFilteredCanceledRequests(filteredCanceled) - setFilteredReceivedRequests(filteredReceived) - setFilteredSubmittedRequests(filteredSubmitted) - }, [ - state, - canceledRequests, - receivedRequests, - submittedRequests, - searchText, - sortValue, - ]) + setFilteredCanceledRequests(filteredCanceled); + setFilteredReceivedRequests(filteredReceived); + setFilteredSubmittedRequests(filteredSubmitted); + }, [ + state, + canceledRequests, + receivedRequests, + submittedRequests, + searchText, + sortValue + ]); - return ( - -
    - - Received Feedback Requests - -
    - { - setSearchText(event.target.value) - setReceivedRequestsExpanded(true) - setSubmittedRequestsExpanded(true) - }} - InputProps={{ - endAdornment: ( - - - - ), - }} - /> + return ( + +
    + + Received Feedback Requests + +
    + { + setSearchText(event.target.value); + setReceivedRequestsExpanded(true); + setSubmittedRequestsExpanded(true); + }} + InputProps={{ + endAdornment: ( + + + + ) + }} + /> - - setSortValue(e.target.value)} - defaultValue={SortOption.SEND_DATE_ASCENDING} - variant="outlined" - > - - Send date (least recent) - - - Send date (most recent) - - - Due date - - - -
    -
    -
    - Received Requests - - setReceivedRequestsExpanded(!receivedRequestsExpanded) - } - aria-label="show more" - className={ - receivedRequestsExpanded - ? classes.expandOpen - : classes.expandClose - } - size="large" - > - - -
    - - + setSortValue(e.target.value)} + defaultValue={SortOption.SEND_DATE_ASCENDING} + variant="outlined" > -
    - - {receivedRequests.length} received request - {receivedRequests.length === 1 ? '' : 's'} currently - hidden - + + Send date (least recent) + + + Send date (most recent) + + Due date + + +
    +
    +
    + Received Requests + setReceivedRequestsExpanded(!receivedRequestsExpanded)} + aria-label="show more" + className={ + receivedRequestsExpanded ? classes.expandOpen : classes.expandClose + } + size="large" + > + + +
    + + +
    + + {receivedRequests.length} received request + {receivedRequests.length === 1 ? '' : 's'} currently hidden + +
    +
    + + {isLoading && ( +
    + {Array.from({ length: 1 }).map((_, index) => ( + + ))} +
    + )} + {!isLoading && ( +
    + {filteredReceivedRequests.length === 0 && ( +
    + + No received feedback requests + +
    + )} + {filteredReceivedRequests.map(request => ( + + ))} +
    + )} +
    +
    + Submitted Requests + + setSubmittedRequestsExpanded(!submittedRequestsExpanded) + } + aria-label="show more" + className={ + submittedRequestsExpanded ? classes.expandOpen : classes.expandClose + } + size="large" + > + + +
    + + + {isLoading && ( +
    + {Array.from({ length: 1 }).map((_, index) => ( + + ))} +
    + )} + {!isLoading && ( +
    + + {submittedRequests.length} submitted request + {submittedRequests.length === 1 ? '' : 's'} currently hidden + +
    + )} +
    + + {!isLoading && ( +
    + {submittedRequests.length === 0 && ( +
    + + No submitted feedback requests + +
    + )} + {submittedRequests.length > 0 && + filteredSubmittedRequests.length === 0 && ( +
    + + No submitted feedback requests +
    - - - {isLoading && ( -
    - {Array.from({ length: 1 }).map((_, index) => ( - - ))} -
    - )} - {!isLoading && ( -
    - {filteredReceivedRequests.length === 0 && ( -
    - - No received feedback requests - -
    - )} - {filteredReceivedRequests.map((request) => ( - - ))} -
    - )} -
    -
    - Submitted Requests - - setSubmittedRequestsExpanded(!submittedRequestsExpanded) - } - aria-label="show more" - className={ - submittedRequestsExpanded - ? classes.expandOpen - : classes.expandClose - } - size="large" - > - - -
    - - - {isLoading && ( -
    - {Array.from({ length: 1 }).map((_, index) => ( - - ))} -
    - )} - {!isLoading && ( -
    - - {submittedRequests.length} submitted request - {submittedRequests.length === 1 ? '' : 's'}{' '} - currently hidden - -
    - )} -
    - - {!isLoading && ( -
    - {submittedRequests.length === 0 && ( -
    - - No submitted feedback requests - -
    - )} - {submittedRequests.length > 0 && - filteredSubmittedRequests.length === 0 && ( -
    - - No submitted feedback requests - -
    - )} - {filteredSubmittedRequests.map((request) => ( - - ))} -
    - )} -
    -
    - Canceled Requests - - setCanceledRequestsExpanded(!canceledRequestsExpanded) - } - aria-label="show more" - className={ - canceledRequestsExpanded - ? classes.expandOpen - : classes.expandClose - } - size="large" - > - - -
    - - - {isLoading && ( -
    - {Array.from({ length: 1 }).map((_, index) => ( - - ))} -
    - )} - {!isLoading && ( -
    - - {canceledRequests.length} canceled request - {canceledRequests.length === 1 ? '' : 's'} currently - hidden - -
    - )} -
    - - {!isLoading && ( -
    - {canceledRequests.length === 0 && ( -
    - - No canceled feedback requests - -
    - )} - {canceledRequests.length > 0 && - filteredCanceledRequests.length === 0 && ( -
    - - No canceled feedback requests - -
    - )} - {filteredCanceledRequests.map((request) => ( - - ))} -
    - )} -
    - - ) -} + )} + {filteredSubmittedRequests.map(request => ( + + ))} +
    + )} +
    +
    + Canceled Requests + setCanceledRequestsExpanded(!canceledRequestsExpanded)} + aria-label="show more" + className={ + canceledRequestsExpanded ? classes.expandOpen : classes.expandClose + } + size="large" + > + + +
    + + + {isLoading && ( +
    + {Array.from({ length: 1 }).map((_, index) => ( + + ))} +
    + )} + {!isLoading && ( +
    + + {canceledRequests.length} canceled request + {canceledRequests.length === 1 ? '' : 's'} currently hidden + +
    + )} +
    + + {!isLoading && ( +
    + {canceledRequests.length === 0 && ( +
    + + No canceled feedback requests + +
    + )} + {canceledRequests.length > 0 && + filteredCanceledRequests.length === 0 && ( +
    + + No canceled feedback requests + +
    + )} + {filteredCanceledRequests.map(request => ( + + ))} +
    + )} +
    + + ); +}; -export default ReceivedRequestsPage +export default ReceivedRequestsPage; diff --git a/web-ui/src/pages/SkillCategoriesPage.css b/web-ui/src/pages/SkillCategoriesPage.css index eb93952daa..df91a48390 100644 --- a/web-ui/src/pages/SkillCategoriesPage.css +++ b/web-ui/src/pages/SkillCategoriesPage.css @@ -1,51 +1,57 @@ .SkillCategoriesPage-root .skill-categories-header { - display: flex; - flex-direction: row; - justify-content: space-between; - margin-bottom: 1rem; - flex-wrap: wrap; + display: flex; + flex-direction: row; + justify-content: space-between; + margin-bottom: 1rem; + flex-wrap: wrap; } .SkillCategoriesPage-root .skill-categories-actions { - display: flex; - flex-direction: row; - gap: 1rem; - align-items: center; - justify-content: flex-end; - flex-wrap: wrap; + display: flex; + flex-direction: row; + gap: 1rem; + align-items: center; + justify-content: flex-end; + flex-wrap: wrap; } @media screen and (max-width: 600px) { - .SkillCategoriesPage-root .skill-categories-header { - display: flex; - flex-direction: column; - gap: 1rem; - } + .SkillCategoriesPage-root .skill-categories-header { + display: flex; + flex-direction: column; + gap: 1rem; + } - .SkillCategoriesPage-root .skill-categories-actions { - display: grid; - grid-template-rows: 1fr 1fr; - grid-template-columns: 1fr 150px; - } + .SkillCategoriesPage-root .skill-categories-actions { + display: grid; + grid-template-rows: 1fr 1fr; + grid-template-columns: 1fr 150px; + } - .SkillCategoriesPage-root .skill-categories-actions .search-skill-categories-field { - grid-row: 1; - grid-column: 1; - } + .SkillCategoriesPage-root + .skill-categories-actions + .search-skill-categories-field { + grid-row: 1; + grid-column: 1; + } - .SkillCategoriesPage-root .skill-categories-actions .download-skills-button { - grid-row: 1; - grid-column: 2; - justify-self: center; - } + .SkillCategoriesPage-root .skill-categories-actions .download-skills-button { + grid-row: 1; + grid-column: 2; + justify-self: center; + } - .SkillCategoriesPage-root .skill-categories-actions .filter-skill-categories-field { - grid-row: 2; - grid-column: 1; - } + .SkillCategoriesPage-root + .skill-categories-actions + .filter-skill-categories-field { + grid-row: 2; + grid-column: 1; + } - .SkillCategoriesPage-root .skill-categories-actions .new-skill-category-button { - grid-row: 2; - grid-column: 2; - } -} \ No newline at end of file + .SkillCategoriesPage-root + .skill-categories-actions + .new-skill-category-button { + grid-row: 2; + grid-column: 2; + } +} diff --git a/web-ui/src/pages/SkillCategoriesPage.jsx b/web-ui/src/pages/SkillCategoriesPage.jsx index 1d4afcabb2..e8d8388af9 100644 --- a/web-ui/src/pages/SkillCategoriesPage.jsx +++ b/web-ui/src/pages/SkillCategoriesPage.jsx @@ -1,7 +1,7 @@ -import React, {useCallback, useContext, useEffect, useState} from "react"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { styled } from '@mui/material/styles'; -import { AppContext } from "../context/AppContext"; +import { AppContext } from '../context/AppContext'; import fileDownload from 'js-file-download'; @@ -10,43 +10,46 @@ import { DialogActions, DialogContent, DialogContentText, - DialogTitle, IconButton, - TextField, Tooltip, + DialogTitle, + IconButton, + TextField, + Tooltip, Typography -} from "@mui/material"; -import SkillCategoryCard from "../components/skill-category-card/SkillCategoryCard"; +} from '@mui/material'; +import SkillCategoryCard from '../components/skill-category-card/SkillCategoryCard'; -import "./SkillCategoriesPage.css"; -import {selectCsrfToken, selectOrderedSkills} from "../context/selectors"; +import './SkillCategoriesPage.css'; +import { selectCsrfToken, selectOrderedSkills } from '../context/selectors'; import { createSkillCategory, deleteSkillCategory, - getSkillCategories, getSkillsCsv -} from "../api/skillcategory"; -import SkillCategoryNewDialog from "../components/skill-category-new-dialog/SkillCategoryNewDialog"; -import {UPDATE_TOAST} from "../context/actions"; -import Dialog from "@mui/material/Dialog"; -import InputAdornment from "@mui/material/InputAdornment"; -import {Search} from "@mui/icons-material"; -import Autocomplete from "@mui/material/Autocomplete"; -import DownloadIcon from "@mui/icons-material/FileDownload"; + getSkillCategories, + getSkillsCsv +} from '../api/skillcategory'; +import SkillCategoryNewDialog from '../components/skill-category-new-dialog/SkillCategoryNewDialog'; +import { UPDATE_TOAST } from '../context/actions'; +import Dialog from '@mui/material/Dialog'; +import InputAdornment from '@mui/material/InputAdornment'; +import { Search } from '@mui/icons-material'; +import Autocomplete from '@mui/material/Autocomplete'; +import DownloadIcon from '@mui/icons-material/FileDownload'; const PREFIX = 'SkillCategoriesPage'; const classes = { - root: `${PREFIX}-root`, + root: `${PREFIX}-root` }; const Root = styled('div')({ [`&.${classes.root}`]: { - backgroundColor: "transparent", - margin: "4rem 2rem 2rem 2rem", - height: "100%", - maxWidth: "100%", + backgroundColor: 'transparent', + margin: '4rem 2rem 2rem 2rem', + height: '100%', + maxWidth: '100%', '@media (max-width: 800px)': { - display: "flex", - flexDirection: "column", - overflowX: "hidden", - margin: "2rem 5% 0 5%", + display: 'flex', + flexDirection: 'column', + overflowX: 'hidden', + margin: '2rem 5% 0 5%' } } }); @@ -59,7 +62,7 @@ const SkillCategoriesPage = () => { const [skillCategories, setSkillCategories] = useState([]); const [dialogOpen, setDialogOpen] = useState(false); const [categoryToDelete, setCategoryToDelete] = useState(null); - const [query, setQuery] = useState(""); + const [query, setQuery] = useState(''); const [skillFilter, setSkillFilter] = useState(null); const retrieveCategories = useCallback(async () => { @@ -81,8 +84,8 @@ const SkillCategoriesPage = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to remove skill from category" + severity: 'error', + toast: 'Failed to remove skill from category' } }); } @@ -106,34 +109,33 @@ const SkillCategoriesPage = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Error: Could not save category" + severity: 'error', + toast: 'Error: Could not save category' } }); } - } + }; const downloadSkills = useCallback(async () => { let res = await getSkillsCsv(csrf); if (!res.error && res.payload.data) { - fileDownload(res.payload.data, "skill_records.csv"); + fileDownload(res.payload.data, 'skill_records.csv'); dispatch({ type: UPDATE_TOAST, payload: { - severity: "success", - toast: "Skills successfully exported" + severity: 'success', + toast: 'Skills successfully exported' } }); } else { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to export skills" + severity: 'error', + toast: 'Failed to export skills' } }); } - }, [csrf, dispatch]); const getFilteredCategories = useCallback(() => { @@ -147,7 +149,9 @@ const SkillCategoriesPage = () => { let skillMatches = true; if (skillFilter) { - skillMatches = category.skills.find(skill => skill.name === skillFilter.name); + skillMatches = category.skills.find( + skill => skill.name === skillFilter.name + ); } return nameMatches && skillMatches; @@ -162,34 +166,42 @@ const SkillCategoriesPage = () => {
    Skill Categories
    - + - + setQuery(event.target.value)} + onChange={event => setQuery(event.target.value)} InputProps={{ - endAdornment: + endAdornment: ( + + + + ) }} /> option.name} + getOptionLabel={option => option.name} filterSelectedOptions value={skillFilter} onChange={(_, newValue) => setSkillFilter(newValue)} - renderInput={(params) => ( + renderInput={params => ( { />
    - {getFilteredCategories().map(category => + {getFilteredCategories().map(category => ( { skills={category.skills} onDelete={() => setCategoryToDelete(category)} /> - )} + ))} setDialogOpen(false)} onConfirm={(categoryName, categoryDescription) => { - createNewSkillCategory(categoryName, categoryDescription) - .then(() => setDialogOpen(false)); + createNewSkillCategory(categoryName, categoryDescription).then(() => + setDialogOpen(false) + ); }} /> - {categoryToDelete && + {categoryToDelete && ( setCategoryToDelete(null)}> + onClose={() => setCategoryToDelete(null)} + > Delete Category? - Are you sure you want to delete the category "{categoryToDelete.name}"? The skills in this category will not be deleted. + + Are you sure you want to delete the category " + {categoryToDelete.name}"? The skills in this category will not be + deleted. + - } + )} ); }; -export default SkillCategoriesPage; \ No newline at end of file +export default SkillCategoriesPage; diff --git a/web-ui/src/pages/SkillCategoriesPage.test.jsx b/web-ui/src/pages/SkillCategoriesPage.test.jsx index e06916d3e3..4c4fe4f14a 100644 --- a/web-ui/src/pages/SkillCategoriesPage.test.jsx +++ b/web-ui/src/pages/SkillCategoriesPage.test.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import {AppContextProvider} from "../context/AppContext"; -import SkillCategoriesPage from "./SkillCategoriesPage"; +import React from 'react'; +import { AppContextProvider } from '../context/AppContext'; +import SkillCategoriesPage from './SkillCategoriesPage'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/pages/SkillCategoryEditPage.css b/web-ui/src/pages/SkillCategoryEditPage.css index 9be13d16dc..ffd9cc92ef 100644 --- a/web-ui/src/pages/SkillCategoryEditPage.css +++ b/web-ui/src/pages/SkillCategoryEditPage.css @@ -1,16 +1,14 @@ .SkillCategoryEditPage-root .edit-skill-category-fields { - margin: 2rem 0; - display: flex; - flex-direction: row; - gap: 2rem; + margin: 2rem 0; + display: flex; + flex-direction: row; + gap: 2rem; } @media screen and (max-width: 600px) { - - .SkillCategoryEditPage-root .edit-skill-category-fields { - display: flex; - flex-direction: column; - gap: 1rem; - } - -} \ No newline at end of file + .SkillCategoryEditPage-root .edit-skill-category-fields { + display: flex; + flex-direction: column; + gap: 1rem; + } +} diff --git a/web-ui/src/pages/SkillCategoryEditPage.jsx b/web-ui/src/pages/SkillCategoryEditPage.jsx index 3ffe143cd4..50a3f73fdf 100644 --- a/web-ui/src/pages/SkillCategoryEditPage.jsx +++ b/web-ui/src/pages/SkillCategoryEditPage.jsx @@ -1,12 +1,16 @@ -import React, {useCallback, useContext, useEffect, useState} from "react"; -import {useParams} from "react-router-dom"; -import {AppContext} from "../context/AppContext"; -import {styled} from "@mui/material/styles"; +import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { AppContext } from '../context/AppContext'; +import { styled } from '@mui/material/styles'; import { Button, Card, - CardHeader, DialogActions, DialogContent, DialogContentText, DialogTitle, + CardHeader, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, IconButton, List, ListItem, @@ -14,38 +18,38 @@ import { TextField, Tooltip, Typography -} from "@mui/material"; -import RemoveIcon from "@mui/icons-material/Remove"; +} from '@mui/material'; +import RemoveIcon from '@mui/icons-material/Remove'; import { createSkillCategorySkills, deleteSkillCategorySkill, getSkillCategory, updateSkillCategory -} from "../api/skillcategory"; -import {selectCsrfToken, selectOrderedSkills} from "../context/selectors"; -import {Add} from "@mui/icons-material"; -import SelectSkillsDialog from "../components/select-skills-dialog/SelectSkillsDialog"; -import {UPDATE_TOAST} from "../context/actions"; -import Dialog from "@mui/material/Dialog"; +} from '../api/skillcategory'; +import { selectCsrfToken, selectOrderedSkills } from '../context/selectors'; +import { Add } from '@mui/icons-material'; +import SelectSkillsDialog from '../components/select-skills-dialog/SelectSkillsDialog'; +import { UPDATE_TOAST } from '../context/actions'; +import Dialog from '@mui/material/Dialog'; -import "./SkillCategoryEditPage.css"; +import './SkillCategoryEditPage.css'; const PREFIX = 'SkillCategoryEditPage'; const classes = { - root: `${PREFIX}-root`, + root: `${PREFIX}-root` }; const Root = styled('div')({ [`&.${classes.root}`]: { - backgroundColor: "transparent", - margin: "4rem 2rem 2rem 2rem", - height: "100%", - maxWidth: "100%", + backgroundColor: 'transparent', + margin: '4rem 2rem 2rem 2rem', + height: '100%', + maxWidth: '100%', '@media (max-width: 800px)': { - display: "flex", - flexDirection: "column", - overflowX: "hidden", - margin: "2rem 5% 0 5%", + display: 'flex', + flexDirection: 'column', + overflowX: 'hidden', + margin: '2rem 5% 0 5%' } } }); @@ -74,10 +78,13 @@ const SkillCategoryEditPage = () => { return []; }, [category, skills]); - const retrieveSkillCategory = useCallback(async (categoryId) => { - const res = await getSkillCategory(categoryId, csrf); - return !res.error ? res.payload.data : null; - }, [csrf]); + const retrieveSkillCategory = useCallback( + async categoryId => { + const res = await getSkillCategory(categoryId, csrf); + return !res.error ? res.payload.data : null; + }, + [csrf] + ); useEffect(() => { if (categoryId) { @@ -93,42 +100,49 @@ const SkillCategoryEditPage = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to refresh category" + severity: 'error', + toast: 'Failed to refresh category' } }); } }); }, [categoryId, dispatch, retrieveSkillCategory]); - const saveCategorySkillIds = useCallback(async (skillIds) => { - if (categoryId) { - const res = await createSkillCategorySkills(categoryId, skillIds, csrf); - if (res.error) { - dispatch({ - type: UPDATE_TOAST, - payload: { - severity: "error", - toast: "Failed to add skill(s) to category" - } + const saveCategorySkillIds = useCallback( + async skillIds => { + if (categoryId) { + const res = await createSkillCategorySkills(categoryId, skillIds, csrf); + if (res.error) { + dispatch({ + type: UPDATE_TOAST, + payload: { + severity: 'error', + toast: 'Failed to add skill(s) to category' + } + }); + } + + refreshSkillCategory().then(() => { + setAddSkillsDialogOpen(false); }); } - - refreshSkillCategory().then(() => { - setAddSkillsDialogOpen(false); - }); - } - }, [categoryId, csrf, dispatch, refreshSkillCategory]); + }, + [categoryId, csrf, dispatch, refreshSkillCategory] + ); const removeSkillFromCategory = useCallback(async () => { if (skillToRemove) { - const res = await deleteSkillCategorySkill(categoryId, skillToRemove.id, csrf); + const res = await deleteSkillCategorySkill( + categoryId, + skillToRemove.id, + csrf + ); if (res.payload.status !== 200) { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to remove skill from category" + severity: 'error', + toast: 'Failed to remove skill from category' } }); } @@ -145,8 +159,8 @@ const SkillCategoryEditPage = () => { dispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Failed to update category" + severity: 'error', + toast: 'Failed to update category' } }); } @@ -158,9 +172,9 @@ const SkillCategoryEditPage = () => {
    { + style={{ width: '250px' }} + value={category ? category.name : ''} + onChange={event => { setCategory({ ...category, name: event.target.value @@ -170,9 +184,9 @@ const SkillCategoryEditPage = () => { /> { + style={{ width: '400px' }} + value={category ? category.description : ''} + onChange={event => { setCategory({ ...category, description: event.target.value @@ -186,53 +200,60 @@ const SkillCategoryEditPage = () => { title="Category Skills" action={ - setAddSkillsDialogOpen(true)}> + setAddSkillsDialogOpen(true)}> + + } /> - - {category && ( - category.skills.length ? ( - category.skills.map(skill => + + {category && + (category.skills.length ? ( + category.skills.map(skill => ( - setSkillToRemove(skill)}> + setSkillToRemove(skill)}> + + } > {skill.description}} + secondary={ + + {skill.description} + + } /> - ) + )) ) : ( - This category contains no skills - ) - )} + + This category contains no skills + + ))} - {addSkillsDialogOpen && + {addSkillsDialogOpen && ( setAddSkillsDialogOpen(false)} selectableSkills={getSelectableSkills()} onSave={saveCategorySkillIds} /> - } - {skillToRemove && - setSkillToRemove(null)}> + )} + {skillToRemove && ( + setSkillToRemove(null)}> Remove Skill? - Are you sure you want to remove "{skillToRemove.name}" from {category.name}? The skill itself will not be deleted. + + Are you sure you want to remove "{skillToRemove.name}" from{' '} + {category.name}? The skill itself will not be deleted. + - } + )} - ) + ); }; -export default SkillCategoryEditPage; \ No newline at end of file +export default SkillCategoryEditPage; diff --git a/web-ui/src/pages/SkillCategoryEditPage.test.jsx b/web-ui/src/pages/SkillCategoryEditPage.test.jsx index 04ff8cfd21..55e8305e57 100644 --- a/web-ui/src/pages/SkillCategoryEditPage.test.jsx +++ b/web-ui/src/pages/SkillCategoryEditPage.test.jsx @@ -1,9 +1,9 @@ -import React from "react"; -import {AppContextProvider} from "../context/AppContext"; -import SkillCategoryEditPage from "./SkillCategoryEditPage"; -import {BrowserRouter} from "react-router-dom"; +import React from 'react'; +import { AppContextProvider } from '../context/AppContext'; +import SkillCategoryEditPage from './SkillCategoryEditPage'; +import { BrowserRouter } from 'react-router-dom'; -it("renders correctly", () => { +it('renders correctly', () => { snapshot( @@ -11,4 +11,4 @@ it("renders correctly", () => { ); -}); \ No newline at end of file +}); diff --git a/web-ui/src/pages/SkillReportPage.css b/web-ui/src/pages/SkillReportPage.css index efb241557f..0c7f3de106 100644 --- a/web-ui/src/pages/SkillReportPage.css +++ b/web-ui/src/pages/SkillReportPage.css @@ -1,29 +1,29 @@ -.skills-report-page { - margin: 2rem; - align-items: center; -} - -.member-skills-card { - max-height: 20rem; - width: flex; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.skills-list { - margin: 1rem; -} - -.search { - display: flex; - justify-content: space-between; - align-items: center; - margin-left: 1rem; - margin-right: 1rem; -} - -.results-section { - align-items: center; - justify-content: space-between; -} \ No newline at end of file +.skills-report-page { + margin: 2rem; + align-items: center; +} + +.member-skills-card { + max-height: 20rem; + width: flex; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.skills-list { + margin: 1rem; +} + +.search { + display: flex; + justify-content: space-between; + align-items: center; + margin-left: 1rem; + margin-right: 1rem; +} + +.results-section { + align-items: center; + justify-content: space-between; +} diff --git a/web-ui/src/pages/SkillReportPage.jsx b/web-ui/src/pages/SkillReportPage.jsx index 7a0b1b9076..fa40d6dd19 100644 --- a/web-ui/src/pages/SkillReportPage.jsx +++ b/web-ui/src/pages/SkillReportPage.jsx @@ -1,21 +1,21 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useState } from 'react'; -import { AppContext } from "../context/AppContext"; -import { reportSkills } from "../api/memberskill.js"; -import SearchResults from "../components/search-results/SearchResults"; +import { AppContext } from '../context/AppContext'; +import { reportSkills } from '../api/memberskill.js'; +import SearchResults from '../components/search-results/SearchResults'; import { selectOrderedSkills, selectCsrfToken, - selectCurrentMemberIds, -} from "../context/selectors"; + selectCurrentMemberIds +} from '../context/selectors'; -import { Button, TextField } from "@mui/material"; +import { Button, TextField } from '@mui/material'; import Autocomplete from '@mui/material/Autocomplete'; -import "./SkillReportPage.css"; +import './SkillReportPage.css'; -const SkillReportPage = (props) => { +const SkillReportPage = props => { const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); const skills = selectOrderedSkills(state); @@ -23,11 +23,10 @@ const SkillReportPage = (props) => { const [searchResults, setSearchResults] = useState([]); const [searchRequestDTO] = useState([]); const [searchSkills, setSearchSkills] = useState([]); - const [editedSearchRequest, setEditedSearchRequest] = useState( - searchRequestDTO - ); + const [editedSearchRequest, setEditedSearchRequest] = + useState(searchRequestDTO); - const handleSearch = async (searchRequestDTO) => { + const handleSearch = async searchRequestDTO => { let res = await reportSkills(searchRequestDTO, csrf); let memberSkillsFound; if (res && res.payload) { @@ -37,7 +36,9 @@ const SkillReportPage = (props) => { : undefined; } // Filter out skills of terminated members - memberSkillsFound = memberSkillsFound.filter(memberSkill => memberIds.includes(memberSkill.id)); + memberSkillsFound = memberSkillsFound.filter(memberSkill => + memberIds.includes(memberSkill.id) + ); if (memberSkillsFound && memberIds) { setSearchResults(memberSkillsFound); } else { @@ -49,7 +50,7 @@ const SkillReportPage = (props) => { return skills.map((skill, index) => { let skillLevel = { id: skill.id, - level: skill.skilllevel, + level: skill.skilllevel }; return skillLevel; }); @@ -62,7 +63,7 @@ const SkillReportPage = (props) => { let newSearchRequest = { skills: skills, members: members, - inclusive: inclusive, + inclusive: inclusive }; setEditedSearchRequest(newSearchRequest); return newSearchRequest; @@ -84,8 +85,8 @@ const SkillReportPage = (props) => { filterSelectedOptions value={searchSkills ? searchSkills : []} onChange={onSkillsChange} - getOptionLabel={(option) => option.name} - renderInput={(params) => ( + getOptionLabel={option => option.name} + renderInput={params => ( { +it('renders correctly', () => { snapshot( diff --git a/web-ui/src/pages/TeamSkillReportPage.css b/web-ui/src/pages/TeamSkillReportPage.css index d0a9b4e817..838d01ac2a 100644 --- a/web-ui/src/pages/TeamSkillReportPage.css +++ b/web-ui/src/pages/TeamSkillReportPage.css @@ -30,4 +30,3 @@ width: 100%; } } - diff --git a/web-ui/src/pages/TeamSkillReportPage.jsx b/web-ui/src/pages/TeamSkillReportPage.jsx index efafadd53f..add3e319eb 100644 --- a/web-ui/src/pages/TeamSkillReportPage.jsx +++ b/web-ui/src/pages/TeamSkillReportPage.jsx @@ -1,20 +1,25 @@ -import React, {useContext, useState} from "react"; - -import {reportSkills} from "../api/memberskill.js"; -import SearchResults from "../components/search-results/SearchResults"; -import {UPDATE_TOAST} from "../context/actions"; -import {AppContext} from "../context/AppContext"; -import {selectCsrfToken, selectOrderedMemberFirstName, selectOrderedSkills, selectSkill,} from "../context/selectors"; -import {levelMap} from "../context/util"; - -import {Button, TextField} from "@mui/material"; +import React, { useContext, useState } from 'react'; + +import { reportSkills } from '../api/memberskill.js'; +import SearchResults from '../components/search-results/SearchResults'; +import { UPDATE_TOAST } from '../context/actions'; +import { AppContext } from '../context/AppContext'; +import { + selectCsrfToken, + selectOrderedMemberFirstName, + selectOrderedSkills, + selectSkill +} from '../context/selectors'; +import { levelMap } from '../context/util'; + +import { Button, TextField } from '@mui/material'; import Autocomplete from '@mui/material/Autocomplete'; -import "./TeamSkillReportPage.css"; -import MemberSelector from "../components/member_selector/MemberSelector"; -import Typography from "@mui/material/Typography"; -import MemberSkillRadar from "../components/member_skill_radar/MemberSkillRadar.jsx"; +import './TeamSkillReportPage.css'; +import MemberSelector from '../components/member_selector/MemberSelector'; +import Typography from '@mui/material/Typography'; +import MemberSkillRadar from '../components/member_skill_radar/MemberSkillRadar.jsx'; const TeamSkillReportPage = () => { const { state } = useContext(AppContext); @@ -30,7 +35,7 @@ const TeamSkillReportPage = () => { const [editedSearchRequest, setEditedSearchRequest] = useState([]); const [showRadar, setShowRadar] = useState(false); - const handleSearch = async (searchRequestDTO) => { + const handleSearch = async searchRequestDTO => { let res = await reportSkills(searchRequestDTO, csrf); let memberSkillsFound; if (res && res.payload) { @@ -42,8 +47,8 @@ const TeamSkillReportPage = () => { if (memberSkillsFound && memberProfiles) { setAllSearchResults(memberSkillsFound); setSearchResults( - memberSkillsFound.filter((mSkill) => - selectedMembers.some((member) => member.id === mSkill.id) + memberSkillsFound.filter(mSkill => + selectedMembers.some(member => member.id === mSkill.id) ) ); } else { @@ -54,10 +59,10 @@ const TeamSkillReportPage = () => { }; function skillsToSkillLevel(skills) { - return skills.map((skill) => { + return skills.map(skill => { return { id: skill.id, - level: skill.skilllevel, + level: skill.skilllevel }; }); } @@ -65,7 +70,7 @@ const TeamSkillReportPage = () => { function createRequest(editedSearchRequest) { let newSearchRequest = { skills: skillsToSkillLevel(searchSkills), - members: [], + members: [] }; setEditedSearchRequest(newSearchRequest); return newSearchRequest; @@ -78,10 +83,10 @@ const TeamSkillReportPage = () => { const skillMap = {}; - const selectedMembersCopy = selectedMembers.map((member) => ({ ...member })); - let searchResultsCopy = searchResults.map((result) => ({ ...result })); - const filteredResults = searchResultsCopy.filter((result) => { - return selectedMembersCopy.some((member) => { + const selectedMembersCopy = selectedMembers.map(member => ({ ...member })); + let searchResultsCopy = searchResults.map(result => ({ ...result })); + const filteredResults = searchResultsCopy.filter(result => { + return selectedMembersCopy.some(member => { return result.name === member.name; }); }); @@ -123,23 +128,22 @@ const TeamSkillReportPage = () => { setSelectedMembers(selected)} + onChange={selected => setSelectedMembers(selected)} />
    - !searchSkills.map((sSkill) => sSkill.id).includes(skill.id) + skill => !searchSkills.map(sSkill => sSkill.id).includes(skill.id) )} value={searchSkills ? searchSkills : []} onChange={onSkillsChange} isOptionEqualToValue={(option, value) => value ? value.id === option.id : false } - getOptionLabel={(option) => option.name} - renderInput={(params) => ( + getOptionLabel={option => option.name} + renderInput={params => ( { window.snackDispatch({ type: UPDATE_TOAST, payload: { - severity: "error", - toast: "Must select a skill", - }, + severity: 'error', + toast: 'Must select a skill' + } }); return; } @@ -169,21 +173,27 @@ const TeamSkillReportPage = () => {
    {showRadar && (
    -
    +
    - Search Results - {!searchResultsCopy.length && - No Matches - } + + Search Results + + {!searchResultsCopy.length && ( + + No Matches + + )}
    - All Employees With Selected Skills + + All Employees With Selected Skills +
    diff --git a/web-ui/src/pages/TeamSkillReportPage.test.jsx b/web-ui/src/pages/TeamSkillReportPage.test.jsx index 7d659d3eeb..410dd21601 100644 --- a/web-ui/src/pages/TeamSkillReportPage.test.jsx +++ b/web-ui/src/pages/TeamSkillReportPage.test.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import TeamSkillReportPage from "./TeamSkillReportPage"; -import { AppContextProvider } from "../context/AppContext"; -import { createMemoryHistory } from "history"; -import { Router } from "react-router-dom"; +import React from 'react'; +import TeamSkillReportPage from './TeamSkillReportPage'; +import { AppContextProvider } from '../context/AppContext'; +import { createMemoryHistory } from 'history'; +import { Router } from 'react-router-dom'; -it("renders correctly", () => { +it('renders correctly', () => { const history = createMemoryHistory(`/profile/12345`); snapshot( diff --git a/web-ui/src/pages/TeamsPage.jsx b/web-ui/src/pages/TeamsPage.jsx index b168fd384f..092d9a2b0b 100644 --- a/web-ui/src/pages/TeamsPage.jsx +++ b/web-ui/src/pages/TeamsPage.jsx @@ -1,16 +1,16 @@ import React from 'react'; import TeamResults from '../components/team-results/TeamResults'; -const displayName = "TeamsPage"; +const displayName = 'TeamsPage'; const TeamsPage = () => { - return ( -
    - -
    - ); + return ( +
    + +
    + ); }; TeamsPage.displayName = displayName; -export default TeamsPage; \ No newline at end of file +export default TeamsPage; diff --git a/web-ui/src/pages/ViewFeedbackPage.css b/web-ui/src/pages/ViewFeedbackPage.css index a93c3a96af..17586c3eda 100644 --- a/web-ui/src/pages/ViewFeedbackPage.css +++ b/web-ui/src/pages/ViewFeedbackPage.css @@ -1,51 +1,51 @@ .view-feedback-page { - padding: 1rem; - margin-top: 1rem; - width: 100%; - padding: 4em 2em 0 2em; + padding: 1rem; + margin-top: 1rem; + width: 100%; + padding: 4em 2em 0 2em; } .view-feedback-header-container { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin-bottom: 2em; - flex-wrap: wrap; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 2em; + flex-wrap: wrap; } .input-row { - display: grid; - grid-template-columns: 360px 260px 260px; - align-items: center; - grid-column-gap: 1em; + display: grid; + grid-template-columns: 360px 260px 260px; + align-items: center; + grid-column-gap: 1em; } @media screen and (min-width: 320px) and (max-width: 1600px) { - .view-feedback-page { - padding: 4em 2em 0 2em; - } + .view-feedback-page { + padding: 4em 2em 0 2em; + } - .input-row { - width: 100%; - } + .input-row { + width: 100%; + } } @media screen and (max-width: 1200px) { - .input-row { - grid-template-columns: 1fr; - grid-template-rows: 1fr 1fr 1fr; - } + .input-row { + grid-template-columns: 1fr; + grid-template-rows: 1fr 1fr 1fr; + } } @media screen and (min-width: 600px) and (max-width: 750px) { - .view-feedback-page { - margin-left: 150px; - } + .view-feedback-page { + margin-left: 150px; + } } @media screen and (max-width: 600px) { - .view-feedback-page { - padding: 4em 2em 0 2em; - } -} \ No newline at end of file + .view-feedback-page { + padding: 4em 2em 0 2em; + } +} diff --git a/web-ui/src/pages/ViewFeedbackPage.jsx b/web-ui/src/pages/ViewFeedbackPage.jsx index 26cf494026..004a5872c0 100644 --- a/web-ui/src/pages/ViewFeedbackPage.jsx +++ b/web-ui/src/pages/ViewFeedbackPage.jsx @@ -1,20 +1,38 @@ -import React, {useCallback, useContext, useEffect, useRef, useState} from 'react'; +import React, { + useCallback, + useContext, + useEffect, + useRef, + useState +} from 'react'; import { styled } from '@mui/material/styles'; -import InputAdornment from "@mui/material/InputAdornment"; -import Search from "@mui/icons-material/Search"; +import InputAdornment from '@mui/material/InputAdornment'; +import Search from '@mui/icons-material/Search'; import MenuItem from '@mui/material/MenuItem'; import FormControl from '@mui/material/FormControl'; import FormControlLabel from '@mui/material/FormControlLabel'; -import TextField from "@mui/material/TextField"; -import Switch from "@mui/material/Switch"; +import TextField from '@mui/material/TextField'; +import Switch from '@mui/material/Switch'; import FeedbackRequestCard from '../components/feedback_request_card/FeedbackRequestCard'; -import Typography from "@mui/material/Typography"; -import "./ViewFeedbackPage.css"; -import {getFeedbackRequestsByCreator, getFeedbackRequestsByRequestees} from "../api/feedback"; -import {AppContext} from "../context/AppContext"; -import {selectCsrfToken, selectCurrentUserId, selectProfile, selectIsAdmin, selectIsSupervisor, selectMyTeam, selectCurrentMembers, selectSubordinates} from "../context/selectors"; -import {getFeedbackTemplate} from "../api/feedbacktemplate"; -import SkeletonLoader from "../components/skeleton_loader/SkeletonLoader" +import Typography from '@mui/material/Typography'; +import './ViewFeedbackPage.css'; +import { + getFeedbackRequestsByCreator, + getFeedbackRequestsByRequestees +} from '../api/feedback'; +import { AppContext } from '../context/AppContext'; +import { + selectCsrfToken, + selectCurrentUserId, + selectProfile, + selectIsAdmin, + selectIsSupervisor, + selectMyTeam, + selectCurrentMembers, + selectSubordinates +} from '../context/selectors'; +import { getFeedbackTemplate } from '../api/feedbacktemplate'; +import SkeletonLoader from '../components/skeleton_loader/SkeletonLoader'; const PREFIX = 'ViewFeedbackPage'; const classes = { @@ -27,56 +45,56 @@ const classes = { const Root = styled('div')({ [`& .${classes.pageTitle}`]: { - paddingRight: "0.4em", - minWidth: "330px", - ['@media screen and (max-width: 600px)']: { // eslint-disable-line no-useless-computed-key - fontSize: "30px", - width: "100%", + paddingRight: '0.4em', + minWidth: '330px', + ['@media screen and (max-width: 600px)']: { + // eslint-disable-line no-useless-computed-key + fontSize: '30px', + width: '100%', padding: 0, - textAlign: "center", - minWidth: "10px" - }, + textAlign: 'center', + minWidth: '10px' + } }, [`& .${classes.textField}`]: { - width: "100%", + width: '100%' }, [`& .${classes.searchField}`]: { - width: "100%", - alignSelf: "start", - marginTop: "30px" + width: '100%', + alignSelf: 'start', + marginTop: '30px' }, [`& .${classes.formControl}`]: { - marginRight: "1em", + marginRight: '1em' }, [`& .${classes.notFoundMessage}`]: { - color: "gray", - marginTop: "4em", - textAlign: "center" + color: 'gray', + marginTop: '4em', + textAlign: 'center' } }); const SortOption = { - SENT_DATE: "sent_date", - SUBMISSION_DATE: "submission_date", - RECIPIENT_NAME_ALPHABETICAL: "recipient_name_alphabetical", - RECIPIENT_NAME_REVERSE_ALPHABETICAL: "recipient_name_reverse_alphabetical" + SENT_DATE: 'sent_date', + SUBMISSION_DATE: 'submission_date', + RECIPIENT_NAME_ALPHABETICAL: 'recipient_name_alphabetical', + RECIPIENT_NAME_REVERSE_ALPHABETICAL: 'recipient_name_reverse_alphabetical' }; const DateRange = { - THREE_MONTHS: "3mo", - SIX_MONTHS: "6mo", - ONE_YEAR: "1yr", - ALL_TIME: "all" + THREE_MONTHS: '3mo', + SIX_MONTHS: '6mo', + ONE_YEAR: '1yr', + ALL_TIME: 'all' }; const ViewFeedbackPage = () => { - const [feedbackRequests, setFeedbackRequests] = useState([]); - const [searchText, setSearchText] = useState(""); + const [searchText, setSearchText] = useState(''); const [searchFocused, setSearchFocused] = useState(false); - const {state} = useContext(AppContext); + const { state } = useContext(AppContext); const csrf = selectCsrfToken(state); - const currentUserId = selectCurrentUserId(state); + const currentUserId = selectCurrentUserId(state); const isAdmin = selectIsAdmin(state); const isSupervisor = selectIsSupervisor(state); const currentMembers = selectCurrentMembers(state); @@ -84,88 +102,110 @@ const ViewFeedbackPage = () => { const myTeam = selectMyTeam(state); const gotRequests = useRef(false); const [teamMembers, setTeamMembers] = useState(null); - const isLoading = useRef(true) + const isLoading = useRef(true); const [sortValue, setSortValue] = useState(SortOption.SENT_DATE); const [dateRange, setDateRange] = useState(DateRange.THREE_MONTHS); const [includeAll, setIncludeAll] = useState(false); useEffect(() => { - if(currentMembers && currentMembers.length > 0) { - isAdmin && includeAll ? setTeamMembers(currentMembers.filter((member) => member?.id !== currentUserId)) : includeAll ? setTeamMembers(subordinates) : setTeamMembers(myTeam); + if (currentMembers && currentMembers.length > 0) { + isAdmin && includeAll + ? setTeamMembers( + currentMembers.filter(member => member?.id !== currentUserId) + ) + : includeAll + ? setTeamMembers(subordinates) + : setTeamMembers(myTeam); } - }, [isAdmin, includeAll, subordinates, currentMembers, myTeam, currentUserId]); + }, [ + isAdmin, + includeAll, + subordinates, + currentMembers, + myTeam, + currentUserId + ]); const toggleIncludeAll = useCallback(() => { - gotRequests.current = false; - setIncludeAll(!includeAll); - }, [includeAll, setIncludeAll]); + gotRequests.current = false; + setIncludeAll(!includeAll); + }, [includeAll, setIncludeAll]); useEffect(() => { - const getFeedbackRequests = async(creatorId) => { + const getFeedbackRequests = async creatorId => { if (csrf) { let res = await getFeedbackRequestsByCreator(creatorId, csrf); return res && res.payload && res.payload.data && !res.error ? res.payload.data : null; } - } - const getFeedbackRequestsForTeamMembers = async(teamMembers) => { + }; + const getFeedbackRequestsForTeamMembers = async teamMembers => { if (csrf) { const batchSize = 50; const teamMemberIdBatches = teamMembers.reduce((batches, member) => { - if (!batches.length || batches[batches.length - 1].length === batchSize) { + if ( + !batches.length || + batches[batches.length - 1].length === batchSize + ) { batches.push([]); } - if(member?.id) { - batches[batches.length - 1].push(member.id) + if (member?.id) { + batches[batches.length - 1].push(member.id); } return batches; }, []); let results = []; for (const requesteeIds of teamMemberIdBatches) { - let res = await getFeedbackRequestsByRequestees(requesteeIds, undefined, csrf); - if(res && res.payload && res.payload.data && !res.error) { + let res = await getFeedbackRequestsByRequestees( + requesteeIds, + undefined, + csrf + ); + if (res && res.payload && res.payload.data && !res.error) { results = [...results, ...res.payload.data]; } } return results; } - } - const getTemplateInfo = async(templateId) => { + }; + const getTemplateInfo = async templateId => { if (csrf) { let res = await getFeedbackTemplate(templateId, csrf); return res && res.payload && res.payload.data && !res.error ? res.payload.data : null; } - } + }; if (!currentUserId || gotRequests.current) return; - const getRequestAndTemplateInfo = async (currentUserId) => { + const getRequestAndTemplateInfo = async currentUserId => { //get feedback requests const feedbackRequests = await getFeedbackRequests(currentUserId); - const contains = (toFind) => feedbackRequests.findIndex(request => request.id === toFind.id) !== -1; + const contains = toFind => + feedbackRequests.findIndex(request => request.id === toFind.id) !== -1; - if(teamMembers && teamMembers.length > 0) { - const memberRequests = await getFeedbackRequestsForTeamMembers(teamMembers); - memberRequests.forEach((request) => { + if (teamMembers && teamMembers.length > 0) { + const memberRequests = + await getFeedbackRequestsForTeamMembers(teamMembers); + memberRequests.forEach(request => { if (!contains(request)) { feedbackRequests.push(request); } }); } return feedbackRequests; - } + }; - const getTemplates = async (feedbackRequests) => { + const getTemplates = async feedbackRequests => { //use returned feedback request information to then get template information, bind request //and associated template info together const templateReqs = []; const templateIds = []; - for(let i=0; i { map[template.id] = template; return map; }, {}); - feedbackRequests.forEach((request) => { + feedbackRequests.forEach(request => { request.templateInfo = templates[request.templateId]; }); return feedbackRequests; - } + }; isLoading.current = true; setFeedbackRequests([]); - getRequestAndTemplateInfo(currentUserId).then(getTemplates).then(requestList => { - if (requestList) { - let groups = []; - for (let i = 0; i < requestList.length; i++) { - let request = requestList[i]; - let filterTemp = groups.filter(element => element.requesteeId === request.requesteeId && element.templateId === request.templateId); - //if top level organizational element does not already exist, create one - if (filterTemp.length === 0) { - const requesteeName = selectProfile(state, request.requesteeId)?.name; - let newElement = { - requesteeId: request.requesteeId, - requesteeName: requesteeName ? requesteeName : "", - templateId: request.templateId, - responses: [request], - templateInfo: request.templateInfo - }; - groups.push(newElement); - } else { - //else, push response into existing responses array of top level elements - const existingGroup = groups.findIndex((element) => element.requesteeId === filterTemp[0].requesteeId && element.templateId === filterTemp[0].templateId); - groups[existingGroup].responses.push(request); + getRequestAndTemplateInfo(currentUserId) + .then(getTemplates) + .then(requestList => { + if (requestList) { + let groups = []; + for (let i = 0; i < requestList.length; i++) { + let request = requestList[i]; + let filterTemp = groups.filter( + element => + element.requesteeId === request.requesteeId && + element.templateId === request.templateId + ); + //if top level organizational element does not already exist, create one + if (filterTemp.length === 0) { + const requesteeName = selectProfile( + state, + request.requesteeId + )?.name; + let newElement = { + requesteeId: request.requesteeId, + requesteeName: requesteeName ? requesteeName : '', + templateId: request.templateId, + responses: [request], + templateInfo: request.templateInfo + }; + groups.push(newElement); + } else { + //else, push response into existing responses array of top level elements + const existingGroup = groups.findIndex( + element => + element.requesteeId === filterTemp[0].requesteeId && + element.templateId === filterTemp[0].templateId + ); + groups[existingGroup].responses.push(request); + } } + isLoading.current = false; + setFeedbackRequests(groups); } - isLoading.current = false; - setFeedbackRequests(groups); - } - }); + }); }, [currentUserId, teamMembers, csrf, state, isSupervisor]); const getFilteredFeedbackRequests = useCallback(() => { if (!feedbackRequests) { return null; } else if (feedbackRequests.length === 0) { - return No feedback requests found + return ( + + No feedback requests found + + ); } let requestsToDisplay = feedbackRequests; if (searchText.trim()) { // allow user to query multiple entries via comma-separated list - const queryList = searchText.split(","); + const queryList = searchText.split(','); let filtered = feedbackRequests; - queryList.forEach((query) => { + queryList.forEach(query => { if (query.trim()) { - filtered = filtered?.filter((request) => { + filtered = filtered?.filter(request => { const requestee = request?.requesteeName; const template = request?.templateInfo.title; - return requestee.toLowerCase().includes(query.trim().toLowerCase()) || - template?.toLowerCase().includes(query.trim().toLowerCase()) + return ( + requestee.toLowerCase().includes(query.trim().toLowerCase()) || + template?.toLowerCase().includes(query.trim().toLowerCase()) + ); }); } }); if (filtered.length === 0) { - return No matching feedback requests + return ( + + No matching feedback requests + + ); } else { requestsToDisplay = filtered; } } - const isInRange = (requestDate) => { + const isInRange = requestDate => { let oldestDate = new Date(); switch (dateRange) { case DateRange.THREE_MONTHS: @@ -260,23 +323,28 @@ const ViewFeedbackPage = () => { } if (Array.isArray(requestDate)) { - requestDate = new Date(requestDate.join("/")); + requestDate = new Date(requestDate.join('/')); // have to do for Safari } return requestDate >= oldestDate; - } + }; return requestsToDisplay?.reduce((toDisplay, request) => { if (request?.responses?.length > 0) { - if(request.responses.filter((response) => isInRange(response.sendDate)).length > 0) { - toDisplay.push(()); + if ( + request.responses.filter(response => isInRange(response.sendDate)) + .length > 0 + ) { + toDisplay.push( + + ); } } return toDisplay; @@ -286,40 +354,41 @@ const ViewFeedbackPage = () => { return (
    - Feedback Requests - - } label="Show All" /> + + Feedback Requests + + } + label="Show All" + />
    setSearchFocused(true)} onBlur={() => setSearchFocused(false)} - onChange={(event) => setSearchText(event.target.value)} + onChange={event => setSearchText(event.target.value)} InputProps={{ startAdornment: ( - - + + - ), + ) }} /> - + setDateRange(e.target.value)} + onChange={e => setDateRange(e.target.value)} defaultValue={DateRange.THREE_MONTHS} variant="outlined" > @@ -330,34 +399,42 @@ const ViewFeedbackPage = () => { - + setSortValue(e.target.value)} + onChange={e => setSortValue(e.target.value)} defaultValue={SortOption.SENT_DATE} variant="outlined" > - Date feedback was submitted - Date request was sent - Recipient name (A-Z) - Recipient name (Z-A) + + Date feedback was submitted + + + Date request was sent + + + Recipient name (A-Z) + + + Recipient name (Z-A) +
    - {!isLoading.current ? getFilteredFeedbackRequests(): Array.from({length: 10}) - .map((_, index) => )} + {!isLoading.current + ? getFilteredFeedbackRequests() + : Array.from({ length: 10 }).map((_, index) => ( + + ))}
    ); -} +}; export default ViewFeedbackPage; diff --git a/web-ui/src/pages/ViewFeedbackPage.test.jsx b/web-ui/src/pages/ViewFeedbackPage.test.jsx index c4b135021c..ef93142a67 100644 --- a/web-ui/src/pages/ViewFeedbackPage.test.jsx +++ b/web-ui/src/pages/ViewFeedbackPage.test.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import ViewFeedbackPage from "./ViewFeedbackPage"; -import {AppContextProvider} from "../context/AppContext"; -import {BrowserRouter} from "react-router-dom"; +import React from 'react'; +import ViewFeedbackPage from './ViewFeedbackPage'; +import { AppContextProvider } from '../context/AppContext'; +import { BrowserRouter } from 'react-router-dom'; - it("renders correctly", () => { - snapshot( - - - - - - ); - }); \ No newline at end of file +it('renders correctly', () => { + snapshot( + + + + + + ); +}); diff --git a/web-ui/src/serviceWorker.js b/web-ui/src/serviceWorker.js index ac08661141..84f6c74f75 100644 --- a/web-ui/src/serviceWorker.js +++ b/web-ui/src/serviceWorker.js @@ -23,7 +23,10 @@ const isLocalhost = Boolean( export function register(config) { if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(import.meta.env.VITE_APP_API_URL, window.location.href); + const publicUrl = new URL( + import.meta.env.VITE_APP_API_URL, + window.location.href + ); if (publicUrl.origin !== window.location.origin) { // Our service worker won't work if PUBLIC_URL is on a different origin // from what our page is served on. This might happen if a CDN is used to @@ -101,7 +104,7 @@ function registerValidSW(swUrl, config) { function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { - headers: { 'Service-Worker': 'script' }, + headers: { 'Service-Worker': 'script' } }) .then(response => { // Ensure service worker exists, and that we really are getting a JS file. diff --git a/web-ui/src/setupTests.js b/web-ui/src/setupTests.js index 041e4fa2a1..2d225433ff 100644 --- a/web-ui/src/setupTests.js +++ b/web-ui/src/setupTests.js @@ -1,16 +1,16 @@ -import "isomorphic-fetch"; -import React from "react"; -import createFetchMock from 'vitest-fetch-mock';; -import requestAnimationFrame from "raf/polyfill"; -import { render } from "@testing-library/react"; -import {screen} from '@testing-library/dom'; +import 'isomorphic-fetch'; +import React from 'react'; +import createFetchMock from 'vitest-fetch-mock'; +import requestAnimationFrame from 'raf/polyfill'; +import { render } from '@testing-library/react'; +import { screen } from '@testing-library/dom'; import '@testing-library/jest-dom'; -const mockModule = await vi.importActual("react-dom"); +const mockModule = await vi.importActual('react-dom'); const mockClone = React.cloneElement; -vi.mock("react-dom", () => { +vi.mock('react-dom', () => { return { __esModule: true, // Use it when dealing with esModules ...mockModule, @@ -19,10 +19,10 @@ vi.mock("react-dom", () => { return mockClone(element, { style: { webkitTransition: '' } }); } return element; - }, + } }; }); -vi.mock("react-transition-group/cjs/Transition"); +vi.mock('react-transition-group/cjs/Transition'); const fetchMocker = createFetchMock(vi); fetchMocker.enableMocks(); @@ -35,8 +35,9 @@ global.waitForSnapshot = async (testId, component, options) => { const rendered = render(component, options); await screen.findByTestId(testId); expect(rendered.container).toMatchSnapshot(); -} +}; global.window = global.window || {}; -global.window.requestAnimationFrame = global.requestAnimationFrame = requestAnimationFrame; +global.window.requestAnimationFrame = global.requestAnimationFrame = + requestAnimationFrame; //global.window.addEventListener = global.addEventListener; diff --git a/web-ui/yarn.lock b/web-ui/yarn.lock index daa5764519..014eb14881 100644 --- a/web-ui/yarn.lock +++ b/web-ui/yarn.lock @@ -7,14 +7,6 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.3.tgz#90749bde8b89cd41764224f5aac29cd4138f75ff" integrity sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ== -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== - dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" - "@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" @@ -30,22 +22,7 @@ dependencies: default-browser-id "3.0.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - -"@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== @@ -53,49 +30,23 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/compat-data@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" - integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== - -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.1.tgz#31c1f66435f2a9c329bb5716a6d6186c516c3742" - integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== - -"@babel/core@^7.12.3": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" - integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-compilation-targets" "^7.17.10" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.9" - "@babel/parser" "^7.17.10" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.10" - "@babel/types" "^7.17.10" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" + integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== -"@babel/core@^7.18.9", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.9": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.3.tgz#568864247ea10fbd4eff04dda1e05f9e2ea985c3" - integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== +"@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.9": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.4.tgz#1f758428e88e0d8c563874741bc4ffc4f71a4717" + integrity sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.24.2" - "@babel/generator" "^7.24.1" + "@babel/generator" "^7.24.4" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.1" - "@babel/parser" "^7.24.1" + "@babel/helpers" "^7.24.4" + "@babel/parser" "^7.24.4" "@babel/template" "^7.24.0" "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" @@ -105,35 +56,16 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" - integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== - dependencies: - "@babel/types" "^7.17.10" - "@jridgewell/gen-mapping" "^0.1.0" - jsesc "^2.5.1" - -"@babel/generator@^7.23.0", "@babel/generator@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" - integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== +"@babel/generator@^7.23.0", "@babel/generator@^7.24.1", "@babel/generator@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.4.tgz#1fc55532b88adf952025d5d2d1e71f946cb1c498" + integrity sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw== dependencies: "@babel/types" "^7.24.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/generator@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" - integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== - dependencies: - "@babel/types" "^7.23.6" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - "@babel/helper-annotate-as-pure@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" @@ -148,16 +80,6 @@ dependencies: "@babel/types" "^7.22.15" -"@babel/helper-compilation-targets@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe" - integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== - dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.20.2" - semver "^6.3.0" - "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" @@ -169,10 +91,10 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz#db58bf57137b623b916e24874ab7188d93d7f68f" - integrity sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA== +"@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz#c806f73788a6800a5cfbbc04d2df7ee4d927cce3" + integrity sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.20" @@ -193,10 +115,10 @@ regexpu-core "^5.3.1" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz#fadc63f0c2ff3c8d02ed905dcea747c5b0fb74fd" - integrity sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA== +"@babel/helper-define-polyfill-provider@^0.6.1", "@babel/helper-define-polyfill-provider@^0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" + integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== dependencies: "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" @@ -204,13 +126,6 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" @@ -238,34 +153,13 @@ dependencies: "@babel/types" "^7.23.0" -"@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.24.1": +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.24.1": version "7.24.3" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== dependencies: "@babel/types" "^7.24.0" -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - "@babel/helper-module-transforms@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" @@ -284,12 +178,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.0": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== @@ -312,13 +201,6 @@ "@babel/helper-member-expression-to-functions" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - "@babel/helper-simple-access@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" @@ -333,13 +215,6 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" @@ -348,25 +223,15 @@ "@babel/types" "^7.22.5" "@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" @@ -381,42 +246,15 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - -"@babel/helpers@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.1.tgz#183e44714b9eba36c3038e442516587b1e0a1a94" - integrity sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg== +"@babel/helpers@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.4.tgz#dc00907fd0d95da74563c142ef4cd21f2cb856b6" + integrity sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw== dependencies: "@babel/template" "^7.24.0" "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" -"@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - "@babel/highlight@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" @@ -427,25 +265,18 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" - integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== - -"@babel/parser@^7.16.7", "@babel/parser@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" - integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== - -"@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" - integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1", "@babel/parser@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88" + integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== -"@babel/parser@^7.22.15", "@babel/parser@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" - integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz#6125f0158543fb4edf1c22f322f3db67f21cb3e1" + integrity sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.1": version "7.24.1" @@ -657,10 +488,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-block-scoping@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz#27af183d7f6dad890531256c7a45019df768ac1f" - integrity sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw== +"@babel/plugin-transform-block-scoping@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz#28f5c010b66fbb8ccdeef853bef1935c434d7012" + integrity sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g== dependencies: "@babel/helper-plugin-utils" "^7.24.0" @@ -672,12 +503,12 @@ "@babel/helper-create-class-features-plugin" "^7.24.1" "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-class-static-block@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz#4e37efcca1d9f2fcb908d1bae8b56b4b6e9e1cb6" - integrity sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA== +"@babel/plugin-transform-class-static-block@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz#1a4653c0cf8ac46441ec406dece6e9bc590356a4" + integrity sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-create-class-features-plugin" "^7.24.4" "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -989,12 +820,12 @@ "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-transform-typescript@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.1.tgz#5c05e28bb76c7dfe7d6c5bed9951324fd2d3ab07" - integrity sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.4.tgz#03e0492537a4b953e491f53f2bc88245574ebd15" + integrity sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-create-class-features-plugin" "^7.24.4" "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-typescript" "^7.24.1" @@ -1030,14 +861,15 @@ "@babel/helper-plugin-utils" "^7.24.0" "@babel/preset-env@^7.23.2": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.3.tgz#f3f138c844ffeeac372597b29c51b5259e8323a3" - integrity sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.4.tgz#46dbbcd608771373b88f956ffb67d471dce0d23b" + integrity sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A== dependencies: - "@babel/compat-data" "^7.24.1" + "@babel/compat-data" "^7.24.4" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.4" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.1" "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.1" @@ -1064,9 +896,9 @@ "@babel/plugin-transform-async-generator-functions" "^7.24.3" "@babel/plugin-transform-async-to-generator" "^7.24.1" "@babel/plugin-transform-block-scoped-functions" "^7.24.1" - "@babel/plugin-transform-block-scoping" "^7.24.1" + "@babel/plugin-transform-block-scoping" "^7.24.4" "@babel/plugin-transform-class-properties" "^7.24.1" - "@babel/plugin-transform-class-static-block" "^7.24.1" + "@babel/plugin-transform-class-static-block" "^7.24.4" "@babel/plugin-transform-classes" "^7.24.1" "@babel/plugin-transform-computed-properties" "^7.24.1" "@babel/plugin-transform-destructuring" "^7.24.1" @@ -1167,53 +999,14 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" - integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.15.4": - version "7.17.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" - integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.18.3", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.0": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" - integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.2.0", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd" + integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA== dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.2.0": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" - integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== - dependencies: - regenerator-runtime "^0.13.10" - -"@babel/template@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/template@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/template@^7.24.0": +"@babel/template@^7.22.15", "@babel/template@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== @@ -1222,22 +1015,6 @@ "@babel/parser" "^7.24.0" "@babel/types" "^7.24.0" -"@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" - integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.6" - "@babel/types" "^7.23.6" - debug "^4.3.1" - globals "^11.1.0" - "@babel/traverse@^7.18.9", "@babel/traverse@^7.23.2", "@babel/traverse@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" @@ -1254,23 +1031,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.3.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.17.10", "@babel/types@^7.4.4": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" - integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.22.19", "@babel/types@^7.24.0": +"@babel/types@^7.0.0", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.24.0", "@babel/types@^7.4.4": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== @@ -1279,15 +1040,6 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" -"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" - integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -1362,13 +1114,13 @@ "@emotion/weak-memoize" "^0.3.1" stylis "4.2.0" -"@emotion/css-prettifier@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@emotion/css-prettifier/-/css-prettifier-1.0.1.tgz#a3ce1667398e83701f52ec43938208faeef2e0a5" - integrity sha512-cA9Dtol47mtvWKasPC+8tkh2DS0wBkX0MMHKieXGSkGyx079V7yFY85KC0pPalcIy+vi0LbMR9DNyiJBqYgJ1Q== +"@emotion/css-prettifier@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@emotion/css-prettifier/-/css-prettifier-1.1.3.tgz#014ff59a87a3be5f2ce555b70f096af66b2dc845" + integrity sha512-KNv23+VQ+pcw3ebd1vSEl11CQ6SKAG5EQkrinjVGsfw3ZTWe6/tpWQrsvFLqCtU2LRiLPi04KgFCE4A9+crfpQ== dependencies: - "@emotion/memoize" "^0.7.4" - stylis "4.0.13" + "@emotion/memoize" "^0.8.1" + stylis "4.2.0" "@emotion/hash@^0.9.1": version "0.9.1" @@ -1389,7 +1141,7 @@ dependencies: "@emotion/memoize" "0.7.1" -"@emotion/is-prop-valid@^1.2.1": +"@emotion/is-prop-valid@^1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== @@ -1397,26 +1149,21 @@ "@emotion/memoize" "^0.8.1" "@emotion/jest@^11.5.0": - version "11.9.1" - resolved "https://registry.yarnpkg.com/@emotion/jest/-/jest-11.9.1.tgz#65224814552eab6acb923504e597c6f6b67e90d6" - integrity sha512-JFf9yBA6a7fKrKCWMmjODGRcgBnjiQsl9AakP1y7oRJ6B147ZKPo8DgzHUZ5qQkI06GKAWwYU1vKROInc7SYVA== + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/jest/-/jest-11.11.0.tgz#4d64b33052308739dcdd7396fd2bc902f7244f82" + integrity sha512-XZlnmdUZ32YjQnInsCFk/plKpkV/NXN1Ab4YoNvXN887MeR3Hr5ZsTyoblIW8AWwdfQiZHHphaPMb56lk6Ofdw== dependencies: - "@babel/runtime" "^7.13.10" - "@emotion/css-prettifier" "^1.0.1" + "@babel/runtime" "^7.18.3" + "@emotion/css-prettifier" "^1.1.3" chalk "^4.1.0" specificity "^0.4.1" - stylis "4.0.13" + stylis "4.2.0" "@emotion/memoize@0.7.1": version "0.7.1" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg== -"@emotion/memoize@^0.7.4": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" - integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== - "@emotion/memoize@^0.8.1": version "0.8.1" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" @@ -1436,10 +1183,10 @@ "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" - integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3", "@emotion/serialize@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451" + integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ== dependencies: "@emotion/hash" "^0.9.1" "@emotion/memoize" "^0.8.1" @@ -1453,14 +1200,14 @@ integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== "@emotion/styled@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + version "11.11.5" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.5.tgz#0c5c8febef9d86e8a926e663b2e5488705545dfb" + integrity sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ== dependencies: "@babel/runtime" "^7.18.3" "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" + "@emotion/is-prop-valid" "^1.2.2" + "@emotion/serialize" "^1.1.4" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" "@emotion/utils" "^1.2.1" @@ -1636,10 +1383,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@fortawesome/fontawesome-common-types@6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.1.tgz#7dc996042d21fc1ae850e3173b5c67b0549f9105" - integrity sha512-wVn5WJPirFTnzN6tR95abCx+ocH+3IFLXAgyavnf9hUmN0CfWoDjPT/BAWsUVwSlYYVBeCLJxaqi7ZGe4uSjBA== +"@fortawesome/fontawesome-common-types@6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz#eaf2f5699f73cef198454ebc0c414e3688898179" + integrity sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw== "@fortawesome/fontawesome-common-types@^0.3.0": version "0.3.0" @@ -1654,58 +1401,62 @@ "@fortawesome/fontawesome-common-types" "^0.3.0" "@fortawesome/free-regular-svg-icons@^6.0.0": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.1.tgz#3f2f58262a839edf0643cbacee7a8a8230061c98" - integrity sha512-xXiW7hcpgwmWtndKPOzG+43fPH7ZjxOaoeyooptSztGmJxCAflHZxXNK0GcT0uEsR4jTGQAfGklDZE5NHoBhKg== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz#e8e04b4368d49920abdf1bacc63c67c870635222" + integrity sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/free-solid-svg-icons@^6.0.0": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.1.tgz#3369e673f8fe8be2fba30b1ec274d47490a830a6" - integrity sha512-0/5exxavOhI/D4Ovm2r3vxNojGZioPwmFrKg0ZUH69Q68uFhFPs6+dhAToh6VEQBntxPRYPuT5Cg1tpNa9JUPg== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz#9b40b077b27400a5e9fcbf2d15b986c7be69e9ca" + integrity sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/react-fontawesome@^0.1.17": - version "0.1.18" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.18.tgz#dae37f718a24e14d7a99a5496c873d69af3fbd73" - integrity sha512-RwLIB4TZw0M9gvy5u+TusAA0afbwM4JQIimNH/j3ygd6aIvYPQLqXMhC9ErY26J23rDPyDZldIfPq/HpTTJ/tQ== + version "0.1.19" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz#2b36917578596f31934e71f92b7cf9c425fd06e4" + integrity sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ== dependencies: prop-types "^15.8.1" "@inquirer/confirm@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.1.0.tgz#526cb71ceab28ba827ea287aa81c969e437017b6" - integrity sha512-nH5mxoTEoqk6WpoBz80GMpDSm9jH5V9AF8n+JZAZfMzd9gHeEG9w1o3KawPRR72lfzpP+QxBHLkOKLEApwhDiQ== + version "3.1.5" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.1.5.tgz#21856f937bc8292eca4146c052271107f8ac949a" + integrity sha512-6+dwZrpko5vr5EFEQmUbfBVhtu6IsnB8lQNsLHgO9S9fbfS5J6MuUj+NY0h98pPpYZXEazLR7qzypEDqVzf6aQ== dependencies: - "@inquirer/core" "^7.1.0" - "@inquirer/type" "^1.2.1" + "@inquirer/core" "^8.0.1" + "@inquirer/type" "^1.3.0" -"@inquirer/core@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-7.1.0.tgz#fb78738fd6624de50f027c08d6f24298b72a402b" - integrity sha512-FRCiDiU54XHt5B/D8hX4twwZuzSP244ANHbu3R7CAsJfiv1dUOz24ePBgCZjygEjDUi6BWIJuk4eWLKJ7LATUw== +"@inquirer/core@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-8.0.1.tgz#ac3d9a34a6826dc193791b2feec19061a9c250ca" + integrity sha512-qJRk1y51Os2ARc11Bg2N6uIwiQ9qBSrmZeuMonaQ/ntFpb4+VlcQ8Gl1TFH67mJLz3HA2nvuave0nbv6Lu8pbg== dependencies: - "@inquirer/type" "^1.2.1" + "@inquirer/figures" "^1.0.1" + "@inquirer/type" "^1.3.0" "@types/mute-stream" "^0.0.4" - "@types/node" "^20.11.26" + "@types/node" "^20.12.7" "@types/wrap-ansi" "^3.0.0" ansi-escapes "^4.3.2" chalk "^4.1.2" cli-spinners "^2.9.2" cli-width "^4.1.0" - figures "^3.2.0" mute-stream "^1.0.0" - run-async "^3.0.0" signal-exit "^4.1.0" strip-ansi "^6.0.1" wrap-ansi "^6.2.0" -"@inquirer/type@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.2.1.tgz#fbc7ab3a2e5050d0c150642d5e8f5e88faa066b8" - integrity sha512-xwMfkPAxeo8Ji/IxfUSqzRi0/+F2GIqJmpc5/thelgMGsjNZcjDDRBO9TLXT1s/hdx/mK5QbVIvgoLIFgXhTMQ== +"@inquirer/figures@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.1.tgz#d65f0bd0e9511a90b4d3543ee6a3ce7211f29417" + integrity sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw== + +"@inquirer/type@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.3.0.tgz#9dcb4e0e8bbec03063aff7806072cc90eea2c61d" + integrity sha512-RW4Zf6RCTnInRaOZuRHTqAUl+v6VJuQGglir7nW2BkT3OXOphMhkIFhvFRjorBx2l0VwtC/M4No8vYR65TdN9Q== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -1731,23 +1482,6 @@ dependencies: "@sinclair/typebox" "^0.27.8" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -1757,25 +1491,10 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/resolve-uri@^3.0.3": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" - integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== - "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" - integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/set-array@^1.2.1": version "1.2.1" @@ -1790,17 +1509,12 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.13" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" - integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== - -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -1808,22 +1522,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@jridgewell/trace-mapping@^0.3.17": - version "0.3.21" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz#5dc1df7b3dc4a6209e503a924e1ca56097a2bb15" - integrity sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@mdx-js/react@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746" @@ -1837,9 +1535,9 @@ integrity sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw== "@mswjs/interceptors@^0.26.14": - version "0.26.14" - resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.26.14.tgz#945c6a7838abfd19a1ed8525fc244fd7a855ed69" - integrity sha512-q4S8RGjOUzv3A3gCawuKkUEcNJXjdPaSqoRHFvuZPWQnc7yOw702iGBRDMJoBK+l0KSv9XN8YP5ek6duRzrpqw== + version "0.26.15" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.26.15.tgz#256ad5c89f325c87d972cc27fc7d0d6d382ce804" + integrity sha512-HM47Lu1YFmnYHKMBynFfjCp0U/yRskHj/8QEJW0CBEPOlw8Gkmjfll+S9b8M7V5CNDw2/ciRxjjnWeaCiblSIQ== dependencies: "@open-draft/deferred-promise" "^2.2.0" "@open-draft/logger" "^0.3.0" @@ -1861,40 +1559,40 @@ clsx "^2.1.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz#f7c57b261904831877220182303761c012d05046" - integrity sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA== +"@mui/core-downloads-tracker@^5.15.15": + version "5.15.15" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.15.tgz#2bc2bda50db66c12f10aefec907c48c8f669ef59" + integrity sha512-aXnw29OWQ6I5A47iuWEI6qSSUfH6G/aCsW9KmW3LiFqr7uXZBK4Ks+z8G+qeIub8k0T5CMqlT2q0L+ZJTMrqpg== "@mui/icons-material@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.15.14.tgz#333468c94988d96203946d1cfeb8f4d7e8e7de34" - integrity sha512-vj/51k7MdFmt+XVw94sl30SCvGx6+wJLsNYjZRgxhS6y3UtnWnypMOsm3Kmg8TN+P0dqwsjy4/fX7B1HufJIhw== + version "5.15.15" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.15.15.tgz#84ce08225a531d9f5dc5132009d91164b456a0ae" + integrity sha512-kkeU/pe+hABcYDH6Uqy8RmIsr2S/y5bP2rp+Gat4CcRjCcVne6KudS1NrZQhUCRysrTDCAhcbcf9gt+/+pGO2g== dependencies: "@babel/runtime" "^7.23.9" "@mui/lab@^5.0.0-alpha.169": - version "5.0.0-alpha.169" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.169.tgz#85b88b2f06ad78c586cde2b47970653e5fd895eb" - integrity sha512-h6xe1K6ISKUbyxTDgdvql4qoDP6+q8ad5fg9nXQxGLUrIeT2jVrBuT/jRECSTufbnhzP+V5kulvYxaMfM8rEdA== + version "5.0.0-alpha.170" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.170.tgz#4519dfc8d1c51ca54fb9d8b91b95a3733d07be16" + integrity sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg== dependencies: "@babel/runtime" "^7.23.9" "@mui/base" "5.0.0-beta.40" - "@mui/system" "^5.15.14" + "@mui/system" "^5.15.15" "@mui/types" "^7.2.14" "@mui/utils" "^5.15.14" clsx "^2.1.0" prop-types "^15.8.1" "@mui/material@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.14.tgz#a40bd5eccfa9fc925535e1f4d70c6cef77fa3a75" - integrity sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ== + version "5.15.15" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.15.15.tgz#e3ba35f50b510aa677cec3261abddc2db7b20b59" + integrity sha512-3zvWayJ+E1kzoIsvwyEvkTUKVKt1AjchFFns+JtluHCuvxgKcLSRJTADw37k0doaRtVAsyh8bz9Afqzv+KYrIA== dependencies: "@babel/runtime" "^7.23.9" "@mui/base" "5.0.0-beta.40" - "@mui/core-downloads-tracker" "^5.15.14" - "@mui/system" "^5.15.14" + "@mui/core-downloads-tracker" "^5.15.15" + "@mui/system" "^5.15.15" "@mui/types" "^7.2.14" "@mui/utils" "^5.15.14" "@types/react-transition-group" "^4.4.10" @@ -1934,9 +1632,9 @@ prop-types "^15.8.1" "@mui/styles@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.15.14.tgz#b0f157ccbb4270bbda68e518b035fb3b71cc7470" - integrity sha512-EspFoCqLf3BadSIRM5dBqrrbE0hioI6/YZXDGzvcPsedQ7j7wAdcIs9Ex6TVqrRUADNWI/Azg6/mhcqWiBDFOg== + version "5.15.15" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.15.15.tgz#cfc974657882cb60c6017d57d81f133d8b5e51a1" + integrity sha512-KBklDHNEddodEjcnZ+/3ieVcp+Mb/pzdQzAagUpt4RDd9m/mn+2JkqJh2rnrWUwS//YLsbL3IbUrONYn5yPxfQ== dependencies: "@babel/runtime" "^7.23.9" "@emotion/hash" "^0.9.1" @@ -1956,10 +1654,10 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@^5.15.14": - version "5.15.14" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.14.tgz#8a0c6571077eeb6b5f1ff7aa7ff6a3dc4a14200d" - integrity sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg== +"@mui/system@^5.15.14", "@mui/system@^5.15.15": + version "5.15.15" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.15.tgz#658771b200ce3c4a0f28e58169f02e5e718d1c53" + integrity sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ== dependencies: "@babel/runtime" "^7.23.9" "@mui/private-theming" "^5.15.14" @@ -1986,9 +1684,9 @@ react-is "^18.2.0" "@mui/x-date-pickers@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-7.0.0.tgz#f277054fe42b76b5401f46b7f43ec9de9e625731" - integrity sha512-/9mp4O2WMixHOso63DBoZVfJVYGrzOHF5voheV2tYQ4XqDdTKp2AdWS3oh8PGwrsvCzqkvb3quzTqhKoEsJUwA== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-7.2.0.tgz#d25275cef2e7b0a9946ce7f9a86b701c222a8209" + integrity sha512-hsXugZ+n1ZnHRYzf7+PFrjZ44T+FyGZmTreBmH0M2RUaAblgK+A1V3KNLT+r4Y9gJLH+92LwePxQ9xyfR+E51A== dependencies: "@babel/runtime" "^7.24.0" "@mui/base" "^5.0.0-beta.40" @@ -2029,6 +1727,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@one-ini/wasm@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323" + integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw== + "@open-draft/deferred-promise@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" @@ -2053,17 +1756,17 @@ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@pmmmwh/react-refresh-webpack-plugin@^0.5.1": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.6.tgz#9ced74cb23dae31ab385f775e237ce4c50422a1d" - integrity sha512-IIWxofIYt/AbMwoeBgj+O2aAXLrlCQVg+A4a2zfpXFNHgP8o8rvi3v+oe5t787Lj+KXlKOh8BAiUp9bhuELXhg== + version "0.5.11" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a" + integrity sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ== dependencies: ansi-html-community "^0.0.8" common-path-prefix "^3.0.0" - core-js-pure "^3.8.1" + core-js-pure "^3.23.3" error-stack-parser "^2.0.6" find-up "^5.0.0" html-entities "^2.1.0" - loader-utils "^2.0.0" + loader-utils "^2.0.4" schema-utils "^3.0.0" source-map "^0.7.3" @@ -2087,129 +1790,139 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-compose-refs" "1.0.1" -"@rollup/rollup-android-arm-eabi@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.1.tgz#88ba199f996e0000689130ed69e47df8b0dfbc70" - integrity sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A== - -"@rollup/rollup-android-arm64@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.1.tgz#c89a55670e1179ed7ba3db06cee0d7da7b3d35ce" - integrity sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA== - -"@rollup/rollup-darwin-arm64@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.1.tgz#52e3496fa66d761833df23a9b4860e517efc7d1d" - integrity sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw== - -"@rollup/rollup-darwin-x64@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.1.tgz#7678922773a8b53d8b4b3c3cc3e77b65fc71b489" - integrity sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g== - -"@rollup/rollup-linux-arm-gnueabihf@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.1.tgz#69c3b896e3ee1c3487492323a02c2a3ae0d4b2e7" - integrity sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw== - -"@rollup/rollup-linux-arm64-gnu@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.1.tgz#13353f0ab65f4add0241f97f7ccc640b3a2b5cf2" - integrity sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ== - -"@rollup/rollup-linux-arm64-musl@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.1.tgz#bf64eaa29b2b1e6bc9195f04bb30b2a4ffdc25ae" - integrity sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA== - -"@rollup/rollup-linux-riscv64-gnu@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.1.tgz#ec05966a4ed1b3338c8842108353ac6d3443dc6a" - integrity sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ== - -"@rollup/rollup-linux-s390x-gnu@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.13.1.tgz#c10a1f1522f0c9191ee45f677bd08763ddfdc039" - integrity sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q== - -"@rollup/rollup-linux-x64-gnu@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.1.tgz#836f948b6efc53f05f57d1d9ba92e90d629b3f22" - integrity sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ== - -"@rollup/rollup-linux-x64-musl@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.1.tgz#07e0351cc18eeef026f903189d8312833cb6bd1f" - integrity sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ== - -"@rollup/rollup-win32-arm64-msvc@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.1.tgz#6f9359bbec6cb4a2c002642c63e3704b0b5e68b7" - integrity sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw== - -"@rollup/rollup-win32-ia32-msvc@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.1.tgz#d6545a29ac9dd8b39a9161b87924f13471eb992e" - integrity sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ== - -"@rollup/rollup-win32-x64-msvc@4.13.1": - version "4.13.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.1.tgz#d1b221daca9afca1885b91a311c6f4a04b0deeb5" - integrity sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw== +"@rollup/rollup-android-arm-eabi@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz#5e8930291f1e5ead7fb1171d53ba5c87718de062" + integrity sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q== + +"@rollup/rollup-android-arm64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz#ffb84f1359c04ec8a022a97110e18a5600f5f638" + integrity sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w== + +"@rollup/rollup-darwin-arm64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz#b2fcee8d4806a0b1b9185ac038cc428ddedce9f4" + integrity sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw== + +"@rollup/rollup-darwin-x64@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz#fcb25ccbaa3dd33a6490e9d1c64bab2e0e16b932" + integrity sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz#40d46bdfe667e5eca31bf40047460e326d2e26bb" + integrity sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw== + +"@rollup/rollup-linux-arm-musleabihf@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz#7741df2448c11c56588b50835dbfe91b1a10b375" + integrity sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg== + +"@rollup/rollup-linux-arm64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz#0a23b02d2933e4c4872ad18d879890b6a4a295df" + integrity sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w== + +"@rollup/rollup-linux-arm64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz#e37ef259358aa886cc07d782220a4fb83c1e6970" + integrity sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg== + +"@rollup/rollup-linux-powerpc64le-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz#8c69218b6de05ee2ba211664a2d2ac1e54e43f94" + integrity sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w== + +"@rollup/rollup-linux-riscv64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz#d32727dab8f538d9a4a7c03bcf58c436aecd0139" + integrity sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng== + +"@rollup/rollup-linux-s390x-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz#d46097246a187d99fc9451fe8393b7155b47c5ec" + integrity sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ== + +"@rollup/rollup-linux-x64-gnu@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz#6356c5a03a4afb1c3057490fc51b4764e109dbc7" + integrity sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA== + +"@rollup/rollup-linux-x64-musl@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz#03a5831a9c0d05877b94653b5ddd3020d3c6fb06" + integrity sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA== + +"@rollup/rollup-win32-arm64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz#6cc0db57750376b9303bdb6f5482af8974fcae35" + integrity sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA== + +"@rollup/rollup-win32-ia32-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz#aea0b7e492bd9ed46971cb80bc34f1eb14e07789" + integrity sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w== + +"@rollup/rollup-win32-x64-msvc@4.16.4": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz#c09ad9a132ccb5a67c4f211d909323ab1294f95f" + integrity sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A== "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@storybook/addon-actions@8.0.4", "@storybook/addon-actions@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.0.4.tgz#fc2285bd26660f10af497b332d0e62e7e00bfbbc" - integrity sha512-EyCWo+8T11/TJGYNL/AXtW4yaB+q1v2E9mixbumryCLxpTl2NtaeGZ4e0dlwfIMuw/7RWgHk2uIypcIPR/UANQ== +"@storybook/addon-actions@8.0.9", "@storybook/addon-actions@^8.0.4": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.0.9.tgz#b7a19abb0ee8fd73df1498def7f1ff307d16cb25" + integrity sha512-+I3VTvlKdj8puHeS2tyaOVv9syDiNLneVZbTfqN+UDOK2i42NwvZr8PVwjTzMlEj9eePJdCZgiipz55xwts5bw== dependencies: - "@storybook/core-events" "8.0.4" + "@storybook/core-events" "8.0.9" "@storybook/global" "^5.0.0" "@types/uuid" "^9.0.1" dequal "^2.0.2" polished "^4.2.2" uuid "^9.0.0" -"@storybook/addon-backgrounds@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.4.tgz#e4250a10fe4768dcc016a3c55a627f2c8a6e8d5b" - integrity sha512-fef0KD2GhJx2zpicOf8iL7k2LiIsNzEbGaQpIIjoy4DMqM1hIfNCt3DGTLH7LN5O8G+NVCLS1xmQg7RLvIVSCA== +"@storybook/addon-backgrounds@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.9.tgz#c08bd534f8c7c9f07b687624376e328696fdadc8" + integrity sha512-pCDecACrVyxPaJKEWS0sHsRb8xw+IPCSxDM1TkjaAQ6zZ468A/dcUnqW+LVK8bSXgQwWzn23wqnqPFSy5yptuQ== dependencies: "@storybook/global" "^5.0.0" memoizerific "^1.11.3" ts-dedent "^2.0.0" -"@storybook/addon-controls@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.0.4.tgz#536ad2a1b9a2b19371848e4ec4eaedb4f41b9ec3" - integrity sha512-K5EYBTsUOTJlvIdA7p6Xj31wnV+RbZAkk56UKQvA7nJD7oDuLOq3E9u46F/uZD1vxddd9zFhf2iONfMe3KTTwQ== +"@storybook/addon-controls@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.0.9.tgz#cc1f8ffde58fdaf9ea2ef7ebf9261c3519f42a39" + integrity sha512-wWdmd62UP/sfPm8M7aJjEA+kEXTUIR/QsYi9PoYBhBZcXiikZ4kNan7oD7GfsnzGGKHrBVfwQhO+TqaENGYytA== dependencies: - "@storybook/blocks" "8.0.4" + "@storybook/blocks" "8.0.9" lodash "^4.17.21" ts-dedent "^2.0.0" -"@storybook/addon-docs@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.0.4.tgz#5cee04859c017bdd0f46bc7337a5064cd415c211" - integrity sha512-m0Y7qGAMnNPLEOEgzW/SBm8GX0xabJBaRN+aYijO6UKTln7F6oXXVve+xPC0Y4s6Gc9HZFdJY8WXZr1YSGEUVA== +"@storybook/addon-docs@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.0.9.tgz#3ad1a18d7be8bb2eea4a018208d67d2959ba68c2" + integrity sha512-x7hX7UuzJtClu6XwU3SfpyFhuckVcgqgD6BU6Ihxl0zs+i4xp6iKVXYSnHFMRM1sgoeT8TjPxab35Ke8w8BVRw== dependencies: "@babel/core" "^7.12.3" "@mdx-js/react" "^3.0.0" - "@storybook/blocks" "8.0.4" - "@storybook/client-logger" "8.0.4" - "@storybook/components" "8.0.4" - "@storybook/csf-plugin" "8.0.4" - "@storybook/csf-tools" "8.0.4" + "@storybook/blocks" "8.0.9" + "@storybook/client-logger" "8.0.9" + "@storybook/components" "8.0.9" + "@storybook/csf-plugin" "8.0.9" + "@storybook/csf-tools" "8.0.9" "@storybook/global" "^5.0.0" - "@storybook/node-logger" "8.0.4" - "@storybook/preview-api" "8.0.4" - "@storybook/react-dom-shim" "8.0.4" - "@storybook/theming" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/node-logger" "8.0.9" + "@storybook/preview-api" "8.0.9" + "@storybook/react-dom-shim" "8.0.9" + "@storybook/theming" "8.0.9" + "@storybook/types" "8.0.9" "@types/react" "^16.8.0 || ^17.0.0 || ^18.0.0" fs-extra "^11.1.0" react "^16.8.0 || ^17.0.0 || ^18.0.0" @@ -2219,86 +1932,86 @@ ts-dedent "^2.0.0" "@storybook/addon-essentials@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.0.4.tgz#64b6bf4ccf82c8f212472457f37ecce0acd5cfb1" - integrity sha512-mUIqhAkSz6Qv7nRqAAyCqMLiXBWVsY/8qN7HEIoaMQgdFq38KW3rYwNdzd2JLeXNWP1bBXwfvfcFe7/eqhYJFA== - dependencies: - "@storybook/addon-actions" "8.0.4" - "@storybook/addon-backgrounds" "8.0.4" - "@storybook/addon-controls" "8.0.4" - "@storybook/addon-docs" "8.0.4" - "@storybook/addon-highlight" "8.0.4" - "@storybook/addon-measure" "8.0.4" - "@storybook/addon-outline" "8.0.4" - "@storybook/addon-toolbars" "8.0.4" - "@storybook/addon-viewport" "8.0.4" - "@storybook/core-common" "8.0.4" - "@storybook/manager-api" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/preview-api" "8.0.4" + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.0.9.tgz#579942c264b1ce17c02a9588e99fbb5cb97e2083" + integrity sha512-mwAgdfrOsTuTDcagvM7veBh+iayZIWmKOazzkhrIWbhYcrXOsweigD2UOVeHgAiAzJK49znr4FXTCKcE1hOWcw== + dependencies: + "@storybook/addon-actions" "8.0.9" + "@storybook/addon-backgrounds" "8.0.9" + "@storybook/addon-controls" "8.0.9" + "@storybook/addon-docs" "8.0.9" + "@storybook/addon-highlight" "8.0.9" + "@storybook/addon-measure" "8.0.9" + "@storybook/addon-outline" "8.0.9" + "@storybook/addon-toolbars" "8.0.9" + "@storybook/addon-viewport" "8.0.9" + "@storybook/core-common" "8.0.9" + "@storybook/manager-api" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/preview-api" "8.0.9" ts-dedent "^2.0.0" -"@storybook/addon-highlight@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.0.4.tgz#32f21a1f850394e83277a1cd553a33c86cb603f4" - integrity sha512-tnEiVaJlXL07v8JBox+QtRPVruoy0YovOTAOWY7fKDiKzF1I9wLaJjQF3wOsvwspHTHu00OZw2gsazgXiH4wLQ== +"@storybook/addon-highlight@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.0.9.tgz#da4c0bfb347aea10234f5f6007252f9343f5f384" + integrity sha512-vaRHGDbx7dpNpQECAHk5wczlZO3ntstprGlqnZt0o7ylz6xB5+pTQwTuIFty0hwKv+3TPcskzzifATUyEOEmyg== dependencies: "@storybook/global" "^5.0.0" "@storybook/addon-links@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-8.0.4.tgz#34c4a3818a52023b09c98fcfe4c00e9ac08a0d10" - integrity sha512-SzE+JPZ4mxjprZqbLHf8Hx7UA2fXfMajFjeY9c3JREKQrDoOF1e4r28nAoVsZYF+frWxQB51U4+hOqjlx06wEA== + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-8.0.9.tgz#1f7375896c8e2ffd28eec24edc0e938bc16525cd" + integrity sha512-FVt+AdW3JFSqbJzkKiqKsMRWqHXqEvCBqFs7lNfk3OW0w0jfv1iREtrxE0dVdJoUFQC9V/2Im/EpJ7UB3C2bNQ== dependencies: - "@storybook/csf" "^0.1.2" + "@storybook/csf" "^0.1.4" "@storybook/global" "^5.0.0" ts-dedent "^2.0.0" -"@storybook/addon-measure@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.0.4.tgz#b4d492da2f1f3744c3a792475bd44e1305239412" - integrity sha512-GZYKo2ss5Br+dfHinoK3bgTaS90z3oKKDkhv6lrFfjjU1mDYzzMJpxajQhd3apCYxHLr3MbUqMQibWu2T/q2DQ== +"@storybook/addon-measure@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.0.9.tgz#4116b96521f74a06da0b5383cce214cc20bd7c8b" + integrity sha512-91svOOGEXmGG4USglwXLE3wtlUVgtbKJVxTKX7xRI+AC5JEEaKByVzP17/X8Qn/8HilUL7AfSQ0kCoqtPSJ5cA== dependencies: "@storybook/global" "^5.0.0" tiny-invariant "^1.3.1" -"@storybook/addon-outline@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.0.4.tgz#a368a493dafe3f0cea79af160103efa9e9b1e21b" - integrity sha512-6J9ezNDUxdA3rMCh8sUEQbUwAgkrr+M9QdiFr1t+gKrk5FKP5gwubw1sr3sF1IRB9+s/AjljcOtJAVulSfq05w== +"@storybook/addon-outline@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.0.9.tgz#497c70332bbca5f35777f4c60afc29e505e3588e" + integrity sha512-fQ+jm356TgUnz81IxsC99/aOesbLw3N5OQRJpo/A6kqbLMzlq3ybVzuXYCKC3f0ArgQRNh4NoMeJBMRFMtaWRw== dependencies: "@storybook/global" "^5.0.0" ts-dedent "^2.0.0" -"@storybook/addon-toolbars@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.0.4.tgz#a1de4472089bf685dfca9863bc648e2faf360063" - integrity sha512-yodRXDYog/90cNEy84kg6s7L+nxQ+egBjHBTsav1L4cJmQI/uAX8yISHHiX4I5ppNc120Jz3UdHdRxXRlo345g== +"@storybook/addon-toolbars@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.0.9.tgz#6601732c6b4cc262bab13a1e50f9b11063d5cc74" + integrity sha512-nNSBnnBOhQ+EJwkrIkK4ZBYPcozNmEH770CZ/6NK85SUJ6WEBZapE6ru33jIUokFGEvlOlNCeai0GUc++cQP8w== -"@storybook/addon-viewport@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.0.4.tgz#628322ea0a94252015814edd4c548e26f2c79f4a" - integrity sha512-E5IKOsxKcOtlOYc0cWgzVJohQB+dVBWwaJcg5FlslToknfVB9M0kfQ/SQcp3KB0C9/cOmJK1Jm388InW+EjrBQ== +"@storybook/addon-viewport@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.0.9.tgz#819496abdcc4aa9ae2fe8d4665a96e57ecebece3" + integrity sha512-Ao4+D56cO7biaw+iTlMU1FBec1idX0cmdosDeCFZin06MSawcPkeBlRBeruaSQYdLes8TBMdZPFgfuqI5yIk6g== dependencies: memoizerific "^1.11.3" -"@storybook/blocks@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.0.4.tgz#844d5882f04f3fc06c62ee057e303e72ffe53499" - integrity sha512-9dRXk9zLJVPOmEWsSXm10XUmIfvS/tVgeBgFXNbusFQZXPpexIPNdRgB004pDGg9RvlY78ykpnd3yP143zaXMg== - dependencies: - "@storybook/channels" "8.0.4" - "@storybook/client-logger" "8.0.4" - "@storybook/components" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/csf" "^0.1.2" - "@storybook/docs-tools" "8.0.4" +"@storybook/blocks@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.0.9.tgz#6500fef1e72618bc7715286b9dbb5bfaae20f4d4" + integrity sha512-F2zSrfSwzTFN7qW3zB80tG+EXtmfmCDC6Ird0F7tolszb6tOqJcAcBOwQbE2O0wI63sLu21qxzXgaKBMkiWvJg== + dependencies: + "@storybook/channels" "8.0.9" + "@storybook/client-logger" "8.0.9" + "@storybook/components" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/csf" "^0.1.4" + "@storybook/docs-tools" "8.0.9" "@storybook/global" "^5.0.0" "@storybook/icons" "^1.2.5" - "@storybook/manager-api" "8.0.4" - "@storybook/preview-api" "8.0.4" - "@storybook/theming" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/manager-api" "8.0.9" + "@storybook/preview-api" "8.0.9" + "@storybook/theming" "8.0.9" + "@storybook/types" "8.0.9" "@types/lodash" "^4.14.167" color-convert "^2.0.1" dequal "^2.0.2" @@ -2312,15 +2025,15 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/builder-manager@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-8.0.4.tgz#5c9baa6138beae7cd75c85e4b836cb1e3115d3c4" - integrity sha512-BafYVxq77uuTmXdjYo5by42OyOrb6qcpWYKva3ntWK2ZhTaLJlwwqAOdahT1DVzi4VeUP6465YvsTCzIE8fuIw== +"@storybook/builder-manager@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-8.0.9.tgz#8c03b04b3550dd637247fea2d2ddd089268408d9" + integrity sha512-/PxDwZIfMc/PSRZcasb6SIdGr3azIlenzx7dBF7Imt8i4jLHiAf1t00GvghlfJsvsrn4DNp95rbRbXTDyTj7tQ== dependencies: "@fal-works/esbuild-plugin-global-externals" "^2.1.2" - "@storybook/core-common" "8.0.4" - "@storybook/manager" "8.0.4" - "@storybook/node-logger" "8.0.4" + "@storybook/core-common" "8.0.9" + "@storybook/manager" "8.0.9" + "@storybook/node-logger" "8.0.9" "@types/ejs" "^3.1.1" "@yarnpkg/esbuild-plugin-pnp" "^3.0.0-rc.10" browser-assert "^1.2.1" @@ -2332,19 +2045,19 @@ process "^0.11.10" util "^0.12.4" -"@storybook/builder-webpack5@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-8.0.4.tgz#94c864d63443edeb4349d67b2c553a76a6c681f4" - integrity sha512-FKXIGfDjZJ7KCq6w8e3NEp2+KATsh4U24UV/K8cFjCrRIU++jDpO274D9ozdpzEmhvHOfxK/QlgalqS4G599Aw== - dependencies: - "@storybook/channels" "8.0.4" - "@storybook/client-logger" "8.0.4" - "@storybook/core-common" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/core-webpack" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/preview" "8.0.4" - "@storybook/preview-api" "8.0.4" +"@storybook/builder-webpack5@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-8.0.9.tgz#811af801f264c7377c5e33d68b713eacf6c2f295" + integrity sha512-bFxlxOO2x8n3TmmA9ACxzhmHxtRd0e68dA0w4AYkvEwBf2wScRQdWJIeS5k4JgRwtcUyFYAt+VcKyE1WMgyaVg== + dependencies: + "@storybook/channels" "8.0.9" + "@storybook/client-logger" "8.0.9" + "@storybook/core-common" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/core-webpack" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/preview" "8.0.9" + "@storybook/preview-api" "8.0.9" "@types/node" "^18.0.0" "@types/semver" "^7.3.4" browser-assert "^1.2.1" @@ -2368,37 +2081,37 @@ util "^0.12.4" util-deprecate "^1.0.2" webpack "5" - webpack-dev-middleware "^6.1.1" + webpack-dev-middleware "^6.1.2" webpack-hot-middleware "^2.25.1" webpack-virtual-modules "^0.5.0" -"@storybook/channels@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-8.0.4.tgz#f237bc4d3a00ed05a2f62b310b1db08d6f685dcc" - integrity sha512-haKV+8RbiSzLjicowUfc7h2fTClZHX/nz9SRUecf4IEZUEu2T78OgM/TzqZvL7rA3+/fKqp5iI+3PN3OA75Sdg== +"@storybook/channels@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-8.0.9.tgz#886aff858a13c11f49ca3d92d8a2ade67f19d407" + integrity sha512-7Lcfyy5CsLWWGhMPO9WG4jZ/Alzp0AjepFhEreYHRPtQrfttp6qMAjE/g1aHgun0qHCYWxwqIG4NLR/hqDNrXQ== dependencies: - "@storybook/client-logger" "8.0.4" - "@storybook/core-events" "8.0.4" + "@storybook/client-logger" "8.0.9" + "@storybook/core-events" "8.0.9" "@storybook/global" "^5.0.0" telejson "^7.2.0" tiny-invariant "^1.3.1" -"@storybook/cli@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-8.0.4.tgz#37037ed476c895f728cda528a7b76df01b9a35a0" - integrity sha512-8jb8hrulRMfyFyNXFEapxHBS51xb42ZZGfVAacXIsHOJtjOd5CnOoSUYn0aOkVl19VF/snoa9JOW7BaW/50Eqw== +"@storybook/cli@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-8.0.9.tgz#20d90c5c357d063c054f8594a6b327ce447364fd" + integrity sha512-lilYTKn8F5YOePijqfRYFa5v2mHVIJxPCIgTn+OXAmAFbcizZ6P8P6niU4J/NXulgx68Ln1M7hYhFtTP25hVTw== dependencies: "@babel/core" "^7.23.0" "@babel/types" "^7.23.0" "@ndelangen/get-tarball" "^3.0.7" - "@storybook/codemod" "8.0.4" - "@storybook/core-common" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/core-server" "8.0.4" - "@storybook/csf-tools" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/telemetry" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/codemod" "8.0.9" + "@storybook/core-common" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/core-server" "8.0.9" + "@storybook/csf-tools" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/telemetry" "8.0.9" + "@storybook/types" "8.0.9" "@types/semver" "^7.3.4" "@yarnpkg/fslib" "2.10.3" "@yarnpkg/libzip" "2.3.0" @@ -2425,25 +2138,25 @@ tiny-invariant "^1.3.1" ts-dedent "^2.0.0" -"@storybook/client-logger@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.0.4.tgz#d603399ad65ef1d38bf013033fcb18728d0d4317" - integrity sha512-2SeEg3PT/d0l/+EAVtyj9hmMLTyTPp+bRBSzxYouBjtJPM1jrdKpFagj1o3uBRovwWm9SIVX6/ZsoRC33PEV1g== +"@storybook/client-logger@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.0.9.tgz#90a099ad79d6959cd3d0ee4f753edb0cc54a54f5" + integrity sha512-LzV/RHkbf07sRc1Jc0ff36RlapKf9Ul7/+9VMvVbI3hshH1CpmrZK4t/tsIdpX/EVOdJ1Gg5cES06PnleOAIPA== dependencies: "@storybook/global" "^5.0.0" -"@storybook/codemod@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-8.0.4.tgz#815c7c729b973f958282df37040581a7ba416324" - integrity sha512-bysG46P4wjlR3RCpr/ntNAUaupWpzLcWYWti3iNtIyZ/iPrX6KtXoA9QCIwJZrlv41us6F+KEZbzLzkgWbymtQ== +"@storybook/codemod@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-8.0.9.tgz#196dae4b4a921244ed384217f79651979eff1b45" + integrity sha512-VBeGpSZSQpL6iyLLqceJSNGhdCqcNwv+xC/aWdDFOkmuE1YfbmNNwpa9QYv4ZFJ2QjUsm4iTWG60qK+9NXeSKA== dependencies: "@babel/core" "^7.23.2" "@babel/preset-env" "^7.23.2" "@babel/types" "^7.23.0" - "@storybook/csf" "^0.1.2" - "@storybook/csf-tools" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/csf" "^0.1.4" + "@storybook/csf-tools" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/types" "8.0.9" "@types/cross-spawn" "^6.0.2" cross-spawn "^7.0.3" globby "^11.0.2" @@ -2453,30 +2166,30 @@ recast "^0.23.5" tiny-invariant "^1.3.1" -"@storybook/components@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.0.4.tgz#45f6548bfe42004bbb1533b45d9a3e65043b5fd7" - integrity sha512-i5ngl5GTOLB9nZ1cmpxTjtWct5IuH9UxzFC73a0jHMkCwN26w16IqufRVDaoQv0AvZN4pd4fNM2in/XVHA10dw== +"@storybook/components@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.0.9.tgz#f087e69d8d95ff0e5766042fc4f9481882db73bb" + integrity sha512-JcwBGADzIJs0PSzqykrrD2KHzNG9wtexUOKuidt+FSv9szpUhe3qBAXIHpdfBRl7mOJ9TRZ5rt+mukEnfncdzA== dependencies: "@radix-ui/react-slot" "^1.0.2" - "@storybook/client-logger" "8.0.4" - "@storybook/csf" "^0.1.2" + "@storybook/client-logger" "8.0.9" + "@storybook/csf" "^0.1.4" "@storybook/global" "^5.0.0" "@storybook/icons" "^1.2.5" - "@storybook/theming" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/theming" "8.0.9" + "@storybook/types" "8.0.9" memoizerific "^1.11.3" util-deprecate "^1.0.2" -"@storybook/core-common@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-8.0.4.tgz#ba851052f1cd61ba2784e07ad64499e3c36bb9a1" - integrity sha512-dzFRLm5FxUa2EFE6Rx/KLDTJNLBIp1S2/+Q1K+rG8V+CLvewCc2Cd486rStZqSXEKI7vDnsRs/aMla+N0X/++Q== +"@storybook/core-common@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-8.0.9.tgz#ccf97c549943f670dcecaefebeb4a8637bac6b42" + integrity sha512-Jmue+sfHFb4GTYBzyWYw1MygoJiQSfISIrKmNIzAmZ+oR9EOr+jpu/i/bH+uetZ2Hqg1AGhj1VB7OtJp9HQyWw== dependencies: - "@storybook/core-events" "8.0.4" - "@storybook/csf-tools" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/core-events" "8.0.9" + "@storybook/csf-tools" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/types" "8.0.9" "@yarnpkg/fslib" "2.10.3" "@yarnpkg/libzip" "2.3.0" chalk "^4.1.0" @@ -2502,35 +2215,35 @@ ts-dedent "^2.0.0" util "^0.12.4" -"@storybook/core-events@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-8.0.4.tgz#14e87ffcbf826139226306de9079a84e0286860b" - integrity sha512-1FgLacIGi9i6/fyxw7ZJDC621RK47IMaA3keH4lc11ASRzCSwJ4YOrXjBFjfPc79EF2BuX72DDJNbhj6ynfF3g== +"@storybook/core-events@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-8.0.9.tgz#d14db371f1f959e8c3baaa6098d2c506bcb3f3ad" + integrity sha512-DxSUx7wG9Qe3OFUBnv3OrYq48J8UWNo2DUR5/JecJCtp3n++L4fAEW3J0IF5FfxpQDMQSp1yTNjZ2PaWCMd2ag== dependencies: ts-dedent "^2.0.0" -"@storybook/core-server@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-8.0.4.tgz#c0f94848109137b303cdf2dbc4a9d451ce5732c8" - integrity sha512-/633Pp7LPcDWXkPLSW+W9VUYUbVkdVBG6peXjuzogV0vzdM0dM9af/T0uV2NQxUhzoy6/7QdSDljE+eEOBs2Lw== +"@storybook/core-server@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-8.0.9.tgz#c3f4790e35b6a116df64c6e6d1161c2077c70c4e" + integrity sha512-BIe1T5YUBl0GYxEjRoTQsvXD2pyuzL8rPTUD41zlzSQM0R8U6Iant9SzRms4u0+rKUm2mGxxKuODlUo5ewqaGA== dependencies: "@aw-web-design/x-default-browser" "1.4.126" "@babel/core" "^7.23.9" "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-manager" "8.0.4" - "@storybook/channels" "8.0.4" - "@storybook/core-common" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/csf" "^0.1.2" - "@storybook/csf-tools" "8.0.4" + "@storybook/builder-manager" "8.0.9" + "@storybook/channels" "8.0.9" + "@storybook/core-common" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/csf" "^0.1.4" + "@storybook/csf-tools" "8.0.9" "@storybook/docs-mdx" "3.0.0" "@storybook/global" "^5.0.0" - "@storybook/manager" "8.0.4" - "@storybook/manager-api" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/preview-api" "8.0.4" - "@storybook/telemetry" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/manager" "8.0.9" + "@storybook/manager-api" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/preview-api" "8.0.9" + "@storybook/telemetry" "8.0.9" + "@storybook/types" "8.0.9" "@types/detect-port" "^1.3.0" "@types/node" "^18.0.0" "@types/pretty-hrtime" "^1.0.0" @@ -2558,44 +2271,44 @@ watchpack "^2.2.0" ws "^8.2.3" -"@storybook/core-webpack@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-8.0.4.tgz#6b1f861ac173a43b626ff2e98d9090ad31672278" - integrity sha512-sECeoJtT6iFWzgZaQbS1TEZvBrXIT4qb9fa0x2/I5YhCTPnprCNL1yyN90hFQTpdLco5vfQ86YnpzMRntODn7A== +"@storybook/core-webpack@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-8.0.9.tgz#ac8211977bcfc26e24900a3b5dd9cdbc6eb31a7e" + integrity sha512-lehuuAmHt/p5z8lZkMW16Y/+uDEh+Z/tExItVadtjEY8jXDe2Ilr1Cts2lvzVNuuESEKd5bqsGJ1L4t9Bf25pg== dependencies: - "@storybook/core-common" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/core-common" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/types" "8.0.9" "@types/node" "^18.0.0" ts-dedent "^2.0.0" -"@storybook/csf-plugin@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.0.4.tgz#b5b1a02a51c91e386f3dc8fecdbc02975abe82d0" - integrity sha512-pEgctWuS/qeKMFZJJUM2JuKwjKBt27ye+216ft7xhNqpsrmCgumJYrkU/ii2CsFJU/qr5Fu9EYw+N+vof1OalQ== +"@storybook/csf-plugin@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.0.9.tgz#af030b3063d01278de332c5985df8cff10e9b63b" + integrity sha512-pXaNCNi++kxKsqSWwvx215fPx8cNqvepLVxQ7B69qXLHj80DHn0Q3DFBO3sLXNiQMJ2JK4OYcTxMfuOiyzszKw== dependencies: - "@storybook/csf-tools" "8.0.4" + "@storybook/csf-tools" "8.0.9" unplugin "^1.3.1" -"@storybook/csf-tools@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-8.0.4.tgz#8322a3310d411a16a19efb36127aec5afdd3b298" - integrity sha512-dMSZxWnXBhmXGOZZOAJ4DKZRCYdA0HaqqZ4/eF9MLLsI+qvW4EklcpjVY6bsIzACgubRWtRZkTpxTnjExi/N1A== +"@storybook/csf-tools@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-8.0.9.tgz#8c24422fc12519be7756b4dcccad900962e6a88a" + integrity sha512-PiNMhL97giLytTdQwuhsZ92buVk4gy9H/8DtrDhUc45/1OmF95gogm6T2Yap729SIFwgpOcuq/U3aVo6d6swVQ== dependencies: "@babel/generator" "^7.23.0" "@babel/parser" "^7.23.0" "@babel/traverse" "^7.23.2" "@babel/types" "^7.23.0" - "@storybook/csf" "^0.1.2" - "@storybook/types" "8.0.4" + "@storybook/csf" "^0.1.4" + "@storybook/types" "8.0.9" fs-extra "^11.1.0" recast "^0.23.5" ts-dedent "^2.0.0" -"@storybook/csf@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.3.tgz#79047a4dece94ba7c8e78003723e9bd9e071379a" - integrity sha512-IPZvXXo4b3G+gpmgBSBqVM81jbp2ePOKsvhgJdhyZJtkYQCII7rg9KKLQhvBQM5sLaF1eU6r0iuwmyynC9d9SA== +"@storybook/csf@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.4.tgz#18224bcd571fa834ccc4bebda8a0ca4cedbc4d91" + integrity sha512-B9UI/lsQMjF+oEfZCI6YXNoeuBcGZoOP5x8yKbe2tIEmsMjSztFKkpPzi5nLCnBk/MBtl6QJeI3ksJnbsWPkOw== dependencies: type-fest "^2.19.0" @@ -2604,14 +2317,15 @@ resolved "https://registry.yarnpkg.com/@storybook/docs-mdx/-/docs-mdx-3.0.0.tgz#5c9b5ce35dcb00ad8aa5dddbabf52ad09fab3974" integrity sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ== -"@storybook/docs-tools@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-8.0.4.tgz#24ebbca47d4075041376c356a5c4d0902f832991" - integrity sha512-PONfG8j/AOHi79NbEkneFRZIscrShbA0sgA+62zeejH4r9+fuIkIKtLnKcAxvr8Bm6uo9aSQbISJZUcBG42WhQ== +"@storybook/docs-tools@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-8.0.9.tgz#4257adede62028a6e1176151a09fa4f4fa146b12" + integrity sha512-OzogAeOmeHea/MxSPKRBWtOQVNSpoq+OOpimO9YRA5h5GBRJ2TUOGT44Gny6QT4ll5AvQA8fIiq9KezKcLekAg== dependencies: - "@storybook/core-common" "8.0.4" - "@storybook/preview-api" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/core-common" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/preview-api" "8.0.9" + "@storybook/types" "8.0.9" "@types/doctrine" "^0.0.3" assert "^2.1.0" doctrine "^3.0.0" @@ -2627,20 +2341,20 @@ resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.9.tgz#bb4a51a79e186b62e2dd0e04928b8617ac573838" integrity sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg== -"@storybook/manager-api@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.0.4.tgz#46bea1b3b65e3085adad77eb2de29a0d5706ed95" - integrity sha512-TudiRmWlsi8kdjwqW0DDLen76Zp4Sci/AnvTbZvZOWe8C2mruxcr6aaGwuIug6y+uxIyXDvURF6Cek5Twz4isg== +"@storybook/manager-api@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.0.9.tgz#5361d253c6704643f44afb95271b3d206d831740" + integrity sha512-99b3yKArDSvfabXL7QE3nA95e4DdW/5H/ZCcr6/E2qCQJayZ6G1v/WWamKXbiaTpkndulFmcb/+ZmnDXcweIIQ== dependencies: - "@storybook/channels" "8.0.4" - "@storybook/client-logger" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/csf" "^0.1.2" + "@storybook/channels" "8.0.9" + "@storybook/client-logger" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/csf" "^0.1.4" "@storybook/global" "^5.0.0" "@storybook/icons" "^1.2.5" - "@storybook/router" "8.0.4" - "@storybook/theming" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/router" "8.0.9" + "@storybook/theming" "8.0.9" + "@storybook/types" "8.0.9" dequal "^2.0.2" lodash "^4.17.21" memoizerific "^1.11.3" @@ -2648,36 +2362,36 @@ telejson "^7.2.0" ts-dedent "^2.0.0" -"@storybook/manager@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-8.0.4.tgz#94c4b27ada34f6d3004b86b6e028a9caf71e7c02" - integrity sha512-M5IofDSxbIQIdAglxUtZOGKjZ1EAq1Mdbh4UolVsF1PKF6dAvBQJLVW6TiLjEbmPBtqgeYKMgrmmYiFNqVcdBQ== +"@storybook/manager@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-8.0.9.tgz#e24971577714bbed02b55596d1363fbda78cfa21" + integrity sha512-+NnRo+5JQFGNqveKrLtC0b+Z08Tae4m44iq292bPeZMpr9OkFsIkU0PBPsHTHPkrqC/zZXRNsCsTEgvu3p2OIA== -"@storybook/node-logger@8.0.4", "@storybook/node-logger@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-8.0.4.tgz#0701a71dfc0bcfa178e7175a00aadd78b965629c" - integrity sha512-cALLHuX53vLQsoJamGRlquh2pfhPq9copXou2JTmFT6mrCcipo77SzhBDfeeuhaGv6vUWPfmGjPBEHXWGPe4+g== +"@storybook/node-logger@8.0.9", "@storybook/node-logger@^8.0.4": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-8.0.9.tgz#0825e53bce014a8faa51029ab89e91b5eac1af8b" + integrity sha512-5ajMdZFrYrjGLJOVDq7dlEQNFsgeLHymt4dCK9MulL/ciXykmXUZXE3Bye0wFy+I2qqDVvrvR8uzCvSFvm5MAQ== "@storybook/preset-create-react-app@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/preset-create-react-app/-/preset-create-react-app-8.0.4.tgz#b1c24e16bc738d2862bac6262b0ec90a31828146" - integrity sha512-qI+Oydkq26gOFRY/+rx1WYGH12VnXwP6MG03uS7RjiGI/xi12oBU9Zuy6IHJ4hV2gb/90usNZTkgMKJoFs25Uw== + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/preset-create-react-app/-/preset-create-react-app-8.0.9.tgz#b09eea0b5b3c873141202fa648b6a31a0d957fe9" + integrity sha512-7IjDztstczSFoLlzhWt6MAE2IKVA1B2CLiXRVlw1aK9+dv5n0ctZQzRCwwvTQXdlI3ABSqB7Gn6khKJOBYUhlg== dependencies: "@pmmmwh/react-refresh-webpack-plugin" "^0.5.1" - "@storybook/types" "8.0.4" + "@storybook/types" "8.0.9" "@types/semver" "^7.5.6" pnp-webpack-plugin "^1.7.0" semver "^7.5.4" -"@storybook/preset-react-webpack@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.4.tgz#17fa28421c6523a86ed638710a16d6657ab8371c" - integrity sha512-XldgoZJOXNbZLGhvP6FqVeRnXigEZXV88uhEveREH4zRceYxXUmiCjFUnFy5aXaYZLcv09GHpqTPCqRoOZ+upg== +"@storybook/preset-react-webpack@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.9.tgz#4070b62a34b23916d720893eb2b3043765eb13b6" + integrity sha512-kkJG03ZOJXM8fhYJuvAX9+3QVwoOMnz1tj75M/45c9i6XafPrBi2imGZWjXzuKXMxg/KO9fS/Y0JZmDh7vPM9g== dependencies: - "@storybook/core-webpack" "8.0.4" - "@storybook/docs-tools" "8.0.4" - "@storybook/node-logger" "8.0.4" - "@storybook/react" "8.0.4" + "@storybook/core-webpack" "8.0.9" + "@storybook/docs-tools" "8.0.9" + "@storybook/node-logger" "8.0.9" + "@storybook/react" "8.0.9" "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" "@types/node" "^18.0.0" "@types/semver" "^7.3.4" @@ -2690,17 +2404,17 @@ tsconfig-paths "^4.2.0" webpack "5" -"@storybook/preview-api@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.0.4.tgz#523e6cb7333b2953cd0b68d43c292e391d5b1337" - integrity sha512-uZCgZ/7BZkFTNudCBWx3YPFVdReMQSZJj9EfQVhQaPmfGORHGMvZMRsQXl0ONhPy7zDD4rVQxu5dSKWmIiYoWQ== +"@storybook/preview-api@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.0.9.tgz#273ac693a8d7333a33e1a8202e663dd9a9f02cc4" + integrity sha512-zHfX34bkAMzzmE7vbDzaqFwSW6ExiBD0HiO1L/IsHF55f0f7xV7IH8uJyFRrDTvAoW3ReSxZDMvvPpeydFPKGA== dependencies: - "@storybook/channels" "8.0.4" - "@storybook/client-logger" "8.0.4" - "@storybook/core-events" "8.0.4" - "@storybook/csf" "^0.1.2" + "@storybook/channels" "8.0.9" + "@storybook/client-logger" "8.0.9" + "@storybook/core-events" "8.0.9" + "@storybook/csf" "^0.1.4" "@storybook/global" "^5.0.0" - "@storybook/types" "8.0.4" + "@storybook/types" "8.0.9" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -2710,10 +2424,10 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/preview@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-8.0.4.tgz#d1ffc175390bd400c5e41b1d0576c9d58c11a81d" - integrity sha512-dJa13bIxQBfa5ZsXAeL6X/oXI6b87Fy31pvpKPkW1o+7M6MC4OvwGQBqgAd7m8yn6NuIHxrdwjEupa7l7PGb6w== +"@storybook/preview@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-8.0.9.tgz#46ebdf09bc7eb9601c4ddce9a09e0c63ae31c662" + integrity sha512-tFsR8xc8AYBZZrZw8enklFbSQt7ZAV+rv20BoxwDhd3q7fjXyK7O4moGPqUwBZ7rukTG13nPoISxr+VXAk/HYA== "@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": version "1.0.6--canary.9.0c3f3b7.0" @@ -2728,32 +2442,32 @@ react-docgen-typescript "^2.2.2" tslib "^2.0.0" -"@storybook/react-dom-shim@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.0.4.tgz#c935e52f7f7df899232872de7c364c8e25b52713" - integrity sha512-H8bci23e+G40WsdYPuPrhAjCeeXypXuAV6mTVvLHGKH+Yb+3wiB1weaXrot/TgzPbkDNybuhTI3Qm48FPLt0bw== +"@storybook/react-dom-shim@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.0.9.tgz#9fcfcc93a41c84f5a046b0b97647684061e2ac7d" + integrity sha512-8011KlRuG3obr5pZZ7bcEyYYNWF3tR596YadoMd267NPoHKvwAbKL1L/DNgb6kiYjZDUf9QfaKSCWW31k0kcRQ== "@storybook/react-webpack5@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/react-webpack5/-/react-webpack5-8.0.4.tgz#c37525b5910eb29c8b63dbbfa513e8dcee871b01" - integrity sha512-HZzcIQLWR6pg28CRwNF9VnFWGTEFEnIAAGKbUAc7mMGysN9AgZgz618FZu0W0JmAUBtWwEJ+pYyLJCIOFoDE6w== + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/react-webpack5/-/react-webpack5-8.0.9.tgz#e91ce60be87b0a79ca9daa4d6d8b6417b27e03c4" + integrity sha512-JJIEL7fXrSurzc/pUhvZMjwVZpKuWNwjq3N9jTjwy0GxN2lDEu6glHCyMglvij/GURWvm4eXsATHUfNf47B1AA== dependencies: - "@storybook/builder-webpack5" "8.0.4" - "@storybook/preset-react-webpack" "8.0.4" - "@storybook/react" "8.0.4" + "@storybook/builder-webpack5" "8.0.9" + "@storybook/preset-react-webpack" "8.0.9" + "@storybook/react" "8.0.9" "@types/node" "^18.0.0" -"@storybook/react@8.0.4", "@storybook/react@^8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.0.4.tgz#8789dfbc17103ea996123ec8e91f5fe53438de6e" - integrity sha512-p4wQSJIhG48UD2fZ6tFDT9zaqrVnvZxjV18+VjSi3dez/pDoEMJ3SWZWcmeDenKwvvk+SPdRH7k5mUHW1Rh0xg== +"@storybook/react@8.0.9", "@storybook/react@^8.0.4": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.0.9.tgz#b9e286245a4ae79ae0211d672b1143d1c73c90d3" + integrity sha512-NeQ6suZG3HKikwe3Tx9cAIaRx7uP8FKCmlVvIiBg4LTTI5orCt94PPakvuZukZcbkqvcCnEBkebAzwUpn8PiJw== dependencies: - "@storybook/client-logger" "8.0.4" - "@storybook/docs-tools" "8.0.4" + "@storybook/client-logger" "8.0.9" + "@storybook/docs-tools" "8.0.9" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "8.0.4" - "@storybook/react-dom-shim" "8.0.4" - "@storybook/types" "8.0.4" + "@storybook/preview-api" "8.0.9" + "@storybook/react-dom-shim" "8.0.9" + "@storybook/types" "8.0.9" "@types/escodegen" "^0.0.6" "@types/estree" "^0.0.51" "@types/node" "^18.0.0" @@ -2770,116 +2484,116 @@ type-fest "~2.19" util-deprecate "^1.0.2" -"@storybook/router@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-8.0.4.tgz#37eb06023e74703703f3c93f4b4d1bbfe38e50c0" - integrity sha512-hlR80QvmLBflAqMeGcgtDuSe6TJlzdizwEAkBLE1lDvFI6tvvEyAliCAXBpIDdOZTe0u/zeeJkOUXKSx33caoQ== +"@storybook/router@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-8.0.9.tgz#69cfff588d8c8a4160404f1f2897ce1feb9cecb1" + integrity sha512-aAOWxbM9J4mt+cp4o88T2PB29mgBBTOzU37/pUsTHYnKnR9XI4npXEXdN8Gv+ryqM0kj0AbBpz/llFlnR2MNNA== dependencies: - "@storybook/client-logger" "8.0.4" + "@storybook/client-logger" "8.0.9" memoizerific "^1.11.3" qs "^6.10.0" -"@storybook/telemetry@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-8.0.4.tgz#39a39b372db7173e04d61092e27603c377f9c66a" - integrity sha512-Q3ITY6J46R/TrrPRIU1fs3WNs69ExpTJZ9UlB8087qOUyV90Ex33SYk3i10xVWRczxCmyC1V58Xuht6nxz7mNQ== +"@storybook/telemetry@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-8.0.9.tgz#148bd044c4bac7197188aaf54e313fb184fd69aa" + integrity sha512-AGGfcup06t+wxhBIkHd0iybieOh9PDVZQJ9oPct5JGB39+ni9wvs0WOD+MYlHbsjp8id7+aGkh6mYuYOvfck+Q== dependencies: - "@storybook/client-logger" "8.0.4" - "@storybook/core-common" "8.0.4" - "@storybook/csf-tools" "8.0.4" + "@storybook/client-logger" "8.0.9" + "@storybook/core-common" "8.0.9" + "@storybook/csf-tools" "8.0.9" chalk "^4.1.0" detect-package-manager "^2.0.1" fetch-retry "^5.0.2" fs-extra "^11.1.0" read-pkg-up "^7.0.1" -"@storybook/theming@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.0.4.tgz#e72aa3b5d27d3db5ed769782ac91d6fdcb1c830e" - integrity sha512-NxtTU2wMC0lj375ejoT3Npdcqwv6NeUpLaJl6EZCMXSR41ve9WG4suUNWQ63olhqKxirjzAz0IL7ggH7c3hPvA== +"@storybook/theming@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.0.9.tgz#cb5a4f6ddc4a15faa64905cfad60422c3db252f2" + integrity sha512-jgfDuYoiNMMirQiASN3Eg0hGDXsEtpdAcMxyShqYGwu9elxgD9yUnYC2nSckYsM74a3ZQ3JaViZ9ZFSe2FHmeQ== dependencies: "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@storybook/client-logger" "8.0.4" + "@storybook/client-logger" "8.0.9" "@storybook/global" "^5.0.0" memoizerific "^1.11.3" -"@storybook/types@8.0.4": - version "8.0.4" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-8.0.4.tgz#650d87808ecab4ba7325fecef5a6f63ac6226f27" - integrity sha512-OO7QY+qZFCYkItDUBACtIV32p75O7sNziAiyS1V2Oxgo7Ln7fwZwr3mJcA1ruBed6ZcrW3c87k7Xs40T2zAWcg== +"@storybook/types@8.0.9": + version "8.0.9" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-8.0.9.tgz#6597c35c0b147e43a6b23b2159514fea312f2214" + integrity sha512-ew0EXzk9k4B557P1qIWYrnvUcgaE0WWA5qQS0AU8l+fRTp5nvl9O3SP/zNIB0SN1qDFO7dXr3idTNTyIikTcEQ== dependencies: - "@storybook/channels" "8.0.4" + "@storybook/channels" "8.0.9" "@types/express" "^4.7.0" file-system-cache "2.3.0" -"@swc/core-darwin-arm64@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.11.tgz#91ef40816e10495a4038a98dc6c8dfcc85d9c59b" - integrity sha512-C1j1Qp/IHSelVWdEnT7f0iONWxQz6FAqzjCF2iaL+0vFg4V5f2nlgrueY8vj5pNNzSGhrAlxsMxEIp4dj1MXkg== - -"@swc/core-darwin-x64@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.11.tgz#6f71e3cd4687ef5df226ba0b8a20adc52fa7dc9e" - integrity sha512-0TTy3Ni8ncgaMCchSQ7FK8ZXQLlamy0FXmGWbR58c+pVZWYZltYPTmheJUvVcR0H2+gPAymRKyfC0iLszDALjg== - -"@swc/core-linux-arm-gnueabihf@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.11.tgz#08521822b5510cb506bc49e728f416636ff0306f" - integrity sha512-XJLB71uw0rog4DjYAPxFGAuGCBQpgJDlPZZK6MTmZOvI/1t0+DelJ24IjHIxk500YYM26Yv47xPabqFPD7I2zQ== - -"@swc/core-linux-arm64-gnu@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.11.tgz#9485bc591aa573b282d08b168b80a60badb8df9b" - integrity sha512-vYQwzJvm/iu052d5Iw27UFALIN5xSrGkPZXxLNMHPySVko2QMNNBv35HLatkEQHbQ3X+VKSW9J9SkdtAvAVRAQ== - -"@swc/core-linux-arm64-musl@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.11.tgz#85eecad7aaab7e94b1ff15ab9d95e80a1e95f356" - integrity sha512-eV+KduiRYUFjPsvbZuJ9aknQH9Tj0U2/G9oIZSzLx/18WsYi+upzHbgxmIIHJ2VJgfd7nN40RI/hMtxNsUzR/g== - -"@swc/core-linux-x64-gnu@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.11.tgz#16259de893489b4699045e36bf52b2afe5d10f6d" - integrity sha512-WA1iGXZ2HpqM1OR9VCQZJ8sQ1KP2or9O4bO8vWZo6HZJIeoQSo7aa9waaCLRpkZvkng1ct/TF/l6ymqSNFXIzQ== - -"@swc/core-linux-x64-musl@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.11.tgz#0f4e644fc2b62c8c966072389d354337a22b4dde" - integrity sha512-UkVJToKf0owwQYRnGvjHAeYVDfeimCEcx0VQSbJoN7Iy0ckRZi7YPlmWJU31xtKvikE2bQWCOVe0qbSDqqcWXA== - -"@swc/core-win32-arm64-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.11.tgz#d836b79d8730bf83e6b38a5b888e83944d6fb233" - integrity sha512-35khwkyly7lF5NDSyvIrukBMzxPorgc5iTSDfVO/LvnmN5+fm4lTlrDr4tUfTdOhv3Emy7CsKlsNAeFRJ+Pm+w== - -"@swc/core-win32-ia32-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.11.tgz#bc60bbdc65134aaa5b214e2aaf209acfce401d17" - integrity sha512-Wx8/6f0ufgQF2pbVPsJ2dAmFLwIOW+xBE5fxnb7VnEbGkTgP1qMDWiiAtD9rtvDSuODG3i1AEmAak/2HAc6i6A== - -"@swc/core-win32-x64-msvc@1.4.11": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.11.tgz#92fd6d4e2d70bbd4fda438f02310d998db8c7b7c" - integrity sha512-0xRFW6K9UZQH2NVC/0pVB0GJXS45lY24f+6XaPBF1YnMHd8A8GoHl7ugyM5yNUTe2AKhSgk5fJV00EJt/XBtdQ== +"@swc/core-darwin-arm64@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.0.tgz#fd56dedb26ebaaf028cc427d0cec998095a275ac" + integrity sha512-dyA25zQjm3xmMFsRPFgBpSqWSW9TITnkndZkZAiPYLjBxH9oTNMa0l09BePsaqEeXySY++tUgAeYu/9onsHLbg== + +"@swc/core-darwin-x64@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.5.0.tgz#cbbc00bba19c01ecd6f6c952b7c6b722f02ef515" + integrity sha512-cO7kZMMA/fcQIBT31LBzcVNSk3AZGVYLqvEPnJhFImjPm3mGKUd6kWpARUEGR68MyRU2VsWhE6eCjMcM+G7bxw== + +"@swc/core-linux-arm-gnueabihf@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.0.tgz#47316c552d7edd06fcd2585a28574f24a82cc4d3" + integrity sha512-BXaXytS4y9lBFRO6vwA6ovvy1d2ZIzS02i2R1oegoZzzNu89CJDpkYXYS9bId0GvK2m9Q9y2ofoZzKE2Rp3PqQ== + +"@swc/core-linux-arm64-gnu@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.0.tgz#c957fdc1bd24d49c2b063fb37147672c29fb4407" + integrity sha512-Bu4/41pGadXKnRsUbox0ig63xImATVH704oPCXcoOvNGkDyMjWgIAhzIi111vrwFNpj9utabgUE4AtlUa2tAOQ== + +"@swc/core-linux-arm64-musl@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.0.tgz#0416382c54182d2e3f326e422716ac3cf7dbad24" + integrity sha512-lUFFvC8tsepNcTnKEHNrePWanVVef6PQ82Rv9wIeebgGHRUqDh6+CyCqodXez+aKz6NyE/PBIfp0r+jPx4hoJA== + +"@swc/core-linux-x64-gnu@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.0.tgz#08ce35c57a0f58e0015731a2b38efce390b34903" + integrity sha512-c6LegFU1qdyMfk+GzNIOvrX61+mksm21Q01FBnXSy1nf1ACj/a86jmr3zkPl0zpNVHfPOw3Ry1QIuLQKD+67YA== + +"@swc/core-linux-x64-musl@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.0.tgz#73edc03943b2a7a06b14cfd4d195d6c0f953ef70" + integrity sha512-I/V8aWBmfDWwjtM1bS8ASG+6PcO/pVFYyPP5g2ok46Vz1o1MnAUd18mHnWX43nqVJokaW+BD/G4ZMZ+gXRl4zQ== + +"@swc/core-win32-arm64-msvc@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.0.tgz#cd07c068c1a06ad66beb69635481adde2845c396" + integrity sha512-nN685BvI7iM58xabrSOSQHUvIY10pcXh5H9DmS8LeYqG6Dkq7QZ8AwYqqonOitIS5C35MUfhSMLpOTzKoLdUqA== + +"@swc/core-win32-ia32-msvc@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.0.tgz#363fba59da64ccc3576f0525070e26966667b388" + integrity sha512-3YjltmEHljI+TvuDOC4lspUzjBUoB3X5BhftRBprSTJx/czuMl0vdoZKs2Snzb5Eqqesp0Rl8q+iQ1E1oJ6dEA== + +"@swc/core-win32-x64-msvc@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.0.tgz#6183c163076da0da6ce994898bcbd4630dbe7514" + integrity sha512-ZairtCwJsaxnUH85DcYCyGpNb9bUoIm9QXYW+VaEoXwbcB95dTIiJwN0aRxPT8B0B2MNw/CXLqjoPo6sDwz5iw== "@swc/core@^1.3.107": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.4.11.tgz#e91f488df9242584cc6f1b034419f8302aeb0c85" - integrity sha512-WKEakMZxkVwRdgMN4AMJ9K5nysY8g8npgQPczmjBeNK5In7QEAZAJwnyccrWwJZU0XjVeHn2uj+XbOKdDW17rg== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.5.0.tgz#189a7770b0d95aeff8ca56b8763705cc27bae90f" + integrity sha512-fjADAC5gOOX54Rpcr1lF9DHLD+nPD5H/zXLtEgK2Ez3esmogT+LfHzCZtUxqetjvaMChKhQ0Pp0ZB6Hpz/tCbw== dependencies: "@swc/counter" "^0.1.2" "@swc/types" "^0.1.5" optionalDependencies: - "@swc/core-darwin-arm64" "1.4.11" - "@swc/core-darwin-x64" "1.4.11" - "@swc/core-linux-arm-gnueabihf" "1.4.11" - "@swc/core-linux-arm64-gnu" "1.4.11" - "@swc/core-linux-arm64-musl" "1.4.11" - "@swc/core-linux-x64-gnu" "1.4.11" - "@swc/core-linux-x64-musl" "1.4.11" - "@swc/core-win32-arm64-msvc" "1.4.11" - "@swc/core-win32-ia32-msvc" "1.4.11" - "@swc/core-win32-x64-msvc" "1.4.11" + "@swc/core-darwin-arm64" "1.5.0" + "@swc/core-darwin-x64" "1.5.0" + "@swc/core-linux-arm-gnueabihf" "1.5.0" + "@swc/core-linux-arm64-gnu" "1.5.0" + "@swc/core-linux-arm64-musl" "1.5.0" + "@swc/core-linux-x64-gnu" "1.5.0" + "@swc/core-linux-x64-musl" "1.5.0" + "@swc/core-win32-arm64-msvc" "1.5.0" + "@swc/core-win32-ia32-msvc" "1.5.0" + "@swc/core-win32-x64-msvc" "1.5.0" "@swc/counter@^0.1.2", "@swc/counter@^0.1.3": version "0.1.3" @@ -2922,9 +2636,9 @@ redent "^3.0.0" "@testing-library/react@^14.2.2": - version "14.2.2" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.2.2.tgz#74f855215c57d423282486a395a4348a837d3c5a" - integrity sha512-SOUuM2ysCvjUWBXTNfQ/ztmnKDmqaiPV3SvoIuyxMUca45rbSWWAT/qB8CUs/JQ/ux/8JFs9DNdFQ3f6jH3crA== + version "14.3.1" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.3.1.tgz#29513fc3770d6fb75245c4e1245c470e4ffdd830" + integrity sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^9.0.0" @@ -2936,9 +2650,9 @@ integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== "@tinymce/tinymce-react@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@tinymce/tinymce-react/-/tinymce-react-5.0.0.tgz#b87913de5d26d7832776d0376b4276907a38a34f" - integrity sha512-5lT0nZ9L/qVO7OWyns4KIF3MDeagHThRFTP1YGuvS4QNtgEc1gWAt9aCswRBptZYMKCXgXNvStVUmq/TVxODGQ== + version "5.0.1" + resolved "https://registry.yarnpkg.com/@tinymce/tinymce-react/-/tinymce-react-5.0.1.tgz#478bbdadf0f4bff9f82d596799e7306f8b530f38" + integrity sha512-tw6yNRqrMGP1iJNeY14wvGsUayC9fc1QpJa7tAvdmeBrUlllyF9PpsrbfvYd+2k8t+w0r2Hq+foTzLZ1d27Fyw== dependencies: prop-types "^15.6.2" tinymce "^7.0.0 || ^6.0.0 || ^5.5.1" @@ -2960,28 +2674,21 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" - integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== - dependencies: - "@babel/types" "^7.3.0" - -"@types/babel__traverse@^7.18.0": +"@types/babel__traverse@*", "@types/babel__traverse@^7.18.0": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== @@ -2989,17 +2696,17 @@ "@babel/types" "^7.20.7" "@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" "@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" @@ -3102,35 +2809,35 @@ integrity sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig== "@types/eslint-scope@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" - integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.4.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" - integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== + version "8.56.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.10.tgz#eb2370a73bf04a901eeba8f22595c7ee0f7eb58d" + integrity sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/estree@1.0.5", "@types/estree@^1.0.0", "@types/estree@^1.0.5": +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0", "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + "@types/express-serve-static-core@^4.17.33": - version "4.17.43" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54" - integrity sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg== + version "4.19.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz#3ae8ab3767d98d0b682cda063c3339e1e86ccfaa" + integrity sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -3155,9 +2862,9 @@ "@types/unist" "*" "@types/hoist-non-react-statics@^3.3.0": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" + integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== dependencies: "@types/react" "*" hoist-non-react-statics "^3.3.0" @@ -3167,20 +2874,15 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== -"@types/istanbul-lib-coverage@^2.0.1": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - -"@types/json-schema@*", "@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== -"@types/json-schema@^7.0.8": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/lodash@^4.14.167": version "4.17.0" @@ -3188,14 +2890,14 @@ integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== "@types/mdx@^2.0.0": - version "2.0.12" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.12.tgz#38db34cc8999b982beaec01399620bee6c65ef2e" - integrity sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw== + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== "@types/mime@^1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/mute-stream@^0.0.4": version "0.0.4" @@ -3204,22 +2906,17 @@ dependencies: "@types/node" "*" -"@types/node@*": - version "17.0.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.33.tgz#3c1879b276dc63e73030bb91165e62a4509cd506" - integrity sha512-miWq2m2FiQZmaHfdZNcbpp9PuXg34W5JZ5CrJ/BaS70VuhoJENBEQybeiYSaPBRNq6KQGnjfEnc/F3PN++D+XQ== - -"@types/node@^18.0.0": - version "18.19.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.26.tgz#18991279d0a0e53675285e8cf4a0823766349729" - integrity sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw== +"@types/node@*", "@types/node@^20.12.7": + version "20.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.7.tgz#04080362fa3dd6c5822061aa3124f5c152cff384" + integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== dependencies: undici-types "~5.26.4" -"@types/node@^20.11.26": - version "20.11.30" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f" - integrity sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw== +"@types/node@^18.0.0": + version "18.19.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.31.tgz#b7d4a00f7cb826b60a543cebdbda5d189aaecdcd" + integrity sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA== dependencies: undici-types "~5.26.4" @@ -3229,29 +2926,24 @@ integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/pretty-hrtime@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== -"@types/prop-types@*": - version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/prop-types@^15.7.11": +"@types/prop-types@*", "@types/prop-types@^15.7.11": version "15.7.12" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.15" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" + integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== "@types/quill@1.3.10": version "1.3.10" @@ -3261,21 +2953,21 @@ parchment "^1.1.2" "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/react-dom@^18.0.0": - version "18.2.22" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.22.tgz#d332febf0815403de6da8a97e5fe282cbe609bae" - integrity sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ== + version "18.2.25" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.25.tgz#2946a30081f53e7c8d585eb138277245caedc521" + integrity sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA== dependencies: "@types/react" "*" "@types/react-redux@^7.1.20": - version "7.1.23" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.23.tgz#3c2bb1bcc698ae69d70735f33c5a8e95f41ac528" - integrity sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw== + version "7.1.33" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15" + integrity sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg== dependencies: "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" @@ -3289,22 +2981,12 @@ dependencies: "@types/react" "*" -"@types/react@*": - version "18.0.9" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" - integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== +"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0": + version "18.2.79" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.79.tgz#c40efb4f255711f554d47b449f796d1c7756d865" + integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@^16.8.0 || ^17.0.0 || ^18.0.0": - version "18.2.71" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.71.tgz#77c3b97b02014bf351b21b684f80273a3a343f96" - integrity sha512-PxEsB9OjmQeYGffoWnYAd/r5FiJuUw2niFQHPc2v2idwh8wGPkkYzOHuinNJJY6NZqfoTCiOIizDOz38gYNsyw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" "@types/resolve@^1.20.2": @@ -3312,11 +2994,6 @@ resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== -"@types/scheduler@*": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== - "@types/semver@^7.3.4", "@types/semver@^7.5.6": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" @@ -3331,12 +3008,13 @@ "@types/node" "*" "@types/serve-static@*": - version "1.13.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" - integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== dependencies: - "@types/mime" "^1" + "@types/http-errors" "*" "@types/node" "*" + "@types/send" "*" "@types/statuses@^2.0.4": version "2.0.5" @@ -3348,12 +3026,7 @@ resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.0.tgz#199a3f473f0c3a6f6e4e1b17cdbc967f274bdc6b" integrity sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw== -"@types/unist@*": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== - -"@types/unist@^3.0.0": +"@types/unist@*", "@types/unist@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== @@ -3381,9 +3054,9 @@ "@swc/core" "^1.3.107" "@vitest/coverage-v8@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-1.4.0.tgz#78ba9e182ff4cd1eba79c45cfafd2edc4c2941ec" - integrity sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg== + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-1.5.1.tgz#45dd72743735afc6e6beb65ce455aa18130fbcf0" + integrity sha512-Zx+dYEDcZg+44ksjIWvWosIGlPLJB1PPpN3O8+Xrh/1qa7WSFA6Y8H7lsZJTYrxu4G2unk9tvP5TgjIGDliF1w== dependencies: "@ampproject/remapping" "^2.2.1" "@bcoe/v8-coverage" "^0.2.3" @@ -3398,46 +3071,45 @@ std-env "^3.5.0" strip-literal "^2.0.0" test-exclude "^6.0.0" - v8-to-istanbul "^9.2.0" -"@vitest/expect@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.4.0.tgz#d64e17838a20007fecd252397f9b96a1ca81bfb0" - integrity sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA== +"@vitest/expect@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.5.1.tgz#a9ad180570a934bd4d63c59175e50ab2c359fff9" + integrity sha512-w3Bn+VUMqku+oWmxvPhTE86uMTbfmBl35aGaIPlwVW7Q89ZREC/icfo2HBsEZ3AAW6YR9lObfZKPEzstw9tJOQ== dependencies: - "@vitest/spy" "1.4.0" - "@vitest/utils" "1.4.0" + "@vitest/spy" "1.5.1" + "@vitest/utils" "1.5.1" chai "^4.3.10" -"@vitest/runner@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.4.0.tgz#907c2d17ad5975b70882c25ab7a13b73e5a28da9" - integrity sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg== +"@vitest/runner@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.5.1.tgz#dbb26a7ce1a3b8c3d186b2c06dd556ed093ddaef" + integrity sha512-mt372zsz0vFR7L1xF/ert4t+teD66oSuXoTyaZbl0eJgilvyzCKP1tJ21gVa8cDklkBOM3DLnkE1ljj/BskyEw== dependencies: - "@vitest/utils" "1.4.0" + "@vitest/utils" "1.5.1" p-limit "^5.0.0" pathe "^1.1.1" -"@vitest/snapshot@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.4.0.tgz#2945b3fb53767a3f4f421919e93edfef2935b8bd" - integrity sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A== +"@vitest/snapshot@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.5.1.tgz#56f459f9327567378ee111384fadcda91d8e6be3" + integrity sha512-h/1SGaZYXmjn6hULRBOlqam2z4oTlEe6WwARRzLErAPBqljAs6eX7tfdyN0K+MpipIwSZ5sZsubDWkCPAiVXZQ== dependencies: magic-string "^0.30.5" pathe "^1.1.1" pretty-format "^29.7.0" -"@vitest/spy@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.4.0.tgz#cf953c93ae54885e801cbe6b408a547ae613f26c" - integrity sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q== +"@vitest/spy@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.5.1.tgz#a0f96a3441afe6e0c5e7c8068d60b2086b0384d3" + integrity sha512-vsqczk6uPJjmPLy6AEtqfbFqgLYcGBe9BTY+XL8L6y8vrGOhyE23CJN9P/hPimKXnScbqiZ/r/UtUSOQ2jIDGg== dependencies: tinyspy "^2.2.0" -"@vitest/utils@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.4.0.tgz#ea6297e0d329f9ff0a106f4e1f6daf3ff6aad3f0" - integrity sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg== +"@vitest/utils@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.5.1.tgz#b373a1f5274b2b8b52ce8d6023db5e006f92d770" + integrity sha512-92pE17bBXUxA0Y7goPcvnATMCuq4NQLOmqsG0e2BtzRi7KLwZB5jpiELi/8ybY8IQNWemKjSD5rMoO7xTdv8ug== dependencies: diff-sequences "^29.6.3" estree-walker "^3.0.3" @@ -3598,10 +3270,10 @@ "@types/emscripten" "^1.39.6" tslib "^1.13.0" -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abbrev@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" + integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" @@ -3642,14 +3314,14 @@ acorn@^8.11.3, acorn@^8.7.1, acorn@^8.8.2: integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== address@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" - integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== agent-base@^7.0.2, agent-base@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" - integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== dependencies: debug "^4.3.4" @@ -3673,7 +3345,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== @@ -3690,10 +3362,10 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" - integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== +ajv@^8.0.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -3752,9 +3424,9 @@ ansi-styles@^6.1.0: integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -3762,7 +3434,7 @@ anymatch@~3.1.2: app-root-dir@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" - integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg= + integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== aria-query@5.1.3: version "5.1.3" @@ -3772,9 +3444,11 @@ aria-query@5.1.3: deep-equal "^2.0.5" aria-query@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" - integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" array-buffer-byte-length@^1.0.0: version "1.0.1" @@ -3787,7 +3461,7 @@ array-buffer-byte-length@^1.0.0: array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-union@^2.1.0: version "2.1.0" @@ -3818,9 +3492,9 @@ ast-types@^0.16.1: tslib "^2.0.1" async@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" - integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== asynckit@^0.4.0: version "0.4.0" @@ -3858,12 +3532,12 @@ babel-plugin-macros@^3.1.0: resolve "^1.19.0" babel-plugin-polyfill-corejs2@^0.4.10: - version "0.4.10" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz#276f41710b03a64f6467433cab72cbc2653c38b1" - integrity sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ== + version "0.4.11" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" + integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== dependencies: "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.6.1" + "@babel/helper-define-polyfill-provider" "^0.6.2" semver "^6.3.1" babel-plugin-polyfill-corejs3@^0.10.4: @@ -3875,11 +3549,11 @@ babel-plugin-polyfill-corejs3@^0.10.4: core-js-compat "^3.36.1" babel-plugin-polyfill-regenerator@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz#4f08ef4c62c7a7f66a35ed4c0d75e30506acc6be" - integrity sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g== + version "0.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" + integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.1" + "@babel/helper-define-polyfill-provider" "^0.6.2" balanced-match@^1.0.0: version "1.0.2" @@ -3909,9 +3583,9 @@ big.js@^5.2.2: integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== bl@^4.0.3, bl@^4.1.0: version "4.1.0" @@ -3943,7 +3617,7 @@ body-parser@1.20.2: boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== bplist-parser@^0.2.0: version "0.2.0" @@ -3986,17 +3660,6 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.20.2: - version "4.20.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" - integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== - dependencies: - caniuse-lite "^1.0.30001332" - electron-to-chromium "^1.4.118" - escalade "^3.1.1" - node-releases "^2.0.3" - picocolors "^1.0.0" - browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" @@ -4023,7 +3686,7 @@ buffer@^5.5.0: bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== bytes@3.1.2: version "3.1.2" @@ -4035,15 +3698,7 @@ cac@^6.7.14: resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -4076,19 +3731,19 @@ camel-case@^4.1.2: tslib "^2.0.3" camelize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" - integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== -caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001587: - version "1.0.30001600" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz" - integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ== +caniuse-lite@^1.0.30001587: + version "1.0.30001612" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz#d34248b4ec1f117b70b24ad9ee04c90e0b8a14ae" + integrity sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g== canvas-confetti@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/canvas-confetti/-/canvas-confetti-1.6.0.tgz#193f71aa8f38fc850a5ba94f59091a7afdb43ead" - integrity sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA== + version "1.9.2" + resolved "https://registry.yarnpkg.com/canvas-confetti/-/canvas-confetti-1.9.2.tgz#c9f74098c7fdf66dd9d1aab5d381061cf74e48f0" + integrity sha512-6Xi7aHHzKwxZsem4mCKoqP6YwUG3HamaHHAlz1hTNQPCqXhARFpSXnkC9TWlahHY5CG6hSL5XexNjxK8irVErg== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -4108,7 +3763,7 @@ chai@^4.3.10: pathval "^1.1.1" type-detect "^4.0.8" -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4165,22 +3820,7 @@ cheerio@1.0.0-rc.12, cheerio@^1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" -chokidar@^3.0.0, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^3.6.0: +chokidar@^3.0.0, chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -4230,9 +3870,9 @@ clean-css@^4.2.1: source-map "~0.6.0" clean-css@^5.2.2: - version "5.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.2.4.tgz#982b058f8581adb2ae062520808fb2429bd487a4" - integrity sha512-nKseG8wCzEuji/4yrgM/5cthL9oTDc5UOQyFMvW/Q53oP6gLH690o1NbuTh6Y18nujr7BxlsFuS7gXLnLzKJGg== + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== dependencies: source-map "~0.6.0" @@ -4248,12 +3888,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.5.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - -cli-spinners@^2.9.2: +cli-spinners@^2.5.0, cli-spinners@^2.9.2: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== @@ -4293,17 +3928,17 @@ clone-deep@^4.0.1: clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== clone@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== clsx@^2.0.0, clsx@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" - integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== color-convert@^1.9.0: version "1.9.3" @@ -4322,7 +3957,7 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" @@ -4330,9 +3965,9 @@ color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^2.0.10: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" @@ -4341,6 +3976,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -4364,7 +4004,7 @@ common-path-prefix@^3.0.0: commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== compressible@~2.0.16: version "2.0.18" @@ -4389,7 +4029,12 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +confbox@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.7.tgz#ccfc0a2bcae36a84838e83a3b7f770fb17d6c579" + integrity sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA== config-chain@^1.1.13: version "1.1.13" @@ -4416,22 +4061,15 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -content-type@~1.0.5: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -convert-source-map@^1.5.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" +convert-source-map@^1.5.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== convert-source-map@^2.0.0: version "2.0.0" @@ -4441,7 +4079,7 @@ convert-source-map@^2.0.0: cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.6.0: version "0.6.0" @@ -4459,16 +4097,16 @@ cookie@^0.5.0: integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== core-js-compat@^3.31.0, core-js-compat@^3.36.1: - version "3.36.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.36.1.tgz#1818695d72c99c25d621dca94e6883e190cea3c8" - integrity sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA== + version "3.37.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.37.0.tgz#d9570e544163779bb4dff1031c7972f44918dc73" + integrity sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA== dependencies: browserslist "^4.23.0" -core-js-pure@^3.8.1: - version "3.22.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.5.tgz#bdee0ed2f9b78f2862cda4338a07b13a49b6c9a9" - integrity sha512-8xo9R00iYD7TcV7OrC98GwxiUEAabVWO3dix+uyWjnYrx9fyASLlIX+f/3p5dW5qByaP2bcZ8X/T47s55et/tA== +core-js-pure@^3.23.3: + version "3.37.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.37.0.tgz#ce99fb4a7cec023fdbbe5b5bd1f06bbcba83316e" + integrity sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ== core-util-is@~1.0.0: version "1.0.3" @@ -4476,9 +4114,9 @@ core-util-is@~1.0.0: integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" @@ -4494,14 +4132,7 @@ create-react-class@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" -cross-fetch@^3.0.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-fetch@^3.0.6: +cross-fetch@^3.0.4, cross-fetch@^3.0.6: version "3.1.8" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== @@ -4532,27 +4163,27 @@ css-box-model@^1.2.0: css-color-keywords@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" - integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== -css-jss@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/css-jss/-/css-jss-10.9.0.tgz#1595c67bacf651100984a05763c1170d1bfa7127" - integrity sha512-CpYclti5ZQ18PfAeXaHQ2bEw4DEUfjC0lTS9sQcUlTRF8hC/Va0h3DIowlRm6AH/Ka/O/+tp41Q5zn9MJQoRsA== +css-jss@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/css-jss/-/css-jss-10.10.0.tgz#bd51fbd255cc24597ac0f0f32368394794d37ef3" + integrity sha512-YyMIS/LsSKEGXEaVJdjonWe18p4vXLo8CMA4FrW/kcaEyqdIGKCFXao31gbJddXEdIxSXFFURWrenBJPlKTgAA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" - jss-preset-default "10.9.0" + jss "^10.10.0" + jss-preset-default "^10.10.0" css-loader@^6.7.1: - version "6.10.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.10.0.tgz#7c172b270ec7b833951b52c348861206b184a4b7" - integrity sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw== + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" postcss "^8.4.33" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.4" - postcss-modules-scope "^3.1.1" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" semver "^7.5.4" @@ -4604,7 +4235,7 @@ css-what@^6.0.1, css-what@^6.1.0: css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== cssesc@^3.0.0: version "3.0.0" @@ -4623,12 +4254,7 @@ csstype@3.1.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -csstype@^3.0.2: - version "3.0.11" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" - integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== - -csstype@^3.1.3: +csstype@^3.0.2, csstype@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -4713,9 +4339,11 @@ data-urls@^5.0.0: whatwg-url "^14.0.0" date-fns@^2.24.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" - integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" debug@2.6.9: version "2.6.9" @@ -4724,14 +4352,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4748,7 +4369,7 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decode-uri-component@^0.2.0: +decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== @@ -4756,7 +4377,7 @@ decode-uri-component@^0.2.0: dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-eql@^4.1.3: version "4.1.3" @@ -4766,16 +4387,16 @@ deep-eql@^4.1.3: type-detect "^4.0.0" deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + version "1.1.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761" + integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg== dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" + is-arguments "^1.1.1" + is-date-object "^1.0.5" + is-regex "^1.1.4" + object-is "^1.1.5" object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" + regexp.prototype.flags "^1.5.1" deep-equal@^2.0.5: version "2.2.3" @@ -4802,9 +4423,9 @@ deep-equal@^2.0.5: which-typed-array "^1.1.13" deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== default-browser-id@3.0.0: version "3.0.0" @@ -4815,9 +4436,9 @@ default-browser-id@3.0.0: untildify "^4.0.0" defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== dependencies: clone "^1.0.2" @@ -4835,15 +4456,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -4858,9 +4471,9 @@ defu@^6.1.4: integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + version "6.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" + integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== dependencies: globby "^11.0.1" graceful-fs "^4.2.4" @@ -4881,7 +4494,7 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -dequal@^2.0.2: +dequal@^2.0.2, dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== @@ -4936,9 +4549,9 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-accessibility-api@^0.5.9: - version "0.5.14" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" - integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== dom-accessibility-api@^0.6.3: version "0.6.3" @@ -5083,37 +4696,32 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -editorconfig@^0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== +editorconfig@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3" + integrity sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q== dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" + "@one-ini/wasm" "0.1.1" + commander "^10.0.0" + minimatch "9.0.1" + semver "^7.5.3" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.8: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.118: - version "1.4.137" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz#186180a45617283f1c012284458510cd99d6787f" - integrity sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== - electron-to-chromium@^1.4.668: - version "1.4.717" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.717.tgz#99db370cae8cd090d5b01f8748e9ad369924d0f8" - integrity sha512-6Fmg8QkkumNOwuZ/5mIbMU9WI3H2fmn5ajcVya64I5Yr5CcNmO7vcLt0Y7c96DCiMO5/9G+4sI2r6eEvdg1F7A== + version "1.4.747" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz#e37fa5b7b7e4c22607c5f59b5cf78f947266e77d" + integrity sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw== emoji-regex@^8.0.0: version "8.0.0" @@ -5133,7 +4741,7 @@ emojis-list@^3.0.0: encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" @@ -5175,9 +4783,9 @@ entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== envinfo@^7.7.3: - version "7.11.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1" - integrity sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg== + version "7.12.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.12.0.tgz#b56723b39c2053d67ea5714f026d05d4f5cc7acd" + integrity sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg== error-ex@^1.3.1: version "1.3.2" @@ -5187,11 +4795,11 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.6: - version "2.0.7" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.7.tgz#b0c6e2ce27d0495cf78ad98715e0cad1219abb57" - integrity sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA== + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== dependencies: - stackframe "^1.1.1" + stackframe "^1.3.4" es-define-property@^1.0.0: version "1.0.0" @@ -5267,9 +4875,9 @@ esbuild-register@^3.5.0: "@esbuild/win32-x64" "0.20.2" escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== escape-goat@^3.0.0: version "3.0.0" @@ -5279,12 +4887,12 @@ escape-goat@^3.0.0: escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^4.0.0: version "4.0.0" @@ -5347,12 +4955,12 @@ esutils@^2.0.2: etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== eventemitter3@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" - integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= + integrity sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg== eventemitter3@^4.0.1: version "4.0.7" @@ -5397,7 +5005,7 @@ execa@^8.0.1: exenv@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" - integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50= + integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw== express@^4.17.3: version "4.19.2" @@ -5457,9 +5065,9 @@ fast-equals@^5.0.1: integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -5478,9 +5086,9 @@ fast-json-stable-stringify@^2.0.0: integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -5489,13 +5097,6 @@ fetch-retry@^5.0.2: resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== -figures@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - file-loader@^6.0.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" @@ -5512,7 +5113,7 @@ file-system-cache@2.3.0: fs-extra "11.1.1" ramda "0.29.0" -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -5529,7 +5130,7 @@ fill-range@^7.0.1: filter-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== finalhandler@1.2.0: version "1.2.0" @@ -5591,22 +5192,23 @@ find-up@^5.0.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" -flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== flow-parser@0.*: - version "0.231.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.231.0.tgz#13daa172b3c06ffacbb31025592dc0db41fe28f3" - integrity sha512-WVzuqwq7ZnvBceCG0DGeTQebZE+iIU0mlk5PmJgYj9DDrt+0isGC2m1ezW9vxL4V+HERJJo9ExppOnwKH2op6Q== + version "0.235.1" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.235.1.tgz#469c70adfa3c156f3a1792e7b6d7017f01f45f1d" + integrity sha512-s04193L4JE+ntEcQXbD6jxRRlyj9QXcgEl2W6xSjH4l9x4b0eHoCHfbYHjqf9LdZFUiM5LhgpiqsvLj/AyOyYQ== follow-redirects@^1.15.6: version "1.15.6" @@ -5663,7 +5265,7 @@ forwarded@0.2.0: fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-constants@^1.0.0: version "1.0.0" @@ -5680,9 +5282,9 @@ fs-extra@11.1.1: universalify "^2.0.0" fs-extra@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -5704,11 +5306,6 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" -fs-monkey@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - fs-monkey@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" @@ -5716,24 +5313,14 @@ fs-monkey@^1.0.4: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.3: +fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" @@ -5764,15 +5351,6 @@ get-func-name@^2.0.1, get-func-name@^2.0.2: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" @@ -5830,30 +5408,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.0.0, glob@^10.3.10: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== +glob@^10.0.0, glob@^10.3.10, glob@^10.3.3: + version "10.3.12" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" + integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg== dependencies: foreground-child "^3.1.0" - jackspeak "^2.3.5" + jackspeak "^2.3.6" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@^7.1.3: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" + minipass "^7.0.4" + path-scurry "^1.10.2" -glob@^7.1.4: +glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -5894,16 +5460,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.11, graceful-fs@^4.2.11: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - graphql@^16.8.1: version "16.8.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" @@ -5922,21 +5483,21 @@ gunzip-maybe@^1.4.2: through2 "^2.0.3" handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: uglify-js "^3.1.4" happy-dom@^14.3.9: - version "14.3.9" - resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-14.3.9.tgz#31b3cee86dec01228ab25fd32e6bf028f3e93b86" - integrity sha512-0kPQchwthekcYpYN8CvCiq+/z5bqFYDLbTxZ+yDLwT8AFRVJDFadShHRxp3VAZRy7a5isOZ1j/LzsU1dtAIZMQ== + version "14.7.1" + resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-14.7.1.tgz#4356617f5fcb722c26ccd4c5c8a235cead675592" + integrity sha512-v60Q0evZ4clvMcrAh5/F8EdxDdfHdFrtffz/CNe10jKD+nFweZVxM91tW+UyY2L4AtpgIaXdZ7TQmiO1pfcwbg== dependencies: entities "^4.5.0" webidl-conversions "^7.0.0" @@ -5950,21 +5511,14 @@ has-bigints@^1.0.1: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-property-descriptors@^1.0.2: +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== @@ -5976,32 +5530,18 @@ has-proto@^1.0.1: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-tostringtag@^1.0.2: +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: has-symbols "^1.0.3" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hasown@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -6072,9 +5612,9 @@ html-encoding-sniffer@^4.0.0: whatwg-encoding "^3.1.1" html-entities@^2.1.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== html-escaper@^2.0.0: version "2.0.2" @@ -6108,14 +5648,14 @@ html-minifier@^4.0.0: uglify-js "^3.5.1" html-tags@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" - integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg== + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + version "5.6.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" + integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -6242,9 +5782,9 @@ ieee754@^1.1.13: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== import-fresh@^3.2.1: version "3.3.0" @@ -6257,7 +5797,7 @@ import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" @@ -6267,7 +5807,7 @@ indent-string@^4.0.0: inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" @@ -6330,7 +5870,7 @@ is-array-buffer@^3.0.2, is-array-buffer@^3.0.4: is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" @@ -6366,14 +5906,7 @@ is-core-module@^2.13.0: dependencies: hasown "^2.0.0" -is-core-module@^2.8.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1, is-date-object@^1.0.5: +is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -6393,7 +5926,7 @@ is-docker@^2.0.0, is-docker@^2.1.1: is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -6422,7 +5955,7 @@ is-gzip@^1.0.0: is-in-browser@^1.0.2, is-in-browser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" - integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= + integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== is-interactive@^1.0.0: version "1.0.0" @@ -6486,7 +6019,7 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.0.4, is-regex@^1.1.4: +is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -6500,11 +6033,11 @@ is-set@^2.0.2, is-set@^2.0.3: integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" is-stream@^2.0.0: version "2.0.1" @@ -6565,7 +6098,7 @@ is-wsl@^2.2.0: isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== isarray@^2.0.5: version "2.0.5" @@ -6575,12 +6108,12 @@ isarray@^2.0.5: isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^3.0.1: version "3.0.1" @@ -6626,7 +6159,7 @@ istanbul-reports@^3.1.6: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^2.3.5: +jackspeak@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== @@ -6636,14 +6169,14 @@ jackspeak@^2.3.5: "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" jest-fetch-mock@^3.0.3: version "3.0.3" @@ -6663,14 +6196,20 @@ jest-worker@^27.4.5: supports-color "^8.0.0" js-beautify@^1.6.14: - version "1.14.3" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.3.tgz#3dd11c949178de7f3bdf3f6f752778d3bed95150" - integrity sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g== + version "1.15.1" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.15.1.tgz#4695afb508c324e1084ee0b952a102023fc65b64" + integrity sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA== dependencies: config-chain "^1.1.13" - editorconfig "^0.15.3" - glob "^7.1.3" - nopt "^5.0.0" + editorconfig "^1.0.4" + glob "^10.3.3" + js-cookie "^3.0.5" + nopt "^7.2.0" + +js-cookie@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== js-file-download@^0.4.12: version "0.4.12" @@ -6682,10 +6221,10 @@ js-file-download@^0.4.12: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-tokens@^8.0.2: - version "8.0.3" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-8.0.3.tgz#1c407ec905643603b38b6be6977300406ec48775" - integrity sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw== +js-tokens@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-9.0.0.tgz#0f893996d6f3ed46df7f0a3b12a03f5fd84223c1" + integrity sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ== jscodeshift@^0.15.1: version "0.15.2" @@ -6748,7 +6287,12 @@ jsesc@^2.5.1: jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" @@ -6765,16 +6309,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json5@^2.1.2, json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" - integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -6784,16 +6323,7 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jss-plugin-camel-case@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz#4921b568b38d893f39736ee8c4c5f1c64670aaf7" - integrity sha512-UH6uPpnDk413/r/2Olmw4+y54yEF2lRIV8XIZyuYpgPYTITLlPOsq6XB9qeqv+75SQSg3KLocq5jUBXW8qWWww== - dependencies: - "@babel/runtime" "^7.3.1" - hyphenate-style-name "^1.0.3" - jss "10.9.0" - -jss-plugin-camel-case@^10.10.0: +jss-plugin-camel-case@10.10.0, jss-plugin-camel-case@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== @@ -6802,24 +6332,16 @@ jss-plugin-camel-case@^10.10.0: hyphenate-style-name "^1.0.3" jss "10.10.0" -jss-plugin-compose@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-compose/-/jss-plugin-compose-10.9.0.tgz#4954583227db9b49bd2e29cd055dcc65b12cb19d" - integrity sha512-Q/0FEZhDwGUpf3/b7+PspmMi6MVSlN3YlTDmvrft7I6N346jUpd8MYkYP/6qM1ZMuVj4v8ky/XYqr1v2ganLLg== +jss-plugin-compose@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-compose/-/jss-plugin-compose-10.10.0.tgz#00d7a79adf7fcfe4927a792febdf0deceb0a7cd2" + integrity sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" + jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-default-unit@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.0.tgz#bb23a48f075bc0ce852b4b4d3f7582bc002df991" - integrity sha512-7Ju4Q9wJ/MZPsxfu4T84mzdn7pLHWeqoGd/D8O3eDNNJ93Xc8PxnLmV8s8ZPNRYkLdxZqKtm1nPQ0BM4JRlq2w== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.9.0" - -jss-plugin-default-unit@^10.10.0: +jss-plugin-default-unit@10.10.0, jss-plugin-default-unit@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== @@ -6827,32 +6349,24 @@ jss-plugin-default-unit@^10.10.0: "@babel/runtime" "^7.3.1" jss "10.10.0" -jss-plugin-expand@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-expand/-/jss-plugin-expand-10.9.0.tgz#96c902f5759fe189184f8418997659d61e927ffe" - integrity sha512-QfZ9jld0HpF1OiYU7cGWQ4q+f6+Wu93mV4X+cA1iVRssiUbSbygwdfZkUwX23UOhS1WWRJeQlLK1aJC94K8/0A== +jss-plugin-expand@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-expand/-/jss-plugin-expand-10.10.0.tgz#5debd80554174ca2d9b9e38d85d4cb6f3e0393ab" + integrity sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" + jss "10.10.0" -jss-plugin-extend@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-extend/-/jss-plugin-extend-10.9.0.tgz#b1163ceb25d908888b326e5b5fa780aaaed4884d" - integrity sha512-xvmosUh3RsKVsm9L14ml6PL3i0Ejj5gB6eo/jTMkGW1kIy42gNXV1EthR8cD5xiowWstnvugQ3JF0pI5+QkPMg== +jss-plugin-extend@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-extend/-/jss-plugin-extend-10.10.0.tgz#94eb450847a8941777e77ea4533a579c1c578430" + integrity sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" + jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-global@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.9.0.tgz#fc07a0086ac97aca174e37edb480b69277f3931f" - integrity sha512-4G8PHNJ0x6nwAFsEzcuVDiBlyMsj2y3VjmFAx/uHk/R/gzJV+yRHICjT4MKGGu1cJq2hfowFWCyrr/Gg37FbgQ== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.9.0" - -jss-plugin-global@^10.10.0: +jss-plugin-global@10.10.0, jss-plugin-global@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== @@ -6860,16 +6374,7 @@ jss-plugin-global@^10.10.0: "@babel/runtime" "^7.3.1" jss "10.10.0" -jss-plugin-nested@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.9.0.tgz#cc1c7d63ad542c3ccc6e2c66c8328c6b6b00f4b3" - integrity sha512-2UJnDrfCZpMYcpPYR16oZB7VAC6b/1QLsRiAutOt7wJaaqwCBvNsosLEu/fUyKNQNGdvg2PPJFDO5AX7dwxtoA== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.9.0" - tiny-warning "^1.0.2" - -jss-plugin-nested@^10.10.0: +jss-plugin-nested@10.10.0, jss-plugin-nested@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== @@ -6878,15 +6383,7 @@ jss-plugin-nested@^10.10.0: jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-props-sort@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.0.tgz#30e9567ef9479043feb6e5e59db09b4de687c47d" - integrity sha512-7A76HI8bzwqrsMOJTWKx/uD5v+U8piLnp5bvru7g/3ZEQOu1+PjHvv7bFdNO3DwNPC9oM0a//KwIJsIcDCjDzw== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.9.0" - -jss-plugin-props-sort@^10.10.0: +jss-plugin-props-sort@10.10.0, jss-plugin-props-sort@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== @@ -6894,16 +6391,7 @@ jss-plugin-props-sort@^10.10.0: "@babel/runtime" "^7.3.1" jss "10.10.0" -jss-plugin-rule-value-function@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.0.tgz#379fd2732c0746fe45168011fe25544c1a295d67" - integrity sha512-IHJv6YrEf8pRzkY207cPmdbBstBaE+z8pazhPShfz0tZSDtRdQua5jjg6NMz3IbTasVx9FdnmptxPqSWL5tyJg== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.9.0" - tiny-warning "^1.0.2" - -jss-plugin-rule-value-function@^10.10.0: +jss-plugin-rule-value-function@10.10.0, jss-plugin-rule-value-function@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== @@ -6912,34 +6400,25 @@ jss-plugin-rule-value-function@^10.10.0: jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-rule-value-observable@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.9.0.tgz#fc48b70f6915a913618fdadb44dedce23982b32d" - integrity sha512-/MWVPJVEn41+ofzQdsvH1GR4wusDqFqNnchh/98HVc580MxPy4NVkmUa2SAEpbHhnJ93sCoETZccW3HJKuvH4A== +jss-plugin-rule-value-observable@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-observable/-/jss-plugin-rule-value-observable-10.10.0.tgz#d17b28c4401156bbe4cd0c4a73a80aad70613e8b" + integrity sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" + jss "10.10.0" symbol-observable "^1.2.0" -jss-plugin-template@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-template/-/jss-plugin-template-10.9.0.tgz#27547e093e04b9dc9e900f35146e874bb196f575" - integrity sha512-lxThUvdt0drCi7xhuJWxADWTgLLy1IWCeFO5k+dtba900xJsNg0IGZplpP9w9UpaJsYS3WUwWMXw8Sxn1dobfQ== +jss-plugin-template@10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-template/-/jss-plugin-template-10.10.0.tgz#072cda74a94c91b02d3a895d9e2408fd978ce033" + integrity sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" + jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-vendor-prefixer@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.0.tgz#aa9df98abfb3f75f7ed59a3ec50a5452461a206a" - integrity sha512-MbvsaXP7iiVdYVSEoi+blrW+AYnTDvHTW6I6zqi7JcwXdc6I9Kbm234nEblayhF38EftoenbM+5218pidmC5gA== - dependencies: - "@babel/runtime" "^7.3.1" - css-vendor "^2.0.8" - jss "10.9.0" - -jss-plugin-vendor-prefixer@^10.10.0: +jss-plugin-vendor-prefixer@10.10.0, jss-plugin-vendor-prefixer@^10.10.0: version "10.10.0" resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== @@ -6948,25 +6427,25 @@ jss-plugin-vendor-prefixer@^10.10.0: css-vendor "^2.0.8" jss "10.10.0" -jss-preset-default@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-10.9.0.tgz#20919ee04e543b3502086001c4179ab15c012153" - integrity sha512-Zdsj+R+UTn7OOJ1TFQi+l8PfEL7APSAM6vRPaU8mJywT8OrMjgslMKckFLrgq1k+qk1hJR1ePAMesvZ5aAXGOQ== +jss-preset-default@10.10.0, jss-preset-default@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-10.10.0.tgz#c8209449a0f6d232526c2ba3a3a6ec69ee97e023" + integrity sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.0" - jss-plugin-camel-case "10.9.0" - jss-plugin-compose "10.9.0" - jss-plugin-default-unit "10.9.0" - jss-plugin-expand "10.9.0" - jss-plugin-extend "10.9.0" - jss-plugin-global "10.9.0" - jss-plugin-nested "10.9.0" - jss-plugin-props-sort "10.9.0" - jss-plugin-rule-value-function "10.9.0" - jss-plugin-rule-value-observable "10.9.0" - jss-plugin-template "10.9.0" - jss-plugin-vendor-prefixer "10.9.0" + jss "10.10.0" + jss-plugin-camel-case "10.10.0" + jss-plugin-compose "10.10.0" + jss-plugin-default-unit "10.10.0" + jss-plugin-expand "10.10.0" + jss-plugin-extend "10.10.0" + jss-plugin-global "10.10.0" + jss-plugin-nested "10.10.0" + jss-plugin-props-sort "10.10.0" + jss-plugin-rule-value-function "10.10.0" + jss-plugin-rule-value-observable "10.10.0" + jss-plugin-template "10.10.0" + jss-plugin-vendor-prefixer "10.10.0" jss@10.10.0, jss@^10.10.0: version "10.10.0" @@ -6978,16 +6457,6 @@ jss@10.10.0, jss@^10.10.0: is-in-browser "^1.1.3" tiny-warning "^1.0.2" -jss@10.9.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.9.0.tgz#7583ee2cdc904a83c872ba695d1baab4b59c141b" - integrity sha512-YpzpreB6kUunQBbrlArlsMpXYyndt9JATbt95tajx0t4MTJJcCJdd4hdNpHmOIDiUJrF/oX5wtVFrS3uofWfGw== - dependencies: - "@babel/runtime" "^7.3.1" - csstype "^3.0.2" - is-in-browser "^1.1.3" - tiny-warning "^1.0.2" - juice@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/juice/-/juice-10.0.0.tgz#c6b717ded8be4b969f12503ac9cfbd2604d35937" @@ -7004,6 +6473,13 @@ keycode@^2.1.7: resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.1.tgz#09c23b2be0611d26117ea2501c2c391a01f39eff" integrity sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -7034,11 +6510,11 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^2.0.0: +loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -7080,7 +6556,7 @@ locate-path@^6.0.0: lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" @@ -7112,7 +6588,7 @@ loupe@^2.3.6, loupe@^2.3.7: lower-case@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== lower-case@^2.0.2: version "2.0.2" @@ -7121,13 +6597,10 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" +lru-cache@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== lru-cache@^5.1.1: version "5.1.1" @@ -7143,36 +6616,31 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -"lru-cache@^9.1.1 || ^10.0.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - lz-string@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== magic-string@^0.30.5: - version "0.30.8" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" - integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== + version "0.30.10" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" + integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" magicast@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.3.tgz#a15760f982deec9dabc5f314e318d7c6bddcb27b" - integrity sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw== + version "0.3.4" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.4.tgz#bbda1791d03190a24b00ff3dd18151e7fd381d19" + integrity sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q== dependencies: - "@babel/parser" "^7.23.6" - "@babel/types" "^7.23.6" - source-map-js "^1.0.2" + "@babel/parser" "^7.24.4" + "@babel/types" "^7.24.0" + source-map-js "^1.2.0" make-cancellable-promise@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-cancellable-promise/-/make-cancellable-promise-1.1.0.tgz#b4e9fcb31db3a27417e44f80cffa598ec9ac9f4e" - integrity sha512-X5Opjm2xcZsOLuJ+Bnhb4t5yfu4ehlA3OKEYLtqUchgVzL/QaqW373ZUVxVHKwvJ38cmYuR4rAHD2yUvAIkTPA== + version "1.3.2" + resolved "https://registry.yarnpkg.com/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz#993c8c8b79cff13c74fa93de0bd8a17fe66685c1" + integrity sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww== make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" @@ -7197,14 +6665,14 @@ make-dir@^4.0.0: semver "^7.5.3" make-event-props@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.3.0.tgz#2434cb390d58bcf40898d009ef5b1f936de9671b" - integrity sha512-oWiDZMcVB1/A487251hEWza1xzgCzl6MXxe9aF24l5Bt9N9UEbqTqKumEfuuLhmlhRZYnc+suVvW4vUs8bwO7Q== + version "1.6.2" + resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.6.2.tgz#c8e0e48eb28b9b808730de38359f6341de7ec5a2" + integrity sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA== map-or-similar@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" - integrity sha1-beJlMXSt+12e3DPGnT6Sobdvrwg= + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== markdown-to-jsx@7.3.2: version "7.3.2" @@ -7214,16 +6682,9 @@ markdown-to-jsx@7.3.2: media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" - integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== - dependencies: - fs-monkey "1.0.3" - -memfs@^3.4.12: +memfs@^3.4.1, memfs@^3.4.12: version "3.6.0" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== @@ -7238,7 +6699,7 @@ memoize-one@^5.1.1: memoizerific@^1.11.3: version "1.11.3" resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" - integrity sha1-fIekZGREwy11Q4VwkF8tvRsagFo= + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== dependencies: map-or-similar "^1.5.0" @@ -7255,12 +6716,12 @@ merge-class-names@^1.1.1: merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-refs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/merge-refs/-/merge-refs-1.0.0.tgz#388348bce22e623782c6df9d3c4fc55888276120" - integrity sha512-WZ4S5wqD9FCR9hxkLgvcHJCBxzXzy3VVE6p8W2OzxRzB+hLRlcadGE2bW9xp2KSzk10rvp4y+pwwKO6JQVguMg== + version "1.2.2" + resolved "https://registry.yarnpkg.com/merge-refs/-/merge-refs-1.2.2.tgz#6142633398dd0d10a37626cae77ddeb1db26db0c" + integrity sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw== merge-stream@^2.0.0: version "2.0.0" @@ -7275,7 +6736,7 @@ merge2@^1.3.0, merge2@^1.4.1: methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.5" @@ -7285,30 +6746,18 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.51.0: - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime-types@^2.1.31: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" - mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -7334,15 +6783,14 @@ min-indent@^1.0.0, min-indent@^1.0.1: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -mini-create-react-context@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" - integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== +minimatch@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== dependencies: - "@babel/runtime" "^7.12.1" - tiny-warning "^1.0.3" + brace-expansion "^2.0.1" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7350,23 +6798,23 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + version "9.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" + integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== dependencies: brace-expansion "^2.0.1" minimist@^1.2.5, minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minipass@^3.0.0: version "3.3.6" @@ -7380,7 +6828,7 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.4: version "7.0.4" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== @@ -7741,7 +7189,7 @@ mkdirp@^1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mlly@^1.2.0, mlly@^1.4.2: +mlly@^1.4.2, mlly@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.6.1.tgz#0983067dc3366d6314fc5e12712884e6978d028f" integrity sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA== @@ -7754,7 +7202,7 @@ mlly@^1.2.0, mlly@^1.4.2: ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.2: version "2.1.2" @@ -7767,9 +7215,9 @@ ms@2.1.3: integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== msw@^2.2.13: - version "2.2.13" - resolved "https://registry.yarnpkg.com/msw/-/msw-2.2.13.tgz#2fd9f554e77a1f99ef803d94008f5aef5c59b9fa" - integrity sha512-ljFf1xZsU0b4zv1l7xzEmC6OZA6yD06hcx0H+dc8V0VypaP3HGYJa1rMLjQbBWl32ptGhcfwcPCWDB1wjmsftw== + version "2.2.14" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.2.14.tgz#ed16b89f99ffc105a84b0295a6fcae2ee99f5c62" + integrity sha512-64i8rNCa1xzDK8ZYsTrVMli05D687jty8+Th+PU5VTbJ2/4P7fkQFVyDQ6ZFT5FrNR8z2BHhbY47fKNvfHrumA== dependencies: "@bundled-es-modules/cookie" "^2.0.0" "@bundled-es-modules/statuses" "^1.0.1" @@ -7794,11 +7242,6 @@ mute-stream@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -nanoid@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -7809,7 +7252,7 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.2: +neo-async@^2.5.0, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -7846,14 +7289,7 @@ node-fetch-native@^1.6.3: resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" integrity sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ== -node-fetch@2.6.7, node-fetch@^2.0.0, node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.12: +node-fetch@^2.0.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -7865,17 +7301,12 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -node-releases@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" - integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== +nopt@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" + integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== dependencies: - abbrev "1" + abbrev "^2.0.0" normalize-package-data@^2.5.0: version "2.5.0" @@ -7907,16 +7338,16 @@ npm-run-path@^5.1.0: path-key "^4.0.0" nth-check@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" - integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== dependencies: boolbase "^1.0.0" nwsapi@^2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" - integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== + version "2.2.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.9.tgz#7f3303218372db2e9f27c27766bcfc59ae7e61c6" + integrity sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg== nypm@^0.3.8: version "0.3.8" @@ -7932,26 +7363,13 @@ nypm@^0.3.8: object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - object-is@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" @@ -8000,7 +7418,7 @@ on-headers@~1.0.2: once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -8018,7 +7436,7 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" -open@^8.0.4: +open@^8.0.4, open@^8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -8027,15 +7445,6 @@ open@^8.0.4: is-docker "^2.1.1" is-wsl "^2.2.0" -open@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" @@ -8118,7 +7527,7 @@ pako@~0.2.0: param-case@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== dependencies: no-case "^2.2.0" @@ -8155,7 +7564,7 @@ parse-json@^5.0.0: parse-srcset@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" - integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= + integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== parse5-htmlparser2-tree-adapter@^7.0.0: version "7.0.0" @@ -8193,7 +7602,7 @@ path-browserify@^1.0.1: path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" @@ -8203,7 +7612,7 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" @@ -8220,18 +7629,18 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== +path-scurry@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7" + integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA== dependencies: - lru-cache "^9.1.1 || ^10.0.0" + lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== path-to-regexp@^1.7.0: version "1.8.0" @@ -8241,16 +7650,16 @@ path-to-regexp@^1.7.0: isarray "0.0.1" path-to-regexp@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== + version "6.2.2" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" + integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw== path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pathe@^1.1.0, pathe@^1.1.1, pathe@^1.1.2: +pathe@^1.1.1, pathe@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== @@ -8321,13 +7730,13 @@ pkg-dir@^5.0.0: find-up "^5.0.0" pkg-types@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" - integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + version "1.1.0" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.1.0.tgz#3ec1bf33379030fd0a34c227b6c650e8ea7ca271" + integrity sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA== dependencies: - jsonc-parser "^3.2.0" - mlly "^1.2.0" - pathe "^1.1.0" + confbox "^0.1.7" + mlly "^1.6.1" + pathe "^1.1.2" pnp-webpack-plugin@^1.7.0: version "1.7.0" @@ -8348,24 +7757,24 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== -postcss-modules-local-by-default@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz#7cbed92abd312b94aaea85b68226d3dec39a14e6" - integrity sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q== +postcss-modules-local-by-default@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" + integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-scope@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz#32cfab55e84887c079a19bbb215e721d683ef134" - integrity sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA== +postcss-modules-scope@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" + integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== dependencies: postcss-selector-parser "^6.0.4" @@ -8376,18 +7785,10 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-selector-parser@^6.0.2: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.4: - version "6.0.9" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" - integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.16" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz#3b88b9f5c5abd989ef4e2fc9ec8eedd34b20fb04" + integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -8406,16 +7807,7 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.3.11: - version "8.4.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" - integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== - dependencies: - nanoid "^3.3.1" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -postcss@^8.4.33, postcss@^8.4.36: +postcss@^8.3.11, postcss@^8.4.33, postcss@^8.4.38: version "8.4.38" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== @@ -8424,12 +7816,7 @@ postcss@^8.4.33, postcss@^8.4.36: picocolors "^1.0.0" source-map-js "^1.2.0" -prettier@2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc" - integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg== - -prettier@^3.1.1: +prettier@3.2.5, prettier@^3.1.1: version "3.2.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== @@ -8463,7 +7850,7 @@ pretty-format@^29.7.0: pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== process-nextick-args@~2.0.0: version "2.0.1" @@ -8476,9 +7863,9 @@ process@^0.11.10: integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== promise-polyfill@^8.1.3: - version "8.2.1" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.1.tgz#1fa955b325bee4f6b8a4311e18148d4e5b46d254" - integrity sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg== + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" + integrity sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg== prompts@^2.4.0: version "2.4.2" @@ -8500,7 +7887,7 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== proxy-addr@~2.0.7: version "2.0.7" @@ -8515,11 +7902,6 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -8555,12 +7937,7 @@ punycode@^1.4.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -punycode@^2.1.1, punycode@^2.3.1: +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== @@ -8572,26 +7949,19 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" -qs@^6.10.0: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - -qs@^6.11.2: - version "6.12.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.0.tgz#edd40c3b823995946a8a0b1f208669c7a200db77" - integrity sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg== +qs@^6.10.0, qs@^6.11.2: + version "6.12.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" + integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ== dependencies: side-channel "^1.0.6" query-string@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1" - integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w== + version "7.1.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== dependencies: - decode-uri-component "^0.2.0" + decode-uri-component "^0.2.2" filter-obj "^1.1.0" split-on-first "^1.0.0" strict-uri-encode "^2.0.0" @@ -8667,9 +8037,9 @@ raw-body@2.5.2: unpipe "1.0.0" react-beautiful-dnd@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz#ec97c81093593526454b0de69852ae433783844d" - integrity sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA== + version "13.1.1" + resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz#b0f3087a5840920abf8bb2325f1ffa46d8c4d0a2" + integrity sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ== dependencies: "@babel/runtime" "^7.9.2" css-box-model "^1.2.0" @@ -8680,9 +8050,9 @@ react-beautiful-dnd@^13.1.0: use-memo-one "^1.1.1" react-colorful@^5.1.2: - version "5.5.1" - resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.5.1.tgz#29d9c4e496f2ca784dd2bb5053a3a4340cfaf784" - integrity sha512-M1TJH2X3RXEt12sWkpa6hLc/bbYS0H6F4rIqjQZ+RxNBstpY67d9TrFXtqdZwhpmBXcCwEi7stKqFue3ZRkiOg== + version "5.6.1" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" + integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== react-display-name@^0.2.4: version "0.2.5" @@ -8713,7 +8083,7 @@ react-docgen@^7.0.0: react-dom-factories@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0" - integrity sha1-63cFxNs2+1AbOqOP91lhaqD/luA= + integrity sha512-Bmic2N3oKji7vw9qjDr2dmwHvOATbFSnKy7EH0uT/qjvzIUsiXp6Yquk72LJ3WfMtRnq3ujXMMo7GsJeLPfFWw== "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0: version "18.2.0" @@ -8755,7 +8125,7 @@ react-html-parser@^2.0.2: dependencies: htmlparser2 "^3.9.0" -react-is@18.1.0, "react-is@^16.12.0 || ^17.0.0 || ^18.0.0": +react-is@18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== @@ -8765,28 +8135,28 @@ react-is@^16.10.2, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + react-is@^17.0.1, react-is@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - react-jss@^10.4.0: - version "10.9.0" - resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-10.9.0.tgz#102332a109d98510f0f812dd090d02f6045b5229" - integrity sha512-xKXTEejrSkzINF+dutFtLllIfYSN6tOA1XmnpiZGjsWZqy7Hum6fjjgAE2TbBmV9h2CW62ekmGj/Mx27ZuMjuw== + version "10.10.0" + resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-10.10.0.tgz#d08ab3257b0eed01e15d6d8275840055c279b0da" + integrity sha512-WLiq84UYWqNBF6579/uprcIUnM1TSywYq6AIjKTTTG5ziJl9Uy+pwuvpN3apuyVwflMbD60PraeTKT7uWH9XEQ== dependencies: "@babel/runtime" "^7.3.1" "@emotion/is-prop-valid" "^0.7.3" - css-jss "10.9.0" + css-jss "10.10.0" hoist-non-react-statics "^3.2.0" is-in-browser "^1.1.3" - jss "10.9.0" - jss-preset-default "10.9.0" + jss "10.10.0" + jss-preset-default "10.10.0" prop-types "^15.6.0" shallow-equal "^1.2.0" theming "^3.3.0" @@ -8798,9 +8168,9 @@ react-lifecycles-compat@^3.0.0: integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== react-modal@^3.14.3: - version "3.15.1" - resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.15.1.tgz#950ce67bfef80971182dd0ed38f2d9b1a681288b" - integrity sha512-duB9bxOaYg7Zt6TMFldIFxQRtSP+Dg3F1ZX3FXxSUn+3tZZ/9JCgeAQKDg7rhZSAqopq8TFRw3yIbnx77gyFTw== + version "3.16.1" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b" + integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg== dependencies: exenv "^1.2.0" prop-types "^15.7.2" @@ -8836,9 +8206,9 @@ react-quill@^1.3.5: react-dom-factories "^1.0.0" react-redux@^7.2.0: - version "7.2.6" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.6.tgz#49633a24fe552b5f9caf58feb8a138936ddfe9aa" - integrity sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ== + version "7.2.9" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" + integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== dependencies: "@babel/runtime" "^7.15.4" "@types/react-redux" "^7.1.20" @@ -8848,28 +8218,27 @@ react-redux@^7.2.0: react-is "^17.0.2" react-router-dom@^5.3.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.1.tgz#0151baf2365c5fcd8493f6ec9b9b31f34d0f8ae1" - integrity sha512-f0pj/gMAbv9e8gahTmCEY20oFhxhrmHwYeIwH5EO5xu0qme+wXtsdB8YfUOAZzUz4VaXmb58m3ceiLtjMhqYmQ== + version "5.3.4" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6" + integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.3.1" + react-router "5.3.4" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.1.tgz#b13e84a016c79b9e80dde123ca4112c4f117e3cf" - integrity sha512-v+zwjqb7bakqgF+wMVKlAPTca/cEmPOvQ9zt7gpSNyPXau1+0qvuYZ5BWzzNDP1y6s15zDwgb9rPN63+SIniRQ== +react-router@5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5" + integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" hoist-non-react-statics "^3.1.0" loose-envify "^1.3.1" - mini-create-react-context "^0.4.0" path-to-regexp "^1.7.0" prop-types "^15.6.2" react-is "^16.6.0" @@ -8983,9 +8352,9 @@ readable-stream@^2.0.0, readable-stream@~2.3.6: util-deprecate "~1.0.1" readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -9017,9 +8386,9 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.12.4: - version "2.12.4" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.12.4.tgz#e560a57cd44ab554c99a0d93bdd58d059b309a2e" - integrity sha512-dM4skmk4fDKEDjL9MNunxv6zcTxePGVEzRnLDXALRpfJ85JoQ0P0APJ/CoJlmnQI0gPjBlOkjzrwrfQrRST3KA== + version "2.12.6" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.12.6.tgz#e466d4af6e552b6d271e456b75af522a20a1c50d" + integrity sha512-D+7j9WI+D0NHauah3fKHuNNcRK8bOypPW7os1DERinogGBGaHI7i6tQKJ0aUF3JXyBZ63dyfKIW2WTOPJDxJ8w== dependencies: clsx "^2.0.0" eventemitter3 "^4.0.1" @@ -9039,9 +8408,9 @@ redent@^3.0.0: strip-indent "^3.0.0" redux@^4.0.0, redux@^4.0.4: - version "4.1.2" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" - integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== dependencies: "@babel/runtime" "^7.9.2" @@ -9062,16 +8431,6 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-runtime@^0.13.10: - version "0.13.10" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" - integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -9084,14 +8443,6 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" - integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - regexp.prototype.flags@^1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" @@ -9147,7 +8498,7 @@ rehype-slug@^6.0.0: relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== renderkid@^3.0.0: version "3.0.0" @@ -9163,7 +8514,7 @@ renderkid@^3.0.0: require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" @@ -9176,9 +8527,9 @@ requires-port@^1.0.0: integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== reselect@^4.0.0: - version "4.1.5" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6" - integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ== + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-from@^4.0.0: version "4.0.0" @@ -9195,7 +8546,7 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.8: +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.8: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -9204,15 +8555,6 @@ resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.8: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.14.2, resolve@^1.19.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -9241,26 +8583,28 @@ rimraf@~2.6.2: glob "^7.1.3" rollup@^4.13.0: - version "4.13.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.13.1.tgz#5bd6d84eafd60280487085b8bf9c91679571005a" - integrity sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg== + version "4.16.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.4.tgz#fe328eb41293f20c9593a095ec23bdc4b5d93317" + integrity sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.13.1" - "@rollup/rollup-android-arm64" "4.13.1" - "@rollup/rollup-darwin-arm64" "4.13.1" - "@rollup/rollup-darwin-x64" "4.13.1" - "@rollup/rollup-linux-arm-gnueabihf" "4.13.1" - "@rollup/rollup-linux-arm64-gnu" "4.13.1" - "@rollup/rollup-linux-arm64-musl" "4.13.1" - "@rollup/rollup-linux-riscv64-gnu" "4.13.1" - "@rollup/rollup-linux-s390x-gnu" "4.13.1" - "@rollup/rollup-linux-x64-gnu" "4.13.1" - "@rollup/rollup-linux-x64-musl" "4.13.1" - "@rollup/rollup-win32-arm64-msvc" "4.13.1" - "@rollup/rollup-win32-ia32-msvc" "4.13.1" - "@rollup/rollup-win32-x64-msvc" "4.13.1" + "@rollup/rollup-android-arm-eabi" "4.16.4" + "@rollup/rollup-android-arm64" "4.16.4" + "@rollup/rollup-darwin-arm64" "4.16.4" + "@rollup/rollup-darwin-x64" "4.16.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.16.4" + "@rollup/rollup-linux-arm-musleabihf" "4.16.4" + "@rollup/rollup-linux-arm64-gnu" "4.16.4" + "@rollup/rollup-linux-arm64-musl" "4.16.4" + "@rollup/rollup-linux-powerpc64le-gnu" "4.16.4" + "@rollup/rollup-linux-riscv64-gnu" "4.16.4" + "@rollup/rollup-linux-s390x-gnu" "4.16.4" + "@rollup/rollup-linux-x64-gnu" "4.16.4" + "@rollup/rollup-linux-x64-musl" "4.16.4" + "@rollup/rollup-win32-arm64-msvc" "4.16.4" + "@rollup/rollup-win32-ia32-msvc" "4.16.4" + "@rollup/rollup-win32-x64-msvc" "4.16.4" fsevents "~2.3.2" rrweb-cssom@^0.6.0: @@ -9268,11 +8612,6 @@ rrweb-cssom@^0.6.0: resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" integrity sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw== -run-async@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" - integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -9296,9 +8635,9 @@ safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sanitize-html@^2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.12.1.tgz#280a0f5c37305222921f6f9d605be1f6558914c7" - integrity sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA== + version "2.13.0" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.13.0.tgz#71aedcdb777897985a4ea1877bf4f895a1170dae" + integrity sha512-Xff91Z+4Mz5QiNSLdLWwjgBDm5b1RU6xBT0+12rapjiaR7SwfRdjw8f+6Rir2MXKLrDicRFHdb51hGOAxmsUIA== dependencies: deepmerge "^4.2.2" escape-string-regexp "^4.0.0" @@ -9321,16 +8660,7 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -schema-utils@^3.0.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -9340,21 +8670,21 @@ schema-utils@^3.2.0: ajv-keywords "^3.5.2" schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" "semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: +semver@^6.0.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -9458,16 +8788,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -side-channel@^1.0.6: +side-channel@^1.0.4, side-channel@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== @@ -9482,11 +8803,6 @@ siginfo@^2.0.0: resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= - signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -9510,14 +8826,9 @@ slash@^3.0.0: slick@^1.12.2: version "1.12.2" resolved "https://registry.yarnpkg.com/slick/-/slick-1.12.2.tgz#bd048ddb74de7d1ca6915faa4a57570b3550c2d7" - integrity sha1-vQSN23TefRymkV+qSldXCzVQwtc= - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + integrity sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A== -source-map-js@^1.2.0: +source-map-js@^1.0.2, source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== @@ -9533,7 +8844,7 @@ source-map-support@^0.5.16, source-map-support@~0.5.20: source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" @@ -9541,9 +8852,9 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== space-separated-tokens@^2.0.0: version "2.0.2" @@ -9591,10 +8902,10 @@ stackback@0.0.2: resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -stackframe@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1" - integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg== +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== statuses@2.0.1, statuses@^2.0.1: version "2.0.1" @@ -9619,11 +8930,11 @@ store2@^2.14.2: integrity sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg== storybook@^8.0.4: - version "8.0.4" - resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.0.4.tgz#f2191d4082d8a1bfa065f358e63e8205533d9efc" - integrity sha512-FUr3Uc2dSAQ80jINH5fSXz7zD7Ncn08OthROjwRtHAH+jMf4wxyZ+RhF3heFy9xLot2/HXOLIWyHyzZZMtGhxg== + version "8.0.9" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.0.9.tgz#169f0625511f4881046a467b56b196b093176a1c" + integrity sha512-/Mvij0Br5bUwJpCvqAUZMEDIWmdRxEyllvVj8Ukw5lIWJePxfpSsz4px5jg9+R6B9tO8sQSqjg4HJvQ/pZk8Tg== dependencies: - "@storybook/cli" "8.0.4" + "@storybook/cli" "8.0.9" stream-shift@^1.0.0: version "1.0.3" @@ -9638,7 +8949,7 @@ strict-event-emitter@^0.5.1: strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" @@ -9680,16 +8991,16 @@ string_decoder@~1.1.1: ansi-regex "^5.0.1" strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-final-newline@^2.0.0: version "2.0.0" @@ -9721,16 +9032,16 @@ strip-json-comments@^3.0.1: integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strip-literal@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-2.0.0.tgz#5d063580933e4e03ebb669b12db64d2200687527" - integrity sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-2.1.0.tgz#6d82ade5e2e74f5c7e8739b6c84692bd65f0bd2a" + integrity sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw== dependencies: - js-tokens "^8.0.2" + js-tokens "^9.0.0" style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + version "3.3.4" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== styled-components@^6.1.8: version "6.1.8" @@ -9747,11 +9058,6 @@ styled-components@^6.1.8: stylis "4.3.1" tslib "2.5.0" -stylis@4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" - integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== - stylis@4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" @@ -9878,9 +9184,9 @@ terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.10: terser "^5.26.0" terser@^5.10.0, terser@^5.26.0: - version "5.30.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.0.tgz#64cb2af71e16ea3d32153f84d990f9be0cdc22bf" - integrity sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw== + version "5.30.4" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.30.4.tgz#62b4d16a819424e6317fd5ceffb4ee8dc769803a" + integrity sha512-xRdd0v64a8mFK9bnsKVdoNP9GQIKUAaJPTaqEQDL4w/J8WaW4sWXXoMZ+6SimPkfT5bElreXf8m9HnmPc3E1BQ== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -9914,35 +9220,30 @@ through2@^2.0.3: readable-stream "~2.3.6" xtend "~4.0.1" -tiny-invariant@^1.0.0, tiny-invariant@^1.0.2, tiny-invariant@^1.0.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" - integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== - -tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: +tiny-invariant@^1.0.0, tiny-invariant@^1.0.2, tiny-invariant@^1.0.6, tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== -tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: +tiny-warning@^1.0.0, tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== tinybench@^2.5.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.6.0.tgz#1423284ee22de07c91b3752c048d2764714b341b" - integrity sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA== + version "2.8.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.8.0.tgz#30e19ae3a27508ee18273ffed9ac7018949acd7b" + integrity sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw== "tinymce@^7.0.0 || ^6.0.0 || ^5.5.1": - version "7.0.0" - resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-7.0.0.tgz#d35441e15f8011cf549b39e58b64648798816e92" - integrity sha512-ggXLfTRrUALAcjeJSRrZcJDOl6MgC2tPXe/zNOEkQXvTDgcKqFypPRoPpfpK5wejexjyaI/7dwETOntJ5MPBFg== + version "7.0.1" + resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-7.0.1.tgz#743f4003027a13497654a5ce5ca74793815386f7" + integrity sha512-0a7DJnhniBx2psRuKcVQ9g4hujN6PAR4fPS0NSF1T1luH1RBDZVVEn2pGND6Ly+AW1lUm/cHOHjsasqBelMhbw== -tinypool@^0.8.2: - version "0.8.3" - resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.3.tgz#e17d0a5315a7d425f875b05f7af653c225492d39" - integrity sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw== +tinypool@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.4.tgz#e217fe1270d941b39e98c625dcecebb1408c9aa8" + integrity sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ== tinyspy@^2.2.0: version "2.2.1" @@ -9952,7 +9253,7 @@ tinyspy@^2.2.0: to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" @@ -9962,9 +9263,9 @@ to-regex-range@^5.0.1: is-number "^7.0.0" tocbot@^4.20.1: - version "4.25.0" - resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.25.0.tgz#bc38aea5ec8f076779bb39636f431b044129a237" - integrity sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA== + version "4.27.4" + resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.27.4.tgz#47f87b97aec2b23eee725c797248500ef0929fd0" + integrity sha512-RJMmos8JXMztNIaasVRyXc/eGQPE+APSkipNBJaFjLC++cYg6zCcRHQRy4EXncpiKiz1Nlax8RTsaSRJMam8CQ== toidentifier@1.0.1: version "1.0.1" @@ -9991,7 +9292,7 @@ tr46@^5.0.0: tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-dedent@^2.0.0: version "2.2.0" @@ -10027,16 +9328,11 @@ tslib@^1.13.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.4.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tslib@^2.0.1, tslib@^2.0.3: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - type-detect@^4.0.0, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -10068,9 +9364,9 @@ type-fest@^2.19.0, type-fest@~2.19: integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== type-fest@^4.9.0: - version "4.14.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.14.0.tgz#46f9a358e605f0ec5ca99ab83deaa7257a7ae379" - integrity sha512-on5/Cw89wwqGZQu+yWO0gGMGu8VNxsaW9SB2HE8yJjllEk7IDTwnSN1dUVldYILhYPN5HzD7WAaw2cc/jBfn0Q== + version "4.17.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.17.0.tgz#4c1b2c2852d2a40ba8c0236d3afc6fc68229e5bf" + integrity sha512-9flrz1zkfLRH3jO3bLflmTxryzKMxVa7841VeMgBaNQGY6vH4RCcpN/sQLB7mQQYh1GZ5utT2deypMuCy4yicw== type-is@~1.6.18: version "1.6.18" @@ -10086,9 +9382,9 @@ ufo@^1.3.2, ufo@^1.4.0: integrity sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw== uglify-js@^3.1.4, uglify-js@^3.5.1: - version "3.15.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.5.tgz#2b10f9e0bfb3f5c15a8e8404393b6361eaeb33b3" - integrity sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ== + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== undici-types@~5.26.4: version "5.26.5" @@ -10114,9 +9410,9 @@ unicode-match-property-value-ecmascript@^2.1.0: integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== unique-string@^2.0.0: version "2.0.0" @@ -10163,19 +9459,19 @@ universalify@^0.2.0: integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unplugin@^1.3.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.10.0.tgz#9cb8140f61e3fbcf27c7c38d305e9d62d5dbbf0b" - integrity sha512-CuZtvvO8ua2Wl+9q2jEaqH6m3DoQ38N7pvBYQbbaeNlWGvK2l6GHiKi29aIHDPoSxdUzQ7Unevf1/ugil5X6Pg== + version "1.10.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.10.1.tgz#8ceda065dc71bc67d923dea0920f05c67f2cd68c" + integrity sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg== dependencies: acorn "^8.11.3" chokidar "^3.6.0" @@ -10198,7 +9494,7 @@ update-browserslist-db@^1.0.13: upper-case@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== uri-js@^4.2.2: version "4.4.1" @@ -10224,14 +9520,14 @@ url@^0.11.0: qs "^6.11.2" use-memo-one@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20" - integrity sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ== + version "1.1.3" + resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99" + integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util@^0.12.4, util@^0.12.5: version "0.12.5" @@ -10247,27 +9543,18 @@ util@^0.12.4, util@^0.12.5: utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== -v8-to-istanbul@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - valid-data-url@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/valid-data-url/-/valid-data-url-3.0.1.tgz#826c1744e71b5632e847dd15dbd45b9fb38aa34f" @@ -10289,7 +9576,7 @@ value-equal@^1.0.1: vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== victory-vendor@^36.6.8: version "36.9.2" @@ -10311,10 +9598,10 @@ victory-vendor@^36.6.8: d3-time "^3.0.0" d3-timer "^3.0.1" -vite-node@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.4.0.tgz#265529d60570ca695ceb69391f87f92847934ad8" - integrity sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw== +vite-node@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.5.1.tgz#5e1a0c6265aa2b553694e6b3dd9421aa3d4dc00c" + integrity sha512-HNpfV7BrAsjkYVNWIcPleJwvJmydJqqJRrRbpoQ/U7QDwJKyEzNa4g5aYg8MjXJyKsk29IUCcMLFRcsEvqUIsA== dependencies: cac "^6.7.14" debug "^4.3.4" @@ -10332,12 +9619,12 @@ vite-tsconfig-paths@^4.3.2: tsconfck "^3.0.3" vite@^5.0.0, vite@^5.2.6: - version "5.2.6" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.6.tgz#fc2ce309e0b4871e938cb0aca3b96c422c01f222" - integrity sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA== + version "5.2.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7" + integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw== dependencies: esbuild "^0.20.1" - postcss "^8.4.36" + postcss "^8.4.38" rollup "^4.13.0" optionalDependencies: fsevents "~2.3.3" @@ -10350,15 +9637,15 @@ vitest-fetch-mock@^0.2.2: cross-fetch "^3.0.6" vitest@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.4.0.tgz#f5c812aaf5023818b89b7fc667fa45327396fece" - integrity sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw== - dependencies: - "@vitest/expect" "1.4.0" - "@vitest/runner" "1.4.0" - "@vitest/snapshot" "1.4.0" - "@vitest/spy" "1.4.0" - "@vitest/utils" "1.4.0" + version "1.5.1" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.5.1.tgz#e661504adab8e587bf6834c6b6790cd1cc72d816" + integrity sha512-3GvBMpoRnUNbZRX1L3mJCv3Ou3NAobb4dM48y8k9ZGwDofePpclTOyO+lqJFKSQpubH1V8tEcAEw/Y3mJKGJQQ== + dependencies: + "@vitest/expect" "1.5.1" + "@vitest/runner" "1.5.1" + "@vitest/snapshot" "1.5.1" + "@vitest/spy" "1.5.1" + "@vitest/utils" "1.5.1" acorn-walk "^8.3.2" chai "^4.3.10" debug "^4.3.4" @@ -10370,9 +9657,9 @@ vitest@^1.4.0: std-env "^3.5.0" strip-literal "^2.0.0" tinybench "^2.5.1" - tinypool "^0.8.2" + tinypool "^0.8.3" vite "^5.0.0" - vite-node "1.4.0" + vite-node "1.5.1" why-is-node-running "^2.2.2" w3c-xmlserializer@^5.0.0: @@ -10400,7 +9687,7 @@ watchpack@^2.2.0, watchpack@^2.4.1: wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" @@ -10419,17 +9706,17 @@ web-resource-inliner@^6.0.1: webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== -webpack-dev-middleware@^6.1.1: - version "6.1.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz#0463232e59b7d7330fa154121528d484d36eb973" - integrity sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ== +webpack-dev-middleware@^6.1.2: + version "6.1.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" + integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== dependencies: colorette "^2.0.10" memfs "^3.4.12" @@ -10499,9 +9786,9 @@ whatwg-encoding@^3.1.1: iconv-lite "0.6.3" whatwg-fetch@^3.4.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.20" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" + integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== whatwg-mimetype@^3.0.0: version "3.0.0" @@ -10524,7 +9811,7 @@ whatwg-url@^14.0.0: whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -10579,7 +9866,7 @@ why-is-node-running@^2.2.2: wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" @@ -10611,7 +9898,7 @@ wrap-ansi@^8.1.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.3.0: version "2.4.3" @@ -10647,11 +9934,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"