diff --git a/specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx b/specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx index ef689b4435e..75f1ab0e646 100644 --- a/specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx +++ b/specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx @@ -136,6 +136,7 @@ export const icons = { userCircle: , variable: , viewList: , + wrench: , x: , } as const; diff --git a/specifyweb/frontend/js_src/lib/components/Header/userToolDefinitions.ts b/specifyweb/frontend/js_src/lib/components/Header/userToolDefinitions.ts index d1d0a110a10..d5383146a5c 100644 --- a/specifyweb/frontend/js_src/lib/components/Header/userToolDefinitions.ts +++ b/specifyweb/frontend/js_src/lib/components/Header/userToolDefinitions.ts @@ -82,7 +82,7 @@ const rawUserTools = ensure>>>()({ repairTree: { title: headerText.repairTree(), url: '/specify/overlay/tree-repair/', - icon: icons.checkCircle, + icon: icons.wrench, enabled: () => getDisciplineTrees().some((treeName) => hasPermission(`/tree/edit/${toLowerCase(treeName)}`, 'repair') diff --git a/specifyweb/frontend/js_src/lib/components/Permissions/definitions.ts b/specifyweb/frontend/js_src/lib/components/Permissions/definitions.ts index f2ec817812f..a770983fd7d 100644 --- a/specifyweb/frontend/js_src/lib/components/Permissions/definitions.ts +++ b/specifyweb/frontend/js_src/lib/components/Permissions/definitions.ts @@ -23,21 +23,23 @@ export const operationPolicies = { 'copy_from_library', ], '/permissions/library/roles': ['read', 'create', 'update', 'delete'], - '/tree/edit/taxon': ['merge', 'move', 'synonymize', 'desynonymize', 'repair'], + '/tree/edit/taxon': ['merge', 'move', 'synonymize', 'desynonymize', 'repair', 'rebuild_full_names'], '/tree/edit/geography': [ 'merge', 'move', 'synonymize', 'desynonymize', 'repair', + 'rebuild_full_names', ], '/tree/edit/storage': [ 'merge', 'move', + 'bulk_move', 'synonymize', 'desynonymize', 'repair', - 'bulk_move', + 'rebuild_full_names', ], '/tree/edit/geologictimeperiod': [ 'merge', @@ -45,6 +47,7 @@ export const operationPolicies = { 'synonymize', 'desynonymize', 'repair', + 'rebuild_full_names', ], '/tree/edit/lithostrat': [ 'merge', @@ -52,6 +55,7 @@ export const operationPolicies = { 'synonymize', 'desynonymize', 'repair', + 'rebuild_full_names', ], '/tree/edit/tectonicunit': [ 'merge', @@ -59,6 +63,7 @@ export const operationPolicies = { 'synonymize', 'desynonymize', 'repair', + 'rebuild_full_names', ], '/querybuilder/query': [ 'execute', diff --git a/specifyweb/frontend/js_src/lib/components/Toolbar/TreeRepair.tsx b/specifyweb/frontend/js_src/lib/components/Toolbar/TreeRepair.tsx index bcccac2084a..fedde9b57fe 100644 --- a/specifyweb/frontend/js_src/lib/components/Toolbar/TreeRepair.tsx +++ b/specifyweb/frontend/js_src/lib/components/Toolbar/TreeRepair.tsx @@ -11,6 +11,7 @@ import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { headerText } from '../../localization/header'; import { treeText } from '../../localization/tree'; +import { ajax } from '../../utils/ajax'; import { ping } from '../../utils/ajax/ping'; import { f } from '../../utils/functools'; import { toLowerCase } from '../../utils/utils'; @@ -27,12 +28,23 @@ import { treeRanksPromise, } from '../InitialContext/treeRanks'; import { Dialog } from '../Molecules/Dialog'; +import { Portal } from '../Molecules/Portal'; import { ResourceEdit } from '../Molecules/ResourceLink'; import { TableIcon } from '../Molecules/TableIcon'; import { hasPermission, hasTreeAccess } from '../Permissions/helpers'; import { formatUrl } from '../Router/queryString'; import { OverlayContext } from '../Router/Router'; +const TREE_RESOURCES = { + Taxon: '/tree/edit/taxon', + Geography: '/tree/edit/geography', + Storage: '/tree/edit/storage', + GeologicTimePeriod: '/tree/edit/geologictimeperiod', + LithoStrat: '/tree/edit/lithostrat', + TectonicUnit: '/tree/edit/tectonicunit', +} as const; +type TreeNameKey = keyof typeof TREE_RESOURCES; + export function TreeSelectOverlay(): JSX.Element { const handleClose = React.useContext(OverlayContext); return ( @@ -108,32 +120,40 @@ export function TreeSelectDialog({