Skip to content
Snippets Groups Projects

Feature/publications search and layout

Merged Tadeusz Miesiąc requested to merge feature/publications-search-and-layout into development
10 unresolved threads

Description

In this PR I refactored Modal Layout and added search bar component for publications list

Merge request reports

Merge request pipeline #85146 passed

Merge request pipeline passed for be986a76

Test coverage 88.43% (-3.86%) from 1 job

Merged by Tadeusz MiesiącTadeusz Miesiąc 1 year ago (Feb 6, 2024 4:34pm UTC)

Loading

Pipeline #85339 passed

Pipeline passed for dd0d629f on development

Test coverage 91.31% (-3.86%) from 1 job

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
1 import { twMerge } from 'tailwind-merge';
2 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
3 import { useAppSelector } from '@/redux/hooks/useAppSelector';
4 import { modalSelector } from '@/redux/modal/modal.selector';
5 import { closeModal } from '@/redux/modal/modal.slice';
6 import { Icon } from '@/shared/Icon';
7 import { MODAL_ROLE } from './ModalLayout.constants';
8
9 type ModalLayoutProps = {
10 children: React.ReactNode;
11 };
12
13 export const ModalLayout = ({ children }: ModalLayoutProps): JSX.Element => {
  • 1 import { twMerge } from 'tailwind-merge';
    2 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
    3 import { useAppSelector } from '@/redux/hooks/useAppSelector';
    4 import { closeModal } from '@/redux/modal/modal.slice';
    5 import { Icon } from '@/shared/Icon';
    6 import { filteredSizeSelector } from '@/redux/publications/publications.selectors';
    7 import { MODAL_ROLE } from './PublicationsModalLayout.constants';
    8 import { PublicationsSearch } from '../PublicationsSearch';
    9
    10 type ModalLayoutProps = {
    11 children: React.ReactNode;
    12 };
    13
    14 export const PublicationsModalLayout = ({ children }: ModalLayoutProps): JSX.Element => {
  • 2 import lensIcon from '@/assets/vectors/icons/lens.svg';
    3 import { useDebounce } from '@/hooks/useDebounce';
    4 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
    5 import { getPublications } from '@/redux/publications/publications.thunks';
    6 import { useAppSelector } from '@/redux/hooks/useAppSelector';
    7 import {
    8 isLoadingSelector,
    9 selectedModelIdSelector,
    10 sortColumnSelector,
    11 sortOrderSelector,
    12 } from '@/redux/publications/publications.selectors';
    13 import Image from 'next/image';
    14 import { setPublicationSearchValue } from '@/redux/publications/publications.slice';
    15 import { DEFAULT_PAGE_SIZE } from '../PublicationsTable/PublicationsTable.constants';
    16
    17 export const PublicationsSearch = (): JSX.Element => {
  • 4 import { useAppSelector } from '@/redux/hooks/useAppSelector';
    5 import { Icon } from '@/shared/Icon';
    6 import {
    7 searchValueSelector,
    8 sortColumnSelector,
    9 } from '@/redux/publications/publications.selectors';
    10 import { SortColumn, SortOrder } from '@/redux/publications/publications.types';
    11 import { getPublications } from '@/redux/publications/publications.thunks';
    12 import { DEFAULT_PAGE_SIZE } from '../PublicationsTable.constants';
    13
    14 type SortByHeaderProps = {
    15 columnName: SortColumn;
    16 children: React.ReactNode;
    17 };
    18
    19 export const SortByHeader = ({ columnName, children }: SortByHeaderProps): JSX.Element => {
  • 107 modelId: selectedId,
    108 }),
    109 );
    110 setPagination(nextState);
    111 };
    112
    113 const table = useReactTable({
    114 state: {
    115 pagination,
    116 },
    117 columns,
    118 data,
    119 getCoreRowModel: getCoreRowModel(),
    120 manualPagination: true,
    121 pageCount: pagesCount,
    122 // onPaginationChange: setPagination,
  • 1 describe('Publications Modal - component', () => {
  • 1 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
    2 import { getPublications } from '@/redux/publications/publications.thunks';
    3 import { useEffect, useMemo } from 'react';
    4 import { publicationsListDataSelector } from '@/redux/publications/publications.selectors';
    5 import { useAppSelector } from '@/redux/hooks/useAppSelector';
    6 import { modelsNameMapSelector } from '@/redux/models/models.selectors';
    7 import { FIRST_ARRAY_ELEMENT } from '@/constants/common';
    8 import { LoadingIndicator } from '@/shared/LoadingIndicator';
    9 import {
    10 PublicationsTable,
    11 PublicationsTableData,
    12 } from './PublicationsTable/PublicationsTable.component';
    13 import { PublicationsModalLayout } from './PublicationsModalLayout';
    14
    15 export const PublicationsModal = (): JSX.Element => {
  • 24 28
    25 29 const sourceDownloadLink = window.location.hostname + apiPath.getSourceFile();
    26 30
    31 useEffect(() => {
    32 // dispatch(getPublications());
    33 }, [dispatch]);
  • 1 import { useEffect, useState } from 'react';
    2
    3 const DEFAULT_DELAY = 500;
    4
    5 export const useDebounce = <T>(value: T, delay?: number): T => {
  • 37 modalName === 'login' && 'h-auto w-[400px]',
    38 )}
    39 >
    40 <div className="flex items-center justify-between bg-white p-[24px] text-xl">
    41 <div>{modalTitle}</div>
    42 <button type="button" onClick={handleCloseModal} aria-label="close button">
    43 <Icon name="close" className="fill-font-500" />
    44 </button>
    45 </div>
    46 {isOpen && modalName === 'overview-images' && <OverviewImagesModal />}
    47 {isOpen && modalName === 'mol-art' && <MolArtModal />}
    48 {isOpen && modalName === 'login' && <LoginModal />}
    49 </div>
    50 </div>
    51 </div>
    34 {isOpen && modalName === 'publications' && <PublicationsModal />}
    • Comment on lines +19 to +34

      That's a weird solution. Cleaner would be to define dynamic wrapper

      export const Modal = (): React.ReactNode => {
        const { isOpen, modalName } = useAppSelector(modalSelector);
      
        const ModalWrapper = modalName === 'publications' ? React.Fragment : ModalLayout;
      
        return (
          <ModalWrapper>
                {isOpen && modalName === 'overview-images' && <OverviewImagesModal />}
                {isOpen && modalName === 'mol-art' && <MolArtModal />}
                {isOpen && modalName === 'login' && <LoginModal />}
                {isOpen && modalName === 'publications' && <PublicationsModal />}
          </ModalWrapper>
        );
      };
    • Please register or sign in to reply
  • Overall LGTM

    There are some tests lacking but RFC from my side is only for more complex components

  • Adrian Orłów approved this merge request

    approved this merge request

  • Please register or sign in to reply
    Loading