jobsys-explore 4.2.19 → 4.3.1

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.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "jobsys-explore": patch
3
+ ---
4
+
5
+ Add matrix component and closable option
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # jobsys-explore
2
2
 
3
+ ## 4.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - modify submit form in beforeSubit
8
+
9
+ ## 4.2.20
10
+
11
+ ### Patch Changes
12
+
13
+ - Fix
14
+ - Build
15
+ - Drop the unused property
16
+ - Add matrix component and closable option
17
+ - Fix clear error in ExSearch
18
+ - Rewrite ExPagiantion
19
+ - Add init and beforeSubmit
20
+ - Fix
21
+ - Add disabled and readonly for ex form
22
+ - hide upload when readonly or disabled
23
+ - Add form item pattern support
24
+ - Add cascader search and filter search issue
25
+ - Fix sector style
26
+ - Fix exupload
27
+ - Add ex-decorator
28
+ - clone the options before traverse
29
+ - Upgrade useFormFormat
30
+ - upgrade
31
+ - Fix
32
+ - Add useFindParentValues
33
+ - Fix form submit await
34
+ - Add status adapter and useFetch loading
35
+ - Adjust form item render order
36
+ - Add pagination expose
37
+ - Fix upload file
38
+ - Add useFindPropertyRecursive
39
+ - upgrade
40
+ - Fix beforeSubmit
41
+
3
42
  ## 4.2.19
4
43
 
5
44
  ### Patch Changes
@@ -0,0 +1 @@
1
+ export * from "./survey"
@@ -0,0 +1,34 @@
1
+ import { defineComponent } from "vue"
2
+ import "./index.less"
3
+
4
+ /**
5
+ * 调查问卷
6
+ * @version 4.4.0
7
+ */
8
+ export default defineComponent({
9
+ name: "ExSurvey",
10
+ props: {
11
+ /**
12
+ * 开场语
13
+ */
14
+ opening: { type: String, default: "" },
15
+
16
+ /**
17
+ * 结束语
18
+ */
19
+ ending: { type: String, default: "" },
20
+ },
21
+ emits: [
22
+ /**
23
+ * @event click
24
+ * @param {Event} event 点击事件
25
+ */
26
+ "click",
27
+ ],
28
+
29
+ setup(props) {
30
+ const openingElem = () => (props.opening ? <div class={`ex-survey__opening`}>{props.opening}</div> : null)
31
+
32
+ return () => <div class={`ex-survey`}>{openingElem()}</div>
33
+ },
34
+ })
@@ -0,0 +1,5 @@
1
+ import _ExSurvey from "./ExSurvey.jsx"
2
+ import withInstall from "../../utils/withInstall"
3
+
4
+ export const ExSurvey = withInstall(_ExSurvey)
5
+ export default ExSurvey
File without changes
@@ -2,7 +2,7 @@ import { computed, defineComponent, ref, watch } from "vue"
2
2
  import PickerWrapper, { pickerProps, pickerSlots } from "./PickerWrapper.jsx"
3
3
  import { Button, Cascader, Search } from "vant"
4
4
  import { defaultFieldProps, defaultOptionsProps, useOptionTrait } from "../utils"
5
- import { useFindTextsFromPath } from "../../hooks"
5
+ import { useFindParentLabels } from "../../hooks"
6
6
  import { isArray, last } from "lodash-es"
7
7
 
