Skip to content

Commit a8c7d8e

Browse files
committed
Merge branch 'jumpy-dropdowns' of Arnei/opencast-admin-interface into r/19.x
Pull request #1559 Fixes #1506 Fix dropdown resetting focus
2 parents 8784723 + 0eff28d commit a8c7d8e

4 files changed

Lines changed: 58 additions & 45 deletions

File tree

src/components/shared/Table.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
selectRowIds,
2424
selectRowById,
2525
rowsSelectors,
26+
resetTableProperties,
2627
} from "../../slices/tableSlice";
2728
import {
2829
changeAllSelected,
@@ -35,12 +36,14 @@ import cn from "classnames";
3536
import EditTableViewModal from "../shared/EditTableViewModal";
3637

3738
import Notifications from "./Notifications";
38-
import { useAppDispatch, useAppSelector } from "../../store";
39+
import { AppThunk, useAppDispatch, useAppSelector } from "../../store";
3940
import { TableColumn } from "../../configs/tableConfigs/aclsTableConfig";
4041
import ButtonLikeAnchor from "./ButtonLikeAnchor";
4142
import { ModalHandle } from "./modals/Modal";
4243
import { ParseKeys } from "i18next";
4344
import { LuChevronDown, LuChevronLeft, LuChevronRight, LuChevronUp } from "react-icons/lu";
45+
import { AsyncThunk } from "@reduxjs/toolkit";
46+
import { useLocation } from "react-router";
4447

4548
const containerPageSize = React.createRef<HTMLDivElement>();
4649

@@ -53,15 +56,49 @@ export type TemplateMap = {
5356
*/
5457
const Table = ({
5558
templateMap,
59+
fetchResource,
60+
loadResourceIntoTable,
5661
}: {
5762
templateMap: TemplateMap
63+
fetchResource: AsyncThunk<any, void, any>,
64+
loadResourceIntoTable: () => AppThunk,
5865
}) => {
5966
const { t } = useTranslation();
6067
const dispatch = useAppDispatch();
68+
const location = useLocation();
6169

6270
const editTableViewModalRef = useRef<ModalHandle>(null);
6371
const selectAllCheckboxRef = useRef<HTMLInputElement>(null);
6472

73+
useEffect(() => {
74+
// State variable for interrupting the load function
75+
let allowLoadIntoTable = true;
76+
77+
// Clear table of previous data
78+
dispatch(resetTableProperties());
79+
80+
// Load resource on mount
81+
const loadResource = async () => {
82+
// Fetching resources from server
83+
await dispatch(fetchResource());
84+
85+
// Load resources into table
86+
if (allowLoadIntoTable) {
87+
dispatch(loadResourceIntoTable());
88+
}
89+
};
90+
loadResource();
91+
92+
// Fetch resources every minute
93+
const fetchResourceInterval = setInterval(loadResource, 5000);
94+
95+
return () => {
96+
allowLoadIntoTable = false;
97+
clearInterval(fetchResourceInterval);
98+
};
99+
// eslint-disable-next-line react-hooks/exhaustive-deps
100+
}, [location.hash]);
101+
65102
const forceDeselectAll = () => {
66103
dispatch(changeAllSelected(false));
67104
if (selectAllCheckboxRef.current?.checked) {

src/components/shared/TableFilters.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
FilterData,
1010
editFilterValue,
1111
editTextFilter,
12+
fetchFilters,
1213
removeTextFilter,
1314
resetFilterValues,
1415
} from "../../slices/tableFilterSlice";
@@ -30,6 +31,7 @@ import SearchContainer from "./SearchContainer";
3031
import { Resource } from "../../slices/tableSlice";
3132
import { HiFunnel } from "react-icons/hi2";
3233
import { LuSettings, LuX } from "react-icons/lu";
34+
import { useLocation } from "react-router";
3335

3436
/**
3537
* This component renders the table filters in the upper right corner of the table
@@ -45,6 +47,7 @@ const TableFilters = ({
4547
}) => {
4648
const { t } = useTranslation();
4749
const dispatch = useAppDispatch();
50+
const location = useLocation();
4851

4952
const filterMap = useAppSelector(state => getFilters(state, resource));
5053
const [selectedFilter, setSelectedFilter] = useState("");
@@ -63,6 +66,11 @@ const TableFilters = ({
6366

6467
const filter = filterMap.find(({ name }) => name === selectedFilter);
6568

69+
useEffect(() => {
70+
dispatch(fetchFilters(resource));
71+
// eslint-disable-next-line react-hooks/exhaustive-deps
72+
}, [location.hash]);
73+
6674
// Remove all selected filters, no filter should be "active" anymore
6775
const removeFilters = async () => {
6876
// Clear state

src/components/shared/TablePage.tsx

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import { ReactNode, useEffect } from "react";
1+
import { ReactNode } from "react";
22
import { useTranslation } from "react-i18next";
33
import TableFilters from "../shared/TableFilters";
44
import Table, { TemplateMap } from "../shared/Table";
55
import Notifications from "../shared/Notifications";
6-
import { fetchFilters } from "../../slices/tableFilterSlice";
76
import { CreateType, NavBarLink } from "../NavBar";
8-
import { AppThunk, RootState, useAppDispatch, useAppSelector } from "../../store";
9-
import { resetTableProperties, Resource } from "../../slices/tableSlice";
7+
import { AppThunk, RootState, useAppSelector } from "../../store";
8+
import { Resource } from "../../slices/tableSlice";
109
import { AsyncThunk } from "@reduxjs/toolkit";
1110
import { ParseKeys } from "i18next";
12-
import { useLocation } from "react-router";
1311
import MainPage from "./MainPage";
1412

1513
/**
@@ -39,43 +37,9 @@ const TablePage = ({
3937
children?: ReactNode
4038
}) => {
4139
const { t } = useTranslation();
42-
const dispatch = useAppDispatch();
43-
44-
const location = useLocation();
4540

4641
const numberOfRows = useAppSelector(state => getTotalResources(state));
4742

48-
useEffect(() => {
49-
// State variable for interrupting the load function
50-
let allowLoadIntoTable = true;
51-
52-
// Clear table of previous data
53-
dispatch(resetTableProperties());
54-
55-
dispatch(fetchFilters(resource));
56-
57-
// Load resource on mount
58-
const loadResource = async () => {
59-
// Fetching resources from server
60-
await dispatch(fetchResource());
61-
62-
// Load resources into table
63-
if (allowLoadIntoTable) {
64-
dispatch(loadResourceIntoTable());
65-
}
66-
};
67-
loadResource();
68-
69-
// Fetch resources every minute
70-
const fetchResourceInterval = setInterval(loadResource, 5000);
71-
72-
return () => {
73-
allowLoadIntoTable = false;
74-
clearInterval(fetchResourceInterval);
75-
};
76-
// eslint-disable-next-line react-hooks/exhaustive-deps
77-
}, [location.hash]);
78-
7943
return (
8044
<MainPage
8145
navBarLinks={navBarLinks}
@@ -100,7 +64,11 @@ const TablePage = ({
10064
<h4>{t("TABLE_SUMMARY", { numberOfRows })}</h4>
10165
</div>
10266
{/* Include table component */}
103-
<Table templateMap={templateMap} />
67+
<Table
68+
templateMap={templateMap}
69+
fetchResource={fetchResource}
70+
loadResourceIntoTable={loadResourceIntoTable}
71+
/>
10472
</MainPage>
10573
);
10674
};
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect } from "react";
2-
import { useAppDispatch, useAppSelector } from "../store";
2+
import store, { useAppDispatch } from "../store";
33
import { resetCorruptedState } from "../slices/tableFilterSlice";
44

55
/**
@@ -9,10 +9,11 @@ import { resetCorruptedState } from "../slices/tableFilterSlice";
99
*/
1010
export const useTableFilterStateValidation = () => {
1111
const dispatch = useAppDispatch();
12-
const tableFilters = useAppSelector(state => state.tableFilters);
1312

1413
useEffect(() => {
1514
// Check for corrupted state and dispatch reset action if needed
15+
const tableFilters = store.getState().tableFilters;
16+
1617
const hasCorruption =
1718
!Array.isArray(tableFilters.data) ||
1819
!Array.isArray(tableFilters.textFilter) ||
@@ -22,6 +23,5 @@ export const useTableFilterStateValidation = () => {
2223
console.warn("Detected corrupted table filter state, resetting to defaults");
2324
dispatch(resetCorruptedState());
2425
}
25-
// eslint-disable-next-line react-hooks/exhaustive-deps
26-
}, []);
26+
}, [dispatch]);
2727
};

0 commit comments

Comments
 (0)