@ithinkdt/page 4.2.1 → 4.2.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ithinkdt/page",
3
- "version": "4.2.1",
3
+ "version": "4.2.3",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "iThinkDT Page",
@@ -39,8 +39,8 @@
39
39
  },
40
40
  "sideEffects": false,
41
41
  "dependencies": {
42
- "@vueuse/core": "^14.3.0",
43
- "nanoid": "^6.0.0",
42
+ "@vueuse/core": "^14.4.0",
43
+ "nanoid": "^6.0.1",
44
44
  "@ithinkdt/common": "~4.2.1"
45
45
  },
46
46
  "peerDependencies": {
@@ -49,9 +49,9 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "typescript": "~6.0.3",
52
- "vite": "^8.1.5",
53
- "vue": "^3.5.40",
54
- "vue-router": "^5.2.0"
52
+ "vite": "^8.2.2",
53
+ "vue": "^3.5.42",
54
+ "vue-router": "^5.3.0"
55
55
  },
56
56
  "scripts": {
57
57
  "release": "pnpm publish --no-git-checks"
package/src/crud.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { MaybeRef, VNodeChild } from 'vue'
2
2
 
3
- import { Awaitable, Falsely, MaybeArray } from '@ithinkdt/common/typed'
3
+ import { Awaitable, Falsely, MaybeArray, MaybePromise } from '@ithinkdt/common/typed'
4
4
 
5
5
  import { PresetKeyField, _DataWithPresetKeyField } from './data-source.js'
6
6
  import { FormItemHelper, FormItemOptions, FormModalOptionsBase } from './form.js'
7
+ import { ModalRenderParam } from './modal.js'
7
8
 
8
9
  export interface CrudConfirmParams {
9
10
  title: () => VNodeChild
@@ -71,13 +72,18 @@ type SimpleCrudOptions<
71
72
  submitText?: VNodeChild | (() => VNodeChild)
72
73
  cancelText?: VNodeChild | (() => VNodeChild)
73
74
  action?: (
74
- params: {
75
- onSubmit(this: void): Promise<boolean>
76
- onCancel(this: void): void
77
- onClose(this: void): void
78
- } & ({ model: CreateParams, type: 'create' }
79
- | { model: UpdateParams, type: 'edit' }
80
- | { model: DetailEntity, type: 'view' }),
75
+ params: Omit<ModalRenderParam, 'onConfirm'> & {
76
+ onSubmit(this: void): MaybePromise<boolean | void>
77
+ } & ({ /** @reactively */ model: CreateParams, type: 'create' }
78
+ | { /** @reactively */ model: UpdateParams, type: 'edit' }
79
+ | { /** @reactively */ model: DetailEntity, type: 'view' }),
80
+ ) => VNodeChild
81
+ actionExtra?: (
82
+ params: Omit<ModalRenderParam, 'onConfirm'> & {
83
+ onSubmit(this: void): MaybePromise<boolean | void>
84
+ } & ({ /** @reactively */ model: CreateParams, type: 'create' }
85
+ | { /** @reactively */ model: UpdateParams, type: 'edit' }
86
+ | { /** @reactively */ model: DetailEntity, type: 'view' }),
81
87
  ) => VNodeChild
82
88
  resizable?: MaybeRef<boolean | undefined>
83
89
  draggable?: MaybeRef<boolean | undefined>
package/src/crud.js CHANGED
@@ -100,6 +100,12 @@ function _useSimpleCrudModal(crudType, getItems, request, options) {
100
100
  type: crudType,
101
101
  })
102
102
  : undefined,
103
+ actionExtra: options.actionExtra
104
+ ? params => options.actionExtra({
105
+ ...params,
106
+ type: crudType,
107
+ })
108
+ : undefined,
103
109
  })
104
110
 
