Skip to content

Commit

Permalink
task/WI-200: User Onboarding and Administration (#1479)
Browse files Browse the repository at this point in the history
* onboarding backend

* onboarding backend adjustments; move allocations to users api

* use onboarding system_access_v3

* use SESSION_COOKIE_DOMAIN for onboarding project membership setting

* add onboarding hooks

* add setup complete and staff steps to user state; webpack onboarding

* add onboarding types

* add onboarding user layout

* do not track onboarding index.html

* onboarding fix allocations; use onboarding step; client wip

* fix immutable query data event state

* admin wip

* onboarding admin search

* fix layout

* show searchbar while table is loading

* show onboarding admin in account dropdown

* onboarding pagination

* ensure state resets on all param changes

* allow reset always

* update admin list state w/ webhooks; individual button state handling

* remove unused import

* client linting

* onboarding test

* server side formatting

* incorporate ds mydata setup in system access step

* fix error

* fix onboarding tests

* fix tests

* disconnect setupevent signal

* fix minor onboarding css

* fix admin list table height

* add orderby dropdown

* add redirects for onboarding incomplete

* fix redirect

* fix dashboard notif message

* fix project membership rt settings

* fix pagination; fix rt tag

* style staffwait actions

* update event modal log when events are processed

* fix project membership step rt queue

* fix links in rt tickets

* fix user admin action layout
  • Loading branch information
rstijerina authored Nov 6, 2024
1 parent ad767fe commit 9274579
Show file tree
Hide file tree
Showing 112 changed files with 5,496 additions and 769 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ designsafe/apps/dashboard/templates/designsafe/apps/dashboard/index.html
designsafe/apps/notifications/templates/designsafe/apps/notifications/index.html
designsafe/apps/nco/templates/designsafe/apps/nco/nco_index.html
designsafe/apps/nco/templates/designsafe/apps/nco/ttc_grants.html
designsafe/apps/onboarding/templates/designsafe/apps/onboarding/index.html

# local config files
conf/elasticsearch/logging.yml
Expand Down
1 change: 1 addition & 0 deletions client/modules/_hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './workspace';
export * from './datafiles';
export * from './systems';
export * from './notifications';
export * from './onboarding';
2 changes: 2 additions & 0 deletions client/modules/_hooks/src/onboarding/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './useOnboarding';
export * from './types';
51 changes: 51 additions & 0 deletions client/modules/_hooks/src/onboarding/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export type TSetupStepEvent = {
step: string;
username: string;
state: string;
time: string;
message: string;
data?: {
setupComplete: boolean;
} | null;
};

export type TOnboardingStep = {
step: string;
displayName: string;
description: string;
userConfirm: string;
staffApprove: string;
staffDeny: string;
state?: string | null;
events: TSetupStepEvent[];
data?: {
userlink?: {
url: string;
text: string;
};
} | null;
customStatus?: string | null;
};

export type TOnboardingUser = {
username: string;
email: string;
firstName: string;
lastName: string;
isStaff: boolean;
setupComplete: boolean;
steps: TOnboardingStep[];
};

export type TOnboardingAdminList = {
users: TOnboardingUser[];
total: number;
totalSteps: number;
};

export type TOnboardingAdminActions =
| 'staff_approve'
| 'staff_deny'
| 'user_confirm'
| 'complete'
| 'reset';
113 changes: 113 additions & 0 deletions client/modules/_hooks/src/onboarding/useOnboarding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { useQuery, useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { useSearchParams } from 'react-router-dom';
import {
TOnboardingUser,
TOnboardingAdminList,
TSetupStepEvent,
TOnboardingAdminActions,
} from './types';
import apiClient, { type TApiError } from '../apiClient';

export type TOnboardingAdminParams = {
showIncompleteOnly?: boolean;
q?: string;
limit?: number;
page?: number;
orderBy?: string;
};

type TOnboardingActionBody = {
step: string;
action: TOnboardingAdminActions;
};

type TGetOnboardingAdminListResponse = {
response: TOnboardingAdminList;
status: number;
};

type TGetOnboardingUserResponse = {
response: TOnboardingUser;
status: number;
};

type TSendOnboardingActionResponse = {
response: TSetupStepEvent;
status: number;
};

async function getOnboardingAdminList(params: TOnboardingAdminParams) {
const res = await apiClient.get<TGetOnboardingAdminListResponse>(
`api/onboarding/admin/`,
{
params,
}
);
return res.data.response;
}

async function getOnboardingUser(username: string) {
const res = await apiClient.get<TGetOnboardingUserResponse>(
`api/onboarding/user/${username}`
);
return res.data.response;
}

async function sendOnboardingAction(
body: TOnboardingActionBody,
username?: string
) {
const res = await apiClient.post<TSendOnboardingActionResponse>(
`api/onboarding/user/${username}/`,
body
);
return res.data.response;
}

const getOnboardingAdminListQuery = (queryParams: TOnboardingAdminParams) => ({
queryKey: ['onboarding', 'adminList', queryParams],
queryFn: () => getOnboardingAdminList(queryParams),
});
export function useGetOnboardingAdminList() {
const [searchParams] = useSearchParams();
const q = searchParams.get('q') || undefined;
const showIncompleteOnly = searchParams.get('showIncompleteOnly') || 'false';
const limit = searchParams.get('limit') || '20';
const page = searchParams.get('page') || '1';
const orderBy = searchParams.get('orderBy') || undefined;
return useQuery(
getOnboardingAdminListQuery({
q,
showIncompleteOnly: showIncompleteOnly === 'true',
limit: +limit,
page: +page,
orderBy,
})
);
}

const getOnboardingUserQuery = (username: string) => ({
queryKey: ['onboarding', 'user', username],
queryFn: () => getOnboardingUser(username),
});
export function useGetOnboardingUser(username: string) {
return useQuery(getOnboardingUserQuery(username));
}
export const useGetOnboardingUserSuspense = (username: string) => {
return useSuspenseQuery(getOnboardingUserQuery(username));
};

export function useSendOnboardingAction() {
return useMutation({
mutationFn: ({
body,
username,
}: {
body: TOnboardingActionBody;
username: string;
}) => {
return sendOnboardingAction(body, username);
},
onError: (err: TApiError) => err,
});
}
2 changes: 2 additions & 0 deletions client/modules/_hooks/src/useAuthenticatedUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export type TUser = {
email: string;
institution: string;
homedir: string;
isStaff: boolean;
setupComplete: boolean;
};

declare global {
Expand Down
Loading

0 comments on commit 9274579

Please sign in to comment.