8
8
  /**
@@ -96,11 +96,7 @@ export default defineComponent({
96
96
  const hasKeyword = item.text.toLowerCase().includes(keyword.toLowerCase())
97
97
 
98
98
  // 如果包含关键字,或者有子级包含关键字,则保留该项
99
- if (hasKeyword || (item.children && filterRecursively(item.children).length > 0)) {
100
- return true
101
- }
102
-
103
- return false
99
+ return hasKeyword || (item.children && filterRecursively(item.children).length > 0)
104
100
  })
105
101
  }
106
102
 
@@ -109,17 +105,13 @@ export default defineComponent({
109
105
  }
110
106
 
111
107
  const displayText = computed(() => {
112
- if (props.modelValue.length === 0) {
108
+ if (!componentValue.value) {
113
109
  return ""
114
110
  }
115
- //textInValue状态下的初始值
116
- if (props.textInValue && props.modelValue && props.modelValue.length === 1) {
117
- return last(props.modelValue).text
118
- }
119
111
 
120
- const mValue = props.textInValue ? props.modelValue.map((item) => item.value) : props.modelValue
121
- const optionsTexts = useFindTextsFromPath(options.value, mValue)
122
- return props.displayTextType === "last" ? last(optionsTexts) : optionsTexts.join("/")
112
+ const labels = useFindParentLabels(options.value, componentValue.value, props.defaultProps?.fieldNames)
113
+
114
+ return labels ? (props.displayTextType === "last" ? last(labels) : labels.join("/")) : ""
123
115
  })
124
116
 
125
117
  const onFinish = ({ selectedOptions }) => {
@@ -96,6 +96,21 @@ export default defineComponent({
96
96
  */
97
97
  submitDisabled: { type: Boolean, default: false },
98
98
 
99
+ /**
100
+ * 是否显示关闭按钮
101
+ */
102
+ closable: { type: Boolean, default: false },
103
+
104
+ /**
105
+ * 取消按钮文字
106
+ */
107
+ cancelButtonText: { type: String, default: "取消" },
108
+
109
+ /**
110
+ * 点击关闭时的动作
111
+ */
112
+ close: { type: Function, default: null },
113
+
99
114
  /**
100
115
  * 当有分割线时,分割线的配置
101
116
  */
