Showing
9 changed files
with
413 additions
and
90 deletions
| @@ -35,10 +35,11 @@ | @@ -35,10 +35,11 @@ | ||
| 35 | .qx-field-setter { | 35 | .qx-field-setter { |
| 36 | display: flex; | 36 | display: flex; |
| 37 | width: 100%; | 37 | width: 100%; |
| 38 | - background-color: transparent; | ||
| 39 | border: 1px solid @N4; | 38 | border: 1px solid @N4; |
| 40 | border-radius: 4px; | 39 | border-radius: 4px; |
| 41 | min-height: 32px; | 40 | min-height: 32px; |
| 41 | + box-sizing: border-box; | ||
| 42 | + background-color: transparent; | ||
| 42 | 43 | ||
| 43 | &__icon-text { | 44 | &__icon-text { |
| 44 | color: @N9; | 45 | color: @N9; |
| @@ -64,48 +65,62 @@ | @@ -64,48 +65,62 @@ | ||
| 64 | border-radius: 4px 0 0 4px; | 65 | border-radius: 4px 0 0 4px; |
| 65 | box-sizing: border-box; | 66 | box-sizing: border-box; |
| 66 | } | 67 | } |
| 68 | + | ||
| 67 | .ant-select-single:not(.ant-select-customize-input) .ant-select-selector { | 69 | .ant-select-single:not(.ant-select-customize-input) .ant-select-selector { |
| 68 | padding: 0 4px 0 8px; | 70 | padding: 0 4px 0 8px; |
| 69 | } | 71 | } |
| 72 | + | ||
| 70 | .ant-picker { | 73 | .ant-picker { |
| 71 | padding: 4px 8px; | 74 | padding: 4px 8px; |
| 72 | } | 75 | } |
| 76 | + | ||
| 73 | .ant-input-number-input { | 77 | .ant-input-number-input { |
| 74 | padding: 0 8px; | 78 | padding: 0 8px; |
| 75 | line-height: 30px; | 79 | line-height: 30px; |
| 76 | } | 80 | } |
| 81 | + | ||
| 77 | .ant-select.select.qx-filter-select { | 82 | .ant-select.select.qx-filter-select { |
| 78 | - width: calc(100% - 24px); | 83 | + width: calc(100% - 32px); |
| 79 | padding: 0; | 84 | padding: 0; |
| 80 | .ant-select-selector { | 85 | .ant-select-selector { |
| 86 | + border-radius: 6px 0 0 6px; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + .ant-select-selector { | ||
| 81 | min-height: 32px; | 90 | min-height: 32px; |
| 82 | padding: 0 4px 4px 8px; | 91 | padding: 0 4px 4px 8px; |
| 83 | } | 92 | } |
| 93 | + | ||
| 84 | .ant-select-selection-overflow-item { | 94 | .ant-select-selection-overflow-item { |
| 85 | height: 28px; | 95 | height: 28px; |
| 86 | } | 96 | } |
| 97 | + | ||
| 87 | .ant-select-selection-placeholder { | 98 | .ant-select-selection-placeholder { |
| 88 | left: 8px; | 99 | left: 8px; |
| 89 | } | 100 | } |
| 101 | + | ||
| 90 | .ant-select-selection-overflow-item-suffix { | 102 | .ant-select-selection-overflow-item-suffix { |
| 91 | padding-top: 4px; | 103 | padding-top: 4px; |
| 92 | } | 104 | } |
| 93 | } | 105 | } |
| 94 | 106 | ||
| 95 | .ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) | 107 | .ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) |
| 96 | - .ant-select-selector { | 108 | + .ant-select-selector { |
| 97 | box-shadow: none; | 109 | box-shadow: none; |
| 98 | } | 110 | } |
| 111 | + | ||
| 99 | .ant-picker { | 112 | .ant-picker { |
| 100 | padding: 4px 8px; | 113 | padding: 4px 8px; |
| 101 | } | 114 | } |
| 102 | 115 | ||
| 103 | .ant-tag { | 116 | .ant-tag { |
| 104 | font-size: 14px; | 117 | font-size: 14px; |
| 118 | + | ||
| 105 | .anticon + span { | 119 | .anticon + span { |
| 106 | margin-left: 0; | 120 | margin-left: 0; |
| 107 | } | 121 | } |
| 108 | } | 122 | } |
| 123 | + | ||
| 109 | // todo 目前表单名字过长导致页面变形 | 124 | // todo 目前表单名字过长导致页面变形 |
| 110 | .qx-tags-input.ant-input .ant-tag, | 125 | .qx-tags-input.ant-input .ant-tag, |
| 111 | .tag.qx-select-tag { | 126 | .tag.qx-select-tag { |
| @@ -131,10 +146,12 @@ | @@ -131,10 +146,12 @@ | ||
| 131 | font-size: 8px; | 146 | font-size: 8px; |
| 132 | } | 147 | } |
| 133 | } | 148 | } |
| 149 | + | ||
| 134 | .qx-tags-input__box { | 150 | .qx-tags-input__box { |
| 135 | margin-top: 4px; | 151 | margin-top: 4px; |
| 136 | padding-left: 0; | 152 | padding-left: 0; |
| 137 | } | 153 | } |
| 154 | + | ||
| 138 | .qx-tags-input.ant-input > .ant-tag:first-child { | 155 | .qx-tags-input.ant-input > .ant-tag:first-child { |
| 139 | margin-left: unset; | 156 | margin-left: unset; |
| 140 | } | 157 | } |
| 1 | ### 选择表单 | 1 | ### 选择表单 |
| 2 | 2 | ||
| 3 | ```tsx | 3 | ```tsx |
| 4 | -import { request } from '@qx/common'; | 4 | +import { request, QxFormSelect } from '@qx/common'; |
| 5 | import React, { useState } from 'react'; | 5 | import React, { useState } from 'react'; |
| 6 | -import { QxFormSelect } from './index'; | ||
| 7 | 6 | ||
| 8 | export default () => { | 7 | export default () => { |
| 9 | const [value, setValue] = useState({}); | 8 | const [value, setValue] = useState({}); |
| @@ -80,11 +80,12 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => { | @@ -80,11 +80,12 @@ export const QxFormSelect: React.FC<FormSelectProps> = (props) => { | ||
| 80 | ), | 80 | ), |
| 81 | }} | 81 | }} |
| 82 | disabled={disabled} | 82 | disabled={disabled} |
| 83 | + popupOnBody={props?.popupOnBody} | ||
| 83 | /> | 84 | /> |
| 84 | 85 | ||
| 85 | {state.modalVisible ? ( | 86 | {state.modalVisible ? ( |
| 86 | <QxAppSelector | 87 | <QxAppSelector |
| 87 | - title={title || placeholder || "选择数据源"} | 88 | + title={title || placeholder || '选择数据源'} |
| 88 | item={{ | 89 | item={{ |
| 89 | flag: 'SINGLE', | 90 | flag: 'SINGLE', |
| 90 | currentId: '', | 91 | currentId: '', |
| @@ -113,6 +114,7 @@ interface FormSelectProps extends InputSelectProps { | @@ -113,6 +114,7 @@ interface FormSelectProps extends InputSelectProps { | ||
| 113 | appId?: string; | 114 | appId?: string; |
| 114 | request?: any; | 115 | request?: any; |
| 115 | disabled?: boolean; | 116 | disabled?: boolean; |
| 117 | + popupOnBody?: boolean; | ||
| 116 | } | 118 | } |
| 117 | interface FormSelectState { | 119 | interface FormSelectState { |
| 118 | visible: boolean; | 120 | visible: boolean; |
| @@ -73,7 +73,13 @@ export const QxInputSelect = React.forwardRef<any, InputSelectProps>( | @@ -73,7 +73,13 @@ export const QxInputSelect = React.forwardRef<any, InputSelectProps>( | ||
| 73 | {...dropdownProps} | 73 | {...dropdownProps} |
| 74 | /> | 74 | /> |
| 75 | )} | 75 | )} |
| 76 | - getPopupContainer={(triggerNode) => triggerNode} | 76 | + getPopupContainer={(triggerNode) => { |
| 77 | + if (props?.popupOnBody) { | ||
| 78 | + return document.body; | ||
| 79 | + } else { | ||
| 80 | + return triggerNode; | ||
| 81 | + } | ||
| 82 | + }} | ||
| 77 | onOpenChange={onVisibleChange} | 83 | onOpenChange={onVisibleChange} |
| 78 | disabled={disabled} | 84 | disabled={disabled} |
| 79 | > | 85 | > |
| @@ -96,6 +102,7 @@ export interface InputSelectProps extends Omit<InputProps, 'onChange'> { | @@ -96,6 +102,7 @@ export interface InputSelectProps extends Omit<InputProps, 'onChange'> { | ||
| 96 | options?: DropdownContentOptions[]; | 102 | options?: DropdownContentOptions[]; |
| 97 | dropdownProps?: DropdownContentProps; | 103 | dropdownProps?: DropdownContentProps; |
| 98 | disabled?: boolean; | 104 | disabled?: boolean; |
| 105 | + popupOnBody?: boolean; | ||
| 99 | } | 106 | } |
| 100 | export interface InputSelectState { | 107 | export interface InputSelectState { |
| 101 | visible: boolean; | 108 | visible: boolean; |
| 1 | /* eslint-disable array-callback-return */ | 1 | /* eslint-disable array-callback-return */ |
| 2 | /* eslint-disable eqeqeq */ | 2 | /* eslint-disable eqeqeq */ |
| 3 | import { | 3 | import { |
| 4 | - DeleteOutlined, | ||
| 5 | - PlusOutlined, | ||
| 6 | - SisternodeOutlined, | ||
| 7 | SnippetsOutlined, | 4 | SnippetsOutlined, |
| 8 | } from '@ant-design/icons'; | 5 | } from '@ant-design/icons'; |
| 9 | import { | 6 | import { |
| @@ -30,7 +27,7 @@ import React, { | @@ -30,7 +27,7 @@ import React, { | ||
| 30 | } from 'react'; | 27 | } from 'react'; |
| 31 | import JSONEditor from './codeMirror'; | 28 | import JSONEditor from './codeMirror'; |
| 32 | import './style.less'; | 29 | import './style.less'; |
| 33 | -import { QxFieldSetter } from '@qx/common'; | 30 | +import { QxFieldSetter, QxFormSelect, ValueOptionProps } from '@qx/common'; |
| 34 | import { formatEnum } from './constant'; | 31 | import { formatEnum } from './constant'; |
| 35 | import { | 32 | import { |
| 36 | typeTranslateFieIdtype, | 33 | typeTranslateFieIdtype, |
| @@ -39,11 +36,10 @@ import { | @@ -39,11 +36,10 @@ import { | ||
| 39 | typeTranslateItemtype, | 36 | typeTranslateItemtype, |
| 40 | } from './constant'; | 37 | } from './constant'; |
| 41 | // import { Controlled as CodeMirror } from 'react-codemirror2' | 38 | // import { Controlled as CodeMirror } from 'react-codemirror2' |
| 42 | -import { cloneDeep, debounce } from 'lodash-es'; | ||
| 43 | -import _ from 'lodash'; | 39 | +import { cloneDeep, debounce, isEmpty } from 'lodash-es'; |
| 44 | import moment from 'dayjs'; | 40 | import moment from 'dayjs'; |
| 45 | import { QxBaseIcon } from '@qx/common'; | 41 | import { QxBaseIcon } from '@qx/common'; |
| 46 | - | 42 | +import Icon from '@ant-design/icons'; |
| 47 | const valueOptions = [ | 43 | const valueOptions = [ |
| 48 | { key: 'STRING', title: '文本' }, | 44 | { key: 'STRING', title: '文本' }, |
| 49 | { key: 'NUMBER', title: '数字' }, | 45 | { key: 'NUMBER', title: '数字' }, |
| @@ -58,6 +54,8 @@ const valueOptions = [ | @@ -58,6 +54,8 @@ const valueOptions = [ | ||
| 58 | { key: 'ORG', title: '部门' }, | 54 | { key: 'ORG', title: '部门' }, |
| 59 | ]; | 55 | ]; |
| 60 | 56 | ||
| 57 | +import { ReactComponent as SubNodeIcon } from './sub-node.svg'; | ||
| 58 | + | ||
| 61 | const timeFormat = [ | 59 | const timeFormat = [ |
| 62 | { lable: '年', value: 'YEAR' }, | 60 | { lable: '年', value: 'YEAR' }, |
| 63 | { lable: '年-月', value: 'YEAR_MONTH' }, | 61 | { lable: '年-月', value: 'YEAR_MONTH' }, |
| @@ -77,9 +75,11 @@ interface ParameterSettingProps { | @@ -77,9 +75,11 @@ interface ParameterSettingProps { | ||
| 77 | handleChangeField: (val?: any, data?: any) => void; | 75 | handleChangeField: (val?: any, data?: any) => void; |
| 78 | handleChange: (e?: any, data?: any, code?: string) => void; | 76 | handleChange: (e?: any, data?: any, code?: string) => void; |
| 79 | handleDrop: (val: any) => void; | 77 | handleDrop: (val: any) => void; |
| 80 | - handleAddtree: (val: any) => void; | 78 | + handleAddTree: (val: any) => void; |
| 81 | handleAdd: (val: any) => void; | 79 | handleAdd: (val: any) => void; |
| 82 | handleDelete: (val: any) => void; | 80 | handleDelete: (val: any) => void; |
| 81 | + appFormList?: any[]; // 当前应用表单list | ||
| 82 | + request?: any, | ||
| 83 | } | 83 | } |
| 84 | const EditableContext = React.createContext<FormInstance<any> | null>(null); | 84 | const EditableContext = React.createContext<FormInstance<any> | null>(null); |
| 85 | 85 | ||
| @@ -115,7 +115,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -115,7 +115,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 115 | handleCancel, | 115 | handleCancel, |
| 116 | handleDrop, | 116 | handleDrop, |
| 117 | handleAdd, | 117 | handleAdd, |
| 118 | - handleAddtree, | 118 | + handleAddTree, |
| 119 | handleDelete, | 119 | handleDelete, |
| 120 | handleChange, | 120 | handleChange, |
| 121 | handleChangeField, | 121 | handleChangeField, |
| @@ -139,7 +139,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -139,7 +139,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | const checkShowTree = (_data: any) => { | 141 | const checkShowTree = (_data: any) => { |
| 142 | - console.log('_data', _data) | 142 | + // console.log('_data', _data) |
| 143 | if (_data.type == 'ARRAY') { | 143 | if (_data.type == 'ARRAY') { |
| 144 | if (_data.child && _data.child.length > 0) { | 144 | if (_data.child && _data.child.length > 0) { |
| 145 | return false; | 145 | return false; |
| @@ -243,36 +243,33 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -243,36 +243,33 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 243 | dataIndex: 'qxProps', | 243 | dataIndex: 'qxProps', |
| 244 | editable: true, | 244 | editable: true, |
| 245 | key: 'qxProps', | 245 | key: 'qxProps', |
| 246 | - render: (text, record) => ( | ||
| 247 | - <div key={record.id}> | ||
| 248 | - <span> | ||
| 249 | - {record.type == 'TIME' | ||
| 250 | - ? moment(text?.min).format( | ||
| 251 | - formatEnum[text?.format] || 'YYYY-MM-DD', | ||
| 252 | - ) | ||
| 253 | - : text?.min} | ||
| 254 | - </span> | ||
| 255 | - {text?.min && ( | ||
| 256 | - <Space style={{ marginLeft: 5, marginRight: 5 }}>-</Space> | ||
| 257 | - )} | ||
| 258 | - <span> | ||
| 259 | - {record.type == 'TIME' | ||
| 260 | - ? moment(text?.max).format( | ||
| 261 | - formatEnum[text?.format] || 'YYYY-MM-DD', | ||
| 262 | - ) | ||
| 263 | - : text?.max} | ||
| 264 | - </span> | ||
| 265 | - </div> | ||
| 266 | - // <Form.Item | ||
| 267 | - // name={'qxProps' + record.id} | ||
| 268 | - // > | ||
| 269 | - // <> | ||
| 270 | - // <Input disabled={record.disabled} defaultValue={text?.min} onBlur={(e) => props.handleChange(e, record, 'qxProps-min')} style={{ width: '45%' }} /> | ||
| 271 | - // - | ||
| 272 | - // <Input disabled={record.disabled} defaultValue={text?.max} onBlur={(e) => props.handleChange(e, record, 'qxProps-max')} style={{ width: '45%' }} /> | ||
| 273 | - // </> | ||
| 274 | - // </Form.Item> | ||
| 275 | - ), | 246 | + render: (text: any, record: any) => { |
| 247 | + console.log('record ====', record); | ||
| 248 | + console.log('text ====', text); | ||
| 249 | + return ( | ||
| 250 | + <> | ||
| 251 | + {record.type === 'FORM' ? <> | ||
| 252 | + <div key={record.id}> | ||
| 253 | + <span> | ||
| 254 | + {text?.name} | ||
| 255 | + </span> | ||
| 256 | + </div> | ||
| 257 | + </> : <> | ||
| 258 | + <div key={record.id}> | ||
| 259 | + <span>{record.type == 'TIME' ? moment(text?.min).format( | ||
| 260 | + formatEnum[text?.format] || 'YYYY-MM-DD',) : text?.min} | ||
| 261 | + </span> | ||
| 262 | + {text?.min && ( | ||
| 263 | + <Space style={{marginLeft: 5, marginRight: 5}}>-</Space> | ||
| 264 | + )} | ||
| 265 | + <span>{record.type == 'TIME' ? moment(text?.max).format( | ||
| 266 | + formatEnum[text?.format] || 'YYYY-MM-DD',) : text?.max} | ||
| 267 | + </span> | ||
| 268 | + </div> | ||
| 269 | + </>} | ||
| 270 | + </> | ||
| 271 | + ) | ||
| 272 | + }, | ||
| 276 | }, | 273 | }, |
| 277 | { | 274 | { |
| 278 | title: '必填', | 275 | title: '必填', |
| @@ -343,26 +340,29 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -343,26 +340,29 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 343 | <Space size="small"> | 340 | <Space size="small"> |
| 344 | {isShowAdd && ( | 341 | {isShowAdd && ( |
| 345 | <Button | 342 | <Button |
| 343 | + size={'small'} | ||
| 346 | type="link" | 344 | type="link" |
| 347 | disabled={record.disabled} | 345 | disabled={record.disabled} |
| 348 | - icon={<PlusOutlined />} | 346 | + icon={<QxBaseIcon style={{fontSize: 16}} type={'qx-icon-plus'} />} |
| 349 | onClick={() => handleAdd(record.pid)} | 347 | onClick={() => handleAdd(record.pid)} |
| 350 | /> | 348 | /> |
| 351 | )} | 349 | )} |
| 352 | {(record.type === 'OBJECT' || record.type === 'ARRAY') && | 350 | {(record.type === 'OBJECT' || record.type === 'ARRAY') && |
| 353 | isShowTree && ( | 351 | isShowTree && ( |
| 354 | <Button | 352 | <Button |
| 353 | + size={'small'} | ||
| 355 | type="link" | 354 | type="link" |
| 356 | disabled={record.disabled} | 355 | disabled={record.disabled} |
| 357 | - icon={<SisternodeOutlined />} | ||
| 358 | - onClick={() => handleAddtree(record.id)} | 356 | + icon={<Icon style={{fontSize: 16}} component={SubNodeIcon} />} |
| 357 | + onClick={() => handleAddTree(record.id)} | ||
| 359 | /> | 358 | /> |
| 360 | )} | 359 | )} |
| 361 | <Button | 360 | <Button |
| 361 | + size={'small'} | ||
| 362 | type="link" | 362 | type="link" |
| 363 | className="btn-high-del" | 363 | className="btn-high-del" |
| 364 | disabled={record.disabled} | 364 | disabled={record.disabled} |
| 365 | - icon={<DeleteOutlined />} | 365 | + icon={<QxBaseIcon style={{fontSize: 16}} className={'title-btn-del-btn'} type={'qx-icon-delete'} />} |
| 366 | onClick={() => handleDelete(record)} | 366 | onClick={() => handleDelete(record)} |
| 367 | /> | 367 | /> |
| 368 | </Space> | 368 | </Space> |
| @@ -648,6 +648,28 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -648,6 +648,28 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 648 | </Select> | 648 | </Select> |
| 649 | </div> | 649 | </div> |
| 650 | ); | 650 | ); |
| 651 | + case 'FORM': | ||
| 652 | + return ( | ||
| 653 | + <div | ||
| 654 | + key={record.id} | ||
| 655 | + ref={inputRef} | ||
| 656 | + className="editable-around-cell" | ||
| 657 | + onBlur={(e) => toggleEdit1(e)} tabIndex={ | ||
| 658 | + 0 | ||
| 659 | + } | ||
| 660 | + > | ||
| 661 | + <QxFormSelect | ||
| 662 | + value={qxProps} | ||
| 663 | + request={props?.request} | ||
| 664 | + options={props?.appFormList} | ||
| 665 | + placeholder={'选择表单'} | ||
| 666 | + popupOnBody={true} | ||
| 667 | + onChange={(val: any) => { | ||
| 668 | + props.handleChange(val, record, 'qxProps'); | ||
| 669 | + }} | ||
| 670 | + /> | ||
| 671 | + </div> | ||
| 672 | + ); | ||
| 651 | default: | 673 | default: |
| 652 | return ( | 674 | return ( |
| 653 | <div | 675 | <div |
| @@ -678,7 +700,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -678,7 +700,7 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 678 | }; | 700 | }; |
| 679 | 701 | ||
| 680 | const handleField = (val) => { | 702 | const handleField = (val) => { |
| 681 | - if (!val || _.isEmpty(val)) { | 703 | + if (!val || isEmpty(val)) { |
| 682 | return; | 704 | return; |
| 683 | } | 705 | } |
| 684 | if (val[0].extVal) { | 706 | if (val[0].extVal) { |
| @@ -1041,8 +1063,8 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | @@ -1041,8 +1063,8 @@ const ParameterModal: React.FC<ParameterSettingProps> = (props) => { | ||
| 1041 | ) : ( | 1063 | ) : ( |
| 1042 | <Row> | 1064 | <Row> |
| 1043 | <Col span={12}> | 1065 | <Col span={12}> |
| 1044 | - <Button type="link" onClick={() => onOpen()}> | ||
| 1045 | - {'</>JSON参数设置'} | 1066 | + <Button type="link" icon={<QxBaseIcon style={{fontSize: 16}} type={'qx-icon-flow-code'} />} onClick={() => onOpen()}> |
| 1067 | + JSON参数设置 | ||
| 1046 | </Button> | 1068 | </Button> |
| 1047 | </Col> | 1069 | </Col> |
| 1048 | <Col | 1070 | <Col |
| 1 | /* eslint-disable eqeqeq */ | 1 | /* eslint-disable eqeqeq */ |
| 2 | /* eslint-disable array-callback-return */ | 2 | /* eslint-disable array-callback-return */ |
| 3 | import React, { useCallback, useEffect, useState } from 'react'; | 3 | import React, { useCallback, useEffect, useState } from 'react'; |
| 4 | -// import type { FRWidgetProps } from '@/packages/qx-form-generator/src'; | ||
| 5 | -import { | ||
| 6 | - DeleteOutlined, | ||
| 7 | - PlusOutlined, | ||
| 8 | - SettingOutlined, | ||
| 9 | -} from '@ant-design/icons'; | ||
| 10 | import { | 4 | import { |
| 11 | Button, | 5 | Button, |
| 12 | Dropdown, | 6 | Dropdown, |
| @@ -17,6 +11,7 @@ import { | @@ -17,6 +11,7 @@ import { | ||
| 17 | Tree, | 11 | Tree, |
| 18 | message, | 12 | message, |
| 19 | } from 'antd'; | 13 | } from 'antd'; |
| 14 | +import Icon from '@ant-design/icons'; | ||
| 20 | import type { TreeProps } from 'antd/lib/tree'; | 15 | import type { TreeProps } from 'antd/lib/tree'; |
| 21 | import ParameterModal from './ParameterModal'; | 16 | import ParameterModal from './ParameterModal'; |
| 22 | import { formatEnum } from './constant'; | 17 | import { formatEnum } from './constant'; |
| @@ -36,6 +31,8 @@ import { QxFieldSetter, QxBaseIcon } from '@qx/common'; | @@ -36,6 +31,8 @@ import { QxFieldSetter, QxBaseIcon } from '@qx/common'; | ||
| 36 | 31 | ||
| 37 | import './style.less'; | 32 | import './style.less'; |
| 38 | 33 | ||
| 34 | +import { ReactComponent as SubNodeIcon } from './sub-node.svg'; | ||
| 35 | + | ||
| 39 | const valueOptions = [ | 36 | const valueOptions = [ |
| 40 | { key: 'STRING', label: '文本' }, | 37 | { key: 'STRING', label: '文本' }, |
| 41 | { key: 'NUMBER', label: '数字' }, | 38 | { key: 'NUMBER', label: '数字' }, |
| @@ -70,12 +67,13 @@ interface ParameterSettingProps { | @@ -70,12 +67,13 @@ interface ParameterSettingProps { | ||
| 70 | onChange: (val: any) => void; | 67 | onChange: (val: any) => void; |
| 71 | value: any; | 68 | value: any; |
| 72 | isHideSearch?: boolean; //是否隐藏搜索框 | 69 | isHideSearch?: boolean; //是否隐藏搜索框 |
| 73 | - isShowTitle?: boolean; //是否显示左侧标题 | ||
| 74 | - isShowField?: boolean; //是否显示下部默认值组件 | ||
| 75 | - title?: string; | 70 | + isShowField?: boolean; // 是否显示下部默认值组件 |
| 71 | + title?: React.ReactNode; // 左侧标题 | ||
| 76 | // component?: any; | 72 | // component?: any; |
| 77 | // componentItem?: any; | 73 | // componentItem?: any; |
| 78 | // comHandleChange?: (val: any) => void; | 74 | // comHandleChange?: (val: any) => void; |
| 75 | + appFormList?: any[]; // 当前应用表单list | ||
| 76 | + request?: any, | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | 79 | export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { |
| @@ -451,7 +449,7 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -451,7 +449,7 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 451 | }; | 449 | }; |
| 452 | 450 | ||
| 453 | //增加子节点 | 451 | //增加子节点 |
| 454 | - const onAddtree = (key: string) => { | 452 | + const onAddTree = (key: string) => { |
| 455 | function addNode(pid: string, data: any) { | 453 | function addNode(pid: string, data: any) { |
| 456 | data.forEach((item) => { | 454 | data.forEach((item) => { |
| 457 | const id = uidGen(); | 455 | const id = uidGen(); |
| @@ -623,18 +621,18 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -623,18 +621,18 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 623 | {(nodeData.type === 'OBJECT' || nodeData.type === 'ARRAY') && | 621 | {(nodeData.type === 'OBJECT' || nodeData.type === 'ARRAY') && |
| 624 | isShowTree && ( | 622 | isShowTree && ( |
| 625 | <Button | 623 | <Button |
| 626 | - icon={<PlusOutlined />} | 624 | + icon={<Icon component={SubNodeIcon} />} |
| 627 | disabled={disabled} | 625 | disabled={disabled} |
| 628 | - type="text" | 626 | + type="link" |
| 629 | className="title-btn" | 627 | className="title-btn" |
| 630 | - onClick={() => onAddtree(nodeData.id)} | 628 | + onClick={() => onAddTree(nodeData.id)} |
| 631 | /> | 629 | /> |
| 632 | )} | 630 | )} |
| 633 | <Button | 631 | <Button |
| 634 | className="title-btn-del" | 632 | className="title-btn-del" |
| 635 | - icon={<DeleteOutlined />} | 633 | + icon={<QxBaseIcon className={'title-btn-del-btn'} type={'qx-icon-delete'} />} |
| 636 | disabled={disabled} | 634 | disabled={disabled} |
| 637 | - type="text" | 635 | + type="link" |
| 638 | onClick={() => deleteParameter(nodeData)} | 636 | onClick={() => deleteParameter(nodeData)} |
| 639 | /> | 637 | /> |
| 640 | </div> | 638 | </div> |
| @@ -702,18 +700,28 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -702,18 +700,28 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 702 | /> | 700 | /> |
| 703 | )} | 701 | )} |
| 704 | > | 702 | > |
| 705 | - <Button type={'link'}> | ||
| 706 | - <PlusOutlined /> | 703 | + <Button |
| 704 | + size={'small'} | ||
| 705 | + type={'link'} | ||
| 706 | + style={{ | ||
| 707 | + padding: '0 0 0 8px', | ||
| 708 | + }} | ||
| 709 | + > | ||
| 710 | + <QxBaseIcon style={{fontSize: '16px'}} type={'qx-icon-plus'} /> | ||
| 707 | 添加参数 | 711 | 添加参数 |
| 708 | </Button> | 712 | </Button> |
| 709 | </Dropdown> | 713 | </Dropdown> |
| 710 | <Button | 714 | <Button |
| 715 | + size={'small'} | ||
| 711 | type={'link'} | 716 | type={'link'} |
| 717 | + style={{ | ||
| 718 | + padding: '0 0 0 12px', | ||
| 719 | + }} | ||
| 712 | onClick={() => { | 720 | onClick={() => { |
| 713 | openModal(); | 721 | openModal(); |
| 714 | }} | 722 | }} |
| 715 | > | 723 | > |
| 716 | - <SettingOutlined /> | 724 | + <QxBaseIcon style={{fontSize: '16px'}} type={'icon-app-terminal-box-line'} /> |
| 717 | 高级设置 | 725 | 高级设置 |
| 718 | </Button> | 726 | </Button> |
| 719 | </div> | 727 | </div> |
| @@ -725,9 +733,9 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -725,9 +733,9 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 725 | onChange={onChange} | 733 | onChange={onChange} |
| 726 | /> | 734 | /> |
| 727 | )} | 735 | )} |
| 728 | - {props.isShowTitle && ( | ||
| 729 | - <div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}> | ||
| 730 | - <span style={{ fontSize: '18px' }}>{props.title}</span> | 736 | + {props.isHideSearch && !!props.title && ( |
| 737 | + <div className={'header-title'}> | ||
| 738 | + {props.title} | ||
| 731 | </div> | 739 | </div> |
| 732 | )} | 740 | )} |
| 733 | </div> | 741 | </div> |
| @@ -749,8 +757,6 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -749,8 +757,6 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 749 | onDrop={onDrop} | 757 | onDrop={onDrop} |
| 750 | draggable | 758 | draggable |
| 751 | blockNode | 759 | blockNode |
| 752 | - selectable | ||
| 753 | - checkStrictly={true} //??这是啥意思 | ||
| 754 | expandedKeys={expandedKeys ? expandedKeys : defaultExpandedKeys} | 760 | expandedKeys={expandedKeys ? expandedKeys : defaultExpandedKeys} |
| 755 | autoExpandParent={autoExpandParent} | 761 | autoExpandParent={autoExpandParent} |
| 756 | onExpand={onExpand} | 762 | onExpand={onExpand} |
| @@ -769,8 +775,10 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | @@ -769,8 +775,10 @@ export const QxParameterSetting: React.FC<ParameterSettingProps> = (props) => { | ||
| 769 | handleDelete={deleteParameter} | 775 | handleDelete={deleteParameter} |
| 770 | handleChange={handleChange} | 776 | handleChange={handleChange} |
| 771 | handleDrop={handleDrop} | 777 | handleDrop={handleDrop} |
| 772 | - handleAddtree={onAddtree} | 778 | + handleAddTree={onAddTree} |
| 773 | visible={visible} | 779 | visible={visible} |
| 780 | + request={props?.request} | ||
| 781 | + appFormList={props?.appFormList} | ||
| 774 | /> | 782 | /> |
| 775 | </div> | 783 | </div> |
| 776 | ); | 784 | ); |
src/qx-parameter-setting/mock.ts
0 → 100644
| 1 | +export const appFormList = [ | ||
| 2 | + { | ||
| 3 | + name: '地址', | ||
| 4 | + code: 'UdXaoSj9EHYr3wZL253', | ||
| 5 | + extract: { | ||
| 6 | + code: 'o72gf', | ||
| 7 | + isTree: false, | ||
| 8 | + appName: 'LT-表单', | ||
| 9 | + type: 'form', | ||
| 10 | + }, | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + name: '测试关联记录按钮', | ||
| 14 | + code: 'ZRLa6NjJ98u3lFVLSur', | ||
| 15 | + extract: { | ||
| 16 | + code: 'vwxxw', | ||
| 17 | + isTree: false, | ||
| 18 | + appName: 'LT-表单', | ||
| 19 | + type: 'form', | ||
| 20 | + }, | ||
| 21 | + }, | ||
| 22 | + { | ||
| 23 | + name: '测试关联记录权限', | ||
| 24 | + code: 'SRqC0JJmcjKquqnn228', | ||
| 25 | + extract: { | ||
| 26 | + code: '60jte', | ||
| 27 | + isTree: false, | ||
| 28 | + appName: 'LT-表单', | ||
| 29 | + type: 'form', | ||
| 30 | + }, | ||
| 31 | + }, | ||
| 32 | + { | ||
| 33 | + name: '子表', | ||
| 34 | + code: 'GYsqE8yphn1amjVM2OY', | ||
| 35 | + extract: { | ||
| 36 | + code: 'oi0d2', | ||
| 37 | + isTree: false, | ||
| 38 | + appName: 'LT-表单', | ||
| 39 | + type: 'form', | ||
| 40 | + }, | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + name: '关联基础', | ||
| 44 | + code: '2wN04K7nF0fHjRbOAvu', | ||
| 45 | + extract: { | ||
| 46 | + code: '0jpbl', | ||
| 47 | + isTree: false, | ||
| 48 | + appName: 'LT-表单', | ||
| 49 | + type: 'form', | ||
| 50 | + }, | ||
| 51 | + }, | ||
| 52 | + { | ||
| 53 | + name: '关联记录', | ||
| 54 | + code: 's6k5W5aovjtiU7kvqVl', | ||
| 55 | + extract: { | ||
| 56 | + code: 'zbynu', | ||
| 57 | + isTree: false, | ||
| 58 | + appName: 'LT-表单', | ||
| 59 | + type: 'form', | ||
| 60 | + }, | ||
| 61 | + }, | ||
| 62 | + { | ||
| 63 | + name: '关联记录-关联记录', | ||
| 64 | + code: 'hfbs4k6Lbs4WV7tOept', | ||
| 65 | + extract: { | ||
| 66 | + code: 'fz7nl', | ||
| 67 | + isTree: false, | ||
| 68 | + appName: 'LT-表单', | ||
| 69 | + type: 'form', | ||
| 70 | + }, | ||
| 71 | + }, | ||
| 72 | + { | ||
| 73 | + name: '关联属性-关联记录', | ||
| 74 | + code: 'WPjXCOemcBxoXqeEX6x', | ||
| 75 | + extract: { | ||
| 76 | + code: 's585f', | ||
| 77 | + isTree: false, | ||
| 78 | + appName: 'LT-表单', | ||
| 79 | + type: 'form', | ||
| 80 | + }, | ||
| 81 | + }, | ||
| 82 | + { | ||
| 83 | + name: '子表-关联记录', | ||
| 84 | + code: 'H3moABKMnhVqjqcVbsa', | ||
| 85 | + extract: { | ||
| 86 | + code: 'snfhq', | ||
| 87 | + isTree: false, | ||
| 88 | + appName: 'LT-表单', | ||
| 89 | + type: 'form', | ||
| 90 | + }, | ||
| 91 | + }, | ||
| 92 | + { | ||
| 93 | + name: '关联记录1', | ||
| 94 | + code: 'PQspcwgyiewytF9iizd', | ||
| 95 | + extract: { | ||
| 96 | + code: 'f53ql', | ||
| 97 | + isTree: false, | ||
| 98 | + appName: 'LT-表单', | ||
| 99 | + type: 'form', | ||
| 100 | + }, | ||
| 101 | + }, | ||
| 102 | + { | ||
| 103 | + name: '富文本', | ||
| 104 | + code: 'On7QbrZv9u1qtVgMAGm', | ||
| 105 | + extract: { | ||
| 106 | + code: 'tmh23', | ||
| 107 | + isTree: false, | ||
| 108 | + appName: 'LT-表单', | ||
| 109 | + type: 'form', | ||
| 110 | + }, | ||
| 111 | + }, | ||
| 112 | + { | ||
| 113 | + name: '关联记录删除', | ||
| 114 | + code: 'MdUFSBxWOYKXSYGSqSk', | ||
| 115 | + extract: { | ||
| 116 | + code: 'uxenf', | ||
| 117 | + isTree: false, | ||
| 118 | + appName: 'LT-表单', | ||
| 119 | + type: 'form', | ||
| 120 | + }, | ||
| 121 | + }, | ||
| 122 | + { | ||
| 123 | + name: '1', | ||
| 124 | + code: 'HAJ8dEcoPLnjx81Uxjc', | ||
| 125 | + extract: { | ||
| 126 | + code: '3xtcr', | ||
| 127 | + isTree: false, | ||
| 128 | + appName: 'LT-表单', | ||
| 129 | + type: 'form', | ||
| 130 | + }, | ||
| 131 | + }, | ||
| 132 | + { | ||
| 133 | + name: '基础表单', | ||
| 134 | + code: 'oOY4njEfrHx7PlSlFRf', | ||
| 135 | + extract: { | ||
| 136 | + code: 'fd3eb', | ||
| 137 | + isTree: false, | ||
| 138 | + appName: 'LT-表单', | ||
| 139 | + type: 'form', | ||
| 140 | + }, | ||
| 141 | + }, | ||
| 142 | + { | ||
| 143 | + name: '关联记录', | ||
| 144 | + code: 'HaIdxngReF8WtKclakp', | ||
| 145 | + extract: { | ||
| 146 | + code: 'qbroi', | ||
| 147 | + isTree: false, | ||
| 148 | + appName: 'LT-表单', | ||
| 149 | + type: 'form', | ||
| 150 | + }, | ||
| 151 | + }, | ||
| 152 | + { | ||
| 153 | + name: '筛选', | ||
| 154 | + code: 'amWz1TlerTCrysLhKdD', | ||
| 155 | + extract: { | ||
| 156 | + code: 'ionr7', | ||
| 157 | + isTree: false, | ||
| 158 | + appName: 'LT-表单', | ||
| 159 | + type: 'form', | ||
| 160 | + }, | ||
| 161 | + }, | ||
| 162 | + { | ||
| 163 | + name: '子表', | ||
| 164 | + code: 'JV5IeD1Xc4MtwWdbPhB', | ||
| 165 | + extract: { | ||
| 166 | + code: 'x4lh4', | ||
| 167 | + isTree: false, | ||
| 168 | + appName: 'LT-表单', | ||
| 169 | + type: 'form', | ||
| 170 | + }, | ||
| 171 | + }, | ||
| 172 | + { | ||
| 173 | + name: '附件图片', | ||
| 174 | + code: 'jCfTNFw7tjERB5jnnWv', | ||
| 175 | + extract: { | ||
| 176 | + code: 'pqqko', | ||
| 177 | + isTree: false, | ||
| 178 | + appName: 'LT-表单', | ||
| 179 | + type: 'form', | ||
| 180 | + }, | ||
| 181 | + }, | ||
| 182 | + { | ||
| 183 | + name: '日期时间', | ||
| 184 | + code: 'WruqGjaxMj0jLsZ6Ufr', | ||
| 185 | + extract: { | ||
| 186 | + code: 'z15we', | ||
| 187 | + isTree: false, | ||
| 188 | + appName: 'LT-表单', | ||
| 189 | + type: 'form', | ||
| 190 | + }, | ||
| 191 | + }, | ||
| 192 | + { | ||
| 193 | + name: '选人员部门', | ||
| 194 | + code: 'wqsubyh5kJFsxXuHYyQ', | ||
| 195 | + extract: { | ||
| 196 | + code: '0h42r', | ||
| 197 | + isTree: false, | ||
| 198 | + appName: 'LT-表单', | ||
| 199 | + type: 'form', | ||
| 200 | + }, | ||
| 201 | + }, | ||
| 202 | + { | ||
| 203 | + name: '数值', | ||
| 204 | + code: 'HEsh8KhnUToggsWuboT', | ||
| 205 | + extract: { | ||
| 206 | + code: 'bb8ev', | ||
| 207 | + isTree: false, | ||
| 208 | + appName: 'LT-表单', | ||
| 209 | + type: 'form', | ||
| 210 | + }, | ||
| 211 | + }, | ||
| 212 | + { | ||
| 213 | + name: '多字段', | ||
| 214 | + code: 'deTV0Jjc1prqYZTERfN', | ||
| 215 | + extract: { | ||
| 216 | + code: 'hxaxj', | ||
| 217 | + isTree: false, | ||
| 218 | + appName: 'LT-表单', | ||
| 219 | + type: 'form', | ||
| 220 | + }, | ||
| 221 | + }, | ||
| 222 | +]; |
| @@ -12,6 +12,14 @@ | @@ -12,6 +12,14 @@ | ||
| 12 | flex-direction: row-reverse; | 12 | flex-direction: row-reverse; |
| 13 | flex-wrap: nowrap; | 13 | flex-wrap: nowrap; |
| 14 | justify-content: space-between; | 14 | justify-content: space-between; |
| 15 | + align-items: flex-end; | ||
| 16 | + | ||
| 17 | + .header-title { | ||
| 18 | + overflow:hidden; | ||
| 19 | + white-space: nowrap; | ||
| 20 | + text-overflow: ellipsis; | ||
| 21 | + -o-text-overflow:ellipsis; | ||
| 22 | + } | ||
| 15 | } | 23 | } |
| 16 | 24 | ||
| 17 | .tree-wrapper { | 25 | .tree-wrapper { |
| @@ -36,10 +44,10 @@ | @@ -36,10 +44,10 @@ | ||
| 36 | } | 44 | } |
| 37 | 45 | ||
| 38 | .border-none | 46 | .border-none |
| 39 | - .ant-select-focused:not(.ant-select-disabled).ant-select:not( | 47 | +.ant-select-focused:not(.ant-select-disabled).ant-select:not( |
| 40 | .ant-select-customize-input | 48 | .ant-select-customize-input |
| 41 | ) | 49 | ) |
| 42 | - .ant-select-selector { | 50 | +.ant-select-selector { |
| 43 | border: none; | 51 | border: none; |
| 44 | box-shadow: none; | 52 | box-shadow: none; |
| 45 | } | 53 | } |
| @@ -61,24 +69,48 @@ | @@ -61,24 +69,48 @@ | ||
| 61 | align-items: center; | 69 | align-items: center; |
| 62 | margin-left: 10px; | 70 | margin-left: 10px; |
| 63 | 71 | ||
| 64 | - .title-btn-del { | ||
| 65 | - display: none; | ||
| 66 | - color: #666; | 72 | + .ant-btn.ant-btn-icon-only, |
| 73 | + .ant-btn.ant-btn-icon-only { | ||
| 74 | + font-size: 16px; | ||
| 75 | + color: @N7; | ||
| 67 | 76 | ||
| 68 | &:hover { | 77 | &:hover { |
| 69 | - color: @E3; | 78 | + color: @B8; |
| 70 | opacity: 1; | 79 | opacity: 1; |
| 80 | + | ||
| 81 | + .anticon { | ||
| 82 | + color: @B8; | ||
| 83 | + | ||
| 84 | + &.title-btn-del-btn { | ||
| 85 | + color: @E3; | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + &:disabled, | ||
| 91 | + &.ant-btn-disabled { | ||
| 92 | + color: @N5; | ||
| 93 | + | ||
| 94 | + &:hover { | ||
| 95 | + color: @N5; | ||
| 96 | + | ||
| 97 | + .anticon { | ||
| 98 | + color: @N5; | ||
| 99 | + | ||
| 100 | + &.title-btn-del-btn { | ||
| 101 | + color: @N5; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + } | ||
| 71 | } | 105 | } |
| 72 | } | 106 | } |
| 73 | 107 | ||
| 74 | - .title-btn { | 108 | + .title-btn-del { |
| 75 | display: none; | 109 | display: none; |
| 76 | - color: #666; | 110 | + } |
| 77 | 111 | ||
| 78 | - &:hover { | ||
| 79 | - color: #91d5ff; | ||
| 80 | - opacity: 1; | ||
| 81 | - } | 112 | + .title-btn { |
| 113 | + display: none; | ||
| 82 | } | 114 | } |
| 83 | 115 | ||
| 84 | .select-tree { | 116 | .select-tree { |
| @@ -100,6 +132,10 @@ | @@ -100,6 +132,10 @@ | ||
| 100 | margin-bottom: 2px; | 132 | margin-bottom: 2px; |
| 101 | overflow: hidden; | 133 | overflow: hidden; |
| 102 | text-overflow: ellipsis; | 134 | text-overflow: ellipsis; |
| 135 | + | ||
| 136 | + .ant-input-affix-wrapper { | ||
| 137 | + border-color: @N4; | ||
| 138 | + } | ||
| 103 | } | 139 | } |
| 104 | 140 | ||
| 105 | .opt-left-down { | 141 | .opt-left-down { |
| @@ -114,6 +150,8 @@ | @@ -114,6 +150,8 @@ | ||
| 114 | margin-bottom: 2px; | 150 | margin-bottom: 2px; |
| 115 | overflow: hidden; | 151 | overflow: hidden; |
| 116 | text-overflow: ellipsis; | 152 | text-overflow: ellipsis; |
| 153 | + background-color: #fff; | ||
| 154 | + border-radius: 4px; | ||
| 117 | } | 155 | } |
| 118 | 156 | ||
| 119 | // .ant-tree-node-content-wrapper :hover .select-tree { | 157 | // .ant-tree-node-content-wrapper :hover .select-tree { |
| @@ -298,3 +336,10 @@ | @@ -298,3 +336,10 @@ | ||
| 298 | padding-top: 0 !important; | 336 | padding-top: 0 !important; |
| 299 | } | 337 | } |
| 300 | } | 338 | } |
| 339 | + | ||
| 340 | +.qx-parameter-setting--search { | ||
| 341 | + .anticon { | ||
| 342 | + font-size: 16px; | ||
| 343 | + color: @N6; | ||
| 344 | + } | ||
| 345 | +} |
src/qx-parameter-setting/sub-node.svg
0 → 100644
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false"><path fill-rule="evenodd" d="M6.333 5.333a1 1 0 0 0-1 1v3h-.667V2.667h10V1.333H1.333v1.334h2v6.666c0 .737.597 1.334 1.333 1.334h.667v3a1 1 0 0 0 1 1h7.333a1 1 0 0 0 1-1V6.333a1 1 0 0 0-1-1H6.333Zm.333 8V6.667h6.667v6.666H6.666Zm2.667-2.666h-2V9.333h2v-2h1.333v2h2v1.334h-2v2H9.333v-2Z" clip-rule="evenodd"/></svg> |