mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Fix layout for Ipad
This commit is contained in:
parent
2ead8e3a4a
commit
10d1da917d
|
@ -15,10 +15,11 @@ import DropdownButton from '../ui/DropdownButton';
|
|||
|
||||
interface SelectGraphFilterProps {
|
||||
value: DependencyMode;
|
||||
dense?: boolean;
|
||||
onChange: (value: DependencyMode) => void;
|
||||
}
|
||||
|
||||
function SelectGraphFilter({ value, onChange }: SelectGraphFilterProps) {
|
||||
function SelectGraphFilter({ value, dense, onChange }: SelectGraphFilterProps) {
|
||||
const menu = useDropdown();
|
||||
const size = useWindowSize();
|
||||
|
||||
|
@ -39,7 +40,7 @@ function SelectGraphFilter({ value, onChange }: SelectGraphFilterProps) {
|
|||
hideTitle={menu.isOpen}
|
||||
className='h-full pr-2'
|
||||
icon={DependencyIcon(value, '1rem', value !== DependencyMode.ALL ? 'icon-primary' : '')}
|
||||
text={size.isSmall ? undefined : labelCstSource(value)}
|
||||
text={dense || size.isSmall ? undefined : labelCstSource(value)}
|
||||
onClick={menu.toggle}
|
||||
/>
|
||||
<Dropdown stretchLeft isOpen={menu.isOpen}>
|
||||
|
@ -49,13 +50,17 @@ function SelectGraphFilter({ value, onChange }: SelectGraphFilterProps) {
|
|||
const source = value as DependencyMode;
|
||||
return (
|
||||
<DropdownButton
|
||||
className='w-[18rem]'
|
||||
className={!dense ? 'w-[18rem]' : undefined}
|
||||
key={`${prefixes.cst_source_list}${index}`}
|
||||
onClick={() => handleChange(source)}
|
||||
>
|
||||
<div className='inline-flex items-center gap-1'>
|
||||
{DependencyIcon(source, '1rem')}
|
||||
{!dense ? (
|
||||
<span>
|
||||
<b>{labelCstSource(source)}:</b> {describeCstSource(source)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</DropdownButton>
|
||||
);
|
||||
|
|
|
@ -15,10 +15,11 @@ import DropdownButton from '../ui/DropdownButton';
|
|||
|
||||
interface SelectMatchModeProps {
|
||||
value: CstMatchMode;
|
||||
dense?: boolean;
|
||||
onChange: (value: CstMatchMode) => void;
|
||||
}
|
||||
|
||||
function SelectMatchMode({ value, onChange }: SelectMatchModeProps) {
|
||||
function SelectMatchMode({ value, dense, onChange }: SelectMatchModeProps) {
|
||||
const menu = useDropdown();
|
||||
const size = useWindowSize();
|
||||
|
||||
|
@ -38,7 +39,7 @@ function SelectMatchMode({ value, onChange }: SelectMatchModeProps) {
|
|||
hideTitle={menu.isOpen}
|
||||
className='h-full pr-2'
|
||||
icon={MatchModeIcon(value, '1rem', value !== CstMatchMode.ALL ? 'icon-primary' : '')}
|
||||
text={size.isSmall ? undefined : labelCstMatchMode(value)}
|
||||
text={dense || size.isSmall ? undefined : labelCstMatchMode(value)}
|
||||
onClick={menu.toggle}
|
||||
/>
|
||||
<Dropdown stretchLeft isOpen={menu.isOpen}>
|
||||
|
@ -48,13 +49,17 @@ function SelectMatchMode({ value, onChange }: SelectMatchModeProps) {
|
|||
const matchMode = value as CstMatchMode;
|
||||
return (
|
||||
<DropdownButton
|
||||
className='w-[20rem]'
|
||||
className={!dense ? 'w-[20rem]' : undefined}
|
||||
key={`${prefixes.cst_source_list}${index}`}
|
||||
onClick={() => handleChange(matchMode)}
|
||||
>
|
||||
<div className='inline-flex items-center gap-1'>
|
||||
{MatchModeIcon(matchMode, '1rem')}
|
||||
{!dense ? (
|
||||
<span>
|
||||
<b>{labelCstMatchMode(matchMode)}:</b> {describeCstMatchMode(matchMode)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</DropdownButton>
|
||||
);
|
||||
|
|
|
@ -38,7 +38,7 @@ interface IOptionsContext {
|
|||
showHelp: boolean;
|
||||
toggleShowHelp: () => void;
|
||||
|
||||
calculateHeight: (offset: string) => string;
|
||||
calculateHeight: (offset: string, minimum?: string) => string;
|
||||
}
|
||||
|
||||
const OptionsContext = createContext<IOptionsContext | null>(null);
|
||||
|
@ -96,13 +96,13 @@ export const OptionsState = ({ children }: OptionsStateProps) => {
|
|||
}, [noNavigation]);
|
||||
|
||||
const calculateHeight = useCallback(
|
||||
(offset: string) => {
|
||||
(offset: string, minimum: string = '0px') => {
|
||||
if (noNavigation) {
|
||||
return `calc(100vh - (${offset}))`;
|
||||
return `max(calc(100vh - (${offset})), ${minimum})`;
|
||||
} else if (noFooter) {
|
||||
return `calc(100vh - 3rem - (${offset}))`;
|
||||
return `max(calc(100vh - 3rem - (${offset})), ${minimum})`;
|
||||
} else {
|
||||
return `calc(100vh - 6.75rem - (${offset}))`;
|
||||
return `max(calc(100vh - 6.75rem - (${offset})), ${minimum})`;
|
||||
}
|
||||
},
|
||||
[noNavigation, noFooter]
|
||||
|
|
|
@ -4,6 +4,7 @@ import clsx from 'clsx';
|
|||
import { AnimatePresence } from 'framer-motion';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { useConceptOptions } from '@/context/OptionsContext';
|
||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||
import useWindowSize from '@/hooks/useWindowSize';
|
||||
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
||||
|
@ -15,7 +16,7 @@ import ConstituentaToolbar from './ConstituentaToolbar';
|
|||
import FormConstituenta from './FormConstituenta';
|
||||
|
||||
// Threshold window width to switch layout.
|
||||
const SIDELIST_LAYOUT_THRESHOLD = 1100; // px
|
||||
const SIDELIST_LAYOUT_THRESHOLD = 1000; // px
|
||||
|
||||
interface EditorConstituentaProps {
|
||||
activeCst?: IConstituenta;
|
||||
|
@ -27,6 +28,7 @@ interface EditorConstituentaProps {
|
|||
function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }: EditorConstituentaProps) {
|
||||
const controller = useRSEdit();
|
||||
const windowSize = useWindowSize();
|
||||
const { calculateHeight } = useConceptOptions();
|
||||
|
||||
const [showList, setShowList] = useLocalStorage(storage.rseditShowList, true);
|
||||
const [toggleReset, setToggleReset] = useState(false);
|
||||
|
@ -37,6 +39,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
|||
);
|
||||
|
||||
const isNarrow = useMemo(() => !!windowSize.width && windowSize.width <= SIDELIST_LAYOUT_THRESHOLD, [windowSize]);
|
||||
const panelHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]);
|
||||
|
||||
function handleInput(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (disabled) {
|
||||
|
@ -76,7 +79,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='overflow-y-auto' style={{ maxHeight: panelHeight }}>
|
||||
{controller.isContentEditable ? (
|
||||
<ConstituentaToolbar
|
||||
disabled={disabled}
|
||||
|
@ -123,7 +126,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
|||
) : null}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,13 @@ import { storage } from '@/utils/constants';
|
|||
|
||||
interface ConstituentsSearchProps {
|
||||
schema?: IRSForm;
|
||||
dense?: boolean;
|
||||
activeID?: ConstituentaID;
|
||||
activeExpression: string;
|
||||
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
|
||||
}
|
||||
|
||||
function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }: ConstituentsSearchProps) {
|
||||
function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFiltered }: ConstituentsSearchProps) {
|
||||
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL);
|
||||
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL);
|
||||
const [filterText, setFilterText] = useState('');
|
||||
|
@ -51,13 +52,13 @@ function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }:
|
|||
}, [filterText, setFiltered, filterSource, activeExpression, schema?.items, schema, filterMatch, activeID]);
|
||||
|
||||
const selectGraph = useMemo(
|
||||
() => <SelectGraphFilter value={filterSource} onChange={newValue => setFilterSource(newValue)} />,
|
||||
[filterSource, setFilterSource]
|
||||
() => <SelectGraphFilter value={filterSource} onChange={newValue => setFilterSource(newValue)} dense={dense} />,
|
||||
[filterSource, setFilterSource, dense]
|
||||
);
|
||||
|
||||
const selectMatchMode = useMemo(
|
||||
() => <SelectMatchMode value={filterMatch} onChange={newValue => setFilterMatch(newValue)} />,
|
||||
[filterMatch, setFilterMatch]
|
||||
() => <SelectMatchMode value={filterMatch} onChange={newValue => setFilterMatch(newValue)} dense={dense} />,
|
||||
[filterMatch, setFilterMatch, dense]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,6 +5,7 @@ import { motion } from 'framer-motion';
|
|||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { useConceptOptions } from '@/context/OptionsContext';
|
||||
import useWindowSize from '@/hooks/useWindowSize';
|
||||
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
||||
import { animateSideView } from '@/styling/animations';
|
||||
|
||||
|
@ -14,6 +15,9 @@ import ConstituentsTable from './ConstituentsTable';
|
|||
// Window width cutoff for expression show
|
||||
const COLUMN_EXPRESSION_HIDE_THRESHOLD = 1500;
|
||||
|
||||
// Window width cutoff for dense search bar
|
||||
const COLUMN_DENSE_SEARCH_THRESHOLD = 1100;
|
||||
|
||||
interface ViewConstituentsProps {
|
||||
expression: string;
|
||||
isBottom?: boolean;
|
||||
|
@ -24,13 +28,14 @@ interface ViewConstituentsProps {
|
|||
|
||||
function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit }: ViewConstituentsProps) {
|
||||
const { calculateHeight } = useConceptOptions();
|
||||
const windowSize = useWindowSize();
|
||||
|
||||
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
||||
|
||||
const table = useMemo(
|
||||
() => (
|
||||
<ConstituentsTable
|
||||
maxHeight={isBottom ? calculateHeight('42rem') : calculateHeight('8.2rem')}
|
||||
maxHeight={isBottom ? calculateHeight('42rem', '10rem') : calculateHeight('8.2rem')}
|
||||
items={filteredData}
|
||||
activeCst={activeCst}
|
||||
onOpenEdit={onOpenEdit}
|
||||
|
@ -54,6 +59,7 @@ function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit
|
|||
exit={{ ...animateSideView.exit }}
|
||||
>
|
||||
<ConstituentsSearch
|
||||
dense={windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD ? true : undefined}
|
||||
schema={schema}
|
||||
activeID={activeCst?.id}
|
||||
activeExpression={expression}
|
||||
|
|
Loading…
Reference in New Issue
Block a user