fix(association-select): data is incorrect when use data scope (#1491)

* fix(association-select): data is incorrect when use data scope

* fix: update

* feat: improve RemoteSelect performance

* feat: use value instated of options when options is empty

* fix: data scope not work

* fix: loading not work

* feat: prepare database method (#1492)

* fix: environment variables (#1490)

* fix: beforeSubAppLoad emit to async

* feat: support custom plugin deployment in dockerfile (#1494)

* fix: collection importer has incorrect reference (#1495)

* fix: collection importer has incorrect reference

* test: reimport test

* fix: export collectionTemplates

* feat: form/button linkage rules (#1456)

* feat(plugin-workflow): add prompt node

* feat(plugin-workflow): useValueGetter for all instructions and triggers

* feat(plugin-workflow): add workflow block initializer

* refactor(plugin-workflow): change prompt node type to manual

* feat(plugin-workflow): add ModeConfig component for mode

* feat(plugin-workflow): add todo drawer

* feat(plugin-workflow): add block value provider

* feat(plugin-workflow): improve todo block and drawer

* fix(plugin-workflow): fix instruction name in test cases

* fix(plugin-workflow): fix test cases

* refactor(plugin-workflow): change param type of collection field initializer

* feat(plugin-workflow): add filter types for getters

* fix(plugin-workflow): fix assignees variable

* fix(plugin-workflow): filter todo by exist workflow

* fix(plugin-workflow): fix duplicated save action in manual config

* fix(plugin-workflow): fix transaction

* feat(plugin-workflow): destroy workflow will be cascaded

* fix(plugin-workflow): fix merge

* fix(plugin-workflow): fix locale

* fix(plugin-workflow): allow open ui view when executed

* fix(plugin-workflow): change todo table filter

* feat(plugin-workflow): use formula for calculation

* fix(plugin-workflow): fix variable template regexp

* fix(plugin-workflow): fix sub-options logic with types

* refactor(plugin-workflow): drop useless component

* fix(plugin-workflow): fix manual node action button

* feat(plugin-workflow): add new variable input component

* refactor(plugin-workflow): change all variable to new component

* fix(plugin-workflow): fix type

* fix(plugin-workflow): fix functions init

* fix(plugin-workflow): change jsonb to json for stable order

* fix(plugin-workflow): fix duplicated field name when initialize

* fix(plugin-workflow): fix manual result in manual block

* test(plugin-workflow): log field initializer props

* fix(plugin-workflow): fix nullable arguments

* test(plugin-workflow): test initializer fields schema

* fix: observer

* fix(plugin-workflow): adjust hints

* fix(plugin-workflow): fix locale and cursor in variable input

* refactor(plugin-workflow): change status keys

* fix(plugin-workflow): fix parallel instruction

* feat: linkage rules

* refactor: linkage rules

* refactor: linkage rules update

* refactor: linkage rules button

* refactor(linakge rules): suport value action

* refactor(linakge rules): suport value action

* fix(workflow test): workflow test

* refactor(linakge rules): action linkage only for detail form

* refactor(linakge rules):  logic calculation

* refactor(linakge rules):  logic calculation

* refactor(linakge rules):  logic calculation

* refactor(linakge rules):  logic calculation

* refactor(linakge rules):  linkageAction

* refactor(linakge rules):  linkageAction

* refactor(linakge rules): field value  linkageAction

* refactor(linakge rules): local

* refactor(linakge rules): local

* fix(linakge rules): value property

* fix(linakge rules): value property

* fix(linakge rules): value property

* fix(linakge rules): conditionAnalyse

* fix(linakge rules): conditionAnalyse

* fix(linakge rules): conditionAnalyse

* fix(linakge rules): conditionAnalyse form fields

* fix(linakge rules): conditionAnalyse form fields

* fix(linakge rules): conditionAnalyse operators

* fix(linakge rules): form button linkage

* fix(linakge rules): form button linkage

* fix(linakge rules): select component suport pattern

* fix(linakge rules):  component suport field patter for disabled

* fix(linakge rules):  component suport field patter for disabled

* fix(linakge rules):  component suport field patter for disabled

* fix(linakge rules):  component suport field patter for disabled

* fix(action): action desginer suport linkage

* refactor: formula calculation assignment

* refactor: formula calculation assignment

* style: unified component disable style

* feat: richText suport disabled

* feat: condiction suport varible

* feat: condiction suport varible

* refactor: variableInput

* refactor: condiction scope

* refactor: multi level linkage

* fix: empry value linkage

* refactor: components using core schema-component

* fix: fix template reference linkage

* refactor: evalute foumala

* fix: mutual linkage fix

* refactor: variables suport obo&oho

* style: style improve

* style: style improve

* style: style improve

* feat: variables suport m2o

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* fix: actions path

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

* refactor: code improve

---------

Co-authored-by: mytharcher <mytharcher@gmail.com>
Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
Co-authored-by: chenos <chenlinxh@gmail.com>

* fix: support mysql lower_case_table_names=1

* fix(linkageRules): support empty condiction (#1496)

* fix: condiction suport empty

* fix: condiction suport empty

* fix: condiction suport empty

* fix: condiction suport empty

* Update zh_CN.ts (#1481)

Co-authored-by: chenos <chenlinxh@gmail.com>

* fix(remote-select): remove fields parameter

* Update actions.md

* fix: filter

---------

Co-authored-by: ChengLei Shao <chareice@live.com>
Co-authored-by: chenos <chenlinxh@gmail.com>
Co-authored-by: katherinehhh <shunai.tang@hand-china.com>
Co-authored-by: mytharcher <mytharcher@gmail.com>
Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
Co-authored-by: justwho <rov7@qq.com>
Co-authored-by: Pearl C <63629092+pearl-cao@users.noreply.github.com>
This commit is contained in:
Dunqing 2023-02-27 09:14:14 +08:00 committed by GitHub
parent 750081e6aa
commit 68fcadf092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 37 deletions

View File

@ -1,45 +1,76 @@
import { useFieldSchema } from '@formily/react';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { useCollection, useCollectionManager } from '../../../collection-manager';
import { useRecord } from '../../../record-provider';
export default function useServiceOptions(props) {
const { action = 'list', service, value } = props;
const { action = 'list', service, fieldNames } = props;
const params = service?.params || {};
const fieldSchema = useFieldSchema();
const { getField } = useCollection();
const { getCollectionFields } = useCollectionManager();
const record = useRecord();
const recordValue = record[fieldSchema.name];
const normalizeValues = useCallback(
(obj) => {
if (obj && typeof obj === 'object') {
return obj[fieldNames.value];
}
return obj;
},
[fieldNames.value],
);
const value = useMemo(() => {
if (recordValue === undefined || recordValue === null) {
return;
}
if (Array.isArray(recordValue)) {
return recordValue.map(normalizeValues);
} else {
return normalizeValues(recordValue);
}
}, [recordValue, normalizeValues]);
const collectionField = useMemo(() => {
return getField(fieldSchema.name);
}, [fieldSchema.name]);
const sourceValue = record?.[collectionField?.sourceKey];
const filter = useMemo(() => {
if (!collectionField) return params?.filter;
let extraFilter = {};
if (['oho', 'o2m'].includes(collectionField.interface)) {
const eqValue = record?.[collectionField.sourceKey];
extraFilter = {
const isOToAny = ['oho', 'o2m'].includes(collectionField?.interface);
return {
$or: [
{
$and: [
isOToAny
? {
[collectionField.foreignKey]: {
$is: null,
},
}
: null,
params?.filter,
],
},
eqValue !== undefined && eqValue !== null
isOToAny && sourceValue !== undefined && sourceValue !== null
? {
[collectionField.foreignKey]: {
$eq: eqValue,
$eq: sourceValue,
},
}
: null,
].filter(Boolean),
};
value
? {
[fieldNames.value]: {
[Array.isArray(value) ? '$in' : '$eq']: value,
},
}
return params?.filter ? { $and: [extraFilter, params?.filter] } : extraFilter;
}, [params?.filter, getCollectionFields, collectionField]);
: null,
],
};
}, [params?.filter, getCollectionFields, collectionField, sourceValue, value, fieldNames.value]);
return useMemo(() => {
return {

View File

@ -1,7 +1,7 @@
import { LoadingOutlined } from '@ant-design/icons';
import { connect, mapProps, mapReadPretty } from '@formily/react';
import { SelectProps } from 'antd';
import React, { useMemo } from 'react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { ResourceActionOptions, useRequest } from '../../../api-client';
import { useCompile } from '../../hooks';
import { defaultFieldNames, Select } from '../select';
@ -17,10 +17,11 @@ export type RemoteSelectProps<P = any> = SelectProps<P, any> & {
const InternalRemoteSelect = connect(
(props: RemoteSelectProps) => {
const { fieldNames = {}, service = {}, wait = 300, ...others } = props;
const { fieldNames = {}, service = {}, wait = 300, value, objectValue, ...others } = props;
const compile = useCompile();
const firstRun = useRef(false);
const { data, run } = useRequest(
const { data, run, loading } = useRequest(
{
action: 'list',
...service,
@ -35,11 +36,27 @@ const InternalRemoteSelect = connect(
},
},
{
manual: true,
debounceWait: wait,
refreshDeps: [service, fieldNames.label, fieldNames.value],
},
);
const runDep = useMemo(
() =>
JSON.stringify({
service,
fieldNames,
}),
[service, fieldNames],
);
useEffect(() => {
// Lazy load
if (firstRun.current) {
run();
}
}, [runDep]);
const onSearch = async (search) => {
run({
filter: {
@ -55,14 +72,39 @@ const InternalRemoteSelect = connect(
});
};
const normalizeOptions = useCallback(
(obj) => {
if (objectValue || typeof obj === 'object') {
return { ...obj, [fieldNames.label]: compile(obj[fieldNames.label]) };
}
return { [fieldNames.value]: obj, [fieldNames.label]: obj };
},
[objectValue, fieldNames.value],
);
const options = useMemo(() => {
if (!data?.data?.length) {
return value !== undefined && value !== null
? Array.isArray(value)
? value.map(normalizeOptions)
: [normalizeOptions(value)]
: [];
}
return (
data?.data?.map((item) => ({
...item,
[fieldNames.label]: compile(item[fieldNames.label]),
})) || []
);
}, [data, fieldNames.label]);
}, [data, fieldNames.label, objectValue, value]);
const onDropdownVisibleChange = () => {
if (firstRun.current) {
return;
}
run();
firstRun.current = true;
};
return (
<Select
@ -71,7 +113,11 @@ const InternalRemoteSelect = connect(
filterSort={null}
fieldNames={fieldNames}
onSearch={onSearch}
onDropdownVisibleChange={onDropdownVisibleChange}
objectValue={objectValue}
value={value}
{...others}
loading={loading}
options={options}
/>
);
@ -79,7 +125,6 @@ const InternalRemoteSelect = connect(
mapProps(
{
dataSource: 'options',
loading: true,
},
(props, field) => {
return {

View File

@ -77,7 +77,6 @@ const InternalSelect = connect(
}
return v;
};
console.log('props', props);
if (objectValue) {
return <ObjectSelect {...others} value={toValue(value)} mode={mode} />;
}
@ -98,7 +97,6 @@ const InternalSelect = connect(
mapProps(
{
dataSource: 'options',
loading: true,
},
(props, field) => {
return {

View File

@ -7,4 +7,3 @@ export * from './useFieldProps';
export * from './useSchemaComponentContext';
export * from './useFieldComponentOptions';
export * from './useFieldTitle';

View File

@ -15,7 +15,7 @@ import {
Sequelize,
SyncOptions,
Transactionable,
Utils
Utils,
} from 'sequelize';
import { SequelizeStorage, Umzug } from 'umzug';
import { Collection, CollectionOptions, RepositoryType } from './collection';
@ -58,7 +58,7 @@ import {
SyncListener,
UpdateListener,
UpdateWithAssociationsListener,
ValidateListener
ValidateListener,
} from './types';
import { patchSequelizeQueryInterface, snakeCase } from './utils';