mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-04 21:28:34 +08:00
Merge branch 'main' into next
This commit is contained in:
commit
937209363a
@ -1529,14 +1529,36 @@ export function appendQueryStringToUrl(url: string, queryString: string) {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useParseURLAndParams = () => {
|
||||||
|
const variables = useVariables();
|
||||||
|
const localVariables = useLocalVariables();
|
||||||
|
|
||||||
|
const parseURLAndParams = useCallback(
|
||||||
|
async (url: string, params: { name: string; value: any }[]) => {
|
||||||
|
const queryString = await parseVariablesAndChangeParamsToQueryString({
|
||||||
|
searchParams: params,
|
||||||
|
variables,
|
||||||
|
localVariables,
|
||||||
|
replaceVariableValue,
|
||||||
|
});
|
||||||
|
const targetUrl = await replaceVariableValue(url, variables, localVariables);
|
||||||
|
const result = appendQueryStringToUrl(targetUrl, queryString);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
[variables, localVariables],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { parseURLAndParams };
|
||||||
|
};
|
||||||
|
|
||||||
export function useLinkActionProps() {
|
export function useLinkActionProps() {
|
||||||
const navigate = useNavigateNoUpdate();
|
const navigate = useNavigateNoUpdate();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const url = fieldSchema?.['x-component-props']?.['url'];
|
const url = fieldSchema?.['x-component-props']?.['url'];
|
||||||
const searchParams = fieldSchema?.['x-component-props']?.['params'] || [];
|
const searchParams = fieldSchema?.['x-component-props']?.['params'] || [];
|
||||||
const variables = useVariables();
|
const { parseURLAndParams } = useParseURLAndParams();
|
||||||
const localVariables = useLocalVariables();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'default',
|
type: 'default',
|
||||||
@ -1545,14 +1567,8 @@ export function useLinkActionProps() {
|
|||||||
message.warning(t('Please configure the URL'));
|
message.warning(t('Please configure the URL'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const queryString = await parseVariablesAndChangeParamsToQueryString({
|
const link = await parseURLAndParams(url, searchParams);
|
||||||
searchParams,
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
replaceVariableValue,
|
|
||||||
});
|
|
||||||
const targetUrl = await replaceVariableValue(url, variables, localVariables);
|
|
||||||
const link = appendQueryStringToUrl(targetUrl, queryString);
|
|
||||||
if (link) {
|
if (link) {
|
||||||
if (isURL(link)) {
|
if (isURL(link)) {
|
||||||
window.open(link, '_blank');
|
window.open(link, '_blank');
|
||||||
|
@ -63,6 +63,7 @@ export * from './variables';
|
|||||||
export { withDynamicSchemaProps } from './hoc/withDynamicSchemaProps';
|
export { withDynamicSchemaProps } from './hoc/withDynamicSchemaProps';
|
||||||
|
|
||||||
export { SchemaSettingsActionLinkItem } from './modules/actions/link/customizeLinkActionSettings';
|
export { SchemaSettingsActionLinkItem } from './modules/actions/link/customizeLinkActionSettings';
|
||||||
|
export { useURLAndParamsSchema } from './modules/actions/link/useURLAndParamsSchema';
|
||||||
export * from './modules/blocks/BlockSchemaToolbar';
|
export * from './modules/blocks/BlockSchemaToolbar';
|
||||||
export * from './modules/blocks/data-blocks/form';
|
export * from './modules/blocks/data-blocks/form';
|
||||||
export * from './modules/blocks/data-blocks/table';
|
export * from './modules/blocks/data-blocks/table';
|
||||||
|
@ -26,7 +26,7 @@ test.describe('Link', () => {
|
|||||||
await page.getByRole('button', { name: 'designer-schema-settings-Action.Link-actionSettings:link-users' }).hover();
|
await page.getByRole('button', { name: 'designer-schema-settings-Action.Link-actionSettings:link-users' }).hover();
|
||||||
await page.getByRole('menuitem', { name: 'Edit link' }).click();
|
await page.getByRole('menuitem', { name: 'Edit link' }).click();
|
||||||
await page
|
await page
|
||||||
.getByLabel('block-item-Variable.TextArea-users-table-URL')
|
.getByLabel('block-item-users-table-URL')
|
||||||
.getByLabel('textbox')
|
.getByLabel('textbox')
|
||||||
.fill(await nocoPage.getUrl());
|
.fill(await nocoPage.getUrl());
|
||||||
await page.getByPlaceholder('Name').fill('id');
|
await page.getByPlaceholder('Name').fill('id');
|
||||||
|
@ -6,34 +6,27 @@
|
|||||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
import { css } from '@emotion/css';
|
|
||||||
import { ArrayItems } from '@formily/antd-v5';
|
import { ArrayItems } from '@formily/antd-v5';
|
||||||
import { useField, useFieldSchema } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useCollectionRecord, useDesignable, useFormBlockContext, useRecord } from '../../../';
|
import { useCollectionRecord, useDesignable } from '../../../';
|
||||||
import { useSchemaToolbar } from '../../../application';
|
import { useSchemaToolbar } from '../../../application';
|
||||||
import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings';
|
import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings';
|
||||||
import { useCollection_deprecated } from '../../../collection-manager';
|
import { useCollection_deprecated } from '../../../collection-manager';
|
||||||
import { ButtonEditor, RemoveButton } from '../../../schema-component/antd/action/Action.Designer';
|
import { ButtonEditor, RemoveButton } from '../../../schema-component/antd/action/Action.Designer';
|
||||||
import { SchemaSettingsLinkageRules, SchemaSettingsModalItem } from '../../../schema-settings';
|
import { SchemaSettingsLinkageRules, SchemaSettingsModalItem } from '../../../schema-settings';
|
||||||
import { useVariableOptions } from '../../../schema-settings/VariableInput/hooks/useVariableOptions';
|
import { useURLAndParamsSchema } from './useURLAndParamsSchema';
|
||||||
|
|
||||||
export function SchemaSettingsActionLinkItem() {
|
export function SchemaSettingsActionLinkItem() {
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { form } = useFormBlockContext();
|
const { urlSchema, paramsSchema } = useURLAndParamsSchema();
|
||||||
const record = useRecord();
|
const initialValues = { url: field.componentProps.url, params: field.componentProps.params || [{}] };
|
||||||
const scope = useVariableOptions({
|
|
||||||
collectionField: { uiSchema: fieldSchema },
|
|
||||||
form,
|
|
||||||
record,
|
|
||||||
uiSchema: fieldSchema,
|
|
||||||
noDisabled: true,
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<SchemaSettingsModalItem
|
<SchemaSettingsModalItem
|
||||||
title={t('Edit link')}
|
title={t('Edit link')}
|
||||||
@ -43,78 +36,10 @@ export function SchemaSettingsActionLinkItem() {
|
|||||||
title: t('Edit link'),
|
title: t('Edit link'),
|
||||||
properties: {
|
properties: {
|
||||||
url: {
|
url: {
|
||||||
title: t('URL'),
|
...urlSchema,
|
||||||
type: 'string',
|
required: true,
|
||||||
default: fieldSchema?.['x-component-props']?.['url'],
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Variable.TextArea',
|
|
||||||
'x-component-props': {
|
|
||||||
scope,
|
|
||||||
changeOnSelect: true,
|
|
||||||
},
|
|
||||||
description: t('Do not concatenate search params in the URL'),
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
type: 'array',
|
|
||||||
'x-component': 'ArrayItems',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
title: `{{t("Search parameters")}}`,
|
|
||||||
default: fieldSchema?.['x-component-props']?.params || [{}],
|
|
||||||
items: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
space: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Space',
|
|
||||||
'x-component-props': {
|
|
||||||
style: {
|
|
||||||
flexWrap: 'nowrap',
|
|
||||||
maxWidth: '100%',
|
|
||||||
},
|
|
||||||
className: css`
|
|
||||||
& > .ant-space-item:first-child,
|
|
||||||
& > .ant-space-item:last-child {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
name: {
|
|
||||||
type: 'string',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Input',
|
|
||||||
'x-component-props': {
|
|
||||||
placeholder: `{{t("Name")}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: 'string',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Variable.TextArea',
|
|
||||||
'x-component-props': {
|
|
||||||
scope,
|
|
||||||
placeholder: `{{t("Value")}}`,
|
|
||||||
useTypedConstant: true,
|
|
||||||
changeOnSelect: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
remove: {
|
|
||||||
type: 'void',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'ArrayItems.Remove',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
add: {
|
|
||||||
type: 'void',
|
|
||||||
title: `{{t("Add parameter")}}`,
|
|
||||||
'x-component': 'ArrayItems.Addition',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
params: paramsSchema,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onSubmit={({ url, params }) => {
|
onSubmit={({ url, params }) => {
|
||||||
@ -133,6 +58,7 @@ export function SchemaSettingsActionLinkItem() {
|
|||||||
});
|
});
|
||||||
dn.refresh();
|
dn.refresh();
|
||||||
}}
|
}}
|
||||||
|
initialValues={initialValues}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { css } from '@emotion/css';
|
||||||
|
import { useFieldSchema } from '@formily/react';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useFormBlockContext } from '../../../block-provider/FormBlockProvider';
|
||||||
|
import { useRecord } from '../../../record-provider';
|
||||||
|
import { Variable } from '../../../schema-component/antd/variable/Variable';
|
||||||
|
import { useVariableOptions } from '../../../schema-settings/VariableInput/hooks/useVariableOptions';
|
||||||
|
|
||||||
|
const getVariableComponentWithScope = (Com) => {
|
||||||
|
return (props) => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { form } = useFormBlockContext();
|
||||||
|
const record = useRecord();
|
||||||
|
const scope = useVariableOptions({
|
||||||
|
collectionField: { uiSchema: fieldSchema },
|
||||||
|
form,
|
||||||
|
record,
|
||||||
|
uiSchema: fieldSchema,
|
||||||
|
noDisabled: true,
|
||||||
|
});
|
||||||
|
return <Com {...props} scope={scope} />;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useURLAndParamsSchema = () => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const Com = useMemo(() => getVariableComponentWithScope(Variable.TextArea), []);
|
||||||
|
|
||||||
|
const urlSchema = useMemo(() => {
|
||||||
|
return {
|
||||||
|
title: t('URL'),
|
||||||
|
type: 'string',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': Com,
|
||||||
|
description: t('Do not concatenate search params in the URL'),
|
||||||
|
'x-reactions': {
|
||||||
|
dependencies: ['mode'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
hidden: '{{$deps[0] === "html"}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}, [t, fieldSchema]);
|
||||||
|
|
||||||
|
const paramsSchema = useMemo(() => {
|
||||||
|
return {
|
||||||
|
type: 'array',
|
||||||
|
'x-component': 'ArrayItems',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
title: `{{t("Search parameters")}}`,
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
space: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Space',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
flexWrap: 'nowrap',
|
||||||
|
maxWidth: '100%',
|
||||||
|
},
|
||||||
|
className: css`
|
||||||
|
& > .ant-space-item:first-child,
|
||||||
|
& > .ant-space-item:last-child {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input',
|
||||||
|
'x-component-props': {
|
||||||
|
placeholder: `{{t("Name")}}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: 'string',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': Com,
|
||||||
|
'x-component-props': {
|
||||||
|
placeholder: `{{t("Value")}}`,
|
||||||
|
useTypedConstant: true,
|
||||||
|
changeOnSelect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
remove: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'ArrayItems.Remove',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-reactions': {
|
||||||
|
dependencies: ['mode'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
hidden: '{{$deps[0] === "html"}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
add: {
|
||||||
|
type: 'void',
|
||||||
|
title: `{{t("Add parameter")}}`,
|
||||||
|
'x-component': 'ArrayItems.Addition',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}, [fieldSchema]);
|
||||||
|
|
||||||
|
return { urlSchema, paramsSchema };
|
||||||
|
};
|
@ -11,10 +11,12 @@ import { FormLayout } from '@formily/antd-v5';
|
|||||||
import { SchemaOptionsContext } from '@formily/react';
|
import { SchemaOptionsContext } from '@formily/react';
|
||||||
import React, { useCallback, useContext } from 'react';
|
import React, { useCallback, useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FormDialog, SchemaComponent, SchemaComponentOptions } from '../../schema-component';
|
import { Router } from 'react-router-dom';
|
||||||
import { SchemaInitializerItem, useSchemaInitializer } from '../../application';
|
import { SchemaInitializerItem, useSchemaInitializer } from '../../application';
|
||||||
import { useGlobalTheme } from '../../global-theme';
|
import { useGlobalTheme } from '../../global-theme';
|
||||||
|
import { FormDialog, SchemaComponent, SchemaComponentOptions } from '../../schema-component';
|
||||||
import { useStyles } from '../../schema-component/antd/menu/MenuItemInitializers';
|
import { useStyles } from '../../schema-component/antd/menu/MenuItemInitializers';
|
||||||
|
import { useURLAndParamsSchema } from '../actions/link/useURLAndParamsSchema';
|
||||||
|
|
||||||
export const LinkMenuItem = () => {
|
export const LinkMenuItem = () => {
|
||||||
const { insert } = useSchemaInitializer();
|
const { insert } = useSchemaInitializer();
|
||||||
@ -22,12 +24,14 @@ export const LinkMenuItem = () => {
|
|||||||
const options = useContext(SchemaOptionsContext);
|
const options = useContext(SchemaOptionsContext);
|
||||||
const { theme } = useGlobalTheme();
|
const { theme } = useGlobalTheme();
|
||||||
const { styles } = useStyles();
|
const { styles } = useStyles();
|
||||||
|
const { urlSchema, paramsSchema } = useURLAndParamsSchema();
|
||||||
|
|
||||||
const handleClick = useCallback(async () => {
|
const handleClick = useCallback(async () => {
|
||||||
const values = await FormDialog(
|
const values = await FormDialog(
|
||||||
t('Add link'),
|
t('Add link'),
|
||||||
() => {
|
() => {
|
||||||
return (
|
return (
|
||||||
|
<Router location={location} navigator={null}>
|
||||||
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
|
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
|
||||||
<FormLayout layout={'vertical'}>
|
<FormLayout layout={'vertical'}>
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
@ -44,23 +48,21 @@ export const LinkMenuItem = () => {
|
|||||||
'x-component': 'IconPicker',
|
'x-component': 'IconPicker',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
},
|
},
|
||||||
href: {
|
href: urlSchema,
|
||||||
title: t('Link'),
|
params: paramsSchema,
|
||||||
'x-component': 'Input',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormLayout>
|
</FormLayout>
|
||||||
</SchemaComponentOptions>
|
</SchemaComponentOptions>
|
||||||
|
</Router>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
theme,
|
theme,
|
||||||
).open({
|
).open({
|
||||||
initialValues: {},
|
initialValues: {},
|
||||||
});
|
});
|
||||||
const { title, href, icon } = values;
|
const { title, href, params, icon } = values;
|
||||||
insert({
|
insert({
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title,
|
title,
|
||||||
@ -69,6 +71,7 @@ export const LinkMenuItem = () => {
|
|||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
icon,
|
icon,
|
||||||
href,
|
href,
|
||||||
|
params,
|
||||||
},
|
},
|
||||||
'x-server-hooks': [
|
'x-server-hooks': [
|
||||||
{
|
{
|
||||||
|
@ -7,71 +7,107 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { uid } from '@formily/shared';
|
||||||
import { expect, groupPageEmpty, test } from '@nocobase/test/e2e';
|
import { expect, groupPageEmpty, test } from '@nocobase/test/e2e';
|
||||||
|
|
||||||
test.describe('add menu item', () => {
|
test.describe('add menu item', () => {
|
||||||
test('header', async ({ page, deletePage }) => {
|
test('header', async ({ page, deletePage }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
|
const pageGroup = uid();
|
||||||
|
const pageItem = uid();
|
||||||
|
const pageLink = uid();
|
||||||
|
|
||||||
// add group
|
// add group
|
||||||
await page.getByTestId('schema-initializer-Menu-header').hover();
|
await page.getByTestId('schema-initializer-Menu-header').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Group' }).click();
|
await page.getByRole('menuitem', { name: 'Group' }).click();
|
||||||
await page.getByRole('textbox').click();
|
await page.getByRole('textbox').click();
|
||||||
await page.getByRole('textbox').fill('page group');
|
await page.getByRole('textbox').fill(pageGroup);
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByLabel('page group', { exact: true })).toBeVisible();
|
await expect(page.getByLabel(pageGroup, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
// add page
|
// add page
|
||||||
await page.getByTestId('schema-initializer-Menu-header').hover();
|
await page.getByTestId('schema-initializer-Menu-header').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Page', exact: true }).click();
|
await page.getByRole('menuitem', { name: 'Page', exact: true }).click();
|
||||||
await page.getByRole('textbox').click();
|
await page.getByRole('textbox').click();
|
||||||
await page.getByRole('textbox').fill('page item');
|
await page.getByRole('textbox').fill(pageItem);
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByLabel('page item', { exact: true })).toBeVisible();
|
await expect(page.getByLabel(pageItem, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
// add link
|
// add link
|
||||||
await page.getByTestId('schema-initializer-Menu-header').hover();
|
await page.getByTestId('schema-initializer-Menu-header').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Link', exact: true }).click();
|
await page.getByRole('menuitem', { name: 'Link', exact: true }).click();
|
||||||
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').click();
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').click();
|
||||||
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').fill('page link');
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').fill(pageLink);
|
||||||
await page.getByLabel('block-item-Input-Link').getByRole('textbox').click();
|
await page.getByLabel('block-item-URL').getByLabel('textbox').fill('baidu.com');
|
||||||
await page.getByLabel('block-item-Input-Link').getByRole('textbox').fill('baidu.com');
|
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByText('page link', { exact: true })).toBeVisible();
|
await expect(page.getByText(pageLink, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
// delete pages
|
// delete pages
|
||||||
await deletePage('page group');
|
await deletePage(pageGroup);
|
||||||
await deletePage('page item');
|
await deletePage(pageItem);
|
||||||
await deletePage('page link');
|
await deletePage(pageLink);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sidebar', async ({ page, mockPage }) => {
|
test('sidebar', async ({ page, mockPage }) => {
|
||||||
await mockPage(groupPageEmpty).goto();
|
await mockPage(groupPageEmpty).goto();
|
||||||
|
|
||||||
|
const pageGroupSide = uid();
|
||||||
|
const pageItemSide = uid();
|
||||||
|
const pageLinkSide = uid();
|
||||||
|
|
||||||
// add group in side
|
// add group in side
|
||||||
await page.getByTestId('schema-initializer-Menu-side').hover();
|
await page.getByTestId('schema-initializer-Menu-side').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Group', exact: true }).click();
|
await page.getByRole('menuitem', { name: 'Group', exact: true }).click();
|
||||||
await page.getByRole('textbox').click();
|
await page.getByRole('textbox').fill(pageGroupSide);
|
||||||
await page.getByRole('textbox').fill('page group side');
|
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByText('page group side', { exact: true })).toBeVisible();
|
await expect(page.getByText(pageGroupSide, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
// add page in side
|
// add page in side
|
||||||
await page.getByTestId('schema-initializer-Menu-side').hover();
|
await page.getByTestId('schema-initializer-Menu-side').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Page', exact: true }).click();
|
await page.getByRole('menuitem', { name: 'Page', exact: true }).click();
|
||||||
await page.getByRole('textbox').click();
|
await page.getByRole('textbox').fill(pageItemSide);
|
||||||
await page.getByRole('textbox').fill('page item side');
|
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByText('page item side', { exact: true })).toBeVisible();
|
await expect(page.getByText(pageItemSide, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
// add link in side
|
// add link in side
|
||||||
await page.getByTestId('schema-initializer-Menu-side').hover();
|
await page.getByTestId('schema-initializer-Menu-side').hover();
|
||||||
await page.getByRole('menuitem', { name: 'Link', exact: true }).click();
|
await page.getByRole('menuitem', { name: 'Link', exact: true }).click();
|
||||||
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').click();
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').click();
|
||||||
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').fill('link item side');
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').fill(pageLinkSide);
|
||||||
await page.getByLabel('block-item-Input-Link').getByRole('textbox').click();
|
await page.getByLabel('block-item-URL').getByLabel('textbox').fill('/');
|
||||||
await page.getByLabel('block-item-Input-Link').getByRole('textbox').fill('/');
|
|
||||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||||
await expect(page.getByText('link item side', { exact: true })).toBeVisible();
|
await expect(page.getByText(pageLinkSide, { exact: true })).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('link: use variable', async ({ page, deletePage }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
const pageLink = uid();
|
||||||
|
|
||||||
|
const token = await page.evaluate(() => {
|
||||||
|
return window.localStorage.getItem('NOCOBASE_TOKEN');
|
||||||
|
});
|
||||||
|
|
||||||
|
// add link
|
||||||
|
await page.getByTestId('schema-initializer-Menu-header').hover();
|
||||||
|
await page.getByRole('menuitem', { name: 'Link', exact: true }).click();
|
||||||
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').click();
|
||||||
|
await page.getByLabel('block-item-Input-Menu item title').getByRole('textbox').fill(pageLink);
|
||||||
|
await page.getByLabel('block-item-URL').getByLabel('textbox').fill('https://www.baidu.com');
|
||||||
|
await page.getByRole('button', { name: 'plus Add parameter' }).click();
|
||||||
|
await page.getByPlaceholder('Name').click();
|
||||||
|
await page.getByPlaceholder('Name').fill('token');
|
||||||
|
await page.getByLabel('block-item-ArrayItems-Search').getByLabel('variable-button').click();
|
||||||
|
await page.getByRole('menuitemcheckbox', { name: 'API token' }).click();
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
|
||||||
|
// open link page
|
||||||
|
await page.getByLabel(pageLink).click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
// After clicking, it will redirect to another page, so we need to get the instance of the new page
|
||||||
|
const newPage = page.context().pages()[1];
|
||||||
|
expect(newPage.url()).toBe('https://www.baidu.com/?token=' + token);
|
||||||
|
|
||||||
|
await deletePage(pageLink);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
SchemaSettingsSubMenu,
|
SchemaSettingsSubMenu,
|
||||||
useAPIClient,
|
useAPIClient,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
|
useURLAndParamsSchema,
|
||||||
} from '../../../';
|
} from '../../../';
|
||||||
|
|
||||||
const toItems = (properties = {}) => {
|
const toItems = (properties = {}) => {
|
||||||
@ -60,6 +61,7 @@ const InsertMenuItems = (props) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
|
const { urlSchema, paramsSchema } = useURLAndParamsSchema();
|
||||||
const isSubMenu = fieldSchema['x-component'] === 'Menu.SubMenu';
|
const isSubMenu = fieldSchema['x-component'] === 'Menu.SubMenu';
|
||||||
if (!isSubMenu && insertPosition === 'beforeEnd') {
|
if (!isSubMenu && insertPosition === 'beforeEnd') {
|
||||||
return null;
|
return null;
|
||||||
@ -184,15 +186,12 @@ const InsertMenuItems = (props) => {
|
|||||||
'x-component': 'IconPicker',
|
'x-component': 'IconPicker',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
},
|
},
|
||||||
href: {
|
href: urlSchema,
|
||||||
title: t('Link'),
|
params: paramsSchema,
|
||||||
'x-component': 'Input',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
} as ISchema
|
} as ISchema
|
||||||
}
|
}
|
||||||
onSubmit={({ title, icon, href }) => {
|
onSubmit={({ title, icon, href, params }) => {
|
||||||
dn.insertAdjacent(insertPosition, {
|
dn.insertAdjacent(insertPosition, {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title,
|
title,
|
||||||
@ -201,6 +200,7 @@ const InsertMenuItems = (props) => {
|
|||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
icon,
|
icon,
|
||||||
href,
|
href,
|
||||||
|
params,
|
||||||
},
|
},
|
||||||
'x-server-hooks': serverHooks,
|
'x-server-hooks': serverHooks,
|
||||||
});
|
});
|
||||||
@ -220,6 +220,7 @@ export const MenuDesigner = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const menuSchema = findMenuSchema(fieldSchema);
|
const menuSchema = findMenuSchema(fieldSchema);
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
|
const { urlSchema, paramsSchema } = useURLAndParamsSchema();
|
||||||
const onSelect = useMemo(
|
const onSelect = useMemo(
|
||||||
() => compile(menuSchema?.['x-component-props']?.['onSelect']),
|
() => compile(menuSchema?.['x-component-props']?.['onSelect']),
|
||||||
[menuSchema?.['x-component-props']?.['onSelect']],
|
[menuSchema?.['x-component-props']?.['onSelect']],
|
||||||
@ -273,15 +274,13 @@ export const MenuDesigner = () => {
|
|||||||
};
|
};
|
||||||
}, [field]);
|
}, [field]);
|
||||||
if (fieldSchema['x-component'] === 'Menu.URL') {
|
if (fieldSchema['x-component'] === 'Menu.URL') {
|
||||||
schema.properties['href'] = {
|
schema.properties['href'] = urlSchema;
|
||||||
title: t('Link'),
|
schema.properties['params'] = paramsSchema;
|
||||||
'x-component': 'Input',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
};
|
|
||||||
initialValues['href'] = field.componentProps.href;
|
initialValues['href'] = field.componentProps.href;
|
||||||
|
initialValues['params'] = field.componentProps.params;
|
||||||
}
|
}
|
||||||
const onEditSubmit: (values: any) => void = useCallback(
|
const onEditSubmit: (values: any) => void = useCallback(
|
||||||
({ title, icon, href }) => {
|
({ title, icon, href, params }) => {
|
||||||
const schema = {
|
const schema = {
|
||||||
['x-uid']: fieldSchema['x-uid'],
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
'x-server-hooks': [
|
'x-server-hooks': [
|
||||||
@ -299,10 +298,12 @@ export const MenuDesigner = () => {
|
|||||||
}
|
}
|
||||||
field.componentProps.icon = icon;
|
field.componentProps.icon = icon;
|
||||||
field.componentProps.href = href;
|
field.componentProps.href = href;
|
||||||
schema['x-component-props'] = { icon, href };
|
field.componentProps.params = params;
|
||||||
|
schema['x-component-props'] = { icon, href, params };
|
||||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||||
fieldSchema['x-component-props']['icon'] = icon;
|
fieldSchema['x-component-props']['icon'] = icon;
|
||||||
fieldSchema['x-component-props']['href'] = href;
|
fieldSchema['x-component-props']['href'] = href;
|
||||||
|
fieldSchema['x-component-props']['params'] = params;
|
||||||
onSelect?.({ item: { props: { schema: fieldSchema } } });
|
onSelect?.({ item: { props: { schema: fieldSchema } } });
|
||||||
dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
schema,
|
schema,
|
||||||
|
@ -24,7 +24,7 @@ import React, { createContext, useCallback, useContext, useEffect, useMemo, useR
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { createDesignable, DndContext, SortableItem, useDesignable, useDesigner } from '../..';
|
import { createDesignable, DndContext, SortableItem, useDesignable, useDesigner } from '../..';
|
||||||
import { Icon, useAPIClient, useSchemaInitializerRender } from '../../../';
|
import { Icon, useAPIClient, useParseURLAndParams, useSchemaInitializerRender } from '../../../';
|
||||||
import { useCollectMenuItems, useMenuItem } from '../../../hooks/useMenuItem';
|
import { useCollectMenuItems, useMenuItem } from '../../../hooks/useMenuItem';
|
||||||
import { useProps } from '../../hooks/useProps';
|
import { useProps } from '../../hooks/useProps';
|
||||||
import { useMenuTranslation } from './locale';
|
import { useMenuTranslation } from './locale';
|
||||||
@ -550,9 +550,55 @@ Menu.Item = observer(
|
|||||||
{ displayName: 'Menu.Item' },
|
{ displayName: 'Menu.Item' },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const MenuURLButton = ({ href, params, icon }) => {
|
||||||
|
const field = useField();
|
||||||
|
const { t } = useMenuTranslation();
|
||||||
|
const Designer = useContext(MenuItemDesignerContext);
|
||||||
|
const { parseURLAndParams } = useParseURLAndParams();
|
||||||
|
const urlRef = useRef(href);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const run = async () => {
|
||||||
|
try {
|
||||||
|
urlRef.current = await parseURLAndParams(href, params || []);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
urlRef.current = href;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
run();
|
||||||
|
}, [href, JSON.stringify(params), parseURLAndParams]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SortableItem
|
||||||
|
className={designerCss}
|
||||||
|
onClick={(event) => {
|
||||||
|
window.open(urlRef.current, '_blank');
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}}
|
||||||
|
removeParentsIfNoChildren={false}
|
||||||
|
aria-label={t(field.title)}
|
||||||
|
>
|
||||||
|
<Icon type={icon} />
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: 'inline-block',
|
||||||
|
width: '100%',
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t(field.title)}
|
||||||
|
</span>
|
||||||
|
<Designer />
|
||||||
|
</SortableItem>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Menu.URL = observer(
|
Menu.URL = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
const { t } = useMenuTranslation();
|
|
||||||
const { pushMenuItem } = useCollectMenuItems();
|
const { pushMenuItem } = useCollectMenuItems();
|
||||||
const { icon, children, ...others } = props;
|
const { icon, children, ...others } = props;
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
@ -575,35 +621,12 @@ Menu.URL = observer(
|
|||||||
label: (
|
label: (
|
||||||
<SchemaContext.Provider value={schema}>
|
<SchemaContext.Provider value={schema}>
|
||||||
<FieldContext.Provider value={field}>
|
<FieldContext.Provider value={field}>
|
||||||
<SortableItem
|
<MenuURLButton icon={icon} href={props.href} params={props.params} />
|
||||||
className={designerCss}
|
|
||||||
onClick={(event) => {
|
|
||||||
window.open(props.href, '_blank');
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}}
|
|
||||||
removeParentsIfNoChildren={false}
|
|
||||||
aria-label={t(field.title)}
|
|
||||||
>
|
|
||||||
<Icon type={icon} />
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
display: 'inline-block',
|
|
||||||
width: '100%',
|
|
||||||
verticalAlign: 'middle',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t(field.title)}
|
|
||||||
</span>
|
|
||||||
<Designer />
|
|
||||||
</SortableItem>
|
|
||||||
</FieldContext.Provider>
|
</FieldContext.Provider>
|
||||||
</SchemaContext.Provider>
|
</SchemaContext.Provider>
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}, [field.title, icon, props.href, schema, Designer]);
|
}, [field.title, icon, props.href, schema, JSON.stringify(props.params)]);
|
||||||
|
|
||||||
pushMenuItem(item);
|
pushMenuItem(item);
|
||||||
return null;
|
return null;
|
||||||
|
@ -9,11 +9,10 @@
|
|||||||
|
|
||||||
import { observer, useField } from '@formily/react';
|
import { observer, useField } from '@formily/react';
|
||||||
import {
|
import {
|
||||||
appendQueryStringToUrl,
|
|
||||||
parseVariablesAndChangeParamsToQueryString,
|
|
||||||
replaceVariableValue,
|
replaceVariableValue,
|
||||||
useBlockHeight,
|
useBlockHeight,
|
||||||
useLocalVariables,
|
useLocalVariables,
|
||||||
|
useParseURLAndParams,
|
||||||
useRequest,
|
useRequest,
|
||||||
useVariables,
|
useVariables,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
@ -49,7 +48,7 @@ export const Iframe: any = observer(
|
|||||||
ready: mode === 'html' && !!htmlId,
|
ready: mode === 'html' && !!htmlId,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
const { parseURLAndParams } = useParseURLAndParams();
|
||||||
const [src, setSrc] = useState(null);
|
const [src, setSrc] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -61,15 +60,7 @@ export const Iframe: any = observer(
|
|||||||
setSrc(dataUrl);
|
setSrc(dataUrl);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const tempUrl = await replaceVariableValue(url, variables, localVariables);
|
const targetUrl = parseURLAndParams(url, params || []);
|
||||||
const queryString = await parseVariablesAndChangeParamsToQueryString({
|
|
||||||
searchParams: params || [],
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
replaceVariableValue,
|
|
||||||
});
|
|
||||||
|
|
||||||
const targetUrl = appendQueryStringToUrl(tempUrl, queryString);
|
|
||||||
setSrc(targetUrl);
|
setSrc(targetUrl);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching target URL:', error);
|
console.error('Error fetching target URL:', error);
|
||||||
|
@ -7,17 +7,17 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { css } from '@emotion/css';
|
|
||||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import {
|
import {
|
||||||
SchemaSettings,
|
SchemaSettings,
|
||||||
|
SchemaSettingsBlockHeightItem,
|
||||||
Variable,
|
Variable,
|
||||||
useAPIClient,
|
useAPIClient,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
SchemaSettingsBlockHeightItem,
|
|
||||||
useFormBlockContext,
|
useFormBlockContext,
|
||||||
useRecord,
|
useRecord,
|
||||||
|
useURLAndParamsSchema,
|
||||||
useVariableOptions,
|
useVariableOptions,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@ -50,7 +50,7 @@ const commonOptions: any = {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const { mode, url, htmlId, height = '60vh' } = fieldSchema['x-component-props'] || {};
|
const { mode, url, params, htmlId, height = '60vh' } = fieldSchema['x-component-props'] || {};
|
||||||
const saveHtml = async (html: string) => {
|
const saveHtml = async (html: string) => {
|
||||||
const options = {
|
const options = {
|
||||||
values: { html },
|
values: { html },
|
||||||
@ -65,7 +65,7 @@ const commonOptions: any = {
|
|||||||
return data?.data;
|
return data?.data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const { urlSchema, paramsSchema } = useURLAndParamsSchema();
|
||||||
const submitHandler = async ({ mode, url, html, height, params }) => {
|
const submitHandler = async ({ mode, url, html, height, params }) => {
|
||||||
const componentProps = fieldSchema['x-component-props'] || {};
|
const componentProps = fieldSchema['x-component-props'] || {};
|
||||||
componentProps['mode'] = mode;
|
componentProps['mode'] = mode;
|
||||||
@ -94,6 +94,7 @@ const commonOptions: any = {
|
|||||||
mode,
|
mode,
|
||||||
url,
|
url,
|
||||||
height,
|
height,
|
||||||
|
params,
|
||||||
};
|
};
|
||||||
if (htmlId) {
|
if (htmlId) {
|
||||||
// eslint-disable-next-line no-unsafe-optional-chaining
|
// eslint-disable-next-line no-unsafe-optional-chaining
|
||||||
@ -118,89 +119,10 @@ const commonOptions: any = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
title: t('URL'),
|
...urlSchema,
|
||||||
type: 'string',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': getVariableComponentWithScope(Variable.TextArea),
|
|
||||||
description: t('Do not concatenate search params in the URL'),
|
|
||||||
required: true,
|
required: true,
|
||||||
'x-reactions': {
|
|
||||||
dependencies: ['mode'],
|
|
||||||
fulfill: {
|
|
||||||
state: {
|
|
||||||
hidden: '{{$deps[0] === "html"}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
type: 'array',
|
|
||||||
'x-component': 'ArrayItems',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
title: `{{t("Search parameters")}}`,
|
|
||||||
default: fieldSchema?.['x-component-props']?.params || [{}],
|
|
||||||
items: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
space: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Space',
|
|
||||||
'x-component-props': {
|
|
||||||
style: {
|
|
||||||
flexWrap: 'nowrap',
|
|
||||||
maxWidth: '100%',
|
|
||||||
},
|
|
||||||
className: css`
|
|
||||||
& > .ant-space-item:first-child,
|
|
||||||
& > .ant-space-item:last-child {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
name: {
|
|
||||||
type: 'string',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Input',
|
|
||||||
'x-component-props': {
|
|
||||||
placeholder: `{{t("Name")}}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: 'string',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': getVariableComponentWithScope(Variable.TextArea),
|
|
||||||
'x-component-props': {
|
|
||||||
placeholder: `{{t("Value")}}`,
|
|
||||||
useTypedConstant: true,
|
|
||||||
changeOnSelect: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
remove: {
|
|
||||||
type: 'void',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'ArrayItems.Remove',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'x-reactions': {
|
|
||||||
dependencies: ['mode'],
|
|
||||||
fulfill: {
|
|
||||||
state: {
|
|
||||||
hidden: '{{$deps[0] === "html"}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
add: {
|
|
||||||
type: 'void',
|
|
||||||
title: `{{t("Add parameter")}}`,
|
|
||||||
'x-component': 'ArrayItems.Addition',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
params: paramsSchema,
|
||||||
html: {
|
html: {
|
||||||
title: t('html'),
|
title: t('html'),
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
Loading…
Reference in New Issue
Block a user