105
111
  return {
package/src/form.d.ts CHANGED
@@ -2,7 +2,7 @@ import { ComputedRef, MaybeRef, MaybeRefOrGetter, VNodeChild } from 'vue'
2
2
 
3
3
  import { Awaitable, MaybeArray, MaybePromise } from '@ithinkdt/common'
4
4
 
5
- import { ModalDialogOptions, ModalDrawerOptions, ModalReturns } from './modal.js'
5
+ import { ModalDialogOptions, ModalDrawerOptions, ModalRenderParam, ModalReturns } from './modal.js'
6
6
 
7
7
  export type ValidationTrigger = MaybeArray<'input' | 'blur' | (string & {})>
8
8
 
@@ -248,10 +248,18 @@ export type FormModalOptions<Model extends {}> = FormModalOptionsBase & FormHelp
248
248
  submitText?: VNodeChild | (() => VNodeChild)
249
249
  readonly?: MaybeRefOrGetter<boolean>
250
250
  action?: (
251
- params: {
252
- onSubmit(this: void): Promise<boolean>
253
- onCancel(this: void): void
254
- onClose(this: void): void
251
+ params: Omit<ModalRenderParam, 'onConfirm'> & {
252
+ onSubmit(this: void): MaybePromise<boolean | void>
253
+ /**
254
+ * 数据
255
+ * @reactively
256
+ */
257
+ model: Partial<Model>
258
+ },
259
+ ) => VNodeChild
260
+ actionExtra?: (
261
+ params: Omit<ModalRenderParam, 'onConfirm'> & {
262
+ onSubmit(this: void): MaybePromise<boolean | void>
255
263
  /**
256
264
  * 数据
257
265
  * @reactively
package/src/form.js CHANGED
@@ -502,7 +502,7 @@ export class ValidationError extends Error {
502
502
  }
503
503
  }
504
504
 
505
- export function useFormModal({ initial, items, rules, onSubmit, submitText, cancelText, action, readonly = false, ...options }) {
505
+ export function useFormModal({ initial, items, rules, onSubmit, submitText, cancelText, action, actionExtra, readonly = false, ...options }) {
506
506
  const { i18n: useI18n, getFormRenderer } = (hasInjectionContext() ? inject(PAGE_INJECTION, pageInjection) : pageInjection) ?? {}
507
507
  if (!getFormRenderer) {
508
508
  throw new Error('`useFormModal` not found `getFormRenderer` in injection, please install the page plugin.')
@@ -583,7 +583,10 @@ export function useFormModal({ initial, items, rules, onSubmit, submitText, canc
583
583
  validation2.value = {}
584
584
  },
585
585
  footer: action
586
- ? params => action({ ...params, model: form.model })
586
+ ? params => action({ ...params, onSubmit: params.onConfirm, model: form.model })
587
+ : undefined,
588
+ footerExtra: actionExtra
589
+ ? params => actionExtra({ ...params, onSubmit: params.onConfirm, model: form.model })
587
590
  : undefined,
588
591
  })
589
592
 
package/src/modal.d.ts CHANGED
@@ -3,15 +3,16 @@ import { CSSProperties, ComputedRef, DefineComponent, MaybeRef, VNodeChild } fro
3
3
  import { MaybePromise } from '@ithinkdt/common'
4
4
 
5
5
  export interface ModalOptionsBase {
6
- title?: VNodeChild | (() => VNodeChild)
7
- content: VNodeChild | (() => VNodeChild)
6
+ title?: VNodeChild | ((params: Omit<ModalRenderParam, 'title' | 'content' | 'footer' | 'footerExtra'>) => VNodeChild)
7
+ content: VNodeChild | ((params: Omit<ModalRenderParam, 'content'>) => VNodeChild)
8
8
  confirmText?: VNodeChild | (() => VNodeChild)
9
9
  confirmDisabled?: MaybeRef<boolean | undefined>
10
10
  confirmLoading?: MaybeRef<boolean | undefined>
11
11
  cancelText?: VNodeChild | (() => VNodeChild)
12
12
  cancelDisabled?: MaybeRef<boolean | undefined>
13
13
  cancelLoading?: MaybeRef<boolean | undefined>
14
- footer?: VNodeChild | ((params: ModalRenderParam) => VNodeChild)
14
+ footer?: VNodeChild | ((params: Omit<ModalRenderParam, 'content' | 'footer' | 'footerExtra'>) => VNodeChild)
15
+ footerExtra?: VNodeChild | ((params: Omit<ModalRenderParam, 'content' | 'footer' | 'footerExtra'>) => VNodeChild)
15
16
  closable?: MaybeRef<boolean | undefined>
16
17
  closeOnEsc?: MaybeRef<boolean | undefined>
17
18
  showMask?: MaybeRef<boolean | undefined>
@@ -41,6 +42,7 @@ export interface ModalRenderParam {
41
42
  title: VNodeChild
42
43
  content: VNodeChild
43
44
  footer: VNodeChild
45
+ footerExtra: VNodeChild
44
46
  visible: boolean
45
47
  loading: boolean | undefined
46
48
  resizable: boolean | undefined
package/src/modal.js CHANGED
@@ -1,21 +1,25 @@
1
1
  import { tryOnScopeDispose } from '@vueuse/core'
2
2
  import { nanoid } from 'nanoid'
3
- import { computed, defineComponent, h, hasInjectionContext, inject, isVNode, provide, reactive, ref, toValue, unref } from 'vue'
3
+ import { computed, defineComponent, h, hasInjectionContext, inject, onActivated, onDeactivated, provide, reactive, ref, renderSlot, toValue, unref, useSlots } from 'vue'
4
4
 
5
- import { IgnoreRejectionError, PAGE_INJECTION, pageInjection } from './plugin.js'
5
+ import { IgnoreRejectionError, PAGE_INJECTION, initModals, pageInjection } from './plugin.js'
6
6
 
7
+ const ModalProviderInjectionKey = Symbol('__MODAL_PROVIDER__')
7
8
  export const ModalProvider = defineComponent({
8
9
  name: 'ModalProvider',
9
10
  setup() {
10
- const { __modals } = inject(PAGE_INJECTION) ?? {}
11
- return () => __modals.value
11
+ const modalProviderInjection = inject(ModalProviderInjectionKey, () => inject(PAGE_INJECTION, pageInjection), true)
12
+ const { modals, addModal } = initModals()
13
+ provide(ModalProviderInjectionKey, { ...modalProviderInjection, __modals: modals, addModal, __isGlobal: false })
14
+ const slots = useSlots()
15
+ return () => [renderSlot(slots, 'default'), ...(modalProviderInjection.__isGlobal === false ? [] : pageInjection.__modals.value), ...modals.value]
12
16
  },
13
17
  })
14
18
 
15
19
  const ModalInjectionKey = Symbol('__MODAL__')
16
20
 
17
- export function useModal({ content, confirmText, confirmLoading, cancelText, cancelLoading, footer, onConfirm, onCancel, onClose, title, ...options }) {
18
- const { i18n: useI18n, getModalRenderer, addModal } = (hasInjectionContext() ? inject(PAGE_INJECTION, pageInjection) : pageInjection) ?? {}
21
+ export function useModal({ content, confirmText, confirmLoading, cancelText, cancelLoading, footer, footerExtra, onConfirm, onCancel, onClose, title, ...options }) {
22
+ const { i18n: useI18n, getModalRenderer, addModal } = (hasInjectionContext() ? inject(ModalProviderInjectionKey, pageInjection) : pageInjection) ?? {}
19
23
  if (!getModalRenderer) {
20
24
  throw new Error('`useModal` not found `getModalRenderer` in injection, please install the page plugin.')
21
25
  }
@@ -24,6 +28,14 @@ export function useModal({ content, confirmText, confirmLoading, cancelText, can
24
28
 
25
29
  const title2 = ref()
26
30
  const visible = ref(false)
31
+ let visibleSaved = visible.value
32
+ onActivated(() => {
33
+ visible.value = visibleSaved
34
+ })
35
+ onDeactivated(() => {
36
+ visibleSaved = visible.value
37
+ visible.value = false
38
+ })
27
39
  let resolve0, reject0
28
40
  const open = (title0) => {
29
41
  if (visible.value) {
@@ -56,6 +68,8 @@ export function useModal({ content, confirmText, confirmLoading, cancelText, can
56
68
  ...options,
57
69
  confirmLoading: computed(() => unref(confirmLoading) ?? confirming.value),
58
70
  cancelLoading: computed(() => unref(cancelLoading) ?? canceling.value),
71
+ confirmText: computed(() => toValue(confirmText ?? (confirmText === null ? null : t('common.confirm.defaultOk')))),
72
+ cancelText: computed(() => toValue(cancelText ?? (cancelText === null ? null : t('common.page.form.cancelText')))),
59
73
  visible,
60
74
  onAfterOpen: () => {
61
75
  options.onAfterOpen?.()
@@ -107,13 +121,16 @@ export function useModal({ content, confirmText, confirmLoading, cancelText, can
107
121
  })
108
122
 
109
123
  return () => {
124
+ const title0 = title2.value ?? (typeof title === 'function' ? title(renderParam) : title)
125
+ const footer0 = typeof footer === 'function' ? footer({ ...renderParam, title: title0 }) : footer
126
+ const footerExtra0 = typeof footerExtra === 'function' ? footerExtra({ ...renderParam, title: title0 }) : footerExtra
127
+ const content0 = typeof content === 'function' ? content({ ...renderParam, title: title0, footer: footer0, footerExtra: footerExtra0 }) : content
110
128
  return renderModal({
111
129
  ...renderParam,
112
- title: toValue(title2.value ?? title),
113
- content: toValue(content),
114
- footer: isVNode(footer) ? footer : footer === null ? null : footer?.(renderParam),
115
- confirmText: toValue(confirmText ?? (confirmText === null ? null : t('common.confirm.defaultOk'))),
116
- cancelText: toValue(cancelText ?? (cancelText === null ? null : t('common.page.form.cancelText'))),
130
+ title: title0,
131
+ footer: footer0,
132
+ footerExtra: footerExtra0,
133
+ content: content0,
117
134
  })
118
135
  }
119
136
  },
package/src/plugin.js CHANGED
@@ -7,22 +7,9 @@ export class IgnoreRejectionError extends Error {}
7
7
  export let pageInjection
8
8
  export function plugin(app, options) {
9
9
  if (options.getModalRenderer) {
10
- options.__modals = shallowRef([])
11
- options.addModal = (modal) => {
12
- if (!options.__modals.value.includes(modal)) {
13
- options.__modals.value = [
14
- ...options.__modals.value,
15
- modal,
16
- ]
17
- }
18
- return () => {
19
- const index = options.__modals.value.indexOf(modal)
20
- if (index !== -1) {
21
- options.__modals.value.splice(index, 1)
22
- options.__modals.value = [...options.__modals.value] // trigger reactivity
23
- }
24
- }
25
- }
10
+ const { modals, addModal } = initModals()
11
+ options.__modals = modals
12
+ options.addModal = addModal
26
13
  }
27
14
  pageInjection = { keyField: 'key', ...options }
28
15
  app.provide(PAGE_INJECTION, pageInjection)
@@ -45,3 +32,26 @@ export const PageProvider = defineComponent(
45
32
  return () => renderSlot(slots, 'default')
46
33
  },
47
34
  )
35
+
36
+ export function initModals() {
37
+ const modals = shallowRef([])
38
+ const addModal = (modal) => {
39
+ if (!modals.value.includes(modal)) {
40
+ modals.value = [
41
+ ...modals.value,
42
+ modal,
43
+ ]
44
+ }
45
+ return () => {
46
+ const index = modals.value.indexOf(modal)
47
+ if (index !== -1) {
48
+ modals.value.splice(index, 1)
49
+ modals.value = [...modals.value] // trigger reactivity
50
+ }
51
+ }
52
+ }
53
+ return {
54
+ modals,
55
+ addModal,
56
+ }
57
+ }