Skip to content

Refine catalog filter layout stability#205

Open
JamesEnglish1028 wants to merge 87 commits intoThePalaceProject:mainfrom
JamesEnglish1028:feat/dashboard-collections-toggle
Open

Refine catalog filter layout stability#205
JamesEnglish1028 wants to merge 87 commits intoThePalaceProject:mainfrom
JamesEnglish1028:feat/dashboard-collections-toggle

Conversation

@JamesEnglish1028
Copy link

Summary: stabilize catalog filter and search layout during collection transitions; restyle entry-point filters; reduce layout shift and preserve audiobook badge styling. Testing: not run.

Move 100+ flat src/components/*.tsx files into 11 domain subdirectories
using git mv to preserve history:

  announcements/ (4)  – Announcement, AnnouncementForm,
                         AnnouncementsSection, SitewideAnnouncements
  book/ (14)          – BookCoverEditor, BookDetails, BookDetailsContainer,
                         BookDetailsEditor, BookDetailsEditorSuppression,
                         BookDetailsTabContainer, BookEditForm,
                         Classifications, ClassificationsForm,
                         ClassificationsTable, ComplaintForm, Complaints,
                         Contributors, GenreForm
  catalog/ (1)        – CatalogPage
  config/ (21)        – CatalogServices, Collections, ConfigPage,
                         ConfigTabContainer, DiscoveryServices,
                         EditableConfigList, IndividualAdminEditForm,
                         IndividualAdmins, Libraries, LibraryEditForm,
                         LibraryRegistration, LibraryRegistrationForm,
                         MetadataServices, PatronAuthServices,
                         ProtocolFormField, SelfTestResult, SelfTests,
                         SelfTestsCategory, SelfTestsTabContainer,
                         ServiceEditForm, ServiceWithRegistrationsEditForm
  dashboard/ (17)     – CirculationEventsDownload,
                         CirculationEventsDownloadForm, DashboardPage,
                         InventoryReportRequestModal, LibraryStats,
                         QuicksightDashboard, QuicksightDashboardPage,
                         SingleStatListItem, Stats, StatsCollectionsBarChart,
                         StatsCollectionsGroup, StatsCollectionsList,
                         StatsGroup, StatsInventoryGroup, StatsPatronGroup,
                         StatsTotalCirculationsGroup, StatsUsageReportsGroup
  diagnostics/ (6)    – DiagnosticsServiceTabs, DiagnosticsServiceType,
                         DiagnosticsTabContainer,
                         TroubleshootingCategoryPage, TroubleshootingPage,
                         TroubleshootingTabContainer
  lanes/ (6)          – Lane, LaneCustomListsEditor, LaneEditor, LanePage,
                         Lanes, LanesSidebar
  layout/ (5)         – ContextProvider, Footer, Header, SetupPage,
                         WelcomePage
  lists/ (14)         – AdvancedSearchBooleanFilter, AdvancedSearchBuilder,
                         AdvancedSearchFilter, AdvancedSearchFilterInput,
                         AdvancedSearchFilterViewer, AdvancedSearchValueFilter,
                         CustomListEditor, CustomListEntriesEditor,
                         CustomListPage, CustomListSearch,
                         CustomListSearchQueryViewer, CustomLists,
                         CustomListsForBook, CustomListsSidebar
  patrons/ (10)       – AccountPage, ChangePasswordForm, DebugAuthentication,
                         DebugResultListItem, ManagePatrons, ManagePatronsForm,
                         ManagePatronsTabContainer, NeighborhoodAnalyticsForm,
                         PatronInfo, ResetAdobeId
  shared/ (24)        – Autocomplete, CollectionImportButton, ColorPicker,
                         ConfirmationModalWithOutcome, EditableInput,
                         EditorField, EntryPointsContainer, EntryPointsTabs,
                         ErrorMessage, InputList, LanguageField,
                         ListLoadingIndicator, LoadButton, PairedMenus,
                         PasswordInput, SaveButton, ShareButton, TabContainer,
                         TextWithEditMode, Timestamp, ToolTip, UpdatingLoader,
                         WithEditButton, WithRemoveButton

Updated all import paths in:
- src/index.tsx (11 page-level imports)
- src/components/__tests__/ (90 Mocha unit test files, paths only)
- tests/jest/components/ (16 Jest test files)
- tests/jest/testUtils/renderWithContext.tsx and withProviders.tsx
- All moved component files (cross-subdir and depth corrections)
- Fixed require('../images/...') depth in layout/Header.tsx
- Fixed ./icons/ to ../icons/ for 39 icon imports in moved files

Unchanged:
- src/components/__tests__/ stays flat (only import paths updated)
- src/components/icons/ stays at components root
- src/images/ stays at src root

Added reproducible migration scripts under scripts/:
- organize-components.mjs
- fix-depth-imports.mjs
- fix-cross-subdir-imports.mjs
- fix-jest-tests.mjs

No behavioral change. All 1062 Mocha tests pass, all 137 Jest tests pass.
TypeScript compiler reports zero errors.
Fix 55 ESLint errors (22 ban-types, 1 display-name, 33 prettier/prettier)
that pre-existed in the codebase and were exposed now that components
live in subdirectories and lint-staged sees them on commit.

@typescript-eslint/ban-types (21 occurrences):
  Replace `{}` as empty state type with `Record<string, never>` in 15
  class components — Announcement, ClassificationsTable, LibraryEditForm,
  LanesSidebar, WelcomePage, CustomListsSidebar, PatronInfo, Autocomplete,
  EntryPointsContainer, LanguageField, LoadButton, SaveButton, Timestamp,
  WithEditButton, WithRemoveButton.

  Replace `{}` in useDrag tuple type (AdvancedSearchValueFilter) with
  `Record<string, unknown>`.

  Replace `{}` as Enzyme context type in test wrapper declarations
  (CustomListsSidebar-test, EditableConfigList-test 3 occurrences).

react/display-name (1 occurrence):
  AdvancedSearchValueFilter was a default-exported anonymous arrow function.
  Convert to named const + explicit default export and add displayName.

prettier/prettier (33 occurrences across 15 files):
  Run prettier --write on all files with formatting violations:
  EditableInput-test, ManagePatronsForm-test, ServiceEditForm-test,
  BookDetailsEditor, PatronAuthServices, WelcomePage,
  AdvancedSearchValueFilter, CustomListEditor, CustomListSearch,
  PatronInfo, LoadButton, SaveButton, Timestamp,
  Admin-test, sitewideAnnouncements reducer.

All 1062 Mocha tests pass, all 137 Jest tests pass.
ESLint reports 0 errors across all src/**/*.ts(x) files.
Remove skipLibCheck: true, which was masking type errors in node_modules
dependencies. Clean up the TypeScript configuration to be explicit and
correct rather than relying on the safety valve.

