Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a tree split widget #3969

Merged
merged 70 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
05e1111
Add a split tree option
CarolineDenis Sep 1, 2023
9bc748b
Display icon for actions when in split mode
CarolineDenis Sep 1, 2023
e61ed07
Format icons svg
CarolineDenis Sep 5, 2023
e396ca6
Add aria-label and title to buttons
CarolineDenis Sep 5, 2023
c10e22b
Rename splitTree context, fix conditional rendering for synonyms
CarolineDenis Sep 5, 2023
c687d4b
Remove negation conditional, remove unnecesary width props
CarolineDenis Sep 5, 2023
9115a3b
Localize string, use onToggle
CarolineDenis Sep 5, 2023
747506d
Refactor tree component
CarolineDenis Sep 5, 2023
d0bc92b
Move splitter from TreeWrapper to TreeView
CarolineDenis Sep 5, 2023
5bd1c80
Remove context
CarolineDenis Sep 5, 2023
a2ab98a
Reverse spli logic
CarolineDenis Sep 5, 2023
b6e16dc
Remove titles
CarolineDenis Sep 6, 2023
85313e3
Reformat code
CarolineDenis Sep 6, 2023
eec30ac
Work in progress: focus node independently in both trees
CarolineDenis Sep 6, 2023
06df6b3
work in progress
CarolineDenis Sep 6, 2023
ff2a6f7
Test to use bottom tree node for focused actions
CarolineDenis Sep 6, 2023
caf38f5
Merge branch 'v7.9-dev' into issue-3600
melton-jason Sep 7, 2023
8013e2b
Remove props
CarolineDenis Sep 12, 2023
578d9b7
Work in progress
CarolineDenis Sep 12, 2023
d1524d4
Test lastFocusedTree
CarolineDenis Sep 13, 2023
52dbbc4
Focuse node separatly in top tree and bottom tree
CarolineDenis Sep 13, 2023
5f28e46
Test
CarolineDenis Sep 13, 2023
2f388f4
Lint code with ESLint and Prettier
CarolineDenis Sep 13, 2023
4b18c79
Remove useEffect and state for focusedRow
CarolineDenis Sep 14, 2023
d2ff3c4
join focusedRow states
CarolineDenis Sep 14, 2023
b72be78
Delete unnecessary icons
CarolineDenis Sep 14, 2023
3045c70
Removes curlies
CarolineDenis Sep 14, 2023
fe8d503
Clean code
CarolineDenis Sep 14, 2023
2d9d573
Remove link incon
CarolineDenis Sep 14, 2023
a9c078d
Add vertical split option
CarolineDenis Sep 14, 2023
d07feec
Add link icon
CarolineDenis Sep 14, 2023
0cd48fe
Create general useState hook
CarolineDenis Sep 15, 2023
8e70808
Merge remote-tracking branch 'origin/v7.9-dev' into issue-3600
CarolineDenis Sep 15, 2023
1b36503
Simplify code hook state
CarolineDenis Sep 15, 2023
5170022
Fix typo
CarolineDenis Sep 15, 2023
e47d9a6
Small fix
CarolineDenis Sep 18, 2023
b74abe9
Lint code with ESLint and Prettier
CarolineDenis Sep 18, 2023
da76fff
refactor(TreeView): Use GetSet
maxpatiiuk Sep 19, 2023
2916826
Delete imports
CarolineDenis Sep 19, 2023
dc67c7e
Merge remote-tracking branch 'origin/v7.9-dev' into issue-3600
CarolineDenis Sep 19, 2023
f5b3f93
Fix overflow issue
CarolineDenis Sep 19, 2023
83a03d1
Lint code with ESLint and Prettier
CarolineDenis Sep 19, 2023
7dd06f0
add className to splitter
CarolineDenis Sep 20, 2023
d3b0e88
Lint code with ESLint and Prettier
CarolineDenis Sep 20, 2023
bcc7543
Test buttons icons
CarolineDenis Sep 21, 2023
0adf783
Reorganize icons
CarolineDenis Sep 21, 2023
6baa65a
Lint code with ESLint and Prettier
CarolineDenis Sep 21, 2023
0b8631a
Merge remote-tracking branch 'origin/production' into issue-3600
CarolineDenis Sep 26, 2023
bf9662c
Fix merge conflicts
CarolineDenis Sep 26, 2023
c01617f
Lint code with ESLint and Prettier
CarolineDenis Sep 26, 2023
a742c40
Use new icons and clean comments
CarolineDenis Sep 26, 2023
324445b
Update Icons.tsx
grantfitzsimmons Sep 26, 2023
470fe4f
Cosmetic changes
CarolineDenis Sep 26, 2023
1f67b09
Lint code with ESLint and Prettier
CarolineDenis Sep 26, 2023
5fb3535
Merge branch 'production' into issue-3600
CarolineDenis Sep 26, 2023
fe86253
Restet pane dimensions to default between orientation switch
CarolineDenis Sep 29, 2023
bc671a3
Disable orientation switch button when not in split view
CarolineDenis Sep 29, 2023
f9c9abe
Remove shadow from trees
CarolineDenis Sep 29, 2023
76bfca9
Move collapse all button to left of search box
CarolineDenis Sep 29, 2023
e98e98b
Lint code with ESLint and Prettier
CarolineDenis Sep 29, 2023
3585074
Fix second scroll bar appearing
CarolineDenis Sep 29, 2023
6a44734
Merge remote-tracking branch 'origin/production' into issue-3600
CarolineDenis Sep 29, 2023
b567578
Add border to the tree viewer
grantfitzsimmons Sep 30, 2023
70d6d6e
Lint code with ESLint and Prettier
grantfitzsimmons Sep 30, 2023
d3ba552
Disable split on narrow screens
CarolineDenis Oct 2, 2023
8a55646
Lint code with ESLint and Prettier
CarolineDenis Oct 2, 2023
51c4ad5
Use listen instead of event listener
CarolineDenis Oct 3, 2023
ae95eda
Chnage the logic for resized window listener
CarolineDenis Oct 4, 2023
0c3fb6c
Merge branch 'production' into issue-3600
CarolineDenis Oct 4, 2023
d88ae1b
Create variable for small screen width
CarolineDenis Oct 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 18 additions & 2 deletions specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx

