Skip to content

Commit

Permalink
handle organization null in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
JeromeBu committed Dec 11, 2024
1 parent 96f7b1d commit def2f0e
Show file tree
Hide file tree
Showing 17 changed files with 270 additions and 80 deletions.
4 changes: 2 additions & 2 deletions web/src/core/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ export async function bootstrapCore(
isUserInitiallyLoggedIn,
jwtClaimByUserKey,
"user": {
"organization": "DINUM",
"email": "[email protected]",
"id": "xxxxx"
}
Expand Down Expand Up @@ -150,7 +149,8 @@ export async function bootstrapCore(
dispatch(usecases.externalDataOrigin.protectedThunks.initialize()),
dispatch(usecases.softwareCatalog.protectedThunks.initialize()),
dispatch(usecases.generalStats.protectedThunks.initialize()),
dispatch(usecases.redirect.protectedThunks.initialize())
dispatch(usecases.redirect.protectedThunks.initialize()),
dispatch(usecases.userAuthentication.protectedThunks.initialize())
]);

return { core };
Expand Down
2 changes: 1 addition & 1 deletion web/src/core/usecases/instanceForm/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace State {
| {
type: "navigated from software form";
justRegisteredSoftwareSillId: number;
userOrganization: string;
userOrganization: string | null;
}
| undefined;
step1Data:
Expand Down
3 changes: 2 additions & 1 deletion web/src/core/usecases/instanceForm/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const thunks = {
assert(oidc.isUserLoggedIn);

const user = await getUser();
const { agent } = await sillApi.getAgent({ email: user.email });

dispatch(
actions.initializationCompleted({
Expand All @@ -91,7 +92,7 @@ export const thunks = {
"type": "navigated from software form",
"justRegisteredSoftwareSillId":
software.softwareId,
"userOrganization": user.organization
"userOrganization": agent.organization
}
})
);
Expand Down
4 changes: 2 additions & 2 deletions web/src/core/usecases/softwareUserAndReferent/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export namespace State {
};

export type SoftwareUser = {
organization: string;
organization: string | null;
usecaseDescription: string;
/** NOTE: undefined if the software is not of type desktop/mobile */
os: ApiTypes.Os | undefined;
Expand All @@ -30,7 +30,7 @@ export namespace State {

export type SoftwareReferent = {
email: string;
organization: string;
organization: string | null;
isTechnicalExpert: boolean;
usecaseDescription: string;
/** NOTE: Can be not undefined only if cloud */
Expand Down
44 changes: 15 additions & 29 deletions web/src/core/usecases/userAccountManagement/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace State {
allowedEmailRegexpStr: string;
allOrganizations: string[];
organization: {
value: string;
value: string | null;
isBeingUpdated: boolean;
};
email: {
Expand All @@ -33,6 +33,17 @@ namespace State {
};
}

type UpdateFieldPayload =
| {
fieldName: "organization";
value: string;
}
| {
fieldName: "aboutAndIsPublic";
about: string;
isPublic: boolean;
};

export const { reducer, actions } = createUsecaseActions({
name,
"initialState": id<State>({
Expand All @@ -53,7 +64,7 @@ export const { reducer, actions } = createUsecaseActions({
payload: {
accountManagementUrl: string | undefined;
allowedEmailRegexpStr: string;
organization: string;
organization: string | null;
email: string;
allOrganizations: string[];
about: string;
Expand Down Expand Up @@ -95,23 +106,7 @@ export const { reducer, actions } = createUsecaseActions({
}
};
},
"updateFieldStarted": (
state,
{
payload
}: {
payload:
| {
fieldName: "organization" | "email";
value: string;
}
| {
fieldName: "aboutAndIsPublic";
about: string;
isPublic: boolean;
};
}
) => {
"updateFieldStarted": (state, { payload }: { payload: UpdateFieldPayload }) => {
assert(state.stateDescription === "ready");

if (payload.fieldName === "aboutAndIsPublic") {
Expand All @@ -129,16 +124,7 @@ export const { reducer, actions } = createUsecaseActions({
"isBeingUpdated": true
};
},
"updateFieldCompleted": (
state,
{
payload
}: {
payload: {
fieldName: "organization" | "email" | "aboutAndIsPublic";
};
}
) => {
"updateFieldCompleted": (state, { payload }: { payload: UpdateFieldPayload }) => {
const { fieldName } = payload;

assert(state.stateDescription === "ready");
Expand Down
10 changes: 5 additions & 5 deletions web/src/core/usecases/userAccountManagement/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@ export const thunks = {
{ keycloakParams },
allowedEmailRegexpStr,
allOrganizations,
{
agent: { about = "", isPublic }
}
{ agent }
] = await Promise.all([
sillApi.getOidcParams(),
sillApi.getAllowedEmailRegexp(),
sillApi.getAllOrganizations(),
sillApi.getAgent({ "email": user.email })
]);

const { about = "", isPublic, organization } = agent;

dispatch(
actions.initialized({
allowedEmailRegexpStr,
"email": user.email,
"organization": user.organization,
"organization": organization,
"accountManagementUrl":
keycloakParams === undefined
? undefined
Expand Down Expand Up @@ -101,7 +101,7 @@ export const thunks = {
}
}

dispatch(actions.updateFieldCompleted({ "fieldName": params.fieldName }));
dispatch(actions.updateFieldCompleted(params));
},
"getAccountManagementUrl":
() =>
Expand Down
1 change: 1 addition & 0 deletions web/src/core/usecases/userAuthentication/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./state";
export * from "./thunks";
export * from "./selectors";
9 changes: 9 additions & 0 deletions web/src/core/usecases/userAuthentication/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { State as RootState } from "core/bootstrap";
import { name } from "./state";

const currentAgent = (rootState: RootState) => {
const state = rootState[name];
return { currentAgent: state.currentAgent };
};

export const selectors = { currentAgent };
65 changes: 64 additions & 1 deletion web/src/core/usecases/userAuthentication/state.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
import { Agent } from "api/dist/src/lib/ApiTypes";
import { createUsecaseActions } from "redux-clean-architecture";
import { assert } from "tsafe/assert";
import { id } from "tsafe/id";
import { actions as usersAccountManagementActions } from "../userAccountManagement";

export const name = "userAuthentication";

export const reducer = null;
export type State = State.NotInitialized | State.Ready;

export namespace State {
export type NotInitialized = {
stateDescription: "not initialized";
isInitializing: boolean;
currentAgent: null;
};

export type Ready = {
stateDescription: "ready";
currentAgent: Agent | null;
};
}

export const { reducer, actions } = createUsecaseActions({
name,
"initialState": id<State>({
"stateDescription": "not initialized",
"currentAgent": null,
"isInitializing": false
}),
"reducers": {
"initializationStarted": state => {
assert(state.stateDescription === "not initialized");
},
"initialized": (_, action: { payload: { agent: Agent | null } }) => ({
stateDescription: "ready",
currentAgent: action.payload.agent
})
},
extraReducers: builder => {
builder.addCase(
usersAccountManagementActions.updateFieldCompleted,
(state, action) => {
if (!state.currentAgent) return state;
if (action.payload.fieldName === "organization") {
return {
...state,
currentAgent: {
...state.currentAgent,
organization: action.payload.value
}
};
}

return {
...state,
currentAgent: {
...state.currentAgent,
about: action.payload.about,
isPublic: action.payload.isPublic
}
};
}
);
}
});
18 changes: 17 additions & 1 deletion web/src/core/usecases/userAuthentication/thunks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import type { Thunks } from "core/bootstrap";
import { assert } from "tsafe/assert";
import { name, actions } from "./state";

export const protectedThunks = {
initialize:
() =>
async (dispatch, getState, { sillApi, oidc, getUser }) => {
console.log("OIDC : is user logged in ?", oidc.isUserLoggedIn);
if (!oidc.isUserLoggedIn) return;
const state = getState()[name];
if (state.stateDescription === "ready" || state.isInitializing) return;
dispatch(actions.initializationStarted());
const user = await getUser();
const { agent } = await sillApi.getAgent({ "email": user.email });
dispatch(actions.initialized({ agent }));
}
} satisfies Thunks;

export const thunks = {
"getIsUserLoggedIn":
() =>
(...args): boolean => {
const [, , { oidc }] = args;

return oidc.isUserLoggedIn;
},
"login":
Expand All @@ -16,6 +31,7 @@ export const thunks = {

const [, , { oidc }] = args;

console.log("asesrting user not logged : ", oidc.isUserLoggedIn);
assert(!oidc.isUserLoggedIn);

return oidc.login({ doesCurrentHrefRequiresAuth });
Expand Down
4 changes: 2 additions & 2 deletions web/src/core/usecases/userProfile/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export namespace State {
export type Ready = {
stateDescription: "ready";
email: string;
organization: string;
organization: string | null;
about: string | undefined;
isHimself: boolean;
declarations: ApiTypes.Agent["declarations"];
Expand All @@ -40,7 +40,7 @@ export const { reducer, actions } = createUsecaseActions({
}: {
payload: {
email: string;
organization: string;
organization: string | null;
about: string | undefined;
isHimself: boolean;
declarations: ApiTypes.Agent["declarations"];
Expand Down
22 changes: 14 additions & 8 deletions web/src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useRoute } from "ui/routes";
import { Header } from "ui/shared/Header";
import { Footer } from "ui/shared/Footer";
import { declareComponentKeys } from "i18nifty";
import { useCore } from "core";
import { useCore, useCoreState } from "core";
import { RouteProvider } from "ui/routes";
import { evtLang } from "ui/i18n";
import { createCoreProvider } from "core";
Expand All @@ -17,6 +17,7 @@ import { keyframes } from "tss-react";
import { LoadingFallback, loadingFallbackClassName } from "ui/shared/LoadingFallback";
import { useDomRect } from "powerhooks/useDomRect";
import { apiUrl, appUrl, appPath } from "urls";
import { PromptForOrganization } from "./shared/PromptForOrganization";

const { CoreProvider } = createCoreProvider({
apiUrl,
Expand Down Expand Up @@ -69,6 +70,7 @@ function ContextualizedApp() {
const route = useRoute();

const { userAuthentication, sillApiVersion } = useCore().functions;
const { currentAgent } = useCoreState("userAuthentication", "currentAgent");

const headerUserAuthenticationApi = useConst(() =>
userAuthentication.getIsUserLoggedIn()
Expand Down Expand Up @@ -116,6 +118,10 @@ function ContextualizedApp() {
return <LoadingFallback />;
}

if (currentAgent && !currentAgent.organization) {
return <PromptForOrganization firstTime={true} />;
}

return (
<page.LazyComponent
route={route}
Expand Down Expand Up @@ -158,13 +164,13 @@ const useStyles = tss
},
"page": {
"animation": `${keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`} 400ms`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`} 400ms`
}
}));

Expand Down
Loading

0 comments on commit def2f0e

Please sign in to comment.