Changes to tsconfig / test infrastructure:
- tsconfig.json: set skipLibCheck: false (from true)
- tsconfig.json: upgrade target from es5 to es2019 (required for
  private class fields used by @open-draft/deferred-promise)
- tsconfig.json: add esModuleInterop: true (required for recharts and
  @reduxjs/toolkit default imports, previously masked by skipLibCheck)
- tsconfig.json: narrow types to ["node"] only; mocha/jest globals
  moved to their own per-runner configs to prevent TS2403 collisions
- tsconfig.json: exclude all src/**/__tests__, src/testHelper.ts, and
  tests/jest from base compilation to keep it free of test-framework globals
- tsconfig.mocha.json (new): extends base, adds mocha types, re-includes
  src/**/* test directories for ts-node/register
- tsconfig.jest.json (new): extends base, adds jest + @testing-library
  types, includes tests/jest/**/* for ts-jest
- jest.config.js: point ts-jest at tsconfig.jest.json
- package.json: prefix test-ts* scripts with TS_NODE_PROJECT=tsconfig.mocha.json

Fix esModuleInterop-related runtime regressions:
- import classNames from "classnames" (was import * as) in
  AdvancedSearchBooleanFilter.tsx and AdvancedSearchValueFilter.tsx
- import("react-axe").then(({ default: axe }) => ...) in src/index.tsx
- import Adapter from "enzyme-adapter-react-16" (was import * as) in
  src/testHelper.ts
- import fetchMock from "fetch-mock-jest" (was import * as) in
  4 jest test files (prototype methods are lost by __importStar)