@@ -110,11 +125,12 @@ export default defineComponent({
110
125
  * @property {string} title 显示的名字
111
126
  * @property {string} [type] 类型,默认是input
112
127
  * @property {array|Function} [options] 组件选项
128
+ * @property {array|Function} [rows] 矩阵组件行标题
113
129
  * @property {string} [placeholder] 组件里的提示
114
130
  * @property {string|Function} [help] ExField 里的提示
115
131
  * @property {string|Function} [append] ExField 外的提示
116
132
  * @property {array} [rules] 验证规则
117
- * @property {boolean} [is-link] 是否展示右侧箭头并开启点击反馈
133
+ * @property {boolean} [isLink] 是否展示右侧箭头并开启点击反馈
118
134
  * @property {boolean} [readonly] 是否只读
119
135
  * @property {boolean|Function} [required] 是否必填,默认是false
120
136
  * @property {boolean|Function} [disabled] 组件不可编辑状态,默认是false
@@ -296,7 +312,7 @@ export default defineComponent({
296
312
  for (const item of itemsWithBeforeSubmit) {
297
313
  form[item.key] = await item.beforeSubmit({
298
314
  value: form[item.key],
299
- submitForm: state.submitForm,
315
+ submitForm: form, //改成将 form 传出去,这样可以在 form 中添加参数
300
316
  })
301
317
  }
302
318
 
@@ -418,7 +434,7 @@ export default defineComponent({
418
434
  return null
419
435
  }
420
436
 
421
- const submitBtnElem = () => {
437
+ const buttonsElem = () => {
422
438
  if (state.isInitializing) {
423
439
  return null
424
440
  }
@@ -426,30 +442,44 @@ export default defineComponent({
426
442
  return null
427
443
  }
428
444
 
445
+ const cancelBtn = (
446
+ <ExButton
447
+ class={"ex-form__cancel-btn"}
448
+ type={"default"}
449
+ plain
450
+ onClick={() => {
451
+ if (props.close && isFunction(props.close)) {
452
+ props.close()
453
+ }
454
+ }}
455
+ >
456
+ {() => props.cancelButtonText}
457
+ </ExButton>
458
+ )
459
+
429
460
  const submitBtn = (
430
461
  <ExButton disabled={props.submitDisabled} type={"primary"} fetcher={state.submitFetcher} buttonProps={{ nativeType: "submit" }}>
431
- {{
432
- default: () => props.submitButtonText || "提交",
433
- }}
462
+ {() => props.submitButtonText}
434
463
  </ExButton>
435
464
  )
436
465
 
437
466
  if (props.fixed) {
438
- return <div class={"ex-form__submit-btn-fixed van-hairline--top"}>{submitBtn}</div>
467
+ return <div class={"ex-form__btn-wrapper-fixed van-hairline--top"}>{[props.closable ? cancelBtn : null, submitBtn]}</div>
439
468
  }
440
469
 
441
- return <div class={"ex-form__submit-btn"}>{submitBtn}</div>
470
+ return <div class={"ex-form__btn-wrapper"}>{[props.closable ? cancelBtn : null, submitBtn]}</div>
442
471
  }
443
472
 
444
473
  return () => (
445
474
  <Form
446
475
  ref={formRef}
447
- scrollToError={true}
448
476
  labelWidth={props.labelWidth}
449
477
  colon={props.colon}
450
478
  class={`ex-form ${props.fixed ? "ex-form__fixed" : ""}`}
451
479
  disabled={props.disabled}
452
480
  readonly={props.readonly}
481
+ scrollToError={true}
482
+ validateFirst={true}
453
483
  onSubmit={onSubmit}
454
484
  >
455
485
  {{
@@ -458,7 +488,7 @@ export default defineComponent({
458
488
  {{ default: () => skeletonElem() }}
459
489
  </CellGroup>,
460
490
  footerElem(),
461
- submitBtnElem(),
491
+ buttonsElem(),
462
492
  ],
463
493
  }}
464
494
  </Form>
@@ -0,0 +1,99 @@
1
+ import { defineComponent, ref, watch } from "vue"
2
+ import { defaultFieldProps, defaultOptionsProps, useOptionTrait } from "../utils"
3
+ import { Checkbox } from "vant"
4
+ import ExField from "./ExField.jsx"
5
+ import { isFunction, pick, remove } from "lodash-es"
6
+
7
+ /**
8
+ * ExMatrixRadio 矩阵单选
9
+ * @version 1.0.0
10
+ */
11
+ export default defineComponent({
12
+ name: "ExMatrixRadio",
13
+ props: {
14
+ ...defaultFieldProps,
15
+ ...defaultOptionsProps,
16
+
17
+ /**
18
+ * 行标题
19
+ */
20
+ rows: { type: [Array, Function], default: () => [] },
21
+ modelValue: { type: Object, default: () => ({}) },
22
+ },
23
+ emits: ["update:modelValue"],
24
+ setup(props, { emit, slots }) {
25
+ const componentValue = ref(props.modelValue)
26
+
27
+ watch(
28
+ () => props.modelValue,
29
+ () => (componentValue.value = props.modelValue),
30
+ )
31
+
32
+ const options = ref([])
33
+
34
+ useOptionTrait(options, props)
35
+
36
+ const rows = isFunction(props.rows) ? props.rows() : props.rows
37
+
38
+ const onChange = (row, value) => {
39
+ if (!componentValue.value[row]) {
40
+ componentValue.value[row] = []
41
+ }
42
+ if (componentValue.value[row].includes(value)) {
43
+ remove(componentValue.value[row], (item) => item === value)
44
+ } else {
45
+ componentValue.value[row].push(value)
46
+ }
47
+ emit("update:modelValue", componentValue.value)
48
+ }
49
+
50
+ const fieldProps = pick(props, Object.keys(defaultFieldProps))
51
+
52
+ return () => (
53
+ <ExField class={"ex-matrix"} {...fieldProps}>
54
+ {{
55
+ ...slots,
56
+ input: () => (
57
+ <div class={"ex-matrix-container"}>
58
+ <table>
59
+ <thead>
60
+ <tr>
61
+ <th></th>
62
+ {options.value.map((item) => (
63
+ <th>
64
+ <div class={"ex-matrix-option"}>{item.text}</div>
65
+ </th>
66
+ ))}
67
+ </tr>
68
+ </thead>
69
+ <tbody>
70
+ {rows.map((row) => (
71
+ <tr>
72
+ <td>
73
+ <div class={"ex-matrix-row"}>{row}</div>
74
+ </td>
75
+ {options.value.map((option) => {
76
+ const checked = ref(componentValue.value[row]?.includes(option.value))
77
+ return (
78
+ <td>
79
+ <div class={"ex-matrix-option"}>
80
+ <Checkbox
81
+ v-model={checked.value}
82
+ shape={"square"}
83
+ onClick={() => onChange(row, option.value)}
84
+ ></Checkbox>
85
+ </div>
86
+ </td>
87
+ )
88
+ })}
89
+ </tr>
90
+ ))}
91
+ </tbody>
92
+ </table>
93
+ </div>
94
+ ),
95
+ }}
96
+ </ExField>
97
+ )
98
+ },
99
+ })
@@ -0,0 +1,86 @@
1
+ import { defineComponent, ref, watch } from "vue"
2
+ import { defaultFieldProps, defaultOptionsProps, useOptionTrait } from "../utils"
3
+ import { Radio, RadioGroup } from "vant"
4
+ import ExField from "./ExField.jsx"
5
+ import { isFunction, pick } from "lodash-es"
6
+
7
+ /**
8
+ * ExMatrixRadio 矩阵单选
9
+ * @version 1.0.0
10
+ */
11
+ export default defineComponent({
12
+ name: "ExMatrixRadio",
13
+ props: {
14
+ ...defaultFieldProps,
15
+ ...defaultOptionsProps,
16
+
17
+ /**
18
+ * 行标题
19
+ */
20
+ rows: { type: [Array, Function], default: () => [] },
21
+ modelValue: { type: Object, default: () => ({}) },
22
+ },
23
+ emits: ["update:modelValue"],
24
+ setup(props, { emit, slots }) {
25
+ const componentValue = ref(props.modelValue)
26
+
27
+ watch(
28
+ () => props.modelValue,
29
+ () => (componentValue.value = props.modelValue),
30
+ )
31
+
32
+ const options = ref([])
33
+
34
+ useOptionTrait(options, props)
35
+
36
+ const rows = isFunction(props.rows) ? props.rows() : props.rows
37
+
38
+ const onChange = () => {
39
+ emit("update:modelValue", componentValue.value)
40
+ }
41
+
42
+ const fieldProps = pick(props, Object.keys(defaultFieldProps))
43
+
44
+ return () => (
45
+ <ExField class={"ex-matrix"} {...fieldProps}>
46
+ {{
47
+ ...slots,
48
+ input: () => (
49
+ <div class={"ex-matrix-container"}>
50
+ <table>
51
+ <thead>
52
+ <tr>
53
+ <th></th>
54
+ {options.value.map((item) => (
55
+ <th>
56
+ <div class={"ex-matrix-option"}>{item.text}</div>
57
+ </th>
58
+ ))}
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ {rows.map((row) => (
63
+ <tr>
64
+ <td>
65
+ <div class={"ex-matrix-row"}>{row}</div>
66
+ </td>
67
+ {options.value.map((option) => (
68
+ <td>
69
+ <div class={"ex-matrix-option"}>
70
+ <RadioGroup onChange={onChange} v-model={componentValue.value[row]}>
71
+ {() => <Radio name={option.value}></Radio>}
72
+ </RadioGroup>
73
+ </div>
74
+ </td>
75
+ ))}
76
+ </tr>
77
+ ))}
78
+ </tbody>
79
+ </table>
80
+ </div>
81
+ ),
82
+ }}
83
+ </ExField>
84
+ )
85
+ },
86
+ })
@@ -0,0 +1,97 @@
1
+ import { defineComponent, ref, watch } from "vue"
2
+ import { defaultFieldProps, defaultOptionsProps, useOptionTrait } from "../utils"
3
+ import { Radio, RadioGroup } from "vant"
4
+ import ExField from "./ExField.jsx"
5
+ import { isFunction, pick } from "lodash-es"
6
+
7
+ /**
8
+ * ExMatrixScale 矩阵量表
9
+ * @version 1.0.0
10
+ */
11
+ export default defineComponent({
12
+ name: "ExMatrixScale",
13
+ props: {
14
+ ...defaultFieldProps,
15
+ ...defaultOptionsProps,
16
+
17
+ /**
18
+ * 行标题
19
+ */
20
+ rows: { type: [Array, Function], default: () => [] },
21
+ modelValue: { type: Object, default: () => ({}) },
22
+ },
23
+ emits: ["update:modelValue"],
24
+ setup(props, { emit, slots }) {
25
+ const componentValue = ref(props.modelValue)
26
+
27
+ watch(
28
+ () => props.modelValue,
29
+ () => (componentValue.value = props.modelValue),
30
+ )
31
+
32
+ let options = ref([])
33
+
34
+ useOptionTrait(options, props)
35
+
36
+ const level = props.defaultProps?.level || 5
37
+
38
+ if (options.value.length > level) {
39
+ options.value = options.value.slice(0, level)
40
+ } else if (options.value.length < level) {
41
+ //如果选项不及量表等级则补全
42
+ for (let i = options.value.length; i < level; i += 1) {
43
+ options.value.push({ text: i + 1, value: i + 1 })
44
+ }
45
+ }
46
+
47
+ const rows = isFunction(props.rows) ? props.rows() : props.rows
48
+
49
+ const onChange = () => {
50
+ emit("update:modelValue", componentValue.value)
51
+ }
52
+
53
+ const fieldProps = pick(props, Object.keys(defaultFieldProps))
54
+
55
+ return () => (
56
+ <ExField class={"ex-matrix"} {...fieldProps}>
57
+ {{
58
+ ...slots,
59
+ input: () => (
60
+ <div class={"ex-matrix-container"}>
61
+ <table>
62
+ <thead>
63
+ <tr>
64
+ <th></th>
65
+ {options.value.map((item) => (
66
+ <th>
67
+ <div class={"ex-matrix-option"}>{item.text}</div>
68
+ </th>
69
+ ))}
70
+ </tr>
71
+ </thead>
72
+ <tbody>
73
+ {rows.map((row) => (
74
+ <tr>
75
+ <td>
76
+ <div class={"ex-matrix-row"}>{row}</div>
77
+ </td>
78
+ {options.value.map((option, index) => (
79
+ <td>
80
+ <div class={"ex-matrix-option"}>
81
+ <RadioGroup onChange={onChange} v-model={componentValue.value[row]}>
82
+ {() => <Radio name={index + 1}></Radio>}
83
+ </RadioGroup>
84
+ </div>
85
+ </td>
86
+ ))}
87
+ </tr>
88
+ ))}
89
+ </tbody>
90
+ </table>
91
+ </div>
92
+ ),
93
+ }}
94
+ </ExField>
95
+ )
96
+ },
97
+ })
@@ -15,14 +15,17 @@ import ExAddress from "./ExAddress.jsx"
15
15
  import ExCascader from "./ExCascader.jsx"
16
16
  import ExTime from "./ExTime.jsx"
17
17
  import ExFieldUploader from "./ExFieldUploader.jsx"
18
+ import ExMatrixRadio from "./ExMatrixRadio.jsx"
19
+ import ExMatrixScale from "./ExMatrixScale.jsx"
20
+ import ExMatrixCheckbox from "./ExMatrixCheckbox.jsx"
18
21
  import { Divider } from "vant"
19
22
 
20
23
  /**
21
24
  *
22
- * @param item
23
- * @param submitForm
24
- * @param props
25
- * @param slots
25
+ * @param {FormItemConfig} item
26
+ * @param {Object} submitForm
27
+ * @param {Object} [props]
28
+ * @param {Object} [slots]
26
29
  * @return {*|JSX.Element}
27
30
  */
28
31
  const render = (item, submitForm, { props, slots }) => {
@@ -48,19 +51,18 @@ const render = (item, submitForm, { props, slots }) => {
48
51
  fieldProps.name = item.key
49
52
  fieldProps.placeholder = fieldProps.placeholder || (isPicker ? `请选择${item.title}` : `请填写${item.title}`)
50
53
  fieldProps.rules = fieldProps.rules?.length
51
- ? fieldProps.rules.map((rule) => {
52
- if (rule.pattern) {
53
- return {
54
- ...rule,
55
- pattern: new RegExp(rule.pattern),
56
- }
57
- }
58
- return { ...rule }
59
- })
54
+ ? fieldProps.rules.map((rule) =>
55
+ rule.pattern
56
+ ? {
57
+ ...rule,
58
+ pattern: new RegExp(rule.pattern),
59
+ }
60
+ : { ...rule },
61
+ )
60
62
  : []
61
63
 
62
64
  // 具体组件的 props
63
- const componentProps = merge(pick(item, ["options", "defaultProps"]), item.exProps || {})
65
+ const componentProps = merge(pick(item, ["options", "defaultProps", "rows"]), item.exProps || {})
64
66
 
65
67
  //混合了Field和input slot组件的slots组合
66
68
  const componentSlots = item.defaultSlots || {}
@@ -241,6 +243,48 @@ const render = (item, submitForm, { props, slots }) => {
241
243
  </ExField>
242
244
  )
243
245
  break
246
+ case "matrix-radio": {
247
+ if (item.required) {
248
+ fieldProps.rules[fieldProps.rules.length - 1].validator = () => {
249
+ for (let i = 0; i < item.rows.length; i++) {
250
+ if (!submitForm[item.key][item.rows[i]]) {
251
+ return `请选择${item.rows[i]}`
252
+ }
253
+ }
254
+ return true
255
+ }
256
+ }
257
+ renderItem = <ExMatrixRadio v-model={submitForm[item.key]} {...componentProps} {...fieldProps} />
258
+ break
259
+ }
260
+ case "matrix-scale": {
261
+ if (item.required) {
262
+ fieldProps.rules[fieldProps.rules.length - 1].validator = () => {
263
+ for (let i = 0; i < item.rows.length; i++) {
264
+ if (!submitForm[item.key][item.rows[i]]) {
265
+ return `请选择${item.rows[i]}`
266
+ }
267
+ }
268
+ return true
269
+ }
270
+ }
271
+ renderItem = <ExMatrixScale v-model={submitForm[item.key]} {...componentProps} {...fieldProps} />
272
+ break
273
+ }
274
+ case "matrix-checkbox": {
275
+ if (item.required) {
276
+ fieldProps.rules[fieldProps.rules.length - 1].validator = () => {
277
+ for (let i = 0; i < item.rows.length; i++) {
278
+ if (!submitForm[item.key][item.rows[i]]) {
279
+ return `请选择${item.rows[i]}`
280
+ }
281
+ }
282
+ return true
283
+ }
284
+ }
285
+ renderItem = <ExMatrixCheckbox v-model={submitForm[item.key]} {...componentProps} {...fieldProps} />
286
+ break
287
+ }
244
288
  default:
245
289
  renderItem = (
246
290
  <ExField v-model={submitForm[item.key]} {...fieldProps}>
@@ -20,6 +20,7 @@ import _ExSwitch from "./ExSwitch.jsx"
20
20
  import _ExRate from "./ExRate.jsx"
21
21
  import _ExSlider from "./ExSlider.jsx"
22
22
  import _ExFieldUploader from "./ExFieldUploader.jsx"
23
+ import _ExMatrixRadio from "./ExMatrixRadio.jsx"
23
24
 
24
25
  import _ExForm from "./ExForm.jsx"
25
26
 
@@ -40,5 +41,6 @@ export const ExSwitch = withInstall(_ExSwitch)
40
41
  export const ExRate = withInstall(_ExRate)
41
42
  export const ExSlider = withInstall(_ExSlider)
42
43
  export const ExFieldUploader = withInstall(_ExFieldUploader)
44
+ export const ExMatrixRadio = withInstall(_ExMatrixRadio)
43
45
 
44
46
  export const ExForm = withInstall(_ExForm)