Large diffs are not rendered by default.

34 changes: 24 additions & 10 deletions specifyweb/frontend/js_src/lib/components/Forms/DeleteButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function DeleteButton<SCHEMA extends AnySchema>({
deferred: initialDeferred = false,
component: ButtonComponent = Button.Secondary,
onDeleted: handleDeleted,
isIcon = false,
}: {
readonly resource: SpecifyResource<SCHEMA>;
readonly deletionMessage?: React.ReactNode;
Expand All @@ -55,10 +56,12 @@ export function DeleteButton<SCHEMA extends AnySchema>({
readonly deferred?: boolean;
readonly component?: typeof Button['Secondary'];
readonly onDeleted?: () => void;
readonly isIcon?: boolean;
}): JSX.Element {
const [deferred, setDeferred] = useLiveState<boolean>(
React.useCallback(() => initialDeferred, [initialDeferred, resource])
);

const [blockers, setBlockers] = useAsyncState<RA<DeleteBlocker>>(
React.useCallback(
async () => (deferred ? undefined : fetchBlockers(resource)),
Expand All @@ -76,16 +79,27 @@ export function DeleteButton<SCHEMA extends AnySchema>({

return (
<>
<ButtonComponent
title={isBlocked ? formsText.deleteBlocked() : undefined}
onClick={(): void => {
handleOpen();
setDeferred(false);
}}
>
{isBlocked ? icons.exclamation : undefined}
{commonText.delete()}
</ButtonComponent>
{isIcon ? (
<Button.Icon
title={isBlocked ? formsText.deleteBlocked() : commonText.delete()}
CarolineDenis marked this conversation as resolved.
Show resolved Hide resolved
icon="trash"
onClick={(): void => {
CarolineDenis marked this conversation as resolved.
Show resolved Hide resolved
handleOpen();
setDeferred(false);
}}
/>
) : (
<ButtonComponent
title={isBlocked ? formsText.deleteBlocked() : undefined}
onClick={(): void => {
handleOpen();
setDeferred(false);
}}
>
{isBlocked ? icons.exclamation : undefined}
{commonText.delete()}
</ButtonComponent>
)}
{isOpen ? (
blockers === undefined ? (
<Dialog
Expand Down
65 changes: 36 additions & 29 deletions specifyweb/frontend/js_src/lib/components/TreeView/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { queryText } from '../../localization/query';
import { treeText } from '../../localization/tree';
import { formData } from '../../utils/ajax/helpers';
import { ping } from '../../utils/ajax/ping';
import type { GetOrSet, RA } from '../../utils/types';
import type { GetSet, RA } from '../../utils/types';
import { toLowerCase } from '../../utils/utils';
import { Button } from '../Atoms/Button';
import { Link } from '../Atoms/Link';
Expand All @@ -35,7 +35,7 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
actionRow,
onChange: handleChange,
onRefresh: handleRefresh,
setFocusPath,
focusPath: [focusPath, setFocusPath],
}: {
readonly tableName: SCHEMA['tableName'];
readonly focusRef: React.MutableRefObject<HTMLAnchorElement | null>;
Expand All @@ -44,7 +44,7 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
readonly actionRow: Row | undefined;
readonly onChange: (row: Row | undefined) => void;
readonly onRefresh: () => void;
readonly setFocusPath: GetOrSet<RA<number> | undefined>[1];
readonly focusPath: GetSet<RA<number>>;
}): JSX.Element {
const isRoot = ranks[0] === focusedRow?.rankId;

Expand Down Expand Up @@ -77,22 +77,28 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
<li className="contents">
{typeof focusedRow === 'object' ? (
isRoot ? (
<Button.Small onClick={undefined}>
{queryText.query()}
</Button.Small>
<Button.Icon
title={queryText.query()}
onClick={undefined}
icon="search"
/>
) : (
<Link.Small
<Link.Icon
forwardRef={focusRef}
href={`/specify/query/fromtree/${tableName.toLowerCase()}/${
focusedRow.nodeId
}/`}
target="_blank"
>
{queryText.query()}
</Link.Small>
title={queryText.query()}
icon="search"
/>
)
) : (
<Button.Small onClick={undefined}>{queryText.query()}</Button.Small>
<Button.Icon
title={queryText.query()}
onClick={undefined}
icon="search"
/>
)}
</li>
)}
Expand All @@ -119,7 +125,7 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
tableName={tableName}
onDeleted={() => {
handleRefresh();
setFocusPath((path) => path?.slice(0, -1));
setFocusPath(focusPath?.slice(0, -1));
}}
/>
</li>
Expand All @@ -144,30 +150,32 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
)}
{hasPermission(resourceName, 'move') && (
<li className="contents">
<Button.Small
<Button.Icon
title={treeText.move()}
disabled={disableButtons || isRoot}
onClick={(): void => setAction('move')}
>
{treeText.move()}
</Button.Small>
icon="arrowsMove"
/>
</li>
)}
{hasPermission(resourceName, 'merge') && (
<li className="contents">
<Button.Small
<Button.Icon
icon="merge"
title={treeText.merge()}
disabled={disableButtons || isRoot}
onClick={(): void => setAction('merge')}
>
{treeText.merge()}
</Button.Small>
/>
</li>
)}
{hasPermission(
resourceName,
isSynonym ? 'desynonymize' : 'synonymize'
) && (
<li className="contents">
<Button.Small
<Button.Icon
icon={isSynonym ? 'undoSynonym' : 'synonym'}
title={isSynonym ? treeText.undoSynonymy() : treeText.synonymize()}
disabled={
disableButtons ||
isRoot ||
Expand All @@ -178,9 +186,7 @@ export function TreeViewActions<SCHEMA extends AnyTree>({
onClick={(): void =>
setAction(isSynonym ? 'desynonymize' : 'synonymize')
}
>
{isSynonym ? treeText.undoSynonymy() : treeText.synonymize()}
</Button.Small>
/>
</li>
)}
</menu>
Expand Down Expand Up @@ -237,13 +243,13 @@ function EditRecordDialog<SCHEMA extends AnyTree>({

return (
<>
<Button.Small
<Button.Icon
aria-pressed={isOpen}
disabled={nodeId === undefined || disabled}
onClick={handleToggle}
>
{label}
</Button.Small>
title={label}
icon={addNew === false ? 'pencil' : 'plus'}
/>
{isOpen && typeof resource === 'object' && (
<ResourceView
dialog="nonModal"
Expand Down Expand Up @@ -452,13 +458,14 @@ function NodeDeleteButton({
);

return disabled || resource === undefined ? (
<Button.Small onClick={undefined}>{commonText.delete()}</Button.Small>
<Button.Icon onClick={undefined} title={commonText.delete()} icon="trash" />
) : (
<DeleteButton
component={Button.Small}
deferred
resource={resource}
onDeleted={handleDeleted}
isIcon={true}
/>
);
}
6 changes: 3 additions & 3 deletions specifyweb/frontend/js_src/lib/components/TreeView/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ export function TreeRow({
color:
typeof row.acceptedId === 'number' ? synonymColor : undefined,
}}
onClick={({ metaKey, shiftKey }): void =>
metaKey || shiftKey ? handleFocusNode([]) : handleToggle(false)
}
onClick={({ metaKey, shiftKey }): void => {
metaKey || shiftKey ? handleFocusNode([]) : handleToggle(false);
}}
onKeyDown={(event): void => {
const action = mapKey(event);
if (action === undefined) return undefined;
Expand Down