Skip to content

Commit 58fb417

Browse files
committed
Merge branch 'main' into seperate-user-and-non-user-roles
2 parents 3041e64 + 099b37e commit 58fb417

15 files changed

Lines changed: 157 additions & 88 deletions

File tree

src/App.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Acls from "./components/users/Acls";
1515
import About from "./components/About";
1616
import { useAppDispatch } from "./store";
1717
import { fetchOcVersion, fetchUserInfo } from "./slices/userInfoSlice";
18+
import { subscribeToAuthEvents } from "./utils/broadcastSync";
1819

1920
function App() {
2021
const dispatch = useAppDispatch();
@@ -24,6 +25,9 @@ function App() {
2425
// Load information about current opencast version on mount
2526
dispatch(fetchOcVersion());
2627

28+
// Subscribe to the auth event to follow the login - logout events!
29+
subscribeToAuthEvents();
30+
2731
// Add event listener for back button to check if we are still logged in
2832
window.addEventListener("popstate", function (event) {
2933
dispatch(fetchUserInfo());

src/components/Header.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,14 @@ import { HiTranslate } from "react-icons/hi";
2424
import { IconContext } from "react-icons";
2525
import ButtonLikeAnchor from "./shared/ButtonLikeAnchor";
2626
import { ModalHandle } from "./shared/modals/Modal";
27+
import { broadcastLogout } from "../utils/broadcastSync";
2728

2829
// References for detecting a click outside of the container of the dropdown menus
2930
const containerLang = React.createRef<HTMLDivElement>();
3031
const containerHelp = React.createRef<HTMLDivElement>();
3132
const containerUser = React.createRef<HTMLDivElement>();
3233
const containerNotify = React.createRef<HTMLDivElement>();
3334

34-
function logout() {
35-
window.location.href = "/j_spring_security_logout";
36-
}
37-
3835
/**
3936
* Component that renders the header and the navigation in the upper right corner.
4037
*/
@@ -417,6 +414,12 @@ const MenuHelp = ({
417414

418415
const MenuUser = () => {
419416
const { t } = useTranslation();
417+
418+
const logout = () => {
419+
// Here we broadcast logout, in order to redirect other tabs to login page!
420+
broadcastLogout();
421+
window.location.href = "/j_spring_security_logout";
422+
}
420423
return (
421424
<ul className="dropdown-ul">
422425
<li>

src/components/events/partials/ModalTabsAndPages/SeriesDetailsThemeTab.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { updateSeriesTheme } from "../../../../slices/seriesDetailsSlice";
1111
import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons";
1212
import ModalContentTable from "../../../shared/modals/ModalContentTable";
1313

14+
type SeriesTheme = { id: string; value: string; };
15+
1416
/**
1517
* This component renders the tab for editing the theme of a certain series
1618
*/
@@ -19,23 +21,20 @@ const SeriesDetailsThemeTab = ({
1921
themeNames,
2022
seriesId,
2123
}: {
22-
theme: string,
23-
themeNames: {
24-
id: string;
25-
value: string;
26-
}[],
24+
theme: SeriesTheme | null,
25+
themeNames: SeriesTheme[],
2726
seriesId: string
2827
}) => {
2928
const { t } = useTranslation();
3029
const dispatch = useAppDispatch();
3130

3231
const user = useAppSelector(state => getUserInformation(state));
3332

34-
const handleSubmit = (values: { theme: string }) => {
33+
const handleSubmit = (values: { theme: SeriesTheme | null }) => {
3534
dispatch(updateSeriesTheme({id: seriesId, values: values}));
3635
};
3736

38-
const checkValidity = (formik: FormikProps<{theme: string }>) => {
37+
const checkValidity = (formik: FormikProps<{theme: SeriesTheme | null }>) => {
3938
if (formik.dirty && formik.isValid) {
4039
// check if user provided values differ from initial ones
4140
return !_.isEqual(formik.values, formik.initialValues);
@@ -64,13 +63,13 @@ const SeriesDetailsThemeTab = ({
6463
{themeNames.length > 0 && (
6564
<div className="editable">
6665
<DropDown
67-
value={formik.values.theme}
68-
text={formik.values.theme}
66+
value={formik.values.theme?.id}
67+
text={formik.values.theme?.value || ''}
6968
options={themeNames.map(names => ({ label: names.value, value: names.id }))}
7069
required={false}
7170
handleChange={(element) => {
7271
if (element) {
73-
formik.setFieldValue("theme", element.value)
72+
formik.setFieldValue("theme", {id: element.value, value: element.label})
7473
}
7574
}}
7675
placeholder={t("EVENTS.SERIES.NEW.THEME.LABEL")}

src/components/shared/Table.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const Table = ({
8686
// State of dropdown menu
8787
const [showPageSizes, setShowPageSizes] = useState(false);
8888
const editTableViewModalRef = useRef<ModalHandle>(null);
89+
const selectAllCheckboxRef = useRef<HTMLInputElement>(null);
8990

9091
useEffect(() => {
9192
// Function for handling clicks outside of an open dropdown menu
@@ -128,6 +129,8 @@ const Table = ({
128129
};
129130

130131
const sortByColumn = (colName: string) => {
132+
// By sorting, any selected item has to be deselected!
133+
forceDeselectAll();
131134
dispatch(setSortBy(colName));
132135
let direction: ReverseOptions = "ASC";
133136
if (reverse && reverse === "ASC") {
@@ -137,6 +140,13 @@ const Table = ({
137140
dispatch(updatePages());
138141
};
139142

143+
const forceDeselectAll = () => {
144+
dispatch(changeAllSelected(false));
145+
if (selectAllCheckboxRef.current?.checked) {
146+
selectAllCheckboxRef.current.checked = false;
147+
}
148+
}
149+
140150
const showEditTableViewModal = async () => {
141151
editTableViewModalRef.current?.open()
142152
};
@@ -186,6 +196,7 @@ const Table = ({
186196
<th className="small">
187197
{/*Checkbox to select all rows*/}
188198
<input
199+
ref={selectAllCheckboxRef}
189200
type="checkbox"
190201
onChange={(e) => onChangeAllSelected(e)}
191202
aria-label={t("EVENTS.EVENTS.TABLE.SELECT_ALL")}

src/components/shared/wizard/SelectContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ const SelectContainer = ({
264264
onChange={(e) => handleChangeRemove(e)}
265265
value={markedForRemoval}
266266
>
267-
{/* @ts-expect-error TS(7006): Parameter 'item' implicitly has an 'any' type. */}
267+
{/* @ts-expect-error TS(7006): Parameter 'item' implicitly has an 'any' type. */}
268268
{selectedItems.map((item, key) => (
269269
<option key={key} value={item.name}>
270270
{item.name}

src/components/users/partials/modal/AclDetails.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const AclDetails = ({
8888
{/* Navigation buttons and validation */}
8989
<WizardNavigationButtons
9090
formik={formik}
91+
previousPage={close}
9192
submitPage={
9293
async () => {
9394
if (await dispatch(checkAcls(formik.values.policies))) {

src/components/users/partials/modal/GroupDetails.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const GroupDetails: React.FC<{
8787
{/* Navigation buttons and validation */}
8888
<WizardNavigationButtons
8989
formik={formik}
90+
previousPage={close}
9091
createTranslationString="SUBMIT"
9192
cancelTranslationString="CANCEL"
9293
isLast

src/components/users/partials/modal/UserDetails.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { useAppDispatch, useAppSelector } from "../../../../store";
1010
import { UpdateUser, updateUserDetails } from "../../../../slices/userDetailsSlice";
1111
import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons";
1212
import { ParseKeys } from "i18next";
13+
import { UserRole } from "../../../../slices/userSlice";
14+
import { SerializedError } from "@reduxjs/toolkit";
1315

1416
/**
1517
* This component manages the pages of the user details
@@ -24,9 +26,11 @@ const UserDetails: React.FC<{
2426
const [page, setPage] = useState(0);
2527

2628
const userDetails = useAppSelector(state => getUserDetails(state));
29+
const assignedRoles = userDetails.roles.filter(role => role.type === "GROUP" || role.type === "INTERNAL");
2730

2831
const initialValues = {
2932
...userDetails,
33+
assignedRoles,
3034
password: "",
3135
passwordConfirmation: "",
3236
};
@@ -58,8 +62,23 @@ const UserDetails: React.FC<{
5862
setPage(tabNr);
5963
};
6064

61-
const handleSubmit = (values: UpdateUser) => {
62-
dispatch(updateUserDetails({values: values, username: userDetails.username}));
65+
const handleSubmit = (values: {
66+
username: string,
67+
name?: string,
68+
email?: string,
69+
password?: string,
70+
roles?: UserRole[],
71+
assignedRoles?: UserRole[],
72+
}) => {
73+
const newValues: UpdateUser = {
74+
username: values.username,
75+
name: values.name,
76+
email: values.email,
77+
password: values.password,
78+
roles: values.assignedRoles,
79+
};
80+
81+
dispatch(updateUserDetails({values: newValues, username: userDetails.username}));
6382
close();
6483
};
6584

@@ -84,6 +103,7 @@ const UserDetails: React.FC<{
84103
{page !== 2 && (
85104
<WizardNavigationButtons
86105
formik={formik}
106+
previousPage={close}
87107
createTranslationString="SUBMIT"
88108
cancelTranslationString="CANCEL"
89109
isLast

src/components/users/partials/wizard/NewUserWizard.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import UserRolesTab from "./UserRolesTab";
77
import { initialFormValuesNewUser } from "../../../../configs/modalConfig";
88
import { getUsernames } from "../../../../selectors/userSelectors";
99
import { NewUserSchema } from "../../../../utils/validate";
10-
import { NewUser, postNewUser } from "../../../../slices/userSlice";
10+
import { NewUser, postNewUser, UserRole } from "../../../../slices/userSlice";
1111
import { useAppDispatch, useAppSelector } from "../../../../store";
1212
import ButtonLikeAnchor from "../../../shared/ButtonLikeAnchor";
1313
import WizardNavigationButtons from "../../../shared/wizard/WizardNavigationButtons";
14+
import { Role } from "../../../../slices/aclSlice";
1415

1516
/**
1617
* This component renders the new user wizard
@@ -37,8 +38,22 @@ const NewUserWizard = ({
3738
setTab(tabNr);
3839
};
3940

40-
const handleSubmit = (values: NewUser) => {
41-
const response = dispatch(postNewUser(values));
41+
const handleSubmit = (values: {
42+
username: string,
43+
name: string,
44+
email: string,
45+
password: string,
46+
roles: Role[],
47+
assignedRoles: UserRole[],
48+
}) => {
49+
const newValues: NewUser = {
50+
username: values.username,
51+
name: values.name,
52+
email: values.email,
53+
password: values.password,
54+
roles: values.assignedRoles,
55+
}
56+
const response = dispatch(postNewUser(newValues));
4257
console.info(response);
4358
close();
4459
};

src/components/users/partials/wizard/UserRolesTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const UserRolesTab = <T extends RequiredFormProps>({
5454
label: "USERS.USERS.DETAILS.ROLES",
5555
items: roles,
5656
}}
57-
formikField="roles"
57+
formikField="assignedRoles"
5858
manageable={formik.values.manageable}
5959
/>
6060
)}

0 commit comments

Comments
 (0)