- Use require("react-dom") directly in index-test.ts for sinon spy
  (esModuleInterop namespace wrapper uses non-configurable getters that
  sinon cannot overwrite)

Result: tsc --noEmit produces 0 errors; 1062 Mocha + 137 Jest tests pass
Replace four legacy FetchEditReducer-based reducers (roles, media,
languages, rightsStatuses) and their corresponding ActionCreator thunks
with a single RTK Query endpoint group injected into the shared api slice.

New file:
- src/features/referenceData/referenceDataSlice.ts
  Four builder.query endpoints: getRoles, getMedia, getLanguages,
  getRightsStatuses. Exports typed hooks (useGetRolesQuery, etc.) for
  future functional-component consumers.

Data-layer removals:
- src/reducers/roles.ts — deleted
- src/reducers/media.ts — deleted
- src/reducers/languages.ts — deleted
- src/reducers/rightsStatuses.ts — deleted
- src/reducers/index.ts — removed the 4 reducers from State interface
  and combineReducers
- src/actions.ts — removed static readonly constants (ROLES, MEDIA,
  LANGUAGES, RIGHTS_STATUSES) and the 4 corresponding thunk methods;
  removed now-unused type imports from interfaces

Component updates (class components — still uses connect() for now;
Phase 3 will convert to function components with hooks):
- BookDetailsEditor.tsx: mapStateToProps reads from RTK Query cache
  via referenceDataApi.endpoints.*.select(); mapDispatchToProps
  dispatches endpoint.initiate() instead of ActionCreator thunks.
  Removed now-dead DataFetcher / ActionCreator / editorAdapter imports.
- BookCoverEditor.tsx: same pattern for rightsStatuses.
- Libraries.tsx: same pattern for languages.
- CustomLists.tsx: same pattern for languages.

Result: tsc --noEmit → 0 errors; Mocha 1062 passing; Jest 137 passing
Replace 10 legacy FetchEdit/RegisterLibrary reducers with RTK Query
endpoints in configServicesSlice. Removes 26 ActionCreator thunks.

- New: src/features/configServices/configServicesSlice.ts (26 endpoints)
- Updated: 11 components (Libraries, Collections, IndividualAdmins,
  PatronAuthServices, MetadataServices, CatalogServices,
  DiscoveryServices, SitewideAnnouncements, Header,
  QuicksightDashboard, CustomLists)
- Updated: apiSlice.ts, reducers/index.ts, actions.ts, .eslintrc
- Updated: .gitignore (ignore macOS Finder duplicate files)
- Deleted: 10 legacy reducer files, collections reducer test
- Updated: actions-test.ts (removed tests for deleted actions)
Replace complaints, classifications, and bookCover reducers with RTK
Query endpoints in bookMetadataSlice. bookCoverPreview remains as a
local createSlice tracking the previewBookCover mutation lifecycle.

- New: src/features/bookMetadata/bookMetadataSlice.ts (8 endpoints)
- Updated: Complaints.tsx, Classifications.tsx, BookCoverEditor.tsx,
  BookDetailsTabContainer.tsx
- Updated: apiSlice.ts (Complaints + Classifications tagTypes)
- Updated: reducers/index.ts (removed 3 reducers, kept bookCoverPreview
  via bookCoverPreviewSlice)
- Updated: actions.ts (removed 9 thunks and ~22 constants)
- Deleted: complaints.ts, classifications.ts, bookCover.ts,
  bookCoverPreview.ts reducer files
- Updated: actions-test.ts (removed tests for deleted actions)
- Deleted: complaints-test.ts, classifications-test.ts,
  bookCoverPreview-test.ts
- Updated: .eslintrc (add argsIgnorePattern to no-unused-vars rule)
Replace lanes, laneVisibility, resetLanes, and laneOrder reducers with
RTK Query endpoints in lanesSlice. A local lanesUiSlice tracks mutation
loading/error states for mapStateToProps in Lanes.tsx.

