mirror of https://gitee.com/answerdev/answer.git
feat: admin/privilege
This commit is contained in:
parent
9da53361a7
commit
fbb29a0b74
|
@ -1471,6 +1471,11 @@ ui:
|
|||
label: Allow users to change their website
|
||||
allow_update_location:
|
||||
label: Allow users to change their location
|
||||
privilege:
|
||||
title: Privileges
|
||||
level:
|
||||
label: Reputation required level
|
||||
text: Choose the reputation required for the privileges
|
||||
|
||||
form:
|
||||
optional: (optional)
|
||||
|
|
|
@ -161,9 +161,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'form',
|
||||
});
|
||||
|
||||
const { required = [], properties } = schema;
|
||||
|
||||
const { required = [], properties = {} } = schema || {};
|
||||
// check required field
|
||||
const excludes = required.filter((key) => !properties[key]);
|
||||
|
||||
|
@ -196,7 +194,6 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
useEffect(() => {
|
||||
setDefaultValueAsDomBehaviour();
|
||||
}, [formData]);
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target;
|
||||
const data = {
|
||||
|
@ -367,7 +364,9 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
useImperativeHandle(ref, () => ({
|
||||
validator,
|
||||
}));
|
||||
|
||||
if (!formData || !schema || !schema.properties) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Form noValidate onSubmit={handleSubmit}>
|
||||
{keys.map((key) => {
|
||||
|
@ -379,7 +378,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
} = properties[key];
|
||||
const { 'ui:widget': widget = 'input', 'ui:options': uiOpt } =
|
||||
uiSchema[key] || {};
|
||||
const fieldObject = formData[key];
|
||||
const fieldData = formData[key];
|
||||
const uiSimplify = widget === 'legend' || uiOpt?.simplify;
|
||||
let groupClassName: BaseUIOptions['fieldClassName'] = uiOpt?.simplify
|
||||
? 'mb-2'
|
||||
|
@ -390,6 +389,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
if (uiOpt?.fieldClassName) {
|
||||
groupClassName = uiOpt.fieldClassName;
|
||||
}
|
||||
|
||||
return (
|
||||
<Form.Group
|
||||
key={title}
|
||||
|
@ -476,7 +476,7 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
|||
) : null}
|
||||
{/* Unified handling of `Feedback` and `Text` */}
|
||||
<Form.Control.Feedback type="invalid">
|
||||
{fieldObject?.errorMsg}
|
||||
{fieldData?.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
{description ? (
|
||||
<Form.Text className="text-muted">{description}</Form.Text>
|
||||
|
|
|
@ -2,132 +2,51 @@ import { FC, FormEvent, useEffect, useState } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useToast } from '@/hooks';
|
||||
import { FormDataType } from '@/common/interface';
|
||||
import { JSONSchema, SchemaForm, UISchema, initFormData } from '@/components';
|
||||
import {
|
||||
LangsType,
|
||||
FormDataType,
|
||||
AdminSettingsInterface,
|
||||
} from '@/common/interface';
|
||||
import { interfaceStore, loggedUserInfoStore } from '@/stores';
|
||||
import { JSONSchema, SchemaForm, UISchema } from '@/components';
|
||||
import { DEFAULT_TIMEZONE, SYSTEM_AVATAR_OPTIONS } from '@/common/constants';
|
||||
import {
|
||||
updateInterfaceSetting,
|
||||
useInterfaceSetting,
|
||||
getLoggedUserInfo,
|
||||
getPrivilegeSetting,
|
||||
putPrivilegeSetting,
|
||||
AdminSettingsPrivilege,
|
||||
} from '@/services';
|
||||
import {
|
||||
setupAppLanguage,
|
||||
loadLanguageOptions,
|
||||
setupAppTimeZone,
|
||||
} from '@/utils/localize';
|
||||
import { handleFormError } from '@/utils';
|
||||
import * as Type from '@/common/interface';
|
||||
|
||||
const Interface: FC = () => {
|
||||
const Index: FC = () => {
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'admin.interface',
|
||||
keyPrefix: 'admin.privilege',
|
||||
});
|
||||
const storeInterface = interfaceStore.getState().interface;
|
||||
const Toast = useToast();
|
||||
const [langs, setLangs] = useState<LangsType[]>();
|
||||
const { data: setting } = useInterfaceSetting();
|
||||
const [privilege, setPrivilege] = useState<AdminSettingsPrivilege>();
|
||||
|
||||
const schema: JSONSchema = {
|
||||
title: t('page_title'),
|
||||
title: t('title'),
|
||||
properties: {
|
||||
language: {
|
||||
type: 'string',
|
||||
title: t('language.label'),
|
||||
description: t('language.text'),
|
||||
enum: langs?.map((lang) => lang.value),
|
||||
enumNames: langs?.map((lang) => lang.label),
|
||||
default: setting?.language || storeInterface.language,
|
||||
},
|
||||
time_zone: {
|
||||
type: 'string',
|
||||
title: t('time_zone.label'),
|
||||
description: t('time_zone.text'),
|
||||
default: setting?.time_zone || DEFAULT_TIMEZONE,
|
||||
},
|
||||
default_avatar: {
|
||||
type: 'string',
|
||||
title: t('avatar.label'),
|
||||
description: t('avatar.text'),
|
||||
enum: SYSTEM_AVATAR_OPTIONS?.map((v) => v.value),
|
||||
enumNames: SYSTEM_AVATAR_OPTIONS?.map((v) => v.label),
|
||||
level: {
|
||||
type: 'number',
|
||||
title: t('level.label'),
|
||||
description: t('level.text'),
|
||||
enum: privilege?.options.map((_) => _.level),
|
||||
enumNames: privilege?.options.map((_) => _.level_desc),
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const [formData, setFormData] = useState<FormDataType>({
|
||||
language: {
|
||||
value: setting?.language || storeInterface.language,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
time_zone: {
|
||||
value: setting?.time_zone || DEFAULT_TIMEZONE,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
default_avatar: {
|
||||
value: 'system',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
const [formData, setFormData] = useState<FormDataType>(initFormData(schema));
|
||||
|
||||
const uiSchema: UISchema = {
|
||||
language: {
|
||||
level: {
|
||||
'ui:widget': 'select',
|
||||
},
|
||||
time_zone: {
|
||||
'ui:widget': 'timezone',
|
||||
},
|
||||
default_avatar: {
|
||||
'ui:widget': 'select',
|
||||
},
|
||||
};
|
||||
const getLangs = async () => {
|
||||
const res: LangsType[] = await loadLanguageOptions(true);
|
||||
setLangs(res);
|
||||
};
|
||||
|
||||
const checkValidated = (): boolean => {
|
||||
let ret = true;
|
||||
const { language } = formData;
|
||||
const formCheckData = { ...formData };
|
||||
if (!language.value) {
|
||||
ret = false;
|
||||
formCheckData.language = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('language.msg'),
|
||||
};
|
||||
}
|
||||
setFormData({
|
||||
...formCheckData,
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
const onSubmit = (evt: FormEvent) => {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
if (checkValidated() === false) {
|
||||
return;
|
||||
}
|
||||
const reqParams: AdminSettingsInterface = {
|
||||
language: formData.language.value,
|
||||
time_zone: formData.time_zone.value,
|
||||
};
|
||||
|
||||
updateInterfaceSetting(reqParams)
|
||||
const lv = Number(formData.level.value);
|
||||
putPrivilegeSetting(lv)
|
||||
.then(() => {
|
||||
interfaceStore.getState().update(reqParams);
|
||||
setupAppLanguage();
|
||||
setupAppTimeZone();
|
||||
getLoggedUserInfo().then((info) => {
|
||||
loggedUserInfoStore.getState().update(info);
|
||||
});
|
||||
Toast.onShow({
|
||||
msg: t('update', { keyPrefix: 'toast' }),
|
||||
variant: 'success',
|
||||
|
@ -142,27 +61,25 @@ const Interface: FC = () => {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (setting) {
|
||||
const formMeta = {};
|
||||
Object.keys(setting).forEach((k) => {
|
||||
formMeta[k] = { ...formData[k], value: setting[k] };
|
||||
if (k === 'default_avatar') {
|
||||
formMeta[k].value = setting[k] || 'system';
|
||||
}
|
||||
});
|
||||
getPrivilegeSetting().then((resp) => {
|
||||
setPrivilege(resp);
|
||||
const formMeta: Type.FormDataType = {};
|
||||
formMeta.level = {
|
||||
value: resp.selected_level,
|
||||
errorMsg: '',
|
||||
isInvalid: false,
|
||||
};
|
||||
setFormData({ ...formData, ...formMeta });
|
||||
}
|
||||
}, [setting]);
|
||||
useEffect(() => {
|
||||
getLangs();
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleOnChange = (data) => {
|
||||
setFormData(data);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="mb-4">{t('page_title')}</h3>
|
||||
<h3 className="mb-4">{t('title')}</h3>
|
||||
<SchemaForm
|
||||
schema={schema}
|
||||
uiSchema={uiSchema}
|
||||
|
@ -174,4 +91,4 @@ const Interface: FC = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Interface;
|
||||
export default Index;
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
import { handleFormError } from '@/utils';
|
||||
import * as Type from '@/common/interface';
|
||||
|
||||
const Interface: FC = () => {
|
||||
const Index: FC = () => {
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'admin.settings_users',
|
||||
});
|
||||
|
@ -174,4 +174,4 @@ const Interface: FC = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Interface;
|
||||
export default Index;
|
||||
|
|
|
@ -13,6 +13,19 @@ export interface AdminSettingsUsers {
|
|||
default_avatar: string;
|
||||
}
|
||||
|
||||
interface PrivilegeLevel {
|
||||
level: number;
|
||||
level_desc: string;
|
||||
privileges: {
|
||||
label: string;
|
||||
value: number;
|
||||
}[];
|
||||
}
|
||||
export interface AdminSettingsPrivilege {
|
||||
selected_level: number;
|
||||
options: PrivilegeLevel[];
|
||||
}
|
||||
|
||||
export const useGeneralSetting = () => {
|
||||
const apiUrl = `/answer/admin/api/siteinfo/general`;
|
||||
const { data, error } = useSWR<Type.AdminSettingsGeneral, Error>(
|
||||
|
@ -144,3 +157,15 @@ export const getUsersSetting = () => {
|
|||
export const putUsersSetting = (params: AdminSettingsUsers) => {
|
||||
return request.put('/answer/admin/api/siteinfo/users', params);
|
||||
};
|
||||
|
||||
export const getPrivilegeSetting = () => {
|
||||
return request.get<AdminSettingsPrivilege>(
|
||||
'/answer/admin/api/setting/privileges',
|
||||
);
|
||||
};
|
||||
|
||||
export const putPrivilegeSetting = (level: number) => {
|
||||
return request.put('/answer/admin/api/setting/privileges', {
|
||||
level,
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue