mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Minor UI fixes
This commit is contained in:
parent
3e416564b5
commit
a3e60b7d85
|
@ -190,7 +190,7 @@ export default function DataTable<TData extends RowData>({
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>}
|
</table>}
|
||||||
|
|
||||||
{enablePagination &&
|
{!isEmpty && enablePagination &&
|
||||||
<PaginationTools
|
<PaginationTools
|
||||||
table={tableImpl}
|
table={tableImpl}
|
||||||
paginationOptions={paginationOptions}
|
paginationOptions={paginationOptions}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { useCallback, useLayoutEffect, useState } from 'react';
|
import { useCallback, useLayoutEffect } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
import { MagnifyingGlassIcon } from '../../components/Icons';
|
import { MagnifyingGlassIcon } from '../../components/Icons';
|
||||||
import { useAuth } from '../../context/AuthContext';
|
import { useAuth } from '../../context/AuthContext';
|
||||||
import { useConceptNavigation } from '../../context/NagivationContext';
|
import { useConceptNavigation } from '../../context/NagivationContext';
|
||||||
import useLocalStorage from '../../hooks/useLocalStorage';
|
|
||||||
import { ILibraryFilter } from '../../models/miscelanious';
|
import { ILibraryFilter } from '../../models/miscelanious';
|
||||||
import { LibraryFilterStrategy } from '../../models/miscelanious';
|
import { LibraryFilterStrategy } from '../../models/miscelanious';
|
||||||
import PickerStrategy from './PickerStrategy';
|
import PickerStrategy from './PickerStrategy';
|
||||||
|
@ -25,16 +24,17 @@ interface SearchPanelProps {
|
||||||
total: number
|
total: number
|
||||||
filtered: number
|
filtered: number
|
||||||
setFilter: React.Dispatch<React.SetStateAction<ILibraryFilter>>
|
setFilter: React.Dispatch<React.SetStateAction<ILibraryFilter>>
|
||||||
|
query: string
|
||||||
|
setQuery: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
strategy: LibraryFilterStrategy
|
||||||
|
setStrategy: React.Dispatch<React.SetStateAction<LibraryFilterStrategy>>
|
||||||
}
|
}
|
||||||
|
|
||||||
function SearchPanel({ total, filtered, setFilter }: SearchPanelProps) {
|
function SearchPanel({ total, filtered, query, setQuery, strategy, setStrategy, setFilter }: SearchPanelProps) {
|
||||||
const { navigateTo } = useConceptNavigation();
|
const { navigateTo } = useConceptNavigation();
|
||||||
const search = useLocation().search;
|
const search = useLocation().search;
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const [query, setQuery] = useState('');
|
|
||||||
const [strategy, setStrategy] = useLocalStorage<LibraryFilterStrategy>('search_strategy', LibraryFilterStrategy.MANUAL);
|
|
||||||
|
|
||||||
function handleChangeQuery(event: React.ChangeEvent<HTMLInputElement>) {
|
function handleChangeQuery(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
const newQuery = event.target.value;
|
const newQuery = event.target.value;
|
||||||
setQuery(newQuery);
|
setQuery(newQuery);
|
||||||
|
@ -76,7 +76,7 @@ function SearchPanel({ total, filtered, setFilter }: SearchPanelProps) {
|
||||||
{filtered} из {total}
|
{filtered} из {total}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center justify-center w-full pr-[10rem]'>
|
<div className='flex items-center justify-center w-full ml-8'>
|
||||||
<PickerStrategy
|
<PickerStrategy
|
||||||
value={strategy}
|
value={strategy}
|
||||||
onChange={handleChangeStrategy}
|
onChange={handleChangeStrategy}
|
||||||
|
|
|
@ -15,12 +15,12 @@ import { prefixes } from '../../utils/constants';
|
||||||
|
|
||||||
interface ViewLibraryProps {
|
interface ViewLibraryProps {
|
||||||
items: ILibraryItem[]
|
items: ILibraryItem[]
|
||||||
cleanQuery: () => void
|
resetQuery: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<ILibraryItem>();
|
const columnHelper = createColumnHelper<ILibraryItem>();
|
||||||
|
|
||||||
function ViewLibrary({ items, cleanQuery }: ViewLibraryProps) {
|
function ViewLibrary({ items, resetQuery: cleanQuery }: ViewLibraryProps) {
|
||||||
const { navigateTo } = useConceptNavigation();
|
const { navigateTo } = useConceptNavigation();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
@ -42,7 +42,7 @@ function ViewLibrary({ items, cleanQuery }: ViewLibraryProps) {
|
||||||
const item = props.row.original;
|
const item = props.row.original;
|
||||||
return (<>
|
return (<>
|
||||||
<div
|
<div
|
||||||
className='flex items-center justify-start gap-1'
|
className='flex items-center justify-start gap-1 min-w-[2.75rem]'
|
||||||
id={`${prefixes.library_list}${item.id}`}
|
id={`${prefixes.library_list}${item.id}`}
|
||||||
>
|
>
|
||||||
{user && user.subscriptions.includes(item.id) && <p title='Отслеживаемая'><EyeIcon size={3}/></p>}
|
{user && user.subscriptions.includes(item.id) && <p title='Отслеживаемая'><EyeIcon size={3}/></p>}
|
||||||
|
@ -83,10 +83,10 @@ function ViewLibrary({ items, cleanQuery }: ViewLibraryProps) {
|
||||||
columnHelper.accessor('time_update', {
|
columnHelper.accessor('time_update', {
|
||||||
id: 'time_update',
|
id: 'time_update',
|
||||||
header: 'Обновлена',
|
header: 'Обновлена',
|
||||||
size: 220,
|
size: 150,
|
||||||
minSize: 220,
|
minSize: 150,
|
||||||
maxSize: 220,
|
maxSize: 150,
|
||||||
cell: props => new Date(props.cell.getValue()).toLocaleString(intl.locale),
|
cell: props => <div className='text-sm min-w-[8.25rem]'>{new Date(props.cell.getValue()).toLocaleString(intl.locale)}</div>,
|
||||||
enableSorting: true,
|
enableSorting: true,
|
||||||
sortingFn: 'datetime',
|
sortingFn: 'datetime',
|
||||||
sortDescFirst: true
|
sortDescFirst: true
|
||||||
|
@ -95,6 +95,7 @@ function ViewLibrary({ items, cleanQuery }: ViewLibraryProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{items.length > 0 &&
|
||||||
<div className='relative w-full'>
|
<div className='relative w-full'>
|
||||||
<div className='absolute top-[-0.125rem] left-0 flex gap-1 ml-3 z-pop'>
|
<div className='absolute top-[-0.125rem] left-0 flex gap-1 ml-3 z-pop'>
|
||||||
<div id='library-help' className='py-2'>
|
<div id='library-help' className='py-2'>
|
||||||
|
@ -106,21 +107,18 @@ function ViewLibrary({ items, cleanQuery }: ViewLibraryProps) {
|
||||||
</div>
|
</div>
|
||||||
</ConceptTooltip>
|
</ConceptTooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>}
|
||||||
<DataTable
|
<DataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={items}
|
data={items}
|
||||||
|
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<div className='flex flex-col gap-4 justify-center p-2 text-center min-h-[10rem]'>
|
<div className='flex flex-col gap-4 justify-center p-2 text-center min-h-[6rem]'>
|
||||||
<p><b>Список схем пуст</b></p>
|
<p>Список схем пуст</p>
|
||||||
<p>
|
<p className='flex justify-center gap-4'>
|
||||||
<TextURL text='Создать схему' href='/rsform-create'/>
|
<TextURL text='Создать схему' href='/rsform-create'/>
|
||||||
<span> | </span>
|
|
||||||
<TextURL text='Все схемы' href='/library'/>
|
|
||||||
<span> | </span>
|
|
||||||
<span className='cursor-pointer hover:underline text-url' onClick={cleanQuery}>
|
<span className='cursor-pointer hover:underline text-url' onClick={cleanQuery}>
|
||||||
<b>Очистить фильтр</b>
|
Очистить фильтр
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { useLayoutEffect, useState } from 'react';
|
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
import BackendError from '../../components/BackendError'
|
import BackendError from '../../components/BackendError'
|
||||||
import { ConceptLoader } from '../../components/Common/ConceptLoader'
|
import { ConceptLoader } from '../../components/Common/ConceptLoader'
|
||||||
import { useLibrary } from '../../context/LibraryContext';
|
import { useLibrary } from '../../context/LibraryContext';
|
||||||
import { useConceptTheme } from '../../context/ThemeContext';
|
import { useConceptTheme } from '../../context/ThemeContext';
|
||||||
|
import useLocalStorage from '../../hooks/useLocalStorage';
|
||||||
import { ILibraryItem } from '../../models/library';
|
import { ILibraryItem } from '../../models/library';
|
||||||
import { ILibraryFilter } from '../../models/miscelanious';
|
import { ILibraryFilter, LibraryFilterStrategy } from '../../models/miscelanious';
|
||||||
import SearchPanel from './SearchPanel';
|
import SearchPanel from './SearchPanel';
|
||||||
import ViewLibrary from './ViewLibrary';
|
import ViewLibrary from './ViewLibrary';
|
||||||
|
|
||||||
|
@ -16,6 +17,9 @@ function LibraryPage() {
|
||||||
const [ filter, setFilter ] = useState<ILibraryFilter>({});
|
const [ filter, setFilter ] = useState<ILibraryFilter>({});
|
||||||
const [ items, setItems ] = useState<ILibraryItem[]>([]);
|
const [ items, setItems ] = useState<ILibraryItem[]>([]);
|
||||||
|
|
||||||
|
const [query, setQuery] = useState('');
|
||||||
|
const [strategy, setStrategy] = useLocalStorage<LibraryFilterStrategy>('search_strategy', LibraryFilterStrategy.MANUAL);
|
||||||
|
|
||||||
useLayoutEffect(
|
useLayoutEffect(
|
||||||
() => {
|
() => {
|
||||||
setShowScroll(true);
|
setShowScroll(true);
|
||||||
|
@ -27,6 +31,13 @@ function LibraryPage() {
|
||||||
setItems(library.filter(filter));
|
setItems(library.filter(filter));
|
||||||
}, [library, filter, filter.query]);
|
}, [library, filter, filter.query]);
|
||||||
|
|
||||||
|
const resetQuery = useCallback(
|
||||||
|
() => {
|
||||||
|
setQuery('');
|
||||||
|
setStrategy(LibraryFilterStrategy.MANUAL);
|
||||||
|
setFilter({});
|
||||||
|
}, [setStrategy])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
{ library.loading && <ConceptLoader /> }
|
{ library.loading && <ConceptLoader /> }
|
||||||
|
@ -34,12 +45,16 @@ function LibraryPage() {
|
||||||
{ !library.loading && library.items &&
|
{ !library.loading && library.items &&
|
||||||
<div className='flex flex-col w-full'>
|
<div className='flex flex-col w-full'>
|
||||||
<SearchPanel
|
<SearchPanel
|
||||||
|
query={query}
|
||||||
|
setQuery={setQuery}
|
||||||
|
strategy={strategy}
|
||||||
|
setStrategy={setStrategy}
|
||||||
total={library.items.length ?? 0}
|
total={library.items.length ?? 0}
|
||||||
filtered={items.length}
|
filtered={items.length}
|
||||||
setFilter={setFilter}
|
setFilter={setFilter}
|
||||||
/>
|
/>
|
||||||
<ViewLibrary
|
<ViewLibrary
|
||||||
cleanQuery={() => setFilter({})}
|
resetQuery={resetQuery}
|
||||||
items={items}
|
items={items}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -49,7 +49,7 @@ function UserTabs() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{subscriptions.length > 0 && showSubs &&
|
{subscriptions.length > 0 && showSubs &&
|
||||||
<div className='flex flex-col w-full gap-2 pl-4'>
|
<div className='flex flex-col w-full gap-6 pl-4'>
|
||||||
<h1>Отслеживаемые схемы</h1>
|
<h1>Отслеживаемые схемы</h1>
|
||||||
<ViewSubscriptions items={subscriptions} />
|
<ViewSubscriptions items={subscriptions} />
|
||||||
</div>}
|
</div>}
|
||||||
|
|
|
@ -38,10 +38,10 @@ function ViewSubscriptions({items}: ViewSubscriptionsProps) {
|
||||||
columnHelper.accessor('time_update', {
|
columnHelper.accessor('time_update', {
|
||||||
id: 'time_update',
|
id: 'time_update',
|
||||||
header: 'Обновлена',
|
header: 'Обновлена',
|
||||||
minSize: 200,
|
minSize: 150,
|
||||||
size: 200,
|
size: 150,
|
||||||
maxSize: 200,
|
maxSize: 150,
|
||||||
cell: props => new Date(props.cell.getValue()).toLocaleString(intl.locale),
|
cell: props => <div className='min-w-[8.25rem]'>{new Date(props.cell.getValue()).toLocaleString(intl.locale)}</div>,
|
||||||
enableSorting: true
|
enableSorting: true
|
||||||
})
|
})
|
||||||
], [intl]);
|
], [intl]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user