plain-design 1.0.0-beta.160 → 1.0.0-beta.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,178 +1,178 @@
1
- import {computed, designComponent, Fragment, PropType, reactive, watch} from "@peryl/react-compose";
2
- import {PlainObject} from "@peryl/utils/event";
3
- import {iFilterOption, iFilterQueryParam} from "../FilterService/utils/filter.service.utils";
4
- import {InputGroup} from "../InputGroup";
5
- import {Select} from "../Select";
6
- import {Button} from "../Button";
7
- import {FilterService} from "../FilterService";
8
- import {SelectOption} from "../SelectOption";
9
- import {incrementalMerge} from "../../utils/incrementalMerge";
10
- import {mergeQueryParam} from "../FilterService/utils/mergeQueryParam";
11
- import {deepcopy} from "@peryl/utils/deepcopy";
12
- import i18n from "../i18n";
13
-
14
- export interface iFilterFormSingleState {
15
- field: string,
16
- filterHandler: string,
17
- formData: PlainObject,
18
- }
19
-
20
- export type iFilterFormSingleData = iFilterFormSingleState & { filterQueryParam: iFilterQueryParam }
21
-
22
- export const FilterFormSingle = designComponent({
23
- name: 'filter-form-single',
24
- props: {
25
- filterOptions: { type: Array as PropType<iFilterOption[]> },
26
- initialState: { type: Object as PropType<iFilterFormSingleState> },
27
- hideFieldSelector: { type: Boolean },
28
- hideHandlerSelector: { type: Boolean },
29
- hideSearchButton: { type: Boolean },
30
- width: { type: String, default: '440px' },
31
- handleSearch: { type: Function as PropType<(data: iFilterFormSingleData) => void | Promise<void>> },
32
- },
33
- emits: {
34
- onSearch: (data: iFilterFormSingleData) => true,
35
- },
36
- slots: ['prepend', 'append'],
37
- setup({ props, event: { emit }, slots }) {
38
-
39
- const utils = {
40
- createState: ({ defaultField, filterOptions }: { defaultField?: string, filterOptions: iFilterOption[] }): iFilterFormSingleState => {
41
- const defaultOption = filterOptions.find(i => !!defaultField ? i?.field === defaultField : i?.defaultSearch) || (filterOptions[0] as iFilterOption | undefined) || { label: i18n.$it('base.id').d('编号'), filterType: 'text', filterHandler: 'like', field: 'id' };
42
- const formData = FilterService.getDefaultFormData(filterOptions);
43
- return {
44
- field: defaultOption.field,
45
- filterHandler: defaultOption.filterHandler,
46
- formData,
47
- };
48
- }
49
- };
50
-
51
- const state: iFilterFormSingleState = reactive(
52
- deepcopy(props.initialState) ||
53
- utils.createState({ filterOptions: props.filterOptions || [] })
54
- );
55
-
56
- /**
57
- * 正在使用的目标filterOptions
58
- * @author 韦胜健
59
- * @date 2023.1.6 16:00
60
- */
61
- const usingFilterOption = computed((): iFilterOption => ({
62
- ...(props.filterOptions || []).find(i => i.field === state.field)!,
63
- filterHandler: state.filterHandler,
64
- }));
65
-
66
- /**
67
- * props.filterOptions变化时更新内部状态
68
- * @author 韦胜健
69
- * @date 2023.1.6 15:57
70
- */
71
- watch(() => props.filterOptions, newFilterOptions => methods.updateFilterOptions(newFilterOptions || []));
72
-
73
- const methods = {
74
- /**
75
- * 获取当前内部状态
76
- * @author 韦胜健
77
- * @date 2023.1.6 16:12
78
- */
79
- getState: (): iFilterFormSingleState => ({ ...state }),
80
- /**
81
- * 更新当前内部状态
82
- * @author 韦胜健
83
- * @date 2023.1.6 16:12
84
- */
85
- update: (newState: iFilterFormSingleState | null | undefined) => {
86
- if (!!newState) {
87
- Object.assign(state, newState);
88
- } else {
89
- Object.assign(state, utils.createState({ filterOptions: props.filterOptions || [] }));
90
- }
91
- },
92
- /**
93
- * 合并新的filterOptions
94
- * @author 韦胜健
95
- * @date 2023.1.6 15:49
96
- */
97
- updateFilterOptions: (filterOptions: iFilterOption[]) => {
98
- const { formData, filterHandler } = utils.createState({ defaultField: state.field, filterOptions: filterOptions || [] });
99
- state.formData = incrementalMerge(state.formData, formData);
100
- state.filterHandler = filterHandler;
101
- },
102
- /**
103
- * 获取查询数据
104
- * @author 韦胜健
105
- * @date 2023.1.6 18:32
106
- */
107
- getData: async () => {
108
- const { field, formData, filterHandler } = state;
109
- const queryParam = await FilterService.getQueryParam({ option: usingFilterOption.value, formData: state.formData });
110
- const filterQueryParam = !queryParam ? {} : mergeQueryParam(queryParam, {});
111
- return deepcopy({ field, formData, filterHandler, filterQueryParam });
112
- },
113
- /**
114
- * 搜索
115
- * @author 韦胜健
116
- * @date 2023.1.6 12:46
117
- */
118
- search: async () => {
119
- const data = await methods.getData();
120
- emit.onSearch(data);
121
- await props.handleSearch?.(data);
122
- },
123
- };
124
-
125
- const handler = {
126
- onUpdateField: (field: any) => {
127
- const newState = utils.createState({ defaultField: field, filterOptions: props.filterOptions || [] });
128
- const handler = FilterService.getHandler(usingFilterOption.value)!;
129
- handler.clearValue({ formData: state.formData, option: usingFilterOption.value });
130
- state.filterHandler = newState.filterHandler;
131
- state.field = field;
132
- // console.log({ ...state }, props.filterOptions);
133
- },
134
- onUpdateHandler: (filterHandler?: any) => {
135
- const handler = FilterService.getHandler(usingFilterOption.value)!;
136
- handler.clearValue({ formData: state.formData, option: usingFilterOption.value });
137
- state.filterHandler = filterHandler;
138
- },
139
- };
140
-
141
- const inputAttrs = { noClear: true };
142
-
143
- return {
144
- refer: {
145
- state,
146
- ...methods,
147
- },
148
- render: () => (
149
- <InputGroup style={{ width: props.width }}>
150
- {slots.prepend()}
151
- {!props.hideFieldSelector && (
152
- <Select key="field_selector" width={90} modelValue={state.field} onUpdateModelValue={handler.onUpdateField} inputAttrs={inputAttrs}>
153
- {(props.filterOptions || []).map((option) => (
154
- <SelectOption label={option.label} val={option.field} key={option.label + option.field}/>
155
- ))}
156
- </Select>
157
- )}
158
- {!props.hideHandlerSelector && (
159
- <Select key={state.field} width={90} modelValue={state.filterHandler} onUpdateModelValue={handler.onUpdateHandler} inputAttrs={inputAttrs}>
160
- {(FilterService.touch(usingFilterOption.value.filterType)).state.list.map((handler) => (
161
- <SelectOption label={handler.label()} val={handler.name} key={handler.name}/>
162
- ))}
163
- </Select>
164
- )}
165
- <Fragment key={state.filterHandler}>
166
- {FilterService.getHandler(usingFilterOption.value)!.render({ formData: state.formData, option: usingFilterOption.value, confirm: methods.search })}
167
- </Fragment>
168
- {!props.hideSearchButton && (
169
- <Button label={i18n.$it('base.query').d('查询')} icon="pi-search" mode="fill" asyncHandler={methods.search}/>
170
- )}
171
- {slots.append()}
172
- </InputGroup>
173
- )
174
- };
175
- },
176
- });
177
-
178
- export default FilterFormSingle;
1
+ import {computed, designComponent, Fragment, PropType, reactive, watch} from "@peryl/react-compose";
2
+ import {PlainObject} from "@peryl/utils/event";
3
+ import {iFilterOption, iFilterQueryParam} from "../FilterService/utils/filter.service.utils";
4
+ import {InputGroup} from "../InputGroup";
5
+ import {Select} from "../Select";
6
+ import {Button} from "../Button";
7
+ import {FilterService} from "../FilterService";
8
+ import {SelectOption} from "../SelectOption";
9
+ import {incrementalMerge} from "../../utils/incrementalMerge";
10
+ import {mergeQueryParam} from "../FilterService/utils/mergeQueryParam";
11
+ import {deepcopy} from "@peryl/utils/deepcopy";
12
+ import i18n from "../i18n";
13
+
14
+ export interface iFilterFormSingleState {
15
+ field: string,
16
+ filterHandler: string,
17
+ formData: PlainObject,
18
+ }
19
+
20
+ export type iFilterFormSingleData = iFilterFormSingleState & { filterQueryParam: iFilterQueryParam }
21
+
22
+ export const FilterFormSingle = designComponent({
23
+ name: 'filter-form-single',
24
+ props: {
25
+ filterOptions: { type: Array as PropType<iFilterOption[]> },
26
+ initialState: { type: Object as PropType<iFilterFormSingleState> },
27
+ hideFieldSelector: { type: Boolean },
28
+ hideHandlerSelector: { type: Boolean },
29
+ hideSearchButton: { type: Boolean },
30
+ width: { type: String, default: '440px' },
31
+ handleSearch: { type: Function as PropType<(data: iFilterFormSingleData) => void | Promise<void>> },
32
+ },
33
+ emits: {
34
+ onSearch: (data: iFilterFormSingleData) => true,
35
+ },
36
+ slots: ['prepend', 'append'],
37
+ setup({ props, event: { emit }, slots }) {
38
+
39
+ const utils = {
40
+ createState: ({ defaultField, filterOptions }: { defaultField?: string, filterOptions: iFilterOption[] }): iFilterFormSingleState => {
41
+ const defaultOption = filterOptions.find(i => !!defaultField ? i?.field === defaultField : i?.defaultSearch) || (filterOptions[0] as iFilterOption | undefined) || { label: i18n.$it('base.id').d('编号'), filterType: 'text', filterHandler: 'like', field: 'id' };
42
+ const formData = FilterService.getDefaultFormData(filterOptions);
43
+ return {
44
+ field: defaultOption.field,
45
+ filterHandler: defaultOption.filterHandler,
46
+ formData,
47
+ };
48
+ }
49
+ };
50
+
51
+ const state: iFilterFormSingleState = reactive(
52
+ deepcopy(props.initialState) ||
53
+ utils.createState({ filterOptions: props.filterOptions || [] })
54
+ );
55
+
56
+ /**
57
+ * 正在使用的目标filterOptions
58
+ * @author 韦胜健
59
+ * @date 2023.1.6 16:00
60
+ */
61
+ const usingFilterOption = computed((): iFilterOption => ({
62
+ ...(props.filterOptions || []).find(i => i.field === state.field)!,
63
+ filterHandler: state.filterHandler,
64
+ }));
65
+
66
+ /**
67
+ * props.filterOptions变化时更新内部状态
68
+ * @author 韦胜健
69
+ * @date 2023.1.6 15:57
70
+ */
71
+ watch(() => props.filterOptions, newFilterOptions => methods.updateFilterOptions(newFilterOptions || []));
72
+
73
+ const methods = {
74
+ /**
75
+ * 获取当前内部状态
76
+ * @author 韦胜健
77
+ * @date 2023.1.6 16:12
78
+ */
79
+ getState: (): iFilterFormSingleState => ({ ...state }),
80
+ /**
81
+ * 更新当前内部状态
82
+ * @author 韦胜健
83
+ * @date 2023.1.6 16:12
84
+ */
85
+ update: (newState: iFilterFormSingleState | null | undefined) => {
86
+ if (!!newState) {
87
+ Object.assign(state, newState);
88
+ } else {
89
+ Object.assign(state, utils.createState({ filterOptions: props.filterOptions || [] }));
90
+ }
91
+ },
92
+ /**
93
+ * 合并新的filterOptions
94
+ * @author 韦胜健
95
+ * @date 2023.1.6 15:49
96
+ */
97
+ updateFilterOptions: (filterOptions: iFilterOption[]) => {
98
+ const { formData, filterHandler } = utils.createState({ defaultField: state.field, filterOptions: filterOptions || [] });
99
+ state.formData = incrementalMerge(state.formData, formData);
100
+ state.filterHandler = filterHandler;
101
+ },
102
+ /**
103
+ * 获取查询数据
104
+ * @author 韦胜健
105
+ * @date 2023.1.6 18:32
106
+ */
107
+ getData: async () => {
108
+ const { field, formData, filterHandler } = state;
109
+ const queryParam = await FilterService.getQueryParam({ option: usingFilterOption.value, formData: state.formData });
110
+ const filterQueryParam = !queryParam ? {} : mergeQueryParam(queryParam, {});
111
+ return deepcopy({ field, formData, filterHandler, filterQueryParam });
112
+ },
113
+ /**
114
+ * 搜索
115
+ * @author 韦胜健
116
+ * @date 2023.1.6 12:46
117
+ */
118
+ search: async () => {
119
+ const data = await methods.getData();
120
+ emit.onSearch(data);
121
+ await props.handleSearch?.(data);
122
+ },
123
+ };
124
+
125
+ const handler = {
126
+ onUpdateField: (field: any) => {
127
+ const newState = utils.createState({ defaultField: field, filterOptions: props.filterOptions || [] });
128
+ const handler = FilterService.getHandler(usingFilterOption.value)!;
129
+ handler.clearValue({ formData: state.formData, option: usingFilterOption.value });
130
+ state.filterHandler = newState.filterHandler;
131
+ state.field = field;
132
+ // console.log({ ...state }, props.filterOptions);
133
+ },
134
+ onUpdateHandler: (filterHandler?: any) => {
135
+ const handler = FilterService.getHandler(usingFilterOption.value)!;
136
+ handler.clearValue({ formData: state.formData, option: usingFilterOption.value });
137
+ state.filterHandler = filterHandler;
138
+ },
139
+ };
140
+
141
+ const inputAttrs = { noClear: true };
142
+
143
+ return {
144
+ refer: {
145
+ state,
146
+ ...methods,
147
+ },
148
+ render: () => (
149
+ <InputGroup style={{ width: props.width }}>
150
+ {slots.prepend()}
151
+ {!props.hideFieldSelector && (
152
+ <Select key="field_selector" width={90} modelValue={state.field} onUpdateModelValue={handler.onUpdateField} inputAttrs={inputAttrs}>
153
+ {(props.filterOptions || []).map((option) => (
154
+ <SelectOption label={option.label} val={option.field} key={option.label + option.field}/>
155
+ ))}
156
+ </Select>
157
+ )}
158
+ {!props.hideHandlerSelector && (
159
+ <Select key={state.field} width={90} modelValue={state.filterHandler} onUpdateModelValue={handler.onUpdateHandler} inputAttrs={inputAttrs}>
160
+ {(FilterService.touch(usingFilterOption.value.filterType)).state.list.map((handler) => (
161
+ <SelectOption label={handler.label()} val={handler.name} key={handler.name}/>
162
+ ))}
163
+ </Select>
164
+ )}
165
+ <Fragment key={state.filterHandler}>
166
+ {FilterService.getHandler(usingFilterOption.value)!.render({ formData: state.formData, option: usingFilterOption.value, confirm: methods.search })}
167
+ </Fragment>
168
+ {!props.hideSearchButton && (
169
+ <Button label={i18n.$it('base.query').d('查询')} icon="pi-search" mode="fill" asyncHandler={methods.search}/>
170
+ )}
171
+ {slots.append()}
172
+ </InputGroup>
173
+ )
174
+ };
175
+ },
176
+ });
177
+
178
+ export default FilterFormSingle;
@@ -30,8 +30,8 @@ export function installFilterNumber(
30
30
  <NumberRange
31
31
  v-model:start={formData[option.startField]}
32
32
  v-model:end={formData[option.endField]}
33
- startAttrs={{ inputAttrs: { onEnter: confirm } }}
34
- endAttrs={{ inputAttrs: { onEnter: confirm } }}
33
+ onEnterStart={confirm}
34
+ onEnterEnd={confirm}
35
35
  noGroupWrapper
36
36
  />
37
37
  ),
