Merge remote-tracking branch 'github/feat/1.1.2/ui' into feat/1.1.2/user-center

This commit is contained in:
LinkinStars 2023-04-17 11:08:54 +08:00
commit 2bd0ef8a24
7 changed files with 112 additions and 26 deletions

View File

@ -1432,6 +1432,13 @@ ui:
title: Membership
label: Allow new registrations
text: Turn off to prevent anyone from creating a new account.
email_registration:
title: Email registration
label: Allow email registration
text: Turn off to prevent anyone creating new account through email.
allowed_email_domains:
title: Allowed email domains
text: Email domains that users must register accounts with. One domain per line. Ignored when empty.
private:
title: Private
label: Login required

View File

@ -390,6 +390,8 @@ export interface AdminSettingsCustom {
export interface AdminSettingsLogin {
allow_new_registrations: boolean;
login_required: boolean;
allow_email_registrations: boolean;
allow_email_domains: string[];
}
/**

View File

@ -22,6 +22,17 @@ const Index: FC = () => {
description: t('membership.text'),
default: false,
},
allow_email_registrations: {
type: 'boolean',
title: t('email_registration.title'),
description: t('email_registration.text'),
default: true,
},
allow_email_domains: {
type: 'string',
title: t('allowed_email_domains.title'),
description: t('allowed_email_domains.text'),
},
login_required: {
type: 'boolean',
title: t('private.title'),
@ -37,6 +48,15 @@ const Index: FC = () => {
label: t('membership.label'),
},
},
allow_email_registrations: {
'ui:widget': 'switch',
'ui:options': {
label: t('email_registration.label'),
},
},
allow_email_domains: {
'ui:widget': 'textarea',
},
login_required: {
'ui:widget': 'switch',
'ui:options': {
@ -51,8 +71,20 @@ const Index: FC = () => {
evt.preventDefault();
evt.stopPropagation();
const allowedEmailDomains: string[] = [];
if (formData.allow_email_domains.value) {
const domainList = formData.allow_email_domains.value.split('\n');
domainList.forEach((li) => {
li = li.trim();
if (li) {
allowedEmailDomains.push(li);
}
});
}
const reqParams: Type.AdminSettingsLogin = {
allow_new_registrations: formData.allow_new_registrations.value,
allow_email_registrations: formData.allow_email_registrations.value,
allow_email_domains: allowedEmailDomains,
login_required: formData.login_required.value,
};
@ -78,6 +110,13 @@ const Index: FC = () => {
const formMeta = { ...formData };
formMeta.allow_new_registrations.value =
setting.allow_new_registrations;
formMeta.allow_email_registrations.value =
setting.allow_email_registrations;
formMeta.allow_email_domains.value = '';
if (Array.isArray(setting.allow_email_domains)) {
formMeta.allow_email_domains.value =
setting.allow_email_domains.join('\n');
}
formMeta.login_required.value = setting.login_required;
setFormData({ ...formMeta });
}

View File

@ -1,4 +1,4 @@
import { FC } from 'react';
import { FC, useEffect, useState } from 'react';
import { Form, Table, Dropdown, Button, Stack } from 'react-bootstrap';
import { useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
@ -21,7 +21,13 @@ import {
useChangePasswordModal,
useToast,
} from '@/hooks';
import { useQueryUsers, addUser, updateUserPassword } from '@/services';
import {
useQueryUsers,
addUser,
updateUserPassword,
getAdminUcAgent,
AdminUcAgent,
} from '@/services';
import { loggedUserInfoStore, userCenterStore } from '@/stores';
import { formatCount } from '@/utils';
@ -50,6 +56,9 @@ const Users: FC = () => {
const curQuery = urlSearchParams.get('query') || '';
const currentUser = loggedUserInfoStore((state) => state.user);
const { agent: ucAgent } = userCenterStore();
const [adminUcAgent, setAdminUcAgent] = useState<AdminUcAgent>({
user_status_agent_enabled: false,
});
const Toast = useToast();
const {
data,
@ -139,6 +148,13 @@ const Users: FC = () => {
urlSearchParams.delete('page');
setUrlSearchParams(urlSearchParams);
};
useEffect(() => {
if (ucAgent?.enabled) {
getAdminUcAgent().then((resp) => {
setAdminUcAgent(resp);
});
}
}, [ucAgent]);
return (
<>
<h3 className="mb-4">{t('title')}</h3>
@ -248,7 +264,8 @@ const Users: FC = () => {
{t('set_new_password')}
</Dropdown.Item>
) : null}
{!ucAgent?.enabled ? (
{!ucAgent?.enabled ||
!adminUcAgent.user_status_agent_enabled ? (
<Dropdown.Item
onClick={() => handleAction('status', user)}>
{t('change_status')}

View File

@ -1,4 +1,4 @@
import { FC, ReactNode, useEffect } from 'react';
import { FC, ReactNode, useEffect, useState } from 'react';
import { useLocation, useNavigate, useLoaderData } from 'react-router-dom';
import { floppyNavigation } from '@/utils';
@ -15,37 +15,49 @@ const RouteGuard: FC<{
const navigate = useNavigate();
const location = useLocation();
const loaderData = useLoaderData();
const gr = onEnter({
loaderData,
path,
page,
});
const [grOk, setGrOk] = useState(true);
const [routeError, setRouteError] = useState<{
code: string;
msg: string;
}>();
const applyGuard = () => {
if (typeof onEnter !== 'function') {
return;
}
const gr = onEnter({
loaderData,
path,
page,
});
let guardError;
const errCode = gr.error?.code;
if (errCode === '403' || errCode === '404' || errCode === '50X') {
guardError = {
code: errCode,
msg: gr.error?.msg,
};
}
const handleGuardRedirect = () => {
const redirectUrl = gr.redirect;
if (redirectUrl) {
floppyNavigation.navigate(redirectUrl, {
setGrOk(gr.ok);
if (gr.error?.code && /403|404|50X/i.test(gr.error.code.toString())) {
setRouteError({
code: `${gr.error.code}`,
msg: gr.error.msg || '',
});
return;
}
if (gr.redirect) {
floppyNavigation.navigate(gr.redirect, {
handler: navigate,
options: { replace: true },
});
}
};
useEffect(() => {
handleGuardRedirect();
/**
* NOTICE:
* Must be put in `useEffect`,
* otherwise `guard` may not get `loggedUserInfo` correctly
*/
applyGuard();
}, [location]);
return (
<>
{gr.ok ? children : null}
{!gr.ok && guardError ? (
<RouteErrorBoundary errCode={guardError.code} />
{grOk ? children : null}
{!grOk && routeError ? (
<RouteErrorBoundary errCode={routeError.code} />
) : null}
</>
);

View File

@ -37,11 +37,18 @@ export interface UcBranding {
personal_branding: UcBrandingEntry[];
}
export interface AdminUcAgent {
user_status_agent_enabled: boolean;
}
export const getUcAgent = () => {
const apiUrl = `/answer/api/v1/user-center/agent`;
return request.get<UcAgent>(apiUrl);
};
export const getAdminUcAgent = () => {
const apiUrl = `/answer/admin/api/user-center/agent`;
return request.get<AdminUcAgent>(apiUrl);
};
export const getUcSettings = () => {
const apiUrl = `/answer/api/v1/user-center/user/settings`;
return request.get<UcSettings>(apiUrl);

View File

@ -11,6 +11,8 @@ const loginSetting = create<IType>((set) => ({
login: {
allow_new_registrations: true,
login_required: false,
allow_email_registrations: true,
allow_email_domains: [],
},
update: (params) =>
set(() => {