Skip to content

Show registration modal only when unregistered#1600

Open
gregorydlogan wants to merge 8 commits into
opencast:r/19.xfrom
gregorydlogan:t/registration-modal
Open

Show registration modal only when unregistered#1600
gregorydlogan wants to merge 8 commits into
opencast:r/19.xfrom
gregorydlogan:t/registration-modal

Conversation

@gregorydlogan

@gregorydlogan gregorydlogan commented May 4, 2026

Copy link
Copy Markdown
Member

This PR only shows the registraiton modal when the adopter has not already registered.

This PR contains a few extra bits that haven't been turned on yet - notably the warning bell stuff for when the core can't reach the registration server.

This PR now uses the bell if the user is not registered. Notably:
If you haven't registered at all:
Pasted image
If you have registered, but haven't agreed to the latest ToU:
Pasted image (2)

Clicking on either of these notices opens the registration modal.

TODOs:

  • Make the new strings into translatable strings rather than hardcoding them.
  • In the case of an out of date ToU, uncheck the agreed-to-ToU checkbox when presenting the registration modal, and highlight what's wrong.
  • In the case of an out of date ToU, launch the registration modal to the input pane, not the general info pane.

Fixed #1516

@gregorydlogan gregorydlogan added the type:bug Something isn't working label May 4, 2026
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Use docker or podman to test this pull request locally.

Run test server using develop.opencast.org as backend:

podman run --rm -it -p 127.0.0.1:3000:3000 ghcr.io/opencast/admin-interface:pr-1600

Specify a different backend like stable.opencast.org:

podman run --rm -it -p 127.0.0.1:3000:3000 -e PROXY_TARGET=https://stable.opencast.org ghcr.io/opencast/admin-interface:pr-1600

It may take a few seconds for the interface to spin up.
It will then be available at http://127.0.0.1:3000.
For more options you can pass on to the proxy, take a look at the README.md.

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

This pull request is deployed at test.admin-interface.opencast.org/1600/2026-05-11_21-10-31/ .
It might take a few minutes for it to become available.

Comment thread src/components/Header.tsx Outdated
Comment thread src/components/Header.tsx Outdated
Comment on lines +70 to +72
if (registration == null) {
dispatch(fetchRegistration());
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will dispatch a redux action (and thus a fetch request) every time the component rerenders and registration is still null. This could potentially cause multiple fetch requests. To avoid this, we usually use a useEffect that only runs once on component mount for fetch requests. (see the useEffect in e.g. SeriesDetails.tsx).

If you need to monitor the state of the action, you would usually add a variable to the redux state that tracks the action state (LOADING, SUCCEEDED, FAILED what have you). Then track the action state in your component via a selector and use a useEffect to respond properly.

And if you don't actually need all that redux boilerplate, you could also do the fetch requesting and state tracking here with useEffect and useState.

Comment thread src/slices/registrationSlice.ts
@gregorydlogan gregorydlogan force-pushed the t/registration-modal branch from 75e3a11 to 298d1a8 Compare June 10, 2026 22:15
@gregorydlogan

Copy link
Copy Markdown
Member Author

Now that the GHA issues are done, I made a final change and I think this is ready for re-review @Arnei

Comment on lines +164 to +166
.wide-text{
padding-right: 5px;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.wide-text{
padding-right: 5px;
}
.wide-text{
padding-right: 5px;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're using 2 spaces, but the file uses 4.

Comment thread src/components/Header.tsx
Comment on lines 157 to +173
useEffect(() => {
if (!user) { return; }

const isAdmin = user.isAdmin || user.isOrgAdmin;
const isLocalhost = window.location.hostname === "localhost";
const lastDismissed = localStorage.getItem("adopterModalDismissed");
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
const dismissedLongEnough = !lastDismissed || Date.now() - parseInt(lastDismissed) > THIRTY_DAYS;

if (isAdmin && !isLocalhost && dismissedLongEnough) {
showRegistrationModal();
}
}, [user]);
dispatch(fetchRegistration());
dispatch(fetchLatestToU());
dispatch(fetchIsUpToDate());

if (!user) { return; }

const isAdmin = user.isAdmin || user.isOrgAdmin;
const isLocalhost = window.location.hostname === "localhost";
const lastDismissed = localStorage.getItem("adopterModalDismissed");
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
const dismissedLongEnough = !lastDismissed || Date.now() - parseInt(lastDismissed) > THIRTY_DAYS;

if (isAdmin && !isLocalhost && dismissedLongEnough && registration == null) {
showRegistrationModal();
}
}, [user, registration, dispatch]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can cause an infinite loop. dispatch(fetchRegistration()); will eventually update registration, which triggers a rerun of the useEffect hook, which causes dispatch(fetchRegistration()); to be run again...

I recommend putting the dispatch(fetch....'s into their own useEffect hook that runs only once on mount. If you need to run them again, you should probably do so conditionally?

Comment thread src/components/Header.tsx
)}
</li>
))}
{!registering &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not using tab indentation here

Comment thread src/components/Header.tsx
onClick={() => showAdoptersRegistrationModal()}
>
<span className="wide-text">Registration</span>
<span className="multi-value multi-value-yellow">Unregistered</span>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multi-value-yellow does not seem to exist (maybe I removed it in my cleaning frenzy?).

Comment thread src/components/Header.tsx
<ButtonLikeAnchor
onClick={() => showAdoptersRegistrationModal()}
>
<span className="wide-text">Registration</span>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untranslated strings.

@@ -0,0 +1,110 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent use of spaces and tabs in this file.

// These are used for thunks
extraReducers: builder => {
builder
/* .addCase(fetchRegistration.pending, state => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover code?

error: boolean
};

type Temp = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temp is not a great type name ^^

export type RegistrationState = {
registration: Registration | null,
latestToU: string,
isRegistering: boolean,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like isRegistering is a bit confusingly named? This is not about being in the process of registering, is it? Maybe canRegister would be clearer?

name: "registration",
initialState,
reducers: {
setError(state, action: PayloadAction<{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see setError nor error being used anywhere. Leftover code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants