fix: fix switch role and input style (#3226)
* fix: fix switch role and input style * refactor: remove useless code
This commit is contained in:
parent
6d04914e32
commit
c129889df6
packages/core/client/src
44
packages/core/client/src/common/SelectWithTitle.tsx
Normal file
44
packages/core/client/src/common/SelectWithTitle.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Select } from 'antd';
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
export interface SelectWithTitleProps {
|
||||||
|
title?: any;
|
||||||
|
defaultValue?: any;
|
||||||
|
options?: any;
|
||||||
|
fieldNames?: any;
|
||||||
|
onChange?: (...args: any[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SelectWithTitle({ title, defaultValue, onChange, options, fieldNames }: SelectWithTitleProps) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const timerRef = useRef<any>(null);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setOpen((v) => !v);
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
timerRef.current = setTimeout(() => {
|
||||||
|
setOpen(false);
|
||||||
|
}, 200);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
<Select
|
||||||
|
open={open}
|
||||||
|
popupMatchSelectWidth={false}
|
||||||
|
bordered={false}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
onChange={onChange}
|
||||||
|
fieldNames={fieldNames}
|
||||||
|
options={options}
|
||||||
|
style={{ textAlign: 'right', minWidth: 100 }}
|
||||||
|
onMouseEnter={() => {
|
||||||
|
clearTimeout(timerRef.current);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
1
packages/core/client/src/common/index.ts
Normal file
1
packages/core/client/src/common/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './SelectWithTitle';
|
@ -22,9 +22,11 @@ export * from './auth';
|
|||||||
export * from './block-provider';
|
export * from './block-provider';
|
||||||
export * from './china-region';
|
export * from './china-region';
|
||||||
export * from './collection-manager';
|
export * from './collection-manager';
|
||||||
|
export * from './common';
|
||||||
export * from './css-variable';
|
export * from './css-variable';
|
||||||
export * from './document-title';
|
export * from './document-title';
|
||||||
export * from './filter-provider';
|
export * from './filter-provider';
|
||||||
|
export * from './flag-provider';
|
||||||
export * from './formula';
|
export * from './formula';
|
||||||
export * from './global-theme';
|
export * from './global-theme';
|
||||||
export * from './hooks';
|
export * from './hooks';
|
||||||
@ -44,7 +46,6 @@ export * from './schema-settings';
|
|||||||
export * from './schema-templates';
|
export * from './schema-templates';
|
||||||
export * from './style';
|
export * from './style';
|
||||||
export * from './system-settings';
|
export * from './system-settings';
|
||||||
|
export * from './testUtils';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
export * from './variables';
|
export * from './variables';
|
||||||
export * from './flag-provider';
|
|
||||||
export * from './testUtils';
|
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
import { test } from '@nocobase/test/client';
|
||||||
|
|
||||||
|
test('switch role', async ({ page, mockPage }) => {
|
||||||
|
await mockPage().goto();
|
||||||
|
|
||||||
|
await page.getByTestId('user-center-button').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Switch role' }).click();
|
||||||
|
await page.getByRole('option', { name: 'Member' }).click();
|
||||||
|
});
|
@ -4,9 +4,9 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
SchemaInitializerItem,
|
SchemaInitializerItem,
|
||||||
|
SchemaInitializerMenu,
|
||||||
useSchemaInitializer,
|
useSchemaInitializer,
|
||||||
useSchemaInitializerMenuItems,
|
useSchemaInitializerMenuItems,
|
||||||
SchemaInitializerMenu,
|
|
||||||
} from '../../application';
|
} from '../../application';
|
||||||
import { useCompile } from '../../schema-component';
|
import { useCompile } from '../../schema-component';
|
||||||
import { useSchemaTemplateManager } from '../../schema-templates';
|
import { useSchemaTemplateManager } from '../../schema-templates';
|
||||||
@ -48,7 +48,7 @@ export const SearchCollections = ({ value: outValue, onChange }) => {
|
|||||||
<Input
|
<Input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
allowClear
|
allowClear
|
||||||
style={{ padding: '0 4px 6px' }}
|
style={{ padding: '0 4px 6px', boxShadow: 'none' }}
|
||||||
bordered={false}
|
bordered={false}
|
||||||
placeholder={t('Search and select collection')}
|
placeholder={t('Search and select collection')}
|
||||||
value={value}
|
value={value}
|
||||||
|
@ -18,7 +18,6 @@ import {
|
|||||||
MenuProps,
|
MenuProps,
|
||||||
Modal,
|
Modal,
|
||||||
ModalFuncProps,
|
ModalFuncProps,
|
||||||
Select,
|
|
||||||
Space,
|
Space,
|
||||||
Switch,
|
Switch,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
@ -33,7 +32,6 @@ import React, {
|
|||||||
useMemo,
|
useMemo,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
useTransition as useReactTransition,
|
useTransition as useReactTransition,
|
||||||
useRef,
|
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
@ -77,6 +75,7 @@ import {
|
|||||||
useFormActiveFields,
|
useFormActiveFields,
|
||||||
} from '../block-provider/hooks';
|
} from '../block-provider/hooks';
|
||||||
import { useCollectionFilterOptionsV2 } from '../collection-manager/action-hooks';
|
import { useCollectionFilterOptionsV2 } from '../collection-manager/action-hooks';
|
||||||
|
import { SelectWithTitle, SelectWithTitleProps } from '../common/SelectWithTitle';
|
||||||
import {
|
import {
|
||||||
FilterBlockType,
|
FilterBlockType,
|
||||||
getSupportFieldsByAssociation,
|
getSupportFieldsByAssociation,
|
||||||
@ -1976,45 +1975,6 @@ export const isPatternDisabled = (fieldSchema: Schema) => {
|
|||||||
return fieldSchema?.['x-component-props']?.['pattern-disable'] == true;
|
return fieldSchema?.['x-component-props']?.['pattern-disable'] == true;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface SelectWithTitleProps {
|
|
||||||
title?: any;
|
|
||||||
defaultValue?: any;
|
|
||||||
options?: any;
|
|
||||||
onChange?: (...args: any[]) => void;
|
|
||||||
}
|
|
||||||
export function SelectWithTitle({ title, defaultValue, onChange, options }: SelectWithTitleProps) {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const timerRef = useRef<any>(null);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setOpen((v) => !v);
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => {
|
|
||||||
timerRef.current = setTimeout(() => {
|
|
||||||
setOpen(false);
|
|
||||||
}, 200);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
<Select
|
|
||||||
open={open}
|
|
||||||
popupMatchSelectWidth={false}
|
|
||||||
bordered={false}
|
|
||||||
defaultValue={defaultValue}
|
|
||||||
onChange={onChange}
|
|
||||||
options={options}
|
|
||||||
style={{ textAlign: 'right', minWidth: 100 }}
|
|
||||||
onMouseEnter={() => {
|
|
||||||
clearTimeout(timerRef.current);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFieldDefaultValue(fieldSchema: ISchema, collectionField: CollectionFieldOptions) {
|
function getFieldDefaultValue(fieldSchema: ISchema, collectionField: CollectionFieldOptions) {
|
||||||
const result = fieldSchema?.default ?? collectionField?.defaultValue;
|
const result = fieldSchema?.default ?? collectionField?.defaultValue;
|
||||||
return result;
|
return result;
|
||||||
|
@ -120,7 +120,6 @@ export const useChangePassword = () => {
|
|||||||
|
|
||||||
return useMemo<MenuProps['items'][0]>(() => {
|
return useMemo<MenuProps['items'][0]>(() => {
|
||||||
return {
|
return {
|
||||||
role: 'button',
|
|
||||||
key: 'password',
|
key: 'password',
|
||||||
eventKey: 'ChangePassword',
|
eventKey: 'ChangePassword',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
|
@ -76,7 +76,6 @@ export const SettingsMenu: React.FC<{
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
role: 'button',
|
|
||||||
key: 'cache',
|
key: 'cache',
|
||||||
label: t('Clear cache'),
|
label: t('Clear cache'),
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
@ -85,7 +84,6 @@ export const SettingsMenu: React.FC<{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'button',
|
|
||||||
key: 'reboot',
|
key: 'reboot',
|
||||||
label: t('Restart application'),
|
label: t('Restart application'),
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
@ -129,7 +127,6 @@ export const SettingsMenu: React.FC<{
|
|||||||
},
|
},
|
||||||
...controlApp,
|
...controlApp,
|
||||||
{
|
{
|
||||||
role: 'button',
|
|
||||||
key: 'signout',
|
key: 'signout',
|
||||||
label: t('Sign out'),
|
label: t('Sign out'),
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
|
@ -126,7 +126,6 @@ export const useEditProfile = () => {
|
|||||||
|
|
||||||
return useMemo<MenuProps['items'][0]>(() => {
|
return useMemo<MenuProps['items'][0]>(() => {
|
||||||
return {
|
return {
|
||||||
role: 'button',
|
|
||||||
key: 'profile',
|
key: 'profile',
|
||||||
eventKey: 'EditProfile',
|
eventKey: 'EditProfile',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@ -134,7 +133,7 @@ export const useEditProfile = () => {
|
|||||||
ctx?.setVisible(false);
|
ctx?.setVisible(false);
|
||||||
},
|
},
|
||||||
label: (
|
label: (
|
||||||
<div aria-label="edit-profile">
|
<div>
|
||||||
{t('Edit profile')}
|
{t('Edit profile')}
|
||||||
<ActionContextProvider value={{ visible, setVisible }}>
|
<ActionContextProvider value={{ visible, setVisible }}>
|
||||||
<div onClick={(e) => e.stopPropagation()}>
|
<div onClick={(e) => e.stopPropagation()}>
|
||||||
|
@ -11,7 +11,6 @@ export const useLanguageSettings = () => {
|
|||||||
const enabledLanguages: string[] = useMemo(() => data?.data?.enabledLanguages || [], [data?.data?.enabledLanguages]);
|
const enabledLanguages: string[] = useMemo(() => data?.data?.enabledLanguages || [], [data?.data?.enabledLanguages]);
|
||||||
const result = useMemo<MenuProps['items'][0]>(() => {
|
const result = useMemo<MenuProps['items'][0]>(() => {
|
||||||
return {
|
return {
|
||||||
role: 'button',
|
|
||||||
key: 'language',
|
key: 'language',
|
||||||
eventKey: 'LanguageSettings',
|
eventKey: 'LanguageSettings',
|
||||||
label: (
|
label: (
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { MenuProps, Select } from 'antd';
|
import { MenuProps } from 'antd';
|
||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { APIClient, useAPIClient } from '../api-client';
|
import { useAPIClient } from '../api-client';
|
||||||
|
import { SelectWithTitle } from '../common';
|
||||||
import { useCurrentRoles } from './CurrentUserProvider';
|
import { useCurrentRoles } from './CurrentUserProvider';
|
||||||
|
|
||||||
export const useSwitchRole = () => {
|
export const useSwitchRole = () => {
|
||||||
@ -10,12 +11,27 @@ export const useSwitchRole = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const result = useMemo<MenuProps['items'][0]>(() => {
|
const result = useMemo<MenuProps['items'][0]>(() => {
|
||||||
return {
|
return {
|
||||||
role: 'button',
|
|
||||||
key: 'role',
|
key: 'role',
|
||||||
eventKey: 'SwitchRole',
|
eventKey: 'SwitchRole',
|
||||||
label: <SelectWithTitle {...{ t, roles, api }} />,
|
label: (
|
||||||
|
<SelectWithTitle
|
||||||
|
title={t('Switch role')}
|
||||||
|
fieldNames={{
|
||||||
|
label: 'title',
|
||||||
|
value: 'name',
|
||||||
|
}}
|
||||||
|
options={roles}
|
||||||
|
defaultValue={api.auth.role}
|
||||||
|
onChange={async (roleName) => {
|
||||||
|
api.auth.setRole(roleName);
|
||||||
|
await api.resource('users').setDefaultRole({ values: { roleName } });
|
||||||
|
location.reload();
|
||||||
|
window.location.reload();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}, [api, history, roles]);
|
}, [api, roles, t]);
|
||||||
|
|
||||||
if (roles.length <= 1) {
|
if (roles.length <= 1) {
|
||||||
return null;
|
return null;
|
||||||
@ -23,49 +39,3 @@ export const useSwitchRole = () => {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
function SelectWithTitle({ t, roles, api }: { t; roles: any; api: APIClient }) {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const timerRef = useRef<any>(null);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
aria-label="switch-role"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
}}
|
|
||||||
onClick={() => setOpen((v) => !v)}
|
|
||||||
onMouseLeave={() => {
|
|
||||||
timerRef.current = setTimeout(() => {
|
|
||||||
setOpen(false);
|
|
||||||
}, 200);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Switch role')}
|
|
||||||
<Select
|
|
||||||
style={{ textAlign: 'right', minWidth: 100 }}
|
|
||||||
open={open}
|
|
||||||
data-testid="select-switch-role"
|
|
||||||
bordered={false}
|
|
||||||
popupMatchSelectWidth={false}
|
|
||||||
fieldNames={{
|
|
||||||
label: 'title',
|
|
||||||
value: 'name',
|
|
||||||
}}
|
|
||||||
options={roles}
|
|
||||||
value={api.auth.role}
|
|
||||||
onChange={async (roleName) => {
|
|
||||||
api.auth.setRole(roleName);
|
|
||||||
await api.resource('users').setDefaultRole({ values: { roleName } });
|
|
||||||
location.reload();
|
|
||||||
window.location.reload();
|
|
||||||
}}
|
|
||||||
onMouseEnter={() => {
|
|
||||||
clearTimeout(timerRef.current);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user