- New: src/features/lanes/lanesSlice.ts (7 endpoints + lanesUiSlice)
- Updated: apiSlice.ts (Lanes tagType)
- Updated: Lanes.tsx - mapStateToProps/mapDispatchToProps use RTK Query
- Updated: LaneEditor.tsx - editLane returns string responseBody
- Updated: CustomLists.tsx - fetchLanes/lanes state use lanesApi
- Updated: reducers/index.ts - removed 4 lane reducers, added lanesUi
- Updated: actions.ts - removed 6 constants and 7 thunks
- Deleted: lanes.ts, laneVisibility.ts, resetLanes.ts, laneOrder.ts
- Updated: LaneEditor-test.tsx - editLane stub returns Promise<string>
- New: src/features/diagnostics/diagnosticsSlice.ts
  (getSelfTestResults + runSelfTests + selfTestsUiSlice + getDiagnostics)
- Updated: apiSlice.ts (added SelfTests tagType)
- Updated: SelfTests.tsx (removed ActionCreator/DataFetcher, use selfTestsApi)
- Updated: DiagnosticsTabContainer.tsx (removed ActionCreator/DataFetcher, use diagnosticsApi)
- Updated: reducers/index.ts (removed selfTests/diagnostics, added selfTestsUi)
- Updated: actions.ts (removed GET_SELF_TESTS, RUN_SELF_TESTS, DIAGNOSTICS + methods)
- Deleted: selfTests.ts, hasSelfTests.ts, diagnostics.ts reducers
- Updated: actions-test.ts (removed fetchDiagnostics, getSelfTests, runSelfTests blocks)
- New: src/features/patrons/patronsSlice.ts
  (patronLookup + resetAdobeId + changePassword mutations + patronsUiSlice)
- Updated: ManagePatronsForm.tsx (patronsApi.patronLookup + clearPatron)
- Updated: ResetAdobeId.tsx (patronsApi.resetAdobeId)
- Updated: ChangePasswordForm.tsx (patronsApi.changePassword)
- Updated: reducers/index.ts (removed patronManager/changePassword, added patronsUi)
- Updated: actions.ts (removed PATRON_LOOKUP, RESET_ADOBE_ID, CHANGE_PASSWORD, CLEAR_PATRON_DATA + methods)
- Deleted: managePatrons.ts, changePassword.ts reducers + managePatrons-test.ts
- Updated: actions-test.ts (removed patronLookup, resetAdobeId, clearPatronData blocks)
- New: src/features/quicksight/quicksightSlice.ts (getQuicksightEmbedUrl query)
- Updated: QuicksightDashboard.tsx (removed ActionCreator, use quicksightApi)
- Updated: actions.ts (removed QUICKSIGHT_EMBEDDED_URL constant + fetchQuicksightEmbedUrl method + unused imports)
…TK Query (PR 2h)

- New: src/features/customLists/customListsApiSlice.ts
  (getCustomLists + getCustomListsForBook + editCustomListsForBook)
- Updated: apiSlice.ts (CustomLists, CustomListsForBook tagTypes)
- Updated: CustomListsForBook.tsx (full migration - both mapState and mapDispatch)
- Updated: Lanes.tsx (fetchCustomLists now uses RTK; removed ActionCreator + DataFetcher)
- Updated: SelfTestsTabContainer.tsx (fixed broken state reads after PR 2b; now uses configServicesApi)
- Updated: reducers/index.ts (removed customListsForBook)
- Updated: actions.ts (removed CUSTOM_LISTS_FOR_BOOK, EDIT_CUSTOM_LISTS_FOR_BOOK + methods)
- Deleted: customListsForBook.ts reducer
- Install tailwindcss, postcss, autoprefixer, postcss-loader
- Install class-variance-authority, clsx, tailwind-merge, lucide-react
- Add tailwind.config.js (preflight disabled to avoid Bootstrap conflicts)
- Add postcss.config.js
- Wire postcss-loader into webpack SCSS pipeline
- Add @tailwind components/utilities to app.scss
- Add src/lib/utils.ts with cn() merge helper
- Add src/components/ui/alert.tsx (Alert, AlertTitle, AlertDescription)
  with variants: default, destructive, warning, success, info
- Migrate ErrorMessage.tsx from react-bootstrap Alert -> new Alert component

Tests: 136 passed, 1 pre-existing failure (QuicksightDashboard)
…tton/Panel/Form

- Add src/components/ui/button.tsx: drop-in Tailwind Button with legacy
  modifier class support (inverted, danger, success, transparent, small,
  big, centered, squared, etc.) via resolveModifierClasses helper
