diff --git a/assets/.eslintrc.js b/assets/.eslintrc.js index 296a185c..cb116390 100644 --- a/assets/.eslintrc.js +++ b/assets/.eslintrc.js @@ -1,52 +1,48 @@ module.exports = { - root: true, - parser: "@typescript-eslint/parser", - plugins: [ - "@typescript-eslint", - "react", - "jsx-a11y", - ], - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:react/recommended", - "plugin:jsx-a11y/recommended", - ], - "settings": { - "react": { - "version": "detect", - }, + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "react", "jsx-a11y"], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:jsx-a11y/recommended", + ], + settings: { + react: { + version: "detect", }, - "parserOptions": { - "ecmaFeatures": { - "jsx": true, - }, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, }, - "reportUnusedDisableDirectives": true, - "rules": { - "no-console": 0, - "prefer-rest-params": "off", - "@typescript-eslint/ban-ts-comment": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_.*", - "varsIgnorePattern": "^_.*", - "destructuredArrayIgnorePattern": "^_.*", - } - ], - "react/display-name": "off", - "react/function-component-definition": [ - "error", - { - "namedComponents": "arrow-function", - "unnamedComponents": "arrow-function", - }, - ], - "react/hook-use-state": "error", - "react/no-danger": "error", - "jsx-a11y/no-static-element-interactions": "off", - "jsx-a11y/click-events-have-key-events": "off" - } - }; \ No newline at end of file + }, + reportUnusedDisableDirectives: true, + rules: { + "no-console": 0, + "prefer-rest-params": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_.*", + varsIgnorePattern: "^_.*", + destructuredArrayIgnorePattern: "^_.*", + }, + ], + "react/display-name": "off", + "react/function-component-definition": [ + "error", + { + namedComponents: "arrow-function", + unnamedComponents: "arrow-function", + }, + ], + "react/hook-use-state": "error", + "react/no-danger": "error", + "jsx-a11y/no-static-element-interactions": "off", + "jsx-a11y/click-events-have-key-events": "off", + }, +}; diff --git a/assets/index.d.ts b/assets/index.d.ts index e8dc0ac1..3a51ad6d 100644 --- a/assets/index.d.ts +++ b/assets/index.d.ts @@ -1,3 +1,3 @@ declare module "*.png"; declare module "*.jpg"; -declare module '*.svg'; \ No newline at end of file +declare module "*.svg"; diff --git a/assets/js/components/App.tsx b/assets/js/components/App.tsx index 542dc86a..2674d09a 100644 --- a/assets/js/components/App.tsx +++ b/assets/js/components/App.tsx @@ -3,7 +3,7 @@ import { Routes, Route, BrowserRouter } from "react-router-dom"; import { ScreenplayProvider } from "../hooks/useScreenplayContext"; const OutfrontTakeoverTool = React.lazy( - () => import("./OutfrontTakeoverTool/OutfrontTakeoverTool") + () => import("./OutfrontTakeoverTool/OutfrontTakeoverTool"), ); const Dashboard = React.lazy(() => import("./Dashboard/Dashboard")); const PlacesPage = React.lazy(() => import("./Dashboard/PlacesPage")); diff --git a/assets/js/components/Dashboard/AlertBanner.tsx b/assets/js/components/Dashboard/AlertBanner.tsx index 06bfb7e2..d08b267c 100644 --- a/assets/js/components/Dashboard/AlertBanner.tsx +++ b/assets/js/components/Dashboard/AlertBanner.tsx @@ -33,7 +33,7 @@ const AlertBanner: ComponentType = ({ return translateRouteID(alert.affected_list[0]); } else if ( alert.affected_list.every((routeId: string) => - routeId.startsWith("green") + routeId.startsWith("green"), ) ) { return "Green Line"; @@ -72,7 +72,7 @@ const AlertBanner: ComponentType = ({ <> {`${aOrAn( - affectedListString + affectedListString, )} ${affectedListString} ${formatEffect(alert.effect)} alert was just closed.`} {" "} diff --git a/assets/js/components/Dashboard/AlertCard.tsx b/assets/js/components/Dashboard/AlertCard.tsx index 347c40de..4fb0c0ae 100644 --- a/assets/js/components/Dashboard/AlertCard.tsx +++ b/assets/js/components/Dashboard/AlertCard.tsx @@ -30,7 +30,7 @@ const AlertCard = (props: AlertCardProps): JSX.Element => { numberOfScreens, ], prevAlert, - showAnimationOnMount + showAnimationOnMount, ); const isRecurring = alert.active_period.length > 1; diff --git a/assets/js/components/Dashboard/AlertDetails.tsx b/assets/js/components/Dashboard/AlertDetails.tsx index fa7ef3c6..a149fe7d 100644 --- a/assets/js/components/Dashboard/AlertDetails.tsx +++ b/assets/js/components/Dashboard/AlertDetails.tsx @@ -54,11 +54,11 @@ const AlertDetails: ComponentType = () => { const [placesListState, placesListDispatch] = useReducer( placesListReducer, - initialPlacesListState + initialPlacesListState, ); const validAlertId = contextState.allAPIAlertIds.find( - (alert) => alert === id + (alert) => alert === id, ); return selectedAlert ? ( @@ -93,7 +93,7 @@ const AlertDetails: ComponentType = () => { places={placesWithSelectedAlert( selectedAlert, places, - screensByAlertMap + screensByAlertMap, )} noModeFilter isAlertPlacesList diff --git a/assets/js/components/Dashboard/AlertsPage.tsx b/assets/js/components/Dashboard/AlertsPage.tsx index 59ca1301..826a1907 100644 --- a/assets/js/components/Dashboard/AlertsPage.tsx +++ b/assets/js/components/Dashboard/AlertsPage.tsx @@ -28,7 +28,7 @@ const AlertsPage: ComponentType = () => { const { places, alerts, screensByAlertMap } = useScreenplayContext(); const alertsWithPlaces = alerts.filter( - (alert) => screensByAlertMap[alert.id] + (alert) => screensByAlertMap[alert.id], ); return ( @@ -117,7 +117,7 @@ const AlertsList: ComponentType = ({ numPlaces = placesWithSelectedAlert( alert, places, - screensByAlertMap + screensByAlertMap, ).length; } @@ -145,14 +145,14 @@ const AlertsList: ComponentType = ({ if (screenTypeFilterValue !== SCREEN_TYPES[0]) { filteredAlerts = filterAlertsByScreenType( filteredAlerts, - screenTypeFilterValue + screenTypeFilterValue, ); } if (modeLineFilterValue !== MODES_AND_LINES[0]) { filteredAlerts = filterAlertsByModeOrLine( filteredAlerts, - modeLineFilterValue + modeLineFilterValue, ); } return filteredAlerts; @@ -160,7 +160,7 @@ const AlertsList: ComponentType = ({ const filterAlertsByModeOrLine = ( alerts: Alert[], - { label, ids }: { label: string; ids: string[] } + { label, ids }: { label: string; ids: string[] }, ) => { const isRelevantIE: (ie: InformedEntity) => boolean = (() => { switch (label) { @@ -197,7 +197,7 @@ const AlertsList: ComponentType = ({ const filterAlertsByScreenType = ( alerts: Alert[], - { ids }: { label: string; ids: string[] } + { ids }: { label: string; ids: string[] }, ) => { return alerts.filter((alert) => { // Get this alert's list of affected screens. @@ -205,7 +205,7 @@ const AlertsList: ComponentType = ({ return screensWithAlert ? screensWithAlert.find((screen_id) => - ids.includes(screenMetaData[screen_id].type) + ids.includes(screenMetaData[screen_id].type), ) : false; }); @@ -213,7 +213,7 @@ const AlertsList: ComponentType = ({ const compareAlerts = ( { active_period: active_period_1 }: Alert, - { active_period: active_period_2 }: Alert + { active_period: active_period_2 }: Alert, ) => { // Get the soonest start time const start1 = moment(active_period_1[0].start); diff --git a/assets/js/components/Dashboard/Dashboard.tsx b/assets/js/components/Dashboard/Dashboard.tsx index 675a2ad0..935b6653 100644 --- a/assets/js/components/Dashboard/Dashboard.tsx +++ b/assets/js/components/Dashboard/Dashboard.tsx @@ -29,7 +29,7 @@ const Dashboard: ComponentType = () => { }); fetchPlaces((placesList) => - dispatch({ type: "SET_PLACES", places: placesList }) + dispatch({ type: "SET_PLACES", places: placesList }), ); }, []); @@ -114,7 +114,7 @@ const Dashboard: ComponentType = () => { }) // sort them in descending order to get the most recently created or updated alert .sort((a1, a2) => - new Date(a1.updated_at) < new Date(a2.updated_at) ? 1 : -1 + new Date(a1.updated_at) < new Date(a2.updated_at) ? 1 : -1, ) // get the first alert in the list or underfined if there are none .find((alert) => alert) @@ -128,7 +128,7 @@ const Dashboard: ComponentType = () => { type: "SET_BANNER_ALERT", bannerAlert: undefined, }), - 5000 + 5000, ); }; diff --git a/assets/js/components/Dashboard/FilterDropdown.tsx b/assets/js/components/Dashboard/FilterDropdown.tsx index 2dcbd76a..62930d83 100644 --- a/assets/js/components/Dashboard/FilterDropdown.tsx +++ b/assets/js/components/Dashboard/FilterDropdown.tsx @@ -37,7 +37,7 @@ const CustomMenu = React.forwardRef(
    {children}
); - } + }, ); /** @@ -62,7 +62,7 @@ const FilterDropdown = (props: FilterDropdownProps): JSX.Element => { "filter-dropdown__dropdown-button--small": !isDefault(), "filter-dropdown__dropdown-button--large": isDefault(), disabled: props.disabled, - } + }, )} title={props.disabled ? "Coming Soon!" : selectedValue.label} data-testid="filter-dropdown-button" @@ -79,7 +79,7 @@ const FilterDropdown = (props: FilterDropdownProps): JSX.Element => { {!isDefault() && ( @@ -98,7 +98,7 @@ const FilterDropdown = (props: FilterDropdownProps): JSX.Element => { onSelect={onSelect} className={classWithModifier( "filter-dropdown__dropdown", - props.className + props.className, )} > {props.disabled ? ( diff --git a/assets/js/components/Dashboard/PaessDetailContainer.tsx b/assets/js/components/Dashboard/PaessDetailContainer.tsx index 69214287..01f9d5bc 100644 --- a/assets/js/components/Dashboard/PaessDetailContainer.tsx +++ b/assets/js/components/Dashboard/PaessDetailContainer.tsx @@ -8,7 +8,7 @@ interface PaessDetailContainerProps { } const PaessDetailContainer = ( - props: PaessDetailContainerProps + props: PaessDetailContainerProps, ): JSX.Element => { const zonePositions = { left: ["s", "w"], @@ -18,14 +18,15 @@ const PaessDetailContainer = ( const stationCode = props.screens[0].station_code; const leftScreens = props.screens.filter( - (screen) => screen.zone != null && zonePositions.left.includes(screen.zone) + (screen) => screen.zone != null && zonePositions.left.includes(screen.zone), ); const centerScreens = props.screens.filter( (screen) => - screen.zone != null && zonePositions.center.includes(screen.zone) + screen.zone != null && zonePositions.center.includes(screen.zone), ); const rightScreens = props.screens.filter( - (screen) => screen.zone != null && zonePositions.right.includes(screen.zone) + (screen) => + screen.zone != null && zonePositions.right.includes(screen.zone), ); return ( @@ -47,7 +48,7 @@ const PaessDetailContainer = ( zone={screen.zone} label={screen.label} /> - ) + ), )} )} @@ -69,7 +70,7 @@ const PaessDetailContainer = ( zone={screen.zone} label={screen.label} /> - ) + ), )} )} @@ -91,7 +92,7 @@ const PaessDetailContainer = ( zone={screen.zone} label={screen.label} /> - ) + ), )} )} diff --git a/assets/js/components/Dashboard/PlaceRow.tsx b/assets/js/components/Dashboard/PlaceRow.tsx index d008a2b0..5d5cdaa0 100644 --- a/assets/js/components/Dashboard/PlaceRow.tsx +++ b/assets/js/components/Dashboard/PlaceRow.tsx @@ -36,7 +36,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { const { routes, name, description, screens } = props.place; const { activeEventKey } = useContext(AccordionContext); const rowOnClick = useAccordionButton(props.eventKey, () => - props.onClick(props.eventKey) + props.onClick(props.eventKey), ); const { showAnimation } = useUpdateAnimation([], null, props.showAnimation); const isOpen = activeEventKey?.includes(props.eventKey); @@ -77,7 +77,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { return screenList.sort((a, b) => screenTypeOrder.indexOf(a.type) >= screenTypeOrder.indexOf(b.type) ? 1 - : -1 + : -1, ); }; @@ -88,10 +88,10 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { const filterAndGroupScreens = (screens: Screen[]) => { const visibleScreens = screens.filter((screen) => !screen.hidden); const solariScreens = visibleScreens.filter( - (screen) => screen.type === "solari" + (screen) => screen.type === "solari", ); const paEssScreens = visibleScreens.filter( - (screen) => screen.type === "pa_ess" + (screen) => screen.type === "pa_ess", ); const groupedScreens = visibleScreens .filter((screen) => screen.type !== "solari" && screen.type !== "pa_ess") @@ -108,7 +108,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { const groupPaEssScreensbyRoute = ( paEssScreens: Screen[], - groupedScreens: Screen[][] + groupedScreens: Screen[][], ) => { const paEssGroupedByRoute = new Map(); paEssScreens.map((paEssScreen) => { @@ -127,7 +127,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { const renderModesAndLinesIcons = () => { const numberOfGLBranches = routes.filter((route) => - route.startsWith("Green-") + route.startsWith("Green-"), ).length; // If the list of routes contains a single GL branch, show the GL branch icon. @@ -148,7 +148,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { { const getInlineMap = (place: Place, line: string) => { const station = STATION_ORDER_BY_LINE[line].find( - (station) => station.name.toLowerCase() === place.name.toLowerCase() + (station) => station.name.toLowerCase() === place.name.toLowerCase(), ); if (!station) return; @@ -241,7 +241,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { { "place-row__map-segment-container--flipped": !props.defaultSort, - } + }, )} > {getInlineMap(props.place, props.filteredLine.toLowerCase())} @@ -267,7 +267,7 @@ const PlaceRow = (props: PlaceRowProps): JSX.Element => { ) : ( type - ) + ), )} { const line = modeLineFilterValue.label.split(" ")[0]; const sortLabels = SORT_LABELS[line]; @@ -164,7 +164,7 @@ const PlacesList: ComponentType = ({ if (screenTypeFilterValue !== SCREEN_TYPES[0]) { filteredPlaces = filteredPlaces.filter((place) => { return place.screens.some((screen) => - screenTypeFilterValue.ids.includes(screen.type) + screenTypeFilterValue.ids.includes(screen.type), ); }); } @@ -172,18 +172,18 @@ const PlacesList: ComponentType = ({ if (modeLineFilterValue !== MODES_AND_LINES[0]) { filteredPlaces = filteredPlaces.filter((place) => { return place.routes.some((route) => - modeLineFilterValue.ids.includes(route) + modeLineFilterValue.ids.includes(route), ); }); } const filteredPlacesHaveScreenlessPlaces = filteredPlaces.some( - (place) => place.screens.length === 0 + (place) => place.screens.length === 0, ); if (!showScreenlessPlaces) { filteredPlaces = filteredPlaces.filter( - (place) => place.screens.length > 0 + (place) => place.screens.length > 0, ); } // Can add additional filtering in if statements here. diff --git a/assets/js/components/Dashboard/ReportAProblemButton.tsx b/assets/js/components/Dashboard/ReportAProblemButton.tsx index 2f239c6b..13851749 100644 --- a/assets/js/components/Dashboard/ReportAProblemButton.tsx +++ b/assets/js/components/Dashboard/ReportAProblemButton.tsx @@ -7,7 +7,7 @@ interface ReportAProblemButtonProps { } const ReportAProblemButton = ( - props: ReportAProblemButtonProps + props: ReportAProblemButtonProps, ): JSX.Element => { return ( - ) + ), ); const ScreenDetailActionBar = ( - props: ScreenDetailActionBarProps + props: ScreenDetailActionBarProps, ): JSX.Element => { const dropdownRef = useRef(null); const [isOpen, setIsOpen] = useState(false); @@ -77,7 +77,7 @@ const ScreenDetailActionBar = ( type: "SHOW_LINK_COPIED", showLinkCopied: false, }), - 5000 + 5000, ); }; diff --git a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertDetails.tsx b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertDetails.tsx index ab0e088d..119ab0cc 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertDetails.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertDetails.tsx @@ -29,11 +29,11 @@ const AlertDetails = (props: AlertDetailsProps): JSX.Element => { const { created_by, id, message, schedule, stations } = data; const stationScreenOrientationList = useContext( - StationScreenOrientationContext + StationScreenOrientationContext, ); const stationDetails = stations.map((station: string) => - matchStation(station, stationScreenOrientationList) + matchStation(station, stationScreenOrientationList), ); const startDate = new Date(schedule.start); @@ -66,11 +66,11 @@ const AlertDetails = (props: AlertDetailsProps): JSX.Element => { const editAlert = useCallback( (step: number) => startEditWizard(data, step), - [startEditWizard, data] + [startEditWizard, data], ); const clearAlert = useCallback( () => triggerConfirmation(modalDetails), - [triggerConfirmation, modalDetails] + [triggerConfirmation, modalDetails], ); return ( diff --git a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertsList.tsx b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertsList.tsx index 371dbdb9..f45d6fbb 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertsList.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/AlertsList.tsx @@ -36,10 +36,10 @@ const AlertsList = (props: AlertsListProps): JSX.Element => { const clearAlert = ( id: string, - setLastChangeTime: (time: number) => void + setLastChangeTime: (time: number) => void, ) => { const csrfMetaElement = document.head.querySelector( - "[name~=csrf-token][content]" + "[name~=csrf-token][content]", ) as HTMLMetaElement; const csrfToken = csrfMetaElement.content; const data = { id }; @@ -78,7 +78,7 @@ const AlertsList = (props: AlertsListProps): JSX.Element => { const clearAllAlerts = () => { const csrfMetaElement = document.head.querySelector( - "[name~=csrf-token][content]" + "[name~=csrf-token][content]", ) as HTMLMetaElement; const csrfToken = csrfMetaElement.content; diff --git a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertDetails.tsx b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertDetails.tsx index 8181abdf..3b93b5b6 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertDetails.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertDetails.tsx @@ -19,11 +19,11 @@ const PastAlertDetails = (props: PastAlertDetailsProps): JSX.Element => { const { cleared_at, cleared_by, created_by, message, schedule, stations } = props.data; const stationScreenOrientationList = useContext( - StationScreenOrientationContext + StationScreenOrientationContext, ); const stationDetails = stations.map((station: string) => - matchStation(station, stationScreenOrientationList) + matchStation(station, stationScreenOrientationList), ); const startDate = new Date(schedule.start); diff --git a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertsList.tsx b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertsList.tsx index 7a5dcbe3..c0450abd 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertsList.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertDashboard/PastAlertsList.tsx @@ -52,7 +52,7 @@ export class PastAlertsList extends React.Component< sort = (alerts: AlertData[]): AlertData[] => alerts.sort( (a, b) => - new Date(b.cleared_at).valueOf() - new Date(a.cleared_at).valueOf() + new Date(b.cleared_at).valueOf() - new Date(a.cleared_at).valueOf(), ); render() { diff --git a/assets/js/components/OutfrontTakeoverTool/AlertWizard/AlertWizard.tsx b/assets/js/components/OutfrontTakeoverTool/AlertWizard/AlertWizard.tsx index bad2cb87..e4d37084 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertWizard/AlertWizard.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertWizard/AlertWizard.tsx @@ -97,7 +97,7 @@ class AlertWizard extends React.Component { } const selectedStations = stations.map((station: string) => - matchStation(station, this.props.stationScreenOrientationList) + matchStation(station, this.props.stationScreenOrientationList), ); let duration; @@ -245,7 +245,7 @@ class AlertWizard extends React.Component { this.state.id === null ? `${BASE_URL}/create` : `${BASE_URL}/edit`; const csrfMetaElement = document.head.querySelector( - "[name~=csrf-token][content]" + "[name~=csrf-token][content]", ) as HTMLMetaElement; const csrfToken = csrfMetaElement.content; @@ -317,7 +317,7 @@ class AlertWizard extends React.Component { removeStation(station: Station) { this.setState((state) => ({ selectedStations: state.selectedStations.filter( - (x) => !this.stationsAreEqual(x, station) + (x) => !this.stationsAreEqual(x, station), ), })); } @@ -346,7 +346,7 @@ class AlertWizard extends React.Component { }); } else { this.props.stationScreenOrientationList[line].forEach((station) => - this.removeStation(station) + this.removeStation(station), ); } } @@ -384,7 +384,7 @@ class AlertWizard extends React.Component { orientation: string, width: number, height: number, - callback: (dataUrl: string) => void + callback: (dataUrl: string) => void, ) { const canvas = document.createElement("canvas"); canvas.width = width * svgScale; @@ -415,10 +415,10 @@ class AlertWizard extends React.Component { generatePNGs() { this.makePNG("portrait", svgShortSide, svgLongSide, (url) => - this.setState({ portraitPNG: url }) + this.setState({ portraitPNG: url }), ); this.makePNG("landscape", svgLongSide, svgShortSide, (url) => - this.setState({ landscapePNG: url }) + this.setState({ landscapePNG: url }), ); } diff --git a/assets/js/components/OutfrontTakeoverTool/AlertWizard/PickStations.tsx b/assets/js/components/OutfrontTakeoverTool/AlertWizard/PickStations.tsx index 2ce95a14..cd8b17ce 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertWizard/PickStations.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertWizard/PickStations.tsx @@ -17,8 +17,8 @@ const PickStations = (props: PickStationsProps): JSX.Element => { useEffect(() => { setFilteredAlerts( props.activeAlertsStations.filter((station) => - props.selectedStations.map((station) => station.name).includes(station) - ) + props.selectedStations.map((station) => station.name).includes(station), + ), ); }, [props.selectedStations]); diff --git a/assets/js/components/OutfrontTakeoverTool/AlertWizard/SVGPreviews.tsx b/assets/js/components/OutfrontTakeoverTool/AlertWizard/SVGPreviews.tsx index 79b133cd..bd06accf 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertWizard/SVGPreviews.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertWizard/SVGPreviews.tsx @@ -48,7 +48,7 @@ const createSVGText = (message: string, orientation: string) => { return { array: tempArray, lineCount: acc.lineCount }; } }, - { array: [""], lineCount: 0 } + { array: [""], lineCount: 0 }, ); // Take the array of message lines and and individual tspans to the text element diff --git a/assets/js/components/OutfrontTakeoverTool/AlertWizard/StackedStationCards.tsx b/assets/js/components/OutfrontTakeoverTool/AlertWizard/StackedStationCards.tsx index 21dfdad9..7198c2ae 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertWizard/StackedStationCards.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertWizard/StackedStationCards.tsx @@ -13,7 +13,7 @@ interface StackedStationCardsProps { const StackedStationCards = (props: StackedStationCardsProps): JSX.Element => { const stationScreenOrientationList = useContext( - StationScreenOrientationContext + StationScreenOrientationContext, ); return (
{ } const lines = Object.keys(stationScreenOrientationList).filter((key) => - stationScreenOrientationList[key].some((x) => x.name === station.name) + stationScreenOrientationList[key].some( + (x) => x.name === station.name, + ), ); return ( diff --git a/assets/js/components/OutfrontTakeoverTool/AlertWizard/StationColumn.tsx b/assets/js/components/OutfrontTakeoverTool/AlertWizard/StationColumn.tsx index 750651ab..981b7cf5 100644 --- a/assets/js/components/OutfrontTakeoverTool/AlertWizard/StationColumn.tsx +++ b/assets/js/components/OutfrontTakeoverTool/AlertWizard/StationColumn.tsx @@ -15,7 +15,7 @@ interface StationColumnProps { const StationColumn = (props: StationColumnProps): JSX.Element => { const stationScreenOrientationList = useContext( - StationScreenOrientationContext + StationScreenOrientationContext, ); return (
@@ -25,13 +25,13 @@ const StationColumn = (props: StationColumnProps): JSX.Element => { // Ignore disabled stations when determining whether the whole line is selected .filter(({ landscape, portrait }) => landscape || portrait) .every((lineStation) => - props.selectedStations.some((x) => x.name === lineStation.name) + props.selectedStations.some((x) => x.name === lineStation.name), )} checkLine={props.checkLine} /> {stationScreenOrientationList[props.line].map((station) => { const checked = props.selectedStations.some( - (x) => x.name === station.name + (x) => x.name === station.name, ); return (
response.json()) .then((result) => - this.setState({ stationScreenOrientationList: result }) + this.setState({ stationScreenOrientationList: result }), ); this.toggleAlertWizard = this.toggleAlertWizard.bind(this); diff --git a/assets/js/hooks/useScreenplayContext.tsx b/assets/js/hooks/useScreenplayContext.tsx index 8268a616..31ecb7d3 100644 --- a/assets/js/hooks/useScreenplayContext.tsx +++ b/assets/js/hooks/useScreenplayContext.tsx @@ -121,7 +121,7 @@ const reducer = (state: ScreenplayState, action: ReducerAction) => { const placesListReducer = ( state: PlacesListState, - action: PlacesListReducerAction + action: PlacesListReducerAction, ) => { switch (action.type) { case "SET_SORT_DIRECTION": @@ -165,7 +165,7 @@ const placesListReducer = ( const alertsReducer = ( state: AlertsListState, - action: AlertsListReducerAction + action: AlertsListReducerAction, ) => { switch (action.type) { case "SET_MODE_LINE_FILTER": @@ -234,15 +234,15 @@ const [useAlertsListDispatchContext, AlertsListDispatchContextProvider] = const ScreenplayProvider = ({ children }: Props) => { const [screenplayState, screenplayDispatch] = useReducer( reducer, - initialState + initialState, ); const [placesListState, placesListDispatch] = useReducer( placesListReducer, - initialPlacesListState + initialPlacesListState, ); const [alertsListState, alertsListDispatch] = useReducer( alertsReducer, - initialAlertsListState + initialAlertsListState, ); return ( diff --git a/assets/js/hooks/useUpdateAnimation.tsx b/assets/js/hooks/useUpdateAnimation.tsx index 12ea7301..0e60614d 100644 --- a/assets/js/hooks/useUpdateAnimation.tsx +++ b/assets/js/hooks/useUpdateAnimation.tsx @@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from "react"; export const useUpdateAnimation = ( deps: any[], prevValue: any, - showAnimationOnMount?: boolean + showAnimationOnMount?: boolean, ) => { const [showAnimation, setShowAnimation] = useState(false); const timer = useRef(); diff --git a/assets/js/util.ts b/assets/js/util.ts index 2a5c4977..515f590e 100644 --- a/assets/js/util.ts +++ b/assets/js/util.ts @@ -111,14 +111,14 @@ export const convertArrayToListString = (array: string[]) => { export const matchStation = ( station: string, - stationScreenOrientationList: StationsByLine + stationScreenOrientationList: StationsByLine, ) => { const result = Object.values(stationScreenOrientationList) .flat() .find(({ name }) => name === station); if (result === undefined) { throw new TypeError( - `Station ${station} not present in list of all stations!` + `Station ${station} not present in list of all stations!`, ); } return result; @@ -162,14 +162,14 @@ export const formatEffect = (effect: string) => { export const placesWithSelectedAlert = ( alert: Alert | null, places: Place[], - screensByAlertMap: ScreensByAlert + screensByAlertMap: ScreensByAlert, ) => { return alert ? places .map((place) => ({ ...place, screens: place.screens.filter((screen) => - screensByAlertMap[alert.id].includes(screen.id) + screensByAlertMap[alert.id].includes(screen.id), ), })) .filter((place) => place.screens.length > 0) diff --git a/assets/js/utils/api.ts b/assets/js/utils/api.ts index 17e65083..4606d923 100644 --- a/assets/js/utils/api.ts +++ b/assets/js/utils/api.ts @@ -20,8 +20,8 @@ export const fetchAlerts = ( callback: ( all_alert_ids: string[], alerts: Alert[], - screens_by_alert: ScreensByAlert - ) => void + screens_by_alert: ScreensByAlert, + ) => void, ) => { return fetch("/api/alerts") .then((response) => response.json()) diff --git a/assets/package-lock.json b/assets/package-lock.json index 425f21cf..39795839 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -46,7 +46,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^28.1.0", "mini-css-extract-plugin": "^2.8.1", - "prettier": "2.3.2", + "prettier": "3.2.5", "react-test-renderer": "^17.0.2", "sass": "^1.69.5", "sass-loader": "^13.3.2", @@ -12535,14 +12535,18 @@ } }, "node_modules/prettier": { - "version": "2.3.2", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, - "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pretty-format": { diff --git a/assets/package.json b/assets/package.json index e9447603..bc143cd0 100644 --- a/assets/package.json +++ b/assets/package.json @@ -53,7 +53,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^28.1.0", "mini-css-extract-plugin": "^2.8.1", - "prettier": "2.3.2", + "prettier": "3.2.5", "react-test-renderer": "^17.0.2", "sass": "^1.69.5", "sass-loader": "^13.3.2", diff --git a/assets/tests/components/Dashboard/PlacesActionBar.test.tsx b/assets/tests/components/Dashboard/PlacesActionBar.test.tsx index 02fd0add..e6ba624d 100644 --- a/assets/tests/components/Dashboard/PlacesActionBar.test.tsx +++ b/assets/tests/components/Dashboard/PlacesActionBar.test.tsx @@ -54,21 +54,21 @@ describe("PlacesActionBar", () => { showScreenlessPlaces onClickResetFilters={handleClickResetFilters} onClickToggleScreenlessPlaces={handleClickToggleScreenlessPlaces} - /> + />, ); expect(getByTestId("places-action-bar")).toBeInTheDocument(); expect( - queryByTestId("places-action-bar-screenless-places-button") + queryByTestId("places-action-bar-screenless-places-button"), ).not.toBeInTheDocument(); expect( - getByTestId("places-action-bar-reset-filters-button") + getByTestId("places-action-bar-reset-filters-button"), ).toBeInTheDocument(); expect( - getByTestId("places-action-bar-stats-place-count") + getByTestId("places-action-bar-stats-place-count"), ).toHaveTextContent("2"); expect( - getByTestId("places-action-bar-stats-screen-count") + getByTestId("places-action-bar-stats-screen-count"), ).toHaveTextContent("5"); }); @@ -85,21 +85,21 @@ describe("PlacesActionBar", () => { showScreenlessPlaces onClickResetFilters={handleClickResetFilters} onClickToggleScreenlessPlaces={handleClickToggleScreenlessPlaces} - /> + />, ); expect(getByTestId("places-action-bar")).toBeInTheDocument(); expect( - getByTestId("places-action-bar-screenless-places-button") + getByTestId("places-action-bar-screenless-places-button"), ).toBeInTheDocument(); expect( - getByTestId("places-action-bar-reset-filters-button") + getByTestId("places-action-bar-reset-filters-button"), ).toBeInTheDocument(); expect( - getByTestId("places-action-bar-stats-place-count") + getByTestId("places-action-bar-stats-place-count"), ).toHaveTextContent("2"); expect( - getByTestId("places-action-bar-stats-screen-count") + getByTestId("places-action-bar-stats-screen-count"), ).toHaveTextContent("3"); }); @@ -114,7 +114,7 @@ describe("PlacesActionBar", () => { showScreenlessPlaces onClickResetFilters={handleClickResetFilters} onClickToggleScreenlessPlaces={handleClickToggleScreenlessPlaces} - /> + />, ); await act(async () => { @@ -126,7 +126,7 @@ describe("PlacesActionBar", () => { await act(async () => { fireEvent.click( - getByTestId("places-action-bar-screenless-places-button") + getByTestId("places-action-bar-screenless-places-button"), ); }); diff --git a/assets/tests/components/alertCard.test.tsx b/assets/tests/components/alertCard.test.tsx index c2acab1a..beac1a40 100644 --- a/assets/tests/components/alertCard.test.tsx +++ b/assets/tests/components/alertCard.test.tsx @@ -19,7 +19,7 @@ describe("AlertCard", () => { }; const { getByText } = render( - + , ); expect(getByText("Station Closure")).toBeInTheDocument(); @@ -40,7 +40,7 @@ describe("AlertCard", () => { }; const { getByText } = render( - + , ); expect(getByText("Delay—up to 15 minutes")).toBeInTheDocument(); @@ -66,7 +66,7 @@ describe("AlertCard", () => { }; const { getByText } = render( - + , ); expect(getByText("9/16/2022 · 5:00 AM")).toBeInTheDocument(); @@ -93,7 +93,7 @@ describe("AlertCard", () => { }; const { getByText } = render( - + , ); expect(getByText("9/16/2022 · 5:00 AM")).toBeInTheDocument(); diff --git a/assets/tests/components/filterDropdown.test.tsx b/assets/tests/components/filterDropdown.test.tsx index f7e83063..8470a00b 100644 --- a/assets/tests/components/filterDropdown.test.tsx +++ b/assets/tests/components/filterDropdown.test.tsx @@ -15,7 +15,7 @@ describe("FilterDropdown", () => { onSelect={() => null} selectedValue={list[1]} className="test" - /> + />, ); expect(getByTestId("filter-dropdown-clear-button")).toBeVisible(); @@ -40,7 +40,7 @@ describe("FilterDropdown", () => { onSelect={onSelect} selectedValue={selectedValue} className="test" - /> + />, ); expect(getByTestId("filter-dropdown-clear-button")).toBeVisible(); @@ -51,11 +51,11 @@ describe("FilterDropdown", () => { onSelect={onSelect} selectedValue={selectedValue} className="test" - /> + />, ); expect(queryByTestId("filter-dropdown-clear-button")).toBeNull(); expect(getByTestId("filter-dropdown-button").firstChild?.textContent).toBe( - list[0].label + list[0].label, ); }); }); diff --git a/assets/tests/components/paessDetailContainer.test.tsx b/assets/tests/components/paessDetailContainer.test.tsx index 305d4121..4402364e 100644 --- a/assets/tests/components/paessDetailContainer.test.tsx +++ b/assets/tests/components/paessDetailContainer.test.tsx @@ -26,7 +26,7 @@ describe("PaessDetailContainer", () => { const { getByTestId } = render( - + , ); expect(getByTestId("paess-col-left")).toBeVisible(); @@ -49,7 +49,7 @@ describe("PaessDetailContainer", () => { const { getByText } = render( - + , ); expect(getByText("Test Label")).toBeInTheDocument(); diff --git a/assets/tests/components/placeRow.test.tsx b/assets/tests/components/placeRow.test.tsx index 55c7ed0b..b6c1f2db 100644 --- a/assets/tests/components/placeRow.test.tsx +++ b/assets/tests/components/placeRow.test.tsx @@ -37,7 +37,7 @@ describe("PlaceRow", () => { defaultSort /> - + , ); expect(getByTestId("place-row").className).toBe("place-row"); @@ -45,7 +45,7 @@ describe("PlaceRow", () => { expect(handleClick).toHaveBeenCalled(); expect(getByTestId("place-row").className).toBe("place-row open"); expect(getByTestId("place-screen-types").textContent).toBe( - "DUP·Bus Shelter·Solari" + "DUP·Bus Shelter·Solari", ); expect(getByTestId("place-status").textContent).toBe("Auto"); expect(getByAltText("Green-B")).toBeInTheDocument(); @@ -71,7 +71,7 @@ describe("PlaceRow", () => { onClick={handleClick} defaultSort /> - + , ); expect(getByTestId("place-row").className).toBe("place-row disabled"); diff --git a/assets/tests/components/placesPage.test.tsx b/assets/tests/components/placesPage.test.tsx index 8b0c1315..f4f482c0 100644 --- a/assets/tests/components/placesPage.test.tsx +++ b/assets/tests/components/placesPage.test.tsx @@ -84,7 +84,7 @@ describe("PlacesPage", () => { fireEvent.click(await findByRole("button", { name: "Blue Line" })); await waitFor(() => { expect(getAllByTestId("place-row")[0].className).toContain( - "filtered" + "filtered", ); }); }); @@ -116,7 +116,7 @@ describe("PlacesPage", () => { fireEvent.click(await findByRole("button", { name: "Blue Line" })); await waitFor(() => { expect(getByTestId("sort-label").textContent?.trim()).toBe( - "WESTBOUND" + "WESTBOUND", ); }); @@ -124,7 +124,7 @@ describe("PlacesPage", () => { fireEvent.click(await findByRole("button", { name: "Red Line" })); await waitFor(() => { expect(getByTestId("sort-label").textContent?.trim()).toBe( - "SOUTHBOUND" + "SOUTHBOUND", ); }); @@ -154,13 +154,13 @@ describe("PlacesPage", () => { // If not, we would have expected the label to still be that // of the "reverse" direction for the Red Line: "NORTHBOUND" expect(getByTestId("sort-label").textContent?.trim()).toBe( - "SOUTHBOUND" + "SOUTHBOUND", ); }); fireEvent.click(getByTestId("sort-label")); await waitFor(() => { expect(getByTestId("sort-label").textContent?.trim()).toBe( - "NORTHBOUND" + "NORTHBOUND", ); }); @@ -169,7 +169,7 @@ describe("PlacesPage", () => { fireEvent.click(getByTestId("sort-label")); await waitFor(() => { expect(getByTestId("sort-label").textContent?.trim()).toBe( - "EASTBOUND" + "EASTBOUND", ); }); }); @@ -185,8 +185,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "ALEWIFE", "Davis", @@ -200,8 +200,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "ASHMONT", "Park Street", @@ -223,8 +223,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "OAK GROVE", "Malden Center", @@ -238,8 +238,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "Haymarket", "North Station", @@ -261,8 +261,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "MEDFORD/TUFTS", "Ball Square", @@ -285,8 +285,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "Blandford Street", "Boylston", @@ -317,8 +317,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "WONDERLAND", "Revere Beach", @@ -331,8 +331,8 @@ describe("PlacesPage", () => { await waitFor(() => { expect( getAllByTestId("place-name").map( - (placeName) => placeName.textContent - ) + (placeName) => placeName.textContent, + ), ).toStrictEqual([ "Government Center", "Beachmont", diff --git a/assets/tests/components/reportAProblemButton.test.tsx b/assets/tests/components/reportAProblemButton.test.tsx index 9c1a5e9e..52ef3669 100644 --- a/assets/tests/components/reportAProblemButton.test.tsx +++ b/assets/tests/components/reportAProblemButton.test.tsx @@ -5,14 +5,14 @@ import ReportAProblemButton from "../../js/components/Dashboard/ReportAProblemBu describe("ReportAProblemButton", () => { test("uses correct URL for non-admin users", async () => { const { getByTestId } = render( - + , ); await waitFor(() => expect(getByTestId("report-a-problem")).toHaveAttribute( "href", - "https://mbta.slack.com/channels/screens" - ) + "https://mbta.slack.com/channels/screens", + ), ); }); @@ -24,14 +24,14 @@ describe("ReportAProblemButton", () => { const { getByTestId } = render( + />, ); await waitFor(() => expect(getByTestId("report-a-problem")).toHaveAttribute( "href", - "https://mbta.slack.com/channels/screens-team-pios" - ) + "https://mbta.slack.com/channels/screens-team-pios", + ), ); }); }); diff --git a/assets/tests/setup.ts b/assets/tests/setup.ts index 0a85545b..f3e9381f 100644 --- a/assets/tests/setup.ts +++ b/assets/tests/setup.ts @@ -39,12 +39,12 @@ beforeEach(() => { alerts, screens_by_alert: alertsOnScreens, }), - }) + }), ) .mockReturnValueOnce( Promise.resolve({ json: () => Promise.resolve(places), - }) + }), ); }); diff --git a/assets/tests/utils/renderWithScreenplayProvider.tsx b/assets/tests/utils/renderWithScreenplayProvider.tsx index 415d86d0..5dd448b5 100644 --- a/assets/tests/utils/renderWithScreenplayProvider.tsx +++ b/assets/tests/utils/renderWithScreenplayProvider.tsx @@ -20,6 +20,6 @@ export const renderWithScreenplayProvider = (children: ReactNode) => { - + , ); }; diff --git a/assets/tsconfig.test.json b/assets/tsconfig.test.json index d6cc42f3..fc8520e7 100644 --- a/assets/tsconfig.test.json +++ b/assets/tsconfig.test.json @@ -1,3 +1,3 @@ { - "extends": "./tsconfig.json" -} \ No newline at end of file + "extends": "./tsconfig.json" +} diff --git a/assets/webpack.config.js b/assets/webpack.config.js index 706b7a5c..fb95b214 100644 --- a/assets/webpack.config.js +++ b/assets/webpack.config.js @@ -2,23 +2,20 @@ const path = require("path"); const glob = require("glob"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const TerserPlugin = require("terser-webpack-plugin"); -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); module.exports = (env, options) => ({ optimization: { - minimizer: [ - new TerserPlugin({ parallel: true }), - new CssMinimizerPlugin() - ], + minimizer: [new TerserPlugin({ parallel: true }), new CssMinimizerPlugin()], }, entry: { - "app": glob.sync("./vendor/**/*.js").concat(["./js/app.tsx"]), + app: glob.sync("./vendor/**/*.js").concat(["./js/app.tsx"]), }, output: { filename: "app.js", path: path.resolve(__dirname, "../priv/static/js"), - publicPath: "/js/" + publicPath: "/js/", }, devtool: "source-map", module: {