mirror of https://gitee.com/answerdev/answer.git
feat(ui): Add plugin configuration
This commit is contained in:
parent
b8cfde0425
commit
152d8d2f68
|
@ -1379,6 +1379,7 @@ ui:
|
||||||
status: Status
|
status: Status
|
||||||
action: Action
|
action: Action
|
||||||
deactivate: Deactivate
|
deactivate: Deactivate
|
||||||
|
activate: Activate
|
||||||
settings: Settings
|
settings: Settings
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { UIOptions, UIWidget } from '@/components/SchemaForm';
|
||||||
|
|
||||||
export interface FormValue<T = any> {
|
export interface FormValue<T = any> {
|
||||||
value: T;
|
value: T;
|
||||||
isInvalid: boolean;
|
isInvalid: boolean;
|
||||||
|
@ -537,3 +539,24 @@ export interface UserOauthConnectorItem extends OauthConnectorItem {
|
||||||
binding: boolean;
|
binding: boolean;
|
||||||
external_id: string;
|
external_id: string;
|
||||||
}
|
}
|
||||||
|
export interface PluginOption {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PluginItem {
|
||||||
|
name: string;
|
||||||
|
type: UIWidget;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
uiOptions?: UIOptions;
|
||||||
|
option?: PluginOption[];
|
||||||
|
value?: string;
|
||||||
|
required?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PluginConfig {
|
||||||
|
name: string;
|
||||||
|
slug_name: string;
|
||||||
|
config_fields: PluginItem[];
|
||||||
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ function MenuNode({
|
||||||
'text-nowrap d-flex flex-nowrap align-items-center w-100',
|
'text-nowrap d-flex flex-nowrap align-items-center w-100',
|
||||||
{ expanding, 'link-dark': activeKey !== menu.name },
|
{ expanding, 'link-dark': activeKey !== menu.name },
|
||||||
)}>
|
)}>
|
||||||
<span className="me-auto">{t(menu.name)}</span>
|
<span className="me-auto">
|
||||||
|
{menu.displayName ? menu.displayName : t(menu.name)}
|
||||||
|
</span>
|
||||||
{menu.badgeContent ? (
|
{menu.badgeContent ? (
|
||||||
<span className="badge text-bg-dark">{menu.badgeContent}</span>
|
<span className="badge text-bg-dark">{menu.badgeContent}</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -28,18 +28,8 @@ export interface JSONSchema {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export interface UISchema {
|
|
||||||
[key: string]: {
|
export interface UIOptions {
|
||||||
'ui:widget'?:
|
|
||||||
| 'textarea'
|
|
||||||
| 'text'
|
|
||||||
| 'checkbox'
|
|
||||||
| 'radio'
|
|
||||||
| 'select'
|
|
||||||
| 'upload'
|
|
||||||
| 'timezone'
|
|
||||||
| 'switch';
|
|
||||||
'ui:options'?: {
|
|
||||||
rows?: number;
|
rows?: number;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
type?:
|
type?:
|
||||||
|
@ -66,7 +56,20 @@ export interface UISchema {
|
||||||
textRender?: () => React.ReactElement;
|
textRender?: () => React.ReactElement;
|
||||||
imageType?: Type.UploadType;
|
imageType?: Type.UploadType;
|
||||||
acceptType?: string;
|
acceptType?: string;
|
||||||
};
|
}
|
||||||
|
export type UIWidget =
|
||||||
|
| 'textarea'
|
||||||
|
| 'text'
|
||||||
|
| 'checkbox'
|
||||||
|
| 'radio'
|
||||||
|
| 'select'
|
||||||
|
| 'upload'
|
||||||
|
| 'timezone'
|
||||||
|
| 'switch';
|
||||||
|
export interface UISchema {
|
||||||
|
[key: string]: {
|
||||||
|
'ui:widget'?: UIWidget;
|
||||||
|
'ui:options'?: UIOptions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +312,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
<Form.Select
|
<Form.Select
|
||||||
aria-label={description}
|
aria-label={description}
|
||||||
name={key}
|
name={key}
|
||||||
value={formData[key]?.value || defaultValue}
|
value={
|
||||||
|
formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
onChange={handleSelectChange}
|
onChange={handleSelectChange}
|
||||||
isInvalid={formData[key].isInvalid}>
|
isInvalid={formData[key].isInvalid}>
|
||||||
<option disabled selected>
|
<option disabled selected>
|
||||||
|
@ -350,7 +357,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
name={key}
|
name={key}
|
||||||
id={`form-${String(item)}`}
|
id={`form-${String(item)}`}
|
||||||
label={properties[key].enumNames?.[index]}
|
label={properties[key].enumNames?.[index]}
|
||||||
checked={(formData[key]?.value || defaultValue) === item}
|
checked={
|
||||||
|
(formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue) === item
|
||||||
|
}
|
||||||
feedback={formData[key]?.errorMsg}
|
feedback={formData[key]?.errorMsg}
|
||||||
feedbackType="invalid"
|
feedbackType="invalid"
|
||||||
isInvalid={formData[key].isInvalid}
|
isInvalid={formData[key].isInvalid}
|
||||||
|
@ -382,7 +393,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
name={key}
|
name={key}
|
||||||
type="switch"
|
type="switch"
|
||||||
label={label}
|
label={label}
|
||||||
checked={formData[key]?.value || defaultValue}
|
checked={
|
||||||
|
formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
feedback={formData[key]?.errorMsg}
|
feedback={formData[key]?.errorMsg}
|
||||||
feedbackType="invalid"
|
feedbackType="invalid"
|
||||||
isInvalid={formData[key].isInvalid}
|
isInvalid={formData[key].isInvalid}
|
||||||
|
@ -405,7 +420,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
controlId={key}>
|
controlId={key}>
|
||||||
<Form.Label>{title}</Form.Label>
|
<Form.Label>{title}</Form.Label>
|
||||||
<TimeZonePicker
|
<TimeZonePicker
|
||||||
value={formData[key]?.value || defaultValue}
|
value={
|
||||||
|
formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
name={key}
|
name={key}
|
||||||
onChange={handleSelectChange}
|
onChange={handleSelectChange}
|
||||||
/>
|
/>
|
||||||
|
@ -464,7 +483,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
name={key}
|
name={key}
|
||||||
placeholder={options?.placeholder || ''}
|
placeholder={options?.placeholder || ''}
|
||||||
type={options?.type || 'text'}
|
type={options?.type || 'text'}
|
||||||
value={formData[key]?.value || defaultValue}
|
value={
|
||||||
|
formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
isInvalid={formData[key].isInvalid}
|
isInvalid={formData[key].isInvalid}
|
||||||
rows={options?.rows || 3}
|
rows={options?.rows || 3}
|
||||||
|
@ -490,7 +513,11 @@ const SchemaForm: ForwardRefRenderFunction<IRef, IProps> = (
|
||||||
name={key}
|
name={key}
|
||||||
placeholder={options?.placeholder || ''}
|
placeholder={options?.placeholder || ''}
|
||||||
type={options?.type || 'text'}
|
type={options?.type || 'text'}
|
||||||
value={formData[key]?.value || defaultValue}
|
value={
|
||||||
|
formData[key]?.value !== undefined
|
||||||
|
? formData[key]?.value
|
||||||
|
: defaultValue
|
||||||
|
}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
style={options?.type === 'color' ? { width: '6rem' } : {}}
|
style={options?.type === 'color' ? { width: '6rem' } : {}}
|
||||||
isInvalid={formData[key].isInvalid}
|
isInvalid={formData[key].isInvalid}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import { useToast } from '@/hooks';
|
||||||
|
import type * as Types from '@/common/interface';
|
||||||
|
import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components';
|
||||||
|
import { useQueryPluginConfig, updatePluginConfig } from '@/services';
|
||||||
|
|
||||||
|
const Config = () => {
|
||||||
|
const { slug_name } = useParams<{ slug_name: string }>();
|
||||||
|
const { data } = useQueryPluginConfig({ plugin_slug_name: slug_name });
|
||||||
|
const Toast = useToast();
|
||||||
|
const { t } = useTranslation('translation');
|
||||||
|
const [schema, setSchema] = useState<JSONSchema | null>(null);
|
||||||
|
|
||||||
|
const uiSchema: UISchema = {};
|
||||||
|
const required: string[] = [];
|
||||||
|
|
||||||
|
const [formData, setFormData] = useState<Types.FormDataType | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const properties: JSONSchema['properties'] = {};
|
||||||
|
|
||||||
|
data.config_fields?.forEach((item) => {
|
||||||
|
properties[item.name] = {
|
||||||
|
type: 'string',
|
||||||
|
title: item.title,
|
||||||
|
description: item.description,
|
||||||
|
default: item.value,
|
||||||
|
};
|
||||||
|
if (item.uiOptions) {
|
||||||
|
uiSchema[item.name] = {
|
||||||
|
'ui:options': item.uiOptions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (item.required) {
|
||||||
|
required.push(item.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setSchema({
|
||||||
|
title: data?.name || '',
|
||||||
|
required,
|
||||||
|
properties,
|
||||||
|
});
|
||||||
|
}, [data?.config_fields]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!schema || formData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setFormData(initFormData(schema));
|
||||||
|
}, [schema, formData]);
|
||||||
|
|
||||||
|
const onSubmit = (evt) => {
|
||||||
|
if (!formData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
const config_fields = {};
|
||||||
|
Object.keys(formData).forEach((key) => {
|
||||||
|
config_fields[key] = formData[key].value;
|
||||||
|
});
|
||||||
|
const params = {
|
||||||
|
plugin_slug_name: slug_name,
|
||||||
|
config_fields,
|
||||||
|
};
|
||||||
|
updatePluginConfig(params).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
Toast.onShow({
|
||||||
|
msg: t('update', { keyPrefix: 'toast' }),
|
||||||
|
variant: 'success',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOnChange = (form) => {
|
||||||
|
console.log(form);
|
||||||
|
setFormData(form);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!data || !schema || !formData) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(schema.properties)) {
|
||||||
|
return <h3 className="mb-4">{data?.name}</h3>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h3 className="mb-4">{data?.name}</h3>
|
||||||
|
<SchemaForm
|
||||||
|
schema={schema}
|
||||||
|
uiSchema={uiSchema}
|
||||||
|
formData={formData}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Config;
|
|
@ -5,21 +5,18 @@ import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { Pagination, Empty, QueryGroup, Icon } from '@/components';
|
import { Empty, QueryGroup, Icon } from '@/components';
|
||||||
import * as Type from '@/common/interface';
|
import * as Type from '@/common/interface';
|
||||||
import { useQueryUsers } from '@/services';
|
import { useQueryPlugins, updatePluginStatus } from '@/services';
|
||||||
|
|
||||||
const InstalledPluginsFilterKeys: Type.InstalledPluginsFilterBy[] = [
|
const InstalledPluginsFilterKeys: Type.InstalledPluginsFilterBy[] = [
|
||||||
'all',
|
'all',
|
||||||
'active',
|
'active',
|
||||||
'inactive',
|
'inactive',
|
||||||
'outdated',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const bgMap = {
|
const bgMap = {
|
||||||
normal: 'text-bg-success',
|
active: 'text-bg-success',
|
||||||
suspended: 'text-bg-danger',
|
|
||||||
deleted: 'text-bg-danger',
|
|
||||||
inactive: 'text-bg-secondary',
|
inactive: 'text-bg-secondary',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +31,7 @@ const Users: FC = () => {
|
||||||
urlSearchParams.get('filter') || InstalledPluginsFilterKeys[0];
|
urlSearchParams.get('filter') || InstalledPluginsFilterKeys[0];
|
||||||
const curPage = Number(urlSearchParams.get('page') || '1');
|
const curPage = Number(urlSearchParams.get('page') || '1');
|
||||||
const curQuery = urlSearchParams.get('query') || '';
|
const curQuery = urlSearchParams.get('query') || '';
|
||||||
const { data, isLoading } = useQueryUsers({
|
const { data, isLoading, mutate } = useQueryPlugins({
|
||||||
page: curPage,
|
page: curPage,
|
||||||
page_size: PAGE_SIZE,
|
page_size: PAGE_SIZE,
|
||||||
query: curQuery,
|
query: curQuery,
|
||||||
|
@ -46,6 +43,22 @@ const Users: FC = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleAction = (type, plugin) => {
|
const handleAction = (type, plugin) => {
|
||||||
|
if (type === 'deactivate') {
|
||||||
|
updatePluginStatus({
|
||||||
|
enabled: false,
|
||||||
|
plugin_slug_name: plugin.slug_name,
|
||||||
|
}).then(() => {
|
||||||
|
mutate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (type === 'activate') {
|
||||||
|
updatePluginStatus({
|
||||||
|
enabled: true,
|
||||||
|
plugin_slug_name: plugin.slug_name,
|
||||||
|
}).then(() => {
|
||||||
|
mutate();
|
||||||
|
});
|
||||||
|
}
|
||||||
console.log(type, plugin);
|
console.log(type, plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,19 +89,23 @@ const Users: FC = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="align-middle">
|
<tbody className="align-middle">
|
||||||
{data?.list.map((plugin) => {
|
{data?.map((plugin) => {
|
||||||
return (
|
return (
|
||||||
<tr key={plugin.user_id}>
|
<tr key={plugin.slug_name}>
|
||||||
<td>
|
<td>
|
||||||
<div>Twitter Logins</div>
|
<div>{plugin.name}</div>
|
||||||
<div className="text-muted text-small">
|
<div className="text-muted text-small">
|
||||||
Enable login with Twitter
|
{plugin.description}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-break">{plugin.version}</td>
|
<td className="text-break">{plugin.version}</td>
|
||||||
<td>
|
<td>
|
||||||
<span className={classNames('badge', bgMap[plugin.status])}>
|
<span
|
||||||
{t(`filter.${plugin.status}`)}
|
className={classNames(
|
||||||
|
'badge',
|
||||||
|
bgMap[plugin.enabled ? 'active' : 'inactive'],
|
||||||
|
)}>
|
||||||
|
{t(`filter.${plugin.enabled ? 'active' : 'inactive'}`)}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
{curFilter !== 'deleted' ? (
|
{curFilter !== 'deleted' ? (
|
||||||
|
@ -98,10 +115,18 @@ const Users: FC = () => {
|
||||||
<Icon name="three-dots-vertical" />
|
<Icon name="three-dots-vertical" />
|
||||||
</Dropdown.Toggle>
|
</Dropdown.Toggle>
|
||||||
<Dropdown.Menu>
|
<Dropdown.Menu>
|
||||||
|
{plugin.enabled ? (
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
onClick={() => handleAction('deactivate', plugin)}>
|
onClick={() => handleAction('deactivate', plugin)}>
|
||||||
{t('deactivate')}
|
{t('deactivate')}
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
|
) : (
|
||||||
|
<Dropdown.Item
|
||||||
|
onClick={() => handleAction('activate', plugin)}>
|
||||||
|
{t('activate')}
|
||||||
|
</Dropdown.Item>
|
||||||
|
)}
|
||||||
|
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
onClick={() => handleAction('settings', plugin)}>
|
onClick={() => handleAction('settings', plugin)}>
|
||||||
{t('settings')}
|
{t('settings')}
|
||||||
|
@ -115,14 +140,7 @@ const Users: FC = () => {
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
{Number(data?.count) <= 0 && !isLoading && <Empty />}
|
{Number(data?.length) <= 0 && !isLoading && <Empty />}
|
||||||
<div className="mt-4 mb-2 d-flex justify-content-center">
|
|
||||||
<Pagination
|
|
||||||
currentPage={curPage}
|
|
||||||
totalSize={data?.count || 0}
|
|
||||||
pageSize={PAGE_SIZE}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,9 +3,12 @@ import { Container, Row, Col } from 'react-bootstrap';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Outlet, useLocation } from 'react-router-dom';
|
import { Outlet, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
import { usePageTags } from '@/hooks';
|
import { usePageTags } from '@/hooks';
|
||||||
import { AccordionNav } from '@/components';
|
import { AccordionNav } from '@/components';
|
||||||
import { ADMIN_NAV_MENUS } from '@/common/constants';
|
import { ADMIN_NAV_MENUS } from '@/common/constants';
|
||||||
|
import { useQueryPlugins } from '@/services';
|
||||||
|
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
|
@ -24,9 +27,29 @@ const formPaths = [
|
||||||
const Index: FC = () => {
|
const Index: FC = () => {
|
||||||
const { t } = useTranslation('translation', { keyPrefix: 'page_title' });
|
const { t } = useTranslation('translation', { keyPrefix: 'page_title' });
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
const { data: plugins } = useQueryPlugins({
|
||||||
|
query: 'active',
|
||||||
|
});
|
||||||
usePageTags({
|
usePageTags({
|
||||||
title: t('admin'),
|
title: t('admin'),
|
||||||
});
|
});
|
||||||
|
const inactivePlugins = plugins?.filter((v) => v.enabled) || [];
|
||||||
|
|
||||||
|
const menus = cloneDeep(ADMIN_NAV_MENUS);
|
||||||
|
if (inactivePlugins?.length > 0) {
|
||||||
|
menus.forEach((item) => {
|
||||||
|
if (item.name === 'plugins' && item.children) {
|
||||||
|
item.children = [
|
||||||
|
...item.children,
|
||||||
|
...inactivePlugins.map((plugin) => ({
|
||||||
|
name: plugin.slug_name,
|
||||||
|
displayName: plugin.name,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-light py-2">
|
<div className="bg-light py-2">
|
||||||
|
@ -39,7 +62,7 @@ const Index: FC = () => {
|
||||||
<Container className="admin-container">
|
<Container className="admin-container">
|
||||||
<Row>
|
<Row>
|
||||||
<Col lg={2}>
|
<Col lg={2}>
|
||||||
<AccordionNav menus={ADMIN_NAV_MENUS} path="/admin/" />
|
<AccordionNav menus={menus} path="/admin/" />
|
||||||
</Col>
|
</Col>
|
||||||
<Col lg={formPaths.find((v) => pathname.includes(v)) ? 6 : 10}>
|
<Col lg={formPaths.find((v) => pathname.includes(v)) ? 6 : 10}>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
|
|
@ -315,6 +315,10 @@ const routes: RouteNode[] = [
|
||||||
path: 'installed_plugins',
|
path: 'installed_plugins',
|
||||||
page: 'pages/Admin/Plugins/Installed',
|
page: 'pages/Admin/Plugins/Installed',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: ':slug_name',
|
||||||
|
page: 'pages/Admin/Plugins/Config',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// for review
|
// for review
|
||||||
|
|
|
@ -4,3 +4,4 @@ export * from './question';
|
||||||
export * from './settings';
|
export * from './settings';
|
||||||
export * from './users';
|
export * from './users';
|
||||||
export * from './dashboard';
|
export * from './dashboard';
|
||||||
|
export * from './plugins';
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import qs from 'qs';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
|
import type * as Types from '@/common/interface';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
export const useQueryPlugins = (params) => {
|
||||||
|
const apiUrl = `/answer/admin/api/plugins?${qs.stringify(params)}`;
|
||||||
|
const { data, error, mutate } = useSWR<any[], Error>(
|
||||||
|
apiUrl,
|
||||||
|
request.instance.get,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
isLoading: !data && !error,
|
||||||
|
error,
|
||||||
|
mutate,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updatePluginStatus = (params) => {
|
||||||
|
return request.put('/answer/admin/api/plugin/status', params);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useQueryPluginConfig = (params) => {
|
||||||
|
const apiUrl = `/answer/admin/api/plugin/config?${qs.stringify(params)}`;
|
||||||
|
const { data, error, mutate } = useSWR<Types.PluginConfig, Error>(
|
||||||
|
apiUrl,
|
||||||
|
request.instance.get,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
isLoading: !data && !error,
|
||||||
|
error,
|
||||||
|
mutate,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updatePluginConfig = (params) => {
|
||||||
|
return request.put('/answer/admin/api/plugin/config', params);
|
||||||
|
};
|
Loading…
Reference in New Issue