- Add src/components/ui/panel.tsx: collapsible Panel with ARIA attributes,
  panel-{style} class compat, panel-title/panel-heading/panel-body
  class names preserved for test selectors; openByDefault defaults to false
- Add src/components/ui/form.tsx: Form with forwardRef, FormData pass-through
  to onSubmit, errorText/successText/loadingText, hiddenName/hiddenValue support
- Update src/components/ui/index.ts barrel to export Button, Form, Panel
- Update src/components/ui/dialog.tsx: add role=document wrapper, modal-body
  class, fix aria-hidden on backdrop, use h4 for Dialog.Title
- Update all 70 import sites from library-simplified-reusable-components to ../ui
- Remove @import of library CSS from app.scss
- Uninstall library-simplified-reusable-components package
- Fix BookCoverEditor refs to use HTMLFormElement instead of class instance refs
- All 1013 mocha tests pass
- Uninstall bootstrap@^3.3.6 from package.json / node_modules
- Replace @import "~bootstrap/dist/css/bootstrap.css" in app.scss with
  src/stylesheets/bootstrap-compat.scss — lightweight CSS parity for every
  Bootstrap class still in use: navbar-*, nav-tabs, form-group, form-control,
  form-inline, input-group, well, jumbotron, btn-default, clearfix, container,
  pull-*, text-*, bg-* helpers. Also restores box-sizing: border-box globally.
  Class names unchanged in TSX so Mocha/Enzyme tests continue to pass (1013/1013).
- Tailwind preflight remains disabled; safe to re-enable after browser QA.

All 1013 Mocha tests passing, 135/137 Jest tests passing (2 pre-existing failures).
- SaveButton, CirculationEventsDownloadForm, WelcomePage, AccountPage
- SetupPage, ColorPicker, ConfigPage, CustomListPage, LanePage
- ClassificationsTable, LanguageField, LoadButton, UpdatingLoader, WithEditButton
- Announcement, DashboardPage, TroubleshootingCategoryPage, DiscoveryServices
- SingleStatListItem, AdvancedSearchFilterViewer, ManagePatrons, TroubleshootingTabContainer
- ToolTip, WithRemoveButton, Autocomplete, PatronInfo

All 35 new Jest tests pass. 35 Mocha files deleted.
73 Mocha files remain (down from 108).
- TroubleshootingPage, BookDetailsContainer, MetadataServices, DiagnosticsServiceType
- CatalogServices, Timestamp, TabContainer, IndividualAdmins
- ServiceWithRegistrationsEditForm, EntryPointsContainer, EditorField
- EntryPointsTabs, PatronAuthServices, CatalogPage, TroubleshootingPage

All tests pass. 49 migrated total. 59 Mocha files remain.
- AnnouncementsSection, ErrorMessage
- BookDetailsTabContainer, BookDetails, GenreForm

54 migrated total. 54 Mocha files remain.
…mLists, IndividualAdminEditForm, EditableInput, ProtocolFormField)
…asses in StatsUsageReportsGroup

- Add @source "../**/*.{ts,tsx}" to app.scss so Tailwind v4 PostCSS plugin
  correctly scans all component/page files for utility class names
- Remove actionBtn string constant in StatsUsageReportsGroup; inline full
  Tailwind class strings directly on <a> and <button> className attributes
  so JIT scanner always finds them regardless of scanning mode
…lwindcss

Tailwind v4 requires @import "tailwindcss" (not @tailwind directives) to
inject the @theme CSS-variable color/spacing block. SCSS's own @import
intercepts CSS package imports, preventing tailwindcss from resolving.

Changes:
- Add src/stylesheets/app.css: plain CSS entry with @source and
  @import "tailwindcss", processed by css-loader + postcss-loader only
- Update webpack.common.js: add a .css rule without sass-loader and list
  app.css before app.scss in the entry array
- Remove @source, @config, and @tailwind directives from app.scss

