Commit a53e7466b5938d08059040fd71446b18bf6a9e8b

Authored by 陈洋
1 parent 263c4354

pref: 修改引用 删除多余文件

1 1 {
2 2 "name": "@qx/common",
3   - "version": "3.0.0-alpha.3",
  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.3",
  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.4",
  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",
... ...
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/common';
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';
... ...
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 };
... ...
... ... @@ -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;
... ...
1 1 import React, { useEffect, useState } from 'react';
2 2 import type { ColsTreeProps } from '@qx/common';
3 3 import { QxFieldSetter } from '@qx/common';
4   -import { QxFieldPopover } from '../qx-field-popover';
  4 +import {QxFieldPopover} from '@qx/common';
5 5 import { QxBaseIcon } from '@qx/common';
6 6 import { FunctionOutlined } from '@ant-design/icons';
7 7 import {
... ...