@@ -1,93 +1,94 @@
1
- import {computed, designComponent, PropType, useModel} from "@peryl/react-compose";
2
- import {InputGroup} from "../InputGroup";
3
- import {InputNumber} from "../InputNumber";
4
- import {Input} from "../Input";
5
- import {PlainObject} from "@peryl/utils/event";
6
-
7
- export const NumberRange = designComponent({
8
- name: 'number-range',
9
- props: {
10
- start: { type: [String, Number] },
11
- end: { type: [String, Number] },
12
- startAttrs: { type: Object as PropType<PlainObject> },
13
- endAttrs: { type: Object as PropType<PlainObject> },
14
- noGroupWrapper: { type: Boolean },
15
- },
16
- emits: {
17
- onUpdateStart: (val?: string | number) => true,
18
- onUpdateEnd: (val?: string | number) => true,
19
- onBlur: () => true,
20
- onEnter: () => true,
21
- onClear: () => true,
22
- },
23
- setup({ props, event: { emit } }) {
24
-
25
- const startModel = useModel(() => props.start, emit.onUpdateStart);
26
- const endModel = useModel(() => props.end, emit.onUpdateEnd);
27
-
28
- const placeValue = computed(() => {
29
- let start = startModel.value == null ? '' : String(startModel.value).trim();
30
- let end = endModel.value == null ? '' : String(endModel.value).trim();
31
- return start + end;
32
- });
33
-
34
- const checkRange = () => {
35
- let start = startModel.value;
36
- let end = endModel.value;
37
- let startNum = Number(start);
38
- let endNum = Number(end);
39
- if (start == null || end == null || isNaN(startNum) || isNaN(endNum)) {
40
- return;
41
- }
42
- if (startNum > endNum) {
43
- [startNum, endNum] = [endNum, startNum];
44
- startModel.value = startNum;
45
- endModel.value = endNum;
46
- }
47
- };
48
-
49
- const handler = {
50
- onBlur: (): void => {
51
- checkRange();
52
- emit.onBlur();
53
- },
54
- onEnter: () => {
55
- checkRange();
56
- emit.onEnter();
57
- },
58
- onClear: () => {
59
- startModel.value = undefined;
60
- endModel.value = undefined;
61
- emit.onClear();
62
- },
63
- };
64
-
65
- return () => {
66
- const content = (
67
- <Input
68
- suffixIcon="pi-original-size"
69
- placeValue={placeValue.value}
70
- clearHandler={handler.onClear}
71
- >
72
- <InputNumber v-model={startModel.value} onBlur={handler.onBlur} button={null} align="center" onEnter={handler.onEnter} {...{
73
- ...props.startAttrs || {},
74
- inputAttrs: {
75
- ...props.startAttrs?.inputAttrs,
76
- bare: true,
77
- },
78
- }}/>
79
- <InputNumber v-model={endModel.value} onBlur={handler.onBlur} button={null} align="center" onEnter={handler.onEnter} {...{
80
- ...props.endAttrs || {},
81
- inputAttrs: {
82
- ...props.endAttrs?.inputAttrs,
83
- bare: true,
84
- },
85
- }}/>
86
- </Input>
87
- );
88
- return (props.noGroupWrapper ? content : (<InputGroup>{content}</InputGroup>));
89
- };
90
- },
91
- });
92
-
93
- export default NumberRange;
1
+ import {computed, designComponent, PropType, useModel} from "@peryl/react-compose";
2
+ import {InputGroup} from "../InputGroup";
3
+ import {InputNumber} from "../InputNumber";
4
+ import {Input} from "../Input";
5
+ import {PlainObject} from "@peryl/utils/event";
6
+
7
+ export const NumberRange = designComponent({
8
+ name: 'number-range',
9
+ props: {
10
+ start: { type: [String, Number] },
11
+ end: { type: [String, Number] },
12
+ startAttrs: { type: Object as PropType<PlainObject> },
13
+ endAttrs: { type: Object as PropType<PlainObject> },
14
+ noGroupWrapper: { type: Boolean },
15
+ },
16
+ emits: {
17
+ onUpdateStart: (val?: string | number) => true,
18
+ onUpdateEnd: (val?: string | number) => true,
19
+ onBlur: () => true,
20
+ onClear: () => true,
21
+ onEnterStart: () => true,
22
+ onEnterEnd: () => true,
23
+ },
24
+ setup({ props, event: { emit } }) {
25
+
26
+ const startModel = useModel(() => props.start, emit.onUpdateStart);
27
+ const endModel = useModel(() => props.end, emit.onUpdateEnd);
28
+
29
+ const placeValue = computed(() => {
30
+ let start = startModel.value == null ? '' : String(startModel.value).trim();
31
+ let end = endModel.value == null ? '' : String(endModel.value).trim();
32
+ return start + end;
33
+ });
34
+
35
+ const checkRange = () => {
36
+ let start = startModel.value;
37
+ let end = endModel.value;
38
+ let startNum = Number(start);
39
+ let endNum = Number(end);
40
+ if (start == null || end == null || isNaN(startNum) || isNaN(endNum)) {
41
+ return;
42
+ }
43
+ if (startNum > endNum) {
44
+ [startNum, endNum] = [endNum, startNum];
45
+ startModel.value = startNum;
46
+ endModel.value = endNum;
47
+ }
48
+ };
49
+
50
+ const handler = {
51
+ onBlur: (): void => {
52
+ checkRange();
53
+ emit.onBlur();
54
+ },
55
+ onEnter: (type: 'start' | 'end') => {
56
+ checkRange();
57
+ type === "start" ? emit.onEnterStart() : emit.onEnterEnd();
58
+ },
59
+ onClear: () => {
60
+ startModel.value = undefined;
61
+ endModel.value = undefined;
62
+ emit.onClear();
63
+ },
64
+ };
65
+
66
+ return () => {
67
+ const content = (
68
+ <Input
69
+ suffixIcon="pi-original-size"
70
+ placeValue={placeValue.value}
71
+ clearHandler={handler.onClear}
72
+ >
73
+ <InputNumber v-model={startModel.value} onBlur={handler.onBlur} button={null} align="center" onEnter={() => handler.onEnter('start')} {...{
74
+ ...props.startAttrs || {},
75
+ inputAttrs: {
76
+ ...props.startAttrs?.inputAttrs,
77
+ bare: true,
78
+ },
79
+ }}/>
80
+ <InputNumber v-model={endModel.value} onBlur={handler.onBlur} button={null} align="center" onEnter={() => handler.onEnter('end')} {...{
81
+ ...props.endAttrs || {},
82
+ inputAttrs: {
83
+ ...props.endAttrs?.inputAttrs,
84
+ bare: true,
85
+ },
86
+ }}/>
87
+ </Input>
88
+ );
89
+ return (props.noGroupWrapper ? content : (<InputGroup>{content}</InputGroup>));
90
+ };
91
+ },
92
+ });
93
+
94
+ export default NumberRange;
@@ -136,7 +136,7 @@ export {Corner} from './components/Corner';
136
136
  export {useContextmenuOptions} from './components/useContextmenuOptions';
137
137
  export type {iContextmenuOption} from './components/useContextmenuOptions';
138
138
  export {AiChatBox} from './components/AiChatBox';
139
- export type {iChatBoxHistory} from './components/AiChatBox';
139
+ export type {iChatBoxHandleMessage, iChatBoxHistory} from './components/AiChatBox';
140
140
  export {$ai} from './components/$ai';
141
141
  export type {iAiChoice, iAiChatResponse, iAiConfiguration, iAiHistory} from './components/$ai';
142
142
  export {IconPicker} from './components/IconPicker';