Result: generates bg-blue-600, px-4, py-2, gap-2, text-sm, font-semibold,
text-white, shadow-sm, disabled:opacity-50 and all other component utilities
- WelcomePage: replace .jumbotron with .welcome-hero
- welcome_page.scss: update selector to .welcome-hero
- bootstrap-compat.scss: remove .jumbotron, .btn-default, .well blocks
- SaveButton: use ui/Button component (drop btn btn-default)
- ShareButton: use ui/Button component (drop .btn)
- CollectionImportButton: use ui/Button component (drop btn btn-default)
- EditableConfigList: replace btn/btn-default <a> with Tailwind utilities
  (preserve .create-item / .edit-item for test-selector compat)
- DebugAuthentication: use ui/Button component (drop btn btn-default)
- button.tsx TOKEN_MAP: add btn-sm → text-sm mapping
- global.scss: move .well definition here (own it, not Bootstrap's)
- config_tab_container.scss: remove dead a.btn-default rule

1010/1010 tests passing
… + mb-4

- EditableInput.tsx: wrapper class form-group → editable-input-group mb-4
- bootstrap-compat.scss: remove standalone .form-group rule
- global.scss: add .form-group for remaining direct usages (book/, config/,
  patrons/ components) until those are migrated
- CustomListSearch.test.tsx: update 6 .form-group selectors to
  .editable-input-group

1010/1010 tests passing
- Replace user-btn, library-btn, config-btn with single .site-nav__dropdown-btn
- Unify dropdown menu styling for li > a and li > button elements
- Update tests to use .library-dropdown-toggle selector
- All 15 Header tests passing
Fix all 37 failing Jest test suites (124 suites now passing, 1010 tests).
Add semantic CSS classes to components. Change div.config-section-title to
semantic h2/h3 headings. Remove all Mocha/Enzyme infrastructure including
test files, devDependencies (chai, enzyme, mocha, sinon, ts-node), and
test scripts. Move test data files to tests/jest/. Convert sinon/chai
usage to jest.fn() and Jest assertions in affected test files.
- Remove dead ActionCreator import from ManagePatronsTabContainer
- ContextProvider: dispatch SET_FEATURE_FLAGS directly (no ActionCreator)
- Libraries, IndividualAdmins, MetadataServices, CatalogServices,
  PatronAuthServices, Collections, DiscoveryServices,
  SitewideAnnouncements: replace mapStateToProps + mapDispatchToProps +
  connect() with functional wrapper components using RTK Query hooks
- DiagnosticsTabContainer: replace connect() with useGetDiagnosticsQuery hook
- BookDetailsTabContainer: replace connect() + ConnectedProps with
  useGetComplaintsQuery + useSelector + useDispatch; fix class→className
  in BookDetailsContainer
- Defer refetch() calls via setTimeout(0) to avoid 'Cannot refetch a
  query that has not been started yet' during UNSAFE_componentWillMount

All 124 Jest suites passing.
- Install react-router-dom@6, uninstall react-router
- Add withNavigate/withParams HOCs in src/utils/withNavigate.tsx
- Add RouterContextBridge in index.tsx (uses v6 hooks, passes to ContextProvider)
- ContextProvider now provides v3-compatible router shim via legacy context
- Rewrite index.tsx: BrowserRouter + Routes + Route element syntax
- Wrap page components with withParams() for v6 useParams/useLocation
- Fix Link imports: react-router -> react-router-dom (6 files)
- Fix Link state prop in CustomListsForBook (v6 separate state prop)
- Update jest.mock calls from react-router to react-router-dom (5 test files)
- index.test.tsx: check for BrowserRouter instead of Router
- Add MemoryRouter to renderWithContext and withProviders test utilities

All 124 suites / 1010 tests passing.
- Create StatsCollectionsTable component to display collections inventory as a table
- Add view mode toggle (chart/table) to StatsCollectionsGroup
- Display 9 inventory metrics (titles, available, licensed, etc.) as table columns
- Style toggle buttons and sortable inventory table with responsive layout
- Wrap column headers for compact table display
- Preserve chart view as default for backward compatibility
- Add 'series' to searchable fields in AdvancedSearchBuilder for custom list searches
  Enables searching magazines/periodicals by series name (e.g., 'American Scientist')
- Fix Collections component to properly inject admin context
  The delete button was hidden because useAppAdmin() hook was not being called
  This caused getAdminLevel() to always return 1 instead of 3 for system admins
- Align AdminUI with standard config pattern used in Libraries component
- Includes fixes for type annotations and missing keys in list rendering
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant