Commit a05ae88da6b092e5cdd1c8218bff4dabad55c8f2

Authored by 邱嘉伟
2 parents 8bb182d5 a53e7466

Merge branch 'feature/dataflow' of http://gitlab.qgutech.com/tianqiang/qx-common…

… into feature/dataflow

# Conflicts:
#	src/index.ts
#	src/qx-parameter-setting/ParameterModal.tsx
#	src/qx-parameter-setting/index.tsx
1 1 {
2 2 "name": "@qx/common",
3   - "version": "3.0.0-alpha.2",
  3 + "version": "3.0.0-alpha.5",
4 4 "lockfileVersion": 2,
5 5 "requires": true,
6 6 "packages": {
7 7 "": {
8 8 "name": "@qx/common",
9   - "version": "3.0.0-alpha.2",
  9 + "version": "3.0.0-alpha.5",
10 10 "license": "MIT",
11 11 "dependencies": {
12 12 "@ant-design/icons": "^5.2.5",
... ...
1 1 {
2 2 "name": "@qx/common",
3   - "version": "3.0.0-alpha.2",
  3 + "version": "3.0.0-alpha.5",
4 4 "description": "A react library developed with dumi",
5 5 "license": "MIT",
6 6 "module": "dist/index.js",
... ... @@ -45,13 +45,13 @@
45 45 "dependencies": {
46 46 "@ant-design/icons": "^5.2.5",
47 47 "@qx/ui": "0.0.3-beta.1",
  48 + "ahooks": "^3.7.5",
  49 + "classnames": "^2.3.2",
48 50 "codemirror": "5.65.8",
49 51 "dayjs": "^1.11.9",
50 52 "lodash-es": "^4.17.21",
51 53 "rc-virtual-list": "^3.4.13",
52   - "react-codemirror2": "^7.2.1",
53   - "classnames": "^2.3.2",
54   - "ahooks": "^3.7.5"
  54 + "react-codemirror2": "^7.2.1"
55 55 },
56 56 "devDependencies": {
57 57 "@commitlint/cli": "^17.1.2",
... ... @@ -74,16 +74,16 @@
74 74 "react": "^18.0.0",
75 75 "react-cookies": ">=0.1.1",
76 76 "react-dom": "^18.0.0",
77   - "stylelint": "^14.9.1",
78   - "react-router": ">=4.3.1"
  77 + "react-router": ">=4.3.1",
  78 + "stylelint": "^14.9.1"
79 79 },
80 80 "peerDependencies": {
  81 + "@qx/utils": "0.0.58",
  82 + "ahooks": "^3.7.5",
81 83 "antd": ">=5.8.4",
82 84 "react": ">=16.9.0",
83 85 "react-dom": ">=16.9.0",
84   - "ahooks": "^3.7.5",
85   - "react-router": ">=4.3.1",
86   - "@qx/utils": "0.0.58"
  86 + "react-router": ">=4.3.1"
87 87 },
88 88 "publishConfig": {
89 89 "access": "public"
... ...
... ... @@ -4,8 +4,11 @@ export * from './qx-sort-condition';
4 4 export * from './qx-base-icon';
5 5 export * from './qx-tags-input';
6 6 export * from './qx-user-selector';
  7 +export * from './qx-org-selector';
7 8 export * from './qx-form-select';
8 9 export * from './qx-app-selector';
9 10 export * from './utils';
  11 +export * from './qx-field';
10 12 export * from './qx-field-setter';
11   -// export { default as FieldSetter } from './qx-field-setter';
  13 +
  14 +// export * from './qx-btn';
... ...
1   -@import '~@qx/ui/src/style/variable.less';
2   -
3   -.qx-fields-popover {
4   - &.ant-popover {
5   - padding-top: 0;
6   - padding-bottom: 0;
7   - overflow: hidden;
8   - background: #fff;
9   - border-radius: 8px;
10   - box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1);
11   - }
12   -
13   - .ant-popover-arrow {
14   - display: none;
15   - }
16   -
17   - .ant-popover-inner {
18   - padding: 0;
19   - }
20   -
21   - .ant-popover-inner-content {
22   - padding: 0;
23   - overflow: auto;
24   - }
25   -
26   - &__search {
27   - height: 36px;
28   -
29   - .ant-input-prefix {
30   - color: @N7;
31   - font-size: 16px;
32   - }
33   - }
34   -}
35   -
36   -.qx-popover-fields {
37   - max-height: 260px;
38   - margin: 0;
39   - padding: 0;
40   - overflow: auto;
41   -
42   - > li {
43   - padding: 5px 5px 5px 12px;
44   - cursor: pointer;
45   -
46   - &:hover {
47   - background-color: @N3;
48   - }
49   - }
50   -}
51   -
52   -.qx-fields-pop-content {
53   - width: 100%;
54   - max-height: 260px;
55   - overflow-x: hidden;
56   -
57   - &.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title {
58   - margin-top: 0;
59   - margin-bottom: 1px;
60   - background-color: @N2;
61   - }
62   -
63   - .ant-menu-sub.ant-menu-inline {
64   - background-color: #fff;
65   - }
66   -
67   - &.ant-menu-inline > .ant-menu-item,
68   - .ant-menu-sub.ant-menu-inline > .ant-menu-item {
69   - height: 32px;
70   - line-height: 32px;
71   - border-radius: 4px;
72   -
73   - &:hover {
74   - color: inherit;
75   - background-color: @N3;
76   - }
77   - }
78   -
79   - .ant-menu-title-content {
80   - .ant-typography + span {
81   - overflow: hidden;
82   - text-overflow: ellipsis;
83   - }
84   - }
85   -}
86   -.qx-field-pop__footer {
87   - padding-top: 5px;
88   - padding-bottom: 5px;
89   - padding-left: 24px;
90   - border-top: 1px solid @N4;
91   -}
1   -import { Divider, Input, Menu, Popover } from 'antd';
2   -
3   -import * as React from 'react';
4   -import type { ReactElement } from 'react';
5   -import { useEffect, useState } from 'react';
6   -import QxFieldItem from '../qx-field/src/item';
7   -import { useDebounceFn } from 'ahooks';
8   -import { isEmpty } from 'lodash-es';
9   -import { QxBaseIcon } from '@qx/common';
10   -import './index.less';
11   -
12   -export type OptionFieldExtract = {
13   - fieldType?: string;
14   - widget: string;
15   - design?: any;
16   - relId?: string;
17   - //关联数据集的才有
18   - optionsRef?: string;
19   - //关联属性,真实的字段组件
20   - refWidget?: string;
21   - //关联属性,真实的字段类型
22   - refType?: string;
23   - required?: boolean;
24   - // 是否是默认系统字段,值为true时是未配置的系统字段
25   - $default?: boolean;
26   - // 卡片设计 特殊字段配置 回显所用
27   - renderData?: any;
28   -};
29   -
30   -export type OptionField = {
31   - code: string;
32   - name: string;
33   - disabled?: boolean;
34   - //当disabled=true的时候extract不存在
35   - extract?: OptionFieldExtract;
36   -};
37   -
38   -interface QxFieldPopoverProp {
39   - data: OptionField[];
40   - widgets?: string[]; //需要展示的widgets
41   - exclude?: string[]; //排除的字段
42   - width?: string; //pop 宽度
43   - trigger?: 'click' | 'hover' | undefined;
44   - onSelect: (field: OptionField) => void;
45   - disabled?: boolean;
46   - hiddenAfterTrigger?: boolean;
47   - popFooter?: ReactElement;
48   - children?: any;
49   -}
50   -
51   -export const QxFieldPopover: React.FC<QxFieldPopoverProp> = (props) => {
52   - // const [fieldFlatten, setFieldFlatten] = useState<any>({})
53   - const [fields, setFields] = useState<any>([]);
54   - const [filterFields, setFilterFields] = useState<any>([]);
55   - const [visible, setVisible] = useState<boolean>(false);
56   - //TODO 搜索
57   - const [keyword, setKeyword] = useState<string>();
58   -
59   - const getUsefulFieldProp = (field: any) => {
60   - let mode = 'widget'; //TODO 接口废弃,后续要删掉
61   - if (field?.extract) {
62   - mode = 'option';
63   - }
64   - let widget = field?.propertyWidget || field.widget;
65   - let code = field?.fieldName || field.code;
66   - let name = field?.fieldComment || field.title;
67   - let relFunId = field?.relFunId;
68   - if (mode === 'option') {
69   - widget = field?.extract.widget;
70   - relFunId = field?.extract.relId;
71   - code = field?.code;
72   - name = field?.name;
73   - }
74   - return {
75   - widget,
76   - code,
77   - name,
78   - relFunId,
79   - };
80   - };
81   - // @ts-ignore
82   - const excludeFields = (list: OptionField[]) => {
83   - // @ts-ignore
84   - return list.filter((item: any) => {
85   - if (item.children && item.children.length === 0) {
86   - return false;
87   - }
88   -
89   - let allow = true;
90   - const { widget, code } = getUsefulFieldProp(item);
91   - if (props.widgets && props.widgets.length > 0 && props.widgets.indexOf(widget) === -1) {
92   - return false;
93   - }
94   - if (!props.exclude || props.exclude.length === 0) {
95   - allow = true;
96   - } else {
97   - allow = props.exclude.indexOf(code) === -1;
98   - }
99   - return allow;
100   - });
101   - };
102   - useEffect(() => {
103   - if (!isEmpty(props.data)) {
104   - const _fields = excludeFields(props.data);
105   - setFields(_fields);
106   - setFilterFields(_fields);
107   - // setFieldFlatten(flatFields(_fields))
108   - }
109   - }, [props.data]);
110   -
111   - const handleClick = (item: any) => {
112   - if (props.hiddenAfterTrigger) {
113   - setVisible(false);
114   - }
115   - props.onSelect(item);
116   - };
117   -
118   - const { run } = useDebounceFn((field) => handleClick(field), {
119   - wait: 300,
120   - leading: true,
121   - trailing: false,
122   - });
123   -
124   - useEffect(() => {
125   - if (!keyword) {
126   - setFilterFields([...fields]);
127   - } else {
128   - const _filterFields: any = [];
129   -
130   - fields.forEach((item: any) => {
131   - const _item = { ...item };
132   - _item.children = [];
133   - if (item?.children?.length) {
134   - item?.children.forEach((children: any) => {
135   - if (
136   - children?.titleStr?.indexOf(keyword) > -1 ||
137   - children?.name?.indexOf(keyword) > -1
138   - ) {
139   - _item.children.push(children);
140   - }
141   - });
142   - if (_item.children?.length) {
143   - _filterFields.push(_item);
144   - }
145   - } else {
146   - if (item?.titleStr?.indexOf(keyword) > -1 || item?.name?.indexOf(keyword) > -1) {
147   - _filterFields.push(item);
148   - }
149   - }
150   - });
151   - /*const _filterFields = fields.filter(
152   - (item) => item?.titleStr?.indexOf(keyword) > -1 || item?.name?.indexOf(keyword) > -1,
153   - );*/
154   - setFilterFields(_filterFields);
155   - }
156   - }, [keyword, fields]);
157   -
158   - const handleChange = (_keyword: string) => {
159   - setKeyword(_keyword.trim());
160   - };
161   -
162   - const fieldsPopContent = () => {
163   - return (
164   - <div style={{ width: props.width || '192px' }}>
165   - {!fields?.length ? (
166   - <div
167   - className={'ant-empty-normal'}
168   - style={{
169   - textAlign: 'center',
170   - margin: '10px 0',
171   - }}
172   - >
173   - 没有可选字段
174   - </div>
175   - ) : (
176   - <>
177   - <div
178   - onMouseDown={(e) => {
179   - e.preventDefault();
180   - }}
181   - >
182   - <Input
183   - bordered={false}
184   - value={keyword}
185   - className={'qx-fields-popover__search'}
186   - placeholder={'搜索'}
187   - allowClear
188   - prefix={<QxBaseIcon type={'icon-app-search-line'} />}
189   - onChange={(e) => {
190   - handleChange(e.target.value);
191   - }}
192   - />
193   - </div>
194   - <Divider style={{ margin: 0 }} />
195   - {!filterFields.length ? (
196   - <div
197   - className={'ant-empty-normal'}
198   - style={{
199   - textAlign: 'center',
200   - margin: '10px 0',
201   - }}
202   - >
203   - 暂无相关字段
204   - </div>
205   - ) : (
206   - <Menu
207   - mode="inline"
208   - className={'qx-fields-pop-content'}
209   - selectedKeys={[]}
210   - inlineIndent={12}
211   - >
212   - {filterFields.map((field: any) => {
213   - if (!!field?.children?.length) {
214   - return (
215   - <Menu.SubMenu
216   - key={field.code}
217   - title={
218   - field.title || (
219   - <QxFieldItem
220   - widget={field.extract && field.extract.widget}
221   - name={field.name}
222   - />
223   - )
224   - }
225   - >
226   - {field.children.map((item: any) => {
227   - if ((item.children || []).length) {
228   - return (
229   - <Menu.SubMenu
230   - key={item.code}
231   - title={
232   - item.title || (
233   - <QxFieldItem
234   - widget={field.extract && field.extract.widget}
235   - name={field.name}
236   - />
237   - )
238   - }
239   - >
240   - {(item.children || []).map((_it: any) => {
241   - return (
242   - <Menu.Item
243   - key={_it.code}
244   - onClick={() => {
245   - handleClick(_it);
246   - }}
247   - >
248   - {_it.title || (
249   - <QxFieldItem
250   - widget={field.extract && field.extract.widget}
251   - name={field.name}
252   - />
253   - )}
254   - </Menu.Item>
255   - );
256   - })}
257   - </Menu.SubMenu>
258   - );
259   - } else {
260   - return (
261   - <Menu.Item
262   - key={item.code}
263   - onClick={() => {
264   - handleClick(item);
265   - }}
266   - >
267   - {item.title || (
268   - <QxFieldItem
269   - widget={field.extract && field.extract.widget}
270   - name={field.name}
271   - />
272   - )}
273   - </Menu.Item>
274   - );
275   - }
276   - })}
277   - </Menu.SubMenu>
278   - );
279   - } else {
280   - return (
281   - <Menu.Item
282   - style={{
283   - display:
284   - keyword && field?.name?.indexOf(keyword) === -1 ? 'none' : 'block',
285   - }}
286   - onClick={() => {
287   - run(field);
288   - }}
289   - key={field.code}
290   - >
291   - {field.title || (
292   - <QxFieldItem
293   - widget={field.extract && field.extract.widget}
294   - name={field.name}
295   - />
296   - )}
297   - </Menu.Item>
298   - );
299   - }
300   - })}
301   - </Menu>
302   - )}
303   - </>
304   - )}
305   - {props.popFooter ? <div className="qx-field-pop__footer">{props.popFooter}</div> : null}
306   - </div>
307   - );
308   - };
309   -
310   - return (
311   - <Popover
312   - overlayClassName={'qx-fields-popover'}
313   - // getPopupContainer={(triggerNode) => triggerNode}
314   - content={fieldsPopContent()}
315   - placement={'bottomRight'}
316   - trigger={props.disabled ? undefined : props.trigger || 'click'}
317   - open={visible}
318   - onOpenChange={(v) => {
319   - if (!v) {
320   - setTimeout(() => {
321   - setKeyword('');
322   - setFilterFields([...fields]);
323   - }, 0);
324   - }
325   - setVisible(v);
326   - }}
327   - >
328   - {props.children}
329   - </Popover>
330   - );
331   -}
... ... @@ -17,7 +17,7 @@ import { CloseOutlined, ControlOutlined, RightOutlined } from '@ant-design/icons
17 17 import { cloneDeep, isEqual, isEmpty, findIndex, size } from 'lodash-es';
18 18 import { RelTreeSetter } from './components/rel-tree-setter';
19 19 import { AddressSetter } from './components/address-setter';
20   -import {QxFieldPopover} from '../qx-field-popover';
  20 +import {QxFieldPopover} from '@qx/common';
21 21 import { InputSetter } from './components/input-setter';
22 22 import { OrgSetter } from './components/org-setter';
23 23 import { RelSetter } from './components/rel-setter';
... ... @@ -157,7 +157,7 @@ export interface paramColSelectProps extends ColSelectProps {
157 157 allowClear?: boolean;
158 158 }
159 159
160   -export const FieldSetter: React.FC<paramColSelectProps> = ({
  160 +export const QxFieldSetter: React.FC<paramColSelectProps> = ({
161 161 value,
162 162 fieldGroupType,
163 163 fieldType,
... ...
... ... @@ -15,7 +15,7 @@ group:
15 15
16 16 ```tsx
17 17 import React from 'react';
18   -import { QxFieldItem } from './index';
  18 +import { QxFieldItem } from '@qx/common';
19 19
20 20 export default () => {
21 21 return <QxFieldItem name={'标题'} widget={'qxInput'} />;
... ...
1 1 import QxFieldItem from './src/item';
2 2 import QxFieldSelect from './src/select';
  3 +import QxFieldPopover from './src/popover';
  4 +// import QxCheckboxFieldPopover from './src/popover/checkbox';
3 5
4   -export { QxFieldItem, QxFieldSelect };
  6 +export { QxFieldItem, QxFieldSelect, QxFieldPopover };
... ...
... ... @@ -4,7 +4,7 @@ import * as React from 'react';
4 4 import { FC, ReactElement, useEffect, useState } from 'react';
5 5 import type { OptionField } from '../type';
6 6 import { getUsefulFieldProp } from '../util';
7   -import QxFieldItem from '../item';
  7 +import { QxFieldItem } from '@qx/common';
8 8 import './style.less';
9 9 import Checkbox from 'antd/es/checkbox/Checkbox';
10 10 import {QxBaseIcon} from '@qx/common';
... ...
... ... @@ -6,7 +6,7 @@ import { useEffect, useState } from 'react';
6 6 import type { OptionField } from '../type';
7 7 import { getUsefulFieldProp } from '../util';
8 8 // import {flatFields, getUsefulFieldProp} from '../util';
9   -import QxFieldItem from '../item';
  9 +import { QxFieldItem } from '@qx/common';
10 10 import {QxBaseIcon} from '@qx/common';
11 11 import './style.less';
12 12 import { useDebounceFn } from 'ahooks';
... ... @@ -127,107 +127,131 @@ const QxFieldPopover: React.FC<QxFieldPopoverProp> = (props) => {
127 127 </div>
128 128 ) : (
129 129 <>
130   - <Input
131   - className={'qx-selector-sub-search'}
132   - placeholder={'搜索'}
133   - allowClear
134   - prefix={<QxBaseIcon type={'icon-app-search-line'} />}
135   - style={{ paddingTop: '6px' }}
136   - onChange={(e) => {
137   - handleChange(e.target.value);
  130 + <div
  131 + onMouseDown={(e) => {
  132 + e.preventDefault();
138 133 }}
139   - />
  134 + >
  135 + <Input
  136 + bordered={false}
  137 + value={keyword}
  138 + className={'qx-fields-popover__search'}
  139 + placeholder={'搜索'}
  140 + allowClear
  141 + prefix={<QxBaseIcon type={'icon-app-search-line'} />}
  142 + onChange={(e) => {
  143 + handleChange(e.target.value);
  144 + }}
  145 + />
  146 + </div>
140 147 <Divider style={{ margin: 0 }} />
141   - <Menu mode="inline" className={'qx-fields-pop-content'} selectedKeys={[]}>
142   - {filterFields.map((field: any) => {
143   - if (field.children) {
144   - return (
145   - <Menu.SubMenu
146   - key={field.code}
147   - title={
148   - field.title || (
149   - <QxFieldItem
150   - widget={field.extract && field.extract.widget}
151   - name={field.name}
152   - />
153   - )
154   - }
155   - >
156   - {field.children.map((item: any) => {
157   - if ((item.children || []).length) {
158   - return (
159   - <Menu.SubMenu
160   - key={item.code}
161   - title={
162   - item.title || (
  148 + {!filterFields.length ? (
  149 + <div
  150 + className={'ant-empty-normal'}
  151 + style={{
  152 + textAlign: 'center',
  153 + margin: '10px 0',
  154 + }}
  155 + >
  156 + 暂无相关字段
  157 + </div>
  158 + ) : (
  159 + <Menu
  160 + mode="inline"
  161 + className={'qx-fields-pop-content'}
  162 + selectedKeys={[]}
  163 + inlineIndent={12}
  164 + >
  165 + {filterFields.map((field: any) => {
  166 + if (!!field?.children?.length) {
  167 + return (
  168 + <Menu.SubMenu
  169 + key={field.code}
  170 + title={
  171 + field.title || (
  172 + <QxFieldItem
  173 + widget={field.extract && field.extract.widget}
  174 + name={field.name}
  175 + />
  176 + )
  177 + }
  178 + >
  179 + {field.children.map((item: any) => {
  180 + if ((item.children || []).length) {
  181 + return (
  182 + <Menu.SubMenu
  183 + key={item.code}
  184 + title={
  185 + item.title || (
  186 + <QxFieldItem
  187 + widget={field.extract && field.extract.widget}
  188 + name={field.name}
  189 + />
  190 + )
  191 + }
  192 + >
  193 + {(item.children || []).map((_it: any) => {
  194 + return (
  195 + <Menu.Item
  196 + key={_it.code}
  197 + onClick={() => {
  198 + handleClick(_it);
  199 + }}
  200 + >
  201 + {_it.title || (
  202 + <QxFieldItem
  203 + widget={field.extract && field.extract.widget}
  204 + name={field.name}
  205 + />
  206 + )}
  207 + </Menu.Item>
  208 + );
  209 + })}
  210 + </Menu.SubMenu>
  211 + );
  212 + } else {
  213 + return (
  214 + <Menu.Item
  215 + key={item.code}
  216 + onClick={() => {
  217 + handleClick(item);
  218 + }}
  219 + >
  220 + {item.title || (
163 221 <QxFieldItem
164 222 widget={field.extract && field.extract.widget}
165 223 name={field.name}
166 224 />
167   - )
168   - }
169   - >
170   - {(item.children || []).map((_it: any) => {
171   - return (
172   - <Menu.Item
173   - key={_it.code}
174   - onClick={() => {
175   - handleClick(_it);
176   - }}
177   - >
178   - {_it.title || (
179   - <QxFieldItem
180   - widget={field.extract && field.extract.widget}
181   - name={field.name}
182   - />
183   - )}
184   - </Menu.Item>
185   - );
186   - })}
187   - </Menu.SubMenu>
188   - );
189   - } else {
190   - return (
191   - <Menu.Item
192   - key={item.code}
193   - onClick={() => {
194   - handleClick(item);
195   - }}
196   - >
197   - {item.title || (
198   - <QxFieldItem
199   - widget={field.extract && field.extract.widget}
200   - name={field.name}
201   - />
202   - )}
203   - </Menu.Item>
204   - );
205   - }
206   - })}
207   - </Menu.SubMenu>
208   - );
209   - } else {
210   - return (
211   - <Menu.Item
212   - style={{
213   - display: keyword && field?.name?.indexOf(keyword) === -1 ? 'none' : 'block',
214   - }}
215   - onClick={() => {
216   - run(field);
217   - }}
218   - key={field.code}
219   - >
220   - {field.title || (
221   - <QxFieldItem
222   - widget={field.extract && field.extract.widget}
223   - name={field.name}
224   - />
225   - )}
226   - </Menu.Item>
227   - );
228   - }
229   - })}
230   - </Menu>
  225 + )}
  226 + </Menu.Item>
  227 + );
  228 + }
  229 + })}
  230 + </Menu.SubMenu>
  231 + );
  232 + } else {
  233 + return (
  234 + <Menu.Item
  235 + style={{
  236 + display: keyword && field?.name?.indexOf(keyword) === -1 ? 'none' : 'block',
  237 + }}
  238 + onClick={() => {
  239 + run(field);
  240 + }}
  241 + key={field.code}
  242 + >
  243 + {field.title || (
  244 + <QxFieldItem
  245 + widget={field.extract && field.extract.widget}
  246 + name={field.name}
  247 + />
  248 + )}
  249 + </Menu.Item>
  250 + );
  251 + }
  252 + })}
  253 + </Menu>
  254 + )}
231 255 </>
232 256 )}
233 257 {props.popFooter ? <div className="qx-field-pop__footer">{props.popFooter}</div> : null}
... ... @@ -244,6 +268,12 @@ const QxFieldPopover: React.FC<QxFieldPopoverProp> = (props) => {
244 268 trigger={props.disabled ? undefined : props.trigger || 'hover'}
245 269 open={visible}
246 270 onOpenChange={(v) => {
  271 + if (!v) {
  272 + setTimeout(() => {
  273 + setKeyword('');
  274 + setFilterFields([...fields]);
  275 + }, 0);
  276 + }
247 277 setVisible(v);
248 278 }}
249 279 >
... ...
1 1 @import '~@qx/ui/src/style/variable.less';
2 2
3 3 .qx-fields-popover {
4   - padding-top: 0;
  4 + &.ant-popover {
  5 + padding-top: 0;
  6 + padding-bottom: 0;
  7 + overflow: hidden;
  8 + background: #fff;
  9 + border-radius: 8px;
  10 + border: 1px solid #e5e6eb;
  11 + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1);
  12 + }
  13 +
  14 + .ant-popover-inner {
  15 + padding: 0;
  16 + }
5 17
6 18 .ant-popover-arrow {
7 19 display: none;
... ... @@ -11,6 +23,15 @@
11 23 padding: 0;
12 24 overflow: auto;
13 25 }
  26 +
  27 + &__search {
  28 + height: 36px;
  29 +
  30 + .ant-input-prefix {
  31 + color: @N7;
  32 + font-size: 16px;
  33 + }
  34 + }
14 35 }
15 36
16 37 .qx-popover-fields {
... ... @@ -47,15 +68,23 @@
47 68 &.ant-menu-inline > .ant-menu-item,
48 69 .ant-menu-sub.ant-menu-inline > .ant-menu-item {
49 70 height: 32px;
50   - margin: 1px;
51 71 line-height: 32px;
  72 + border-radius: 4px;
52 73
53 74 &:hover {
54 75 color: inherit;
55 76 background-color: @N3;
56 77 }
57 78 }
  79 +
  80 + .ant-menu-title-content {
  81 + .ant-typography + span {
  82 + overflow: hidden;
  83 + text-overflow: ellipsis;
  84 + }
  85 + }
58 86 }
  87 +
59 88 .qx-field-pop__footer {
60 89 padding-top: 5px;
61 90 padding-bottom: 5px;
... ...
... ... @@ -3,19 +3,14 @@ import * as React from 'react';
3 3 import { useEffect, useState } from 'react';
4 4 import type { OptionField, WidgetField } from '../type';
5 5 import { getUsefulFieldProp } from '../util';
6   -import QxFieldItem from '../item';
7   -import { useLocation } from 'react-router';
  6 +import { QxFieldItem } from '@qx/common';
8 7 import { getFieldOptions } from '../../service';
9 8 import './style.less';
10 9
11 10 const QxFieldSelect: React.FC = (props: any) => {
  11 + const {appCode, funCode, schema} = props
12 12 const [fields, setFields] = useState<WidgetField[] | OptionField[]>([]);
13   - const schemaProps = props.schema.props;
14   - // @ts-ignore
15   - const {query} = useLocation();
16   -
17   - const appCode = query?.appCode|| props?.appCode || '8yo7v';
18   - const funCode = query?.funCode|| props?.funCode ||'2eg66';
  13 + const schemaProps = schema?.props;
19 14 const includeFields = (list: WidgetField[] | OptionField[]) => {
20 15 // console.log(list,schemaProps.viewable);
21 16 // @ts-ignore
... ...
1 1 import React, { useEffect, useState } from 'react';
2   -import type { ColsTreeProps } from '../qx-field-setter';
3   -import { FieldSetter } from '../qx-field-setter';
4   -import { QxFieldPopover } from '../qx-field-popover';
  2 +import type { ColsTreeProps } from '@qx/common';
  3 +import { QxFieldSetter } from '@qx/common';
  4 +import {QxFieldPopover} from '@qx/common';
5 5 import { QxBaseIcon } from '@qx/common';
6 6 import { FunctionOutlined } from '@ant-design/icons';
7 7 import {
... ... @@ -625,7 +625,7 @@ export const QxFilterCondition: React.FC<paramFilterConditionProps> = ({
625 625 {Boolean(isUseValOption) ? (
626 626 <div style={{position: 'relative'}}>
627 627 <Button
628   - disabled={!(paramMappings && paramMappings?.length < 20)}
  628 + disabled={(paramMappings && paramMappings?.length > 20)}
629 629 size="small"
630 630 type={'link'}
631 631 onClick={() => setTreeSelectShow(!treeSelectShow)}
... ... @@ -682,10 +682,10 @@ export const QxFilterCondition: React.FC<paramFilterConditionProps> = ({
682 682 <QxFieldPopover
683 683 data={getFields(tableFields || [])}
684 684 onSelect={(field) => onAddCondition(field.code)}
685   - trigger={'click'}
  685 + trigger={(paramMappings && paramMappings?.length > 20) ? undefined : 'click'}
686 686 >
687 687 <Button
688   - disabled={!(paramMappings && paramMappings?.length < 20)}
  688 + disabled={(paramMappings && paramMappings?.length > 20)}
689 689 size="small"
690 690 type={'link'}
691 691 >
... ... @@ -863,7 +863,7 @@ export const QxFilterCondition: React.FC<paramFilterConditionProps> = ({
863 863 </span>
864 864 </div>
865 865 {/* 值选项 TODO field 在工作流那可能有问题 */}
866   - <FieldSetter
  866 + <QxFieldSetter
867 867 value={item?.valuesObj}
868 868 params={props.params || fieldInfo?.params}
869 869 field={getResultField(
... ...
... ... @@ -24,6 +24,8 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => {
24 24 appId,
25 25 request,
26 26 disabled,
  27 + placeholder,
  28 + title
27 29 } = props;
28 30
29 31 const [state, setState] = useSetState<FormSelectState>({
... ... @@ -59,7 +61,7 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => {
59 61 ref={inputSelectRef}
60 62 value={value?.name}
61 63 defaultValue={value?.name}
62   - placeholder="请选择数据源"
  64 + placeholder={placeholder || '请选择数据源'}
63 65 prefix={<BlockOutlined style={{ color: '#52c41a' }} />}
64 66 options={options}
65 67 onChange={handleChange}
... ... @@ -82,7 +84,7 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => {
82 84
83 85 {state.modalVisible ? (
84 86 <QxAppSelector
85   - title="选择数据源"
  87 + title={title || placeholder || "选择数据源"}
86 88 item={{
87 89 flag: 'SINGLE',
88 90 currentId: '',
... ... @@ -94,7 +96,7 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => {
94 96 modalProps={{
95 97 width: 550,
96 98 destroyOnClose: true,
97   - visible: state.modalVisible,
  99 + open: state.modalVisible,
98 100 onOk: () => setState({ modalVisible: false }),
99 101 onCancel: () => setState({ modalVisible: false }),
100 102 }}
... ...
... ... @@ -2,6 +2,7 @@
2 2
3 3 .qx-form-select {
4 4 width: 100%;
  5 + border-radius: 4px;
5 6
6 7 &__dropdown-bottom {
7 8 width: 100% !important;
... ... @@ -10,4 +11,13 @@
10 11 background-color: #fff !important;
11 12 border-top: 1px solid @N4 !important;
12 13 }
  14 + .qx-input-select-dropdown__list-empty {
  15 + display: flex;
  16 + align-items: center;
  17 + justify-content: center;
  18 + flex-direction: column;
  19 + overflow: hidden;
  20 + height: 100%;
  21 + margin: 0;
  22 + }
13 23 }
... ...
  1 +### 选部门组件
  2 +
  3 +```tsx
  4 +/**
  5 + * debug: true
  6 + */
  7 +import { QxOrgSelector, request } from '@qx/common';
  8 +import React from 'react';
  9 +
  10 +export default () => {
  11 + return (
  12 + <div>
  13 + <QxOrgSelector request={request} />
  14 + </div>
  15 + );
  16 +};
  17 +```
  18 +
  19 +### 弹框
  20 +
  21 +```tsx
  22 +import { QxOrgSelector, request } from '@qx/common';
  23 +import React, { useState } from 'react';
  24 +
  25 +export default () => {
  26 + const [visible, setVisible] = useState(false);
  27 + return (
  28 + <div>
  29 + <div onClick={() => setVisible(true)}>点一下</div>
  30 + <QxOrgSelector.Dialog
  31 + request={request}
  32 + checkStrictly
  33 + title={'添加部门'}
  34 + visible={visible}
  35 + multiple={true}
  36 + onOk={(orgIds: any) => {
  37 + console.log(orgIds, 'lllll');
  38 + }}
  39 + onCancel={() => {
  40 + setVisible(false);
  41 + }}
  42 + />
  43 + </div>
  44 + );
  45 +};
  46 +```
... ...
... ... @@ -30,7 +30,7 @@ import React, {
30 30 } from 'react';
31 31 import JSONEditor from './codeMirror';
32 32 import './style.less';
33   -import { FieldSetter } from '@qx/common';
  33 +import { QxFieldSetter } from '@qx/common';
34 34 import { formatEnum } from './constant';
35 35 import {
36 36 typeTranslateFieIdtype,
... ... @@ -705,7 +705,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => {
705 705 ref={inputRef}
706 706 onBlur={() => save('qxProps-default')}
707 707 /> */}
708   - <FieldSetter
  708 + <QxFieldSetter
709 709 value={record.valuesObj || []}
710 710 // value={[{
711 711 // type: typeTranslateItemtype(record.type) || '',
... ...
... ... @@ -19,7 +19,7 @@ import {
19 19 } from 'antd';
20 20 import type { TreeProps } from 'antd/lib/tree';
21 21 import ParameterModal from './ParameterModal';
22   -import { FieldSetter } from '@qx/common';
  22 +import { QxFieldSetter } from '@qx/common';
23 23 import { formatEnum } from './constant';
24 24 // import type { InputRef } from 'antd';
25 25 import {
... ... @@ -29,7 +29,7 @@ import {
29 29 typeTranslateItemtype,
30 30 } from './constant';
31 31
32   -import { cloneDeep, debounce } from 'lodash-es';
  32 +import { cloneDeep } from 'lodash-es';
33 33 import moment from 'dayjs';
34 34 import type { ParamDesignModel } from './constant';
35 35 import { uidGen } from './stringUtil';
... ... @@ -662,7 +662,7 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => {
662 662 </div>
663 663 {props?.isShowField && (
664 664 <div className="opt-left-down">
665   - <FieldSetter
  665 + <QxFieldSetter
666 666 disabled={disabled}
667 667 value={nodeData.valuesObj || []}
668 668 // value={[
... ...
... ... @@ -163,7 +163,10 @@ export const QxSortCondition: React.FC<QxSortConditionProps> = (props) => {
163 163 style={{ width: '100%' }}
164 164 >
165 165 {(sorts || []).map((v: any, k: any) => (
166   - <div style={{ marginBottom: '1em' }} key={v.key}>
  166 + <div
  167 + style={{ marginBottom: sorts?.length - 1 === k ? 0 : '1em' }}
  168 + key={v.key}
  169 + >
167 170 {columns && (
168 171 <Select
169 172 defaultValue={v.key}
... ...
... ... @@ -6,77 +6,26 @@
6 6 */
7 7 import { QxUserSelector } from '@qx/common';
8 8 import React from 'react';
9   -import request from 'umi-request';
10   -
11   -request.interceptors.request.use((url, options) => {
12   - if (url.startsWith('/api/')) {
13   - return { url, options };
14   - }
15   - const headers = { Authorization: 'dev_session:ZGuqjkCF3GMzorijXw7' };
16   - // headers['SERVER-IP'] = '192.168.181.112';
17   -
18   - const fullUrl = url.startsWith('http')
19   - ? url
20   - : `http://10.9.1.180/qx-api${url}`;
21   - return {
22   - url: fullUrl,
23   - options: {
24   - ...options,
25   - ...{
26   - headers: { ...headers, ...(options.customHeaders || {}) },
27   - isInternal: true,
28   - timeout: 30000,
29   - },
30   - },
31   - };
32   -});
33   -
34   -request.interceptors.response.use(async (response, options) => {
35   - if (response.status !== 200) {
36   - return Promise.reject(response);
37   - }
38   -
39   - if (!response.headers.get('content-type')?.includes('application/json')) {
40   - return response.blob();
41   - }
42   -
43   - const body = await response.clone().json();
44   -
45   - // 按正常逻辑处理"文件上传"系列接口
46   - const fsUploadApis = ['/file/checkFile', '/file/uploadByExist', '/fss/file/'];
47   - const isFsUploadApis = fsUploadApis.filter(
48   - (api: string) => options.url.indexOf(api) !== -1,
49   - );
50   - if (isFsUploadApis.length > 0) {
51   - return Promise.resolve(body || null);
52   - }
53   -
54   - if (body.success) {
55   - return Promise.resolve(body.data || null);
56   - }
57   -
58   - console.error('网络请求出错:', body.msg);
59   -
60   - return Promise.reject(body);
61   -});
  9 +import { request } from '@qx/common';
62 10
63 11 export default () => {
64 12 return (
65 13 <div>
66   - <QxUserSelector
67   - request={request}
68   - params={{
69   - org: [{ relType: 'APPOINT_ORG', relIds: [''] }],
70   - pos: null,
71   - range: [
72   - 'ORG:MubDrwZm8IMxuLDU9FM',
73   - 'ORG:a0WZVI96GAdoI5g9IwX',
74   - 'ORG:QPLEku2yJU8hmbpLTtg',
75   - ],
76   - }}
77   - />
  14 + <QxUserSelector request={request} />
  15 +
78 16 <br />
79   - <QxUserSelector request={request} />
  17 + <QxUserSelector
  18 + request={request}
  19 + params={{
  20 + org: [{ relType: 'APPOINT_ORG', relIds: [''] }],
  21 + pos: null,
  22 + range: [
  23 + 'ORG:MubDrwZm8IMxuLDU9FM',
  24 + 'ORG:a0WZVI96GAdoI5g9IwX',
  25 + 'ORG:QPLEku2yJU8hmbpLTtg',
  26 + ],
  27 + }}
  28 + />
80 29 <br />
81 30 <QxUserSelector
82 31 readOnly
... ... @@ -89,6 +38,38 @@ export default () => {
89 38 };
90 39 ```
91 40
  41 +### 弹框
  42 +
  43 +```tsx
  44 +/**
  45 + * debug: true
  46 + */
  47 +import {QxUserSelector} from '@qx/common';
  48 +import React, {useState} from 'react';
  49 +import {request} from '@qx/common';
  50 +
  51 +export default () => {
  52 + const [visible, setVisible] = useState(false)
  53 + return (
  54 + <div>
  55 + <div onClick={()=> setVisible(true)}>点一下</div>
  56 + <QxUserSelector.Dialog
  57 + request={request}
  58 + title={'添加人员'}
  59 + visible={visible}
  60 + multiple={true}
  61 + onOk={(userIds: any) => {
  62 + console.log(userIds,'lllll')
  63 + }}
  64 + onCancel={() => {
  65 + setVisible(false);
  66 + }}
  67 + />
  68 + </div>
  69 + );
  70 +};
  71 +```
  72 +
92 73 ## API
93 74
94 75 | 参数 | 说明 | 类型 | 默认值 |
... ...