fix(client): fix variable component read pretty mode (#1673)

This commit is contained in:
Junyi 2023-04-08 13:40:18 +07:00 committed by GitHub
parent 13b74bde3f
commit 93348c9ce6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 71 deletions

View File

@ -13,7 +13,7 @@ function useOptions({ filter }: CollectionSelectProps) {
const compile = useCompile(); const compile = useCompile();
const { collections = [] } = useCollectionManager(); const { collections = [] } = useCollectionManager();
const filtered = typeof filter === 'function' ? collections.filter(filter) : collections; const filtered = typeof filter === 'function' ? collections.filter(filter) : collections;
return filtered.map(item => ({ return filtered.filter(item => !item.hidden).map(item => ({
label: compile(item.title), label: compile(item.title),
value: item.name, value: item.name,
color: item.category?.color, color: item.category?.color,

View File

@ -1,11 +1,12 @@
import React, { useState, useEffect, useRef, useMemo } from 'react'; import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Input, Cascader, Button } from 'antd'; import { Input, Cascader, Button, Tag } from 'antd';
import { useForm } from '@formily/react'; import { useForm } from '@formily/react';
import { cx, css } from '@emotion/css'; import { cx, css } from '@emotion/css';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import * as sanitizeHTML from 'sanitize-html'; import * as sanitizeHTML from 'sanitize-html';
import { useCompile } from '../..'; import { EllipsisWithTooltip, useCompile } from '../..';
import { useRecord } from '../../../record-provider';
type RangeIndexes = [number, number, number, number]; type RangeIndexes = [number, number, number, number];
@ -380,6 +381,8 @@ export function TextArea(props) {
contentEditable={!disabled} contentEditable={!disabled}
dangerouslySetInnerHTML={{ __html: html }} dangerouslySetInnerHTML={{ __html: html }}
/> />
{!disabled
? (
<Button className={cx('x-button', css` <Button className={cx('x-button', css`
position: relative; position: relative;
`)}> `)}>
@ -435,6 +438,40 @@ export function TextArea(props) {
)} )}
/> />
</Button> </Button>
)
: null
}
</Input.Group> </Input.Group>
); );
} }
TextArea.ReadPretty = (props) => {
const { value, multiline = true, scope } = props;
const compile = useCompile();
const options = compile((typeof scope === 'function' ? scope() : scope) ?? []);
const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [scope]);
const html = renderHTML(value ?? '', keyLabelMap);
const content = (
<span
dangerouslySetInnerHTML={{ __html: html }}
className={css`
overflow: auto;
.ant-tag {
display: inline;
line-height: 19px;
margin: 0 .25em;
padding: 2px 7px;
border-radius: 10px;
}
`}
/>
);
return (
<EllipsisWithTooltip ellipsis popoverContent={content}>
{content}
</EllipsisWithTooltip>
);
}

View File

@ -1,4 +1,4 @@
import { connect } from '@formily/react'; import { connect, mapReadPretty } from '@formily/react';
import { Input } from "./Input"; import { Input } from "./Input";
import { TextArea } from "./TextArea"; import { TextArea } from "./TextArea";
@ -12,7 +12,7 @@ export function Variable() {
Variable.Input = connect(Input); Variable.Input = connect(Input);
Variable.TextArea = connect(TextArea); Variable.TextArea = connect(TextArea, mapReadPretty(TextArea.ReadPretty));
Variable.JSON = connect(JSONInput); Variable.JSON = connect(JSONInput);

View File

@ -1,10 +1,10 @@
import React, { useState } from "react"; import React, { useState, useMemo } from "react";
import { onFieldInputValueChange } from '@formily/core'; import { onFieldInputValueChange, onFormInitialValuesChange } from '@formily/core';
import { observer, connect, mapReadPretty, useFormEffects } from '@formily/react'; import { useForm, observer, connect, mapReadPretty, useFormEffects } from '@formily/react';
import { Tag } from 'antd'; import { Tag } from 'antd';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Variable } from "@nocobase/client"; import { useRecord, Variable } from "@nocobase/client";
import { NAMESPACE } from "../locale"; import { NAMESPACE } from "../locale";
import { useCollectionFieldOptions } from "../variable"; import { useCollectionFieldOptions } from "../variable";
@ -12,10 +12,14 @@ import { useCollectionFieldOptions } from "../variable";
const InternalExpression = observer((props: any) => { const InternalExpression = observer((props: any) => {
const { value, onChange } = props; const { onChange } = props;
const [collection, setCollection] = useState(null); const { values } = useForm();
const [collection, setCollection] = useState(values?.sourceCollection);
useFormEffects(() => { useFormEffects(() => {
onFormInitialValuesChange(form => {
setCollection(form.values.sourceCollection);
});
onFieldInputValueChange('sourceCollection', (f) => { onFieldInputValueChange('sourceCollection', (f) => {
setCollection(f.value); setCollection(f.value);
onChange(null); onChange(null);
@ -26,17 +30,18 @@ const InternalExpression = observer((props: any) => {
return ( return (
<Variable.TextArea <Variable.TextArea
value={value} {...props}
onChange={onChange}
scope={options} scope={options}
/> />
); );
}); });
function Result({ value }) { function Result(props) {
const { t } = useTranslation(); const { t } = useTranslation();
return value const values = useRecord();
? <Tag color="purple">{t('Expression')}</Tag> const options = useMemo(() => useCollectionFieldOptions({ collection: values.sourceCollection }), [values.sourceCollection, values.sourceCollection]);
return props.value
? <Variable.TextArea {...props} scope={options} />
: <Tag>{t('Unconfigured', { ns: NAMESPACE })}</Tag>; : <Tag>{t('Unconfigured', { ns: NAMESPACE })}</Tag>;
} }