From f07d5957014b387dc6f095f3df1f8736d21814ef Mon Sep 17 00:00:00 2001 From: Cora Grant Date: Fri, 16 Aug 2024 18:05:26 -0400 Subject: [PATCH] chore: clean up admin dashboard navigation * Remove all v1 screen tables except Solari, since we should no longer have any active screens of these types * Split nav items into groups and improve styling a bit * Refactor to generate nav links and routes from a constant instead of repeating everything * Remove "admin layout" which was an exact duplicate of the v2 layout --- assets/css/admin.scss | 41 +- assets/src/apps/admin.tsx | 114 +++--- assets/src/components/admin/admin_navbar.tsx | 71 ---- assets/src/components/admin/admin_tables.tsx | 356 ++---------------- .../controllers/admin_controller.ex | 2 +- .../templates/layout/admin.html.eex | 18 - 6 files changed, 119 insertions(+), 483 deletions(-) delete mode 100644 assets/src/components/admin/admin_navbar.tsx delete mode 100644 lib/screens_web/templates/layout/admin.html.eex diff --git a/assets/css/admin.scss b/assets/css/admin.scss index e7b0abe38..05f86e43f 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -1,16 +1,53 @@ +#app { + font-family: sans-serif; + font-size: 14px; +} + .admin__textarea { width: 90vw; height: 90vh; } .admin-navbar { + display: flex; + flex-wrap: wrap; + row-gap: 0.5em; padding: 1em; + margin-bottom: 0.5em; + background-color: #eee; +} + +.admin-navbar__group { + display: flex; + + &:not(:first-child) { + padding-left: 1em; + margin-left: 1em; + border-left: 1px solid gray; + } +} + +.admin-navbar a { + padding: 2px; + padding: 3px 5px 2px; + color: black; + text-decoration: none; + background-color: white; + border: 2px outset gray; + border-radius: 2px; + + &.active { + background-color: lightgray; + border: 2px inset gray; + } + + &:not(:first-child) { + margin-left: 0.5em; + } } .admin-table { padding-bottom: 3em; - font-family: sans-serif; - font-size: 14px; tbody { input, diff --git a/assets/src/apps/admin.tsx b/assets/src/apps/admin.tsx index eb4af6d37..3dd78eeaa 100644 --- a/assets/src/apps/admin.tsx +++ b/assets/src/apps/admin.tsx @@ -1,97 +1,69 @@ require("../../css/admin.scss"); -import React from "react"; +import React, { ComponentType } from "react"; import ReactDOM from "react-dom"; -import { HashRouter as Router, Route, Switch } from "react-router-dom"; +import { HashRouter as Router, NavLink, Route, Switch } from "react-router-dom"; +import weakKey from "weak-key"; -import AdminNavbar from "Components/admin/admin_navbar"; import { AllScreensTable, - BusScreensTable, - GLSingleScreensTable, - GLDoubleScreensTable, SolariScreensTable, - SolariLargeScreensTable, - DupScreensTable, BusEinkV2ScreensTable, GLEinkV2ScreensTable, BuswayV2ScreensTable, - SolariLargeV2ScreensTable, BusShelterV2ScreensTable, PreFareV2ScreensTable, DupV2ScreensTable, TriptychV2ScreensTable, } from "Components/admin/admin_tables"; +import AdminScreenConfigForm from "Components/admin/admin_screen_config_form"; import AdminTriptychPlayerForm from "Components/admin/admin_triptych_player_form"; import ImageManager from "Components/admin/admin_image_manager"; import Devops from "Components/admin/devops"; -import AdminScreenConfigForm from "Components/admin/admin_screen_config_form"; + +const routes: [string, string, ComponentType][][] = [ + [["", "All Screens", AllScreensTable]], + [ + ["bus-eink-v2-screens", "Bus E-ink", BusEinkV2ScreensTable], + ["bus-shelter-v2-screens", "Bus Shelter", BusShelterV2ScreensTable], + ["dup-v2-screens", "DUP", DupV2ScreensTable], + ["gl-eink-v2-screens", "GL E-ink", GLEinkV2ScreensTable], + ["pre-fare-v2-screens", "Pre-Fare", PreFareV2ScreensTable], + ["busway-v2-screens", "Sectional", BuswayV2ScreensTable], + ["triptych-v2-screens", "Triptych", TriptychV2ScreensTable], + ], + [["solari-screens", "Solari (v1)", SolariScreensTable]], + [ + ["screens-json-editor", "Config Editor", AdminScreenConfigForm], + ["triptych-player-json-editor", "Triptych Editor", AdminTriptychPlayerForm], + ], + [["image-manager", "Image Manager", ImageManager]], + [["devops", "Devops", Devops]], +]; const App = (): JSX.Element => { return ( - +
+ {routes.map((group) => ( +
+ {group.map(([path, label]) => ( + + {label} + + ))} +
+ ))} +
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {routes.map((group) => + group.map(([path, , Component]) => ( + + + + )), + )}
); diff --git a/assets/src/components/admin/admin_navbar.tsx b/assets/src/components/admin/admin_navbar.tsx deleted file mode 100644 index 33f316cdc..000000000 --- a/assets/src/components/admin/admin_navbar.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from "react"; -import { Link } from "react-router-dom"; - -const AdminNavbar = (): JSX.Element => { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- ); -}; - -export default AdminNavbar; diff --git a/assets/src/components/admin/admin_tables.tsx b/assets/src/components/admin/admin_tables.tsx index 815a80aa8..51682b553 100644 --- a/assets/src/components/admin/admin_tables.tsx +++ b/assets/src/components/admin/admin_tables.tsx @@ -10,7 +10,6 @@ import { import { EditableCell, - EditableNumberInput, EditableList, EditableSelect, EditableCheckbox, @@ -114,173 +113,6 @@ const AllScreensTable = (): JSX.Element => { return ; }; -const BusScreensTable = (): JSX.Element => { - const columns = [ - { - Header: "Screen ID", - accessor: "id", - Filter: DefaultColumnFilter, - FormCell: FormStaticCell, - }, - { - Header: "Name", - accessor: "name", - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Stop ID", - accessor: buildAppParamAccessor("stop_id"), - mutator: buildAppParamMutator("stop_id"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Service Level", - accessor: buildAppParamAccessor("service_level"), - mutator: buildAppParamMutator("service_level"), - Cell: EditableNumberInput, - Filter: DefaultColumnFilter, - FormCell: buildFormSelect([1, 2, 3, 4, 5], true), - }, - { - Header: "Tags", - accessor: "tags", - Cell: EditableList, - Filter: DefaultColumnFilter, - filter: filterTags, - FormCell: FormTextCell, - }, - { - Header: "PSA Config", - accessor: buildAppParamAccessor("psa_config"), - mutator: buildAppParamMutator("psa_config"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Nearby Connections", - accessor: buildAppParamAccessor("nearby_connections"), - mutator: buildAppParamMutator("nearby_connections"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - ]; - - const dataFilter = ({ app_id }) => { - return app_id === "bus_eink"; - }; - return ; -}; - -const greenLineAppColumns = [ - { - Header: "Screen ID", - accessor: "id", - Filter: DefaultColumnFilter, - FormCell: FormStaticCell, - }, - { - Header: "Name", - accessor: "name", - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Stop ID", - accessor: buildAppParamAccessor("stop_id"), - mutator: buildAppParamMutator("stop_id"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Route ID", - accessor: buildAppParamAccessor("route_id"), - mutator: buildAppParamMutator("route_id"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Direction ID", - accessor: buildAppParamAccessor("direction_id"), - mutator: buildAppParamMutator("direction_id"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: buildFormSelect([0, 1], true), - }, - { - Header: "Platform ID", - accessor: buildAppParamAccessor("platform_id"), - mutator: buildAppParamMutator("platform_id"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Headway Mode", - accessor: buildAppParamAccessor("headway_mode"), - mutator: buildAppParamMutator("headway_mode"), - Cell: EditableCheckbox, - Filter: DefaultColumnFilter, - FormCell: FormBoolean, - }, - { - Header: "Service Level", - accessor: buildAppParamAccessor("service_level"), - mutator: buildAppParamMutator("service_level"), - Cell: EditableNumberInput, - Filter: DefaultColumnFilter, - FormCell: buildFormSelect([1, 2, 3, 4, 5], true), - }, - { - Header: "Tags", - accessor: "tags", - Cell: EditableList, - Filter: DefaultColumnFilter, - filter: filterTags, - FormCell: FormTextCell, - }, - { - Header: "PSA Config", - accessor: buildAppParamAccessor("psa_config"), - mutator: buildAppParamMutator("psa_config"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Nearby Departures", - accessor: buildAppParamAccessor("nearby_departures"), - mutator: buildAppParamMutator("nearby_departures"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, -]; - -const GLSingleScreensTable = (): JSX.Element => { - const columns = greenLineAppColumns; - const dataFilter = ({ app_id }) => { - return app_id === "gl_eink_single"; - }; - return ; -}; - -const GLDoubleScreensTable = (): JSX.Element => { - const columns = greenLineAppColumns; - const dataFilter = ({ app_id }) => { - return app_id === "gl_eink_double"; - }; - return ; -}; - const SolariScreensTable = (): JSX.Element => { const columns = [ { Header: "Screen ID", accessor: "id", Filter: DefaultColumnFilter }, @@ -348,108 +180,6 @@ const SolariScreensTable = (): JSX.Element => { return ; }; -const SolariLargeScreensTable = (): JSX.Element => { - const columns = [ - { Header: "Screen ID", accessor: "id", Filter: DefaultColumnFilter }, - { - Header: "Station Name", - accessor: buildAppParamAccessor("station_name"), - mutator: buildAppParamMutator("station_name"), - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Overhead", - accessor: buildAppParamAccessor("overhead"), - mutator: buildAppParamMutator("overhead"), - Cell: EditableCheckbox, - Filter: DefaultColumnFilter, - FormCell: FormBoolean, - }, - { - Header: "Section Headers", - accessor: buildAppParamAccessor("section_headers"), - mutator: buildAppParamMutator("section_headers"), - Cell: EditableSelect, - Filter: SelectColumnFilter, - FormCell: buildFormSelect([null, "normal", "vertical"]), - }, - { - Header: "Tags", - accessor: "tags", - Cell: EditableList, - Filter: DefaultColumnFilter, - filter: filterTags, - FormCell: FormTextCell, - }, - { - Header: "Sections", - accessor: buildAppParamAccessor("sections"), - mutator: buildAppParamMutator("sections"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Audio PSA", - accessor: buildAppParamAccessor("audio_psa"), - mutator: buildAppParamMutator("audio_psa"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "PSA Config", - accessor: buildAppParamAccessor("psa_config"), - mutator: buildAppParamMutator("psa_config"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - ]; - - const dataFilter = ({ app_id }) => { - return app_id === "solari_large"; - }; - return ; -}; - -const DupScreensTable = (): JSX.Element => { - const columns = [ - { Header: "Screen ID", accessor: "id", Filter: DefaultColumnFilter }, - { - Header: "Primary Departures", - accessor: buildAppParamAccessor("primary"), - mutator: buildAppParamMutator("primary"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Secondary Departures", - accessor: buildAppParamAccessor("secondary"), - mutator: buildAppParamMutator("secondary"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Override", - accessor: buildAppParamAccessor("override"), - mutator: buildAppParamMutator("override"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - ]; - - const dataFilter = ({ app_id }) => { - return app_id === "dup"; - }; - return ; -}; - const DupV2ScreensTable = (): JSX.Element => { const columns = [ { Header: "Screen ID", accessor: "id", Filter: DefaultColumnFilter }, @@ -776,52 +506,44 @@ const PreFareV2ScreensTable = (): JSX.Element => { ); }; -const v2BuswayColumns = [ - { - Header: "Screen ID", - accessor: "id", - Filter: DefaultColumnFilter, - FormCell: FormStaticCell, - }, - { - Header: "Name", - accessor: "name", - Cell: EditableCell, - Filter: DefaultColumnFilter, - FormCell: FormTextCell, - }, - { - Header: "Departures", - accessor: buildAppParamAccessor("departures"), - mutator: buildAppParamMutator("departures"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, - { - Header: "Header", - accessor: buildAppParamAccessor("header"), - mutator: buildAppParamMutator("header"), - Cell: EditableTextarea, - disableFilters: true, - FormCell: FormTextarea, - }, -]; - const BuswayV2ScreensTable = (): JSX.Element => { const dataFilter = ({ app_id }) => { return app_id === "busway_v2"; }; - return ; -}; - -const SolariLargeV2ScreensTable = (): JSX.Element => { - const dataFilter = ({ app_id }) => { - return app_id === "solari_large_v2"; - }; + const columns = [ + { + Header: "Screen ID", + accessor: "id", + Filter: DefaultColumnFilter, + FormCell: FormStaticCell, + }, + { + Header: "Name", + accessor: "name", + Cell: EditableCell, + Filter: DefaultColumnFilter, + FormCell: FormTextCell, + }, + { + Header: "Departures", + accessor: buildAppParamAccessor("departures"), + mutator: buildAppParamMutator("departures"), + Cell: EditableTextarea, + disableFilters: true, + FormCell: FormTextarea, + }, + { + Header: "Header", + accessor: buildAppParamAccessor("header"), + mutator: buildAppParamMutator("header"), + Cell: EditableTextarea, + disableFilters: true, + FormCell: FormTextarea, + }, + ]; - return ; + return ; }; const TriptychV2ScreensTable = (): JSX.Element => { @@ -846,18 +568,12 @@ const TriptychV2ScreensTable = (): JSX.Element => { export { AllScreensTable, - BusScreensTable, - GLSingleScreensTable, - GLDoubleScreensTable, - SolariScreensTable, - SolariLargeScreensTable, - DupScreensTable, - DupV2ScreensTable, BusEinkV2ScreensTable, - GLEinkV2ScreensTable, - BuswayV2ScreensTable, - SolariLargeV2ScreensTable, BusShelterV2ScreensTable, + BuswayV2ScreensTable, + DupV2ScreensTable, + GLEinkV2ScreensTable, PreFareV2ScreensTable, + SolariScreensTable, TriptychV2ScreensTable, }; diff --git a/lib/screens_web/controllers/admin_controller.ex b/lib/screens_web/controllers/admin_controller.ex index ae8e7c952..418660ff9 100644 --- a/lib/screens_web/controllers/admin_controller.ex +++ b/lib/screens_web/controllers/admin_controller.ex @@ -4,7 +4,7 @@ defmodule ScreensWeb.AdminController do def index(conn, _) do conn |> assign(:app_id, "admin") - |> put_layout(html: {ScreensWeb.LayoutView, :admin}) + |> put_layout(html: {ScreensWeb.V2.LayoutView, :app}) |> render(:admin) end end diff --git a/lib/screens_web/templates/layout/admin.html.eex b/lib/screens_web/templates/layout/admin.html.eex deleted file mode 100644 index 0582a14da..000000000 --- a/lib/screens_web/templates/layout/admin.html.eex +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - <%= csrf_meta_tag() %> - - Screens - - "/> - - - <%= @inner_content %> - - - -