1
+ <template >
2
+ <div >
3
+ <div v-if =" !typeName" >
4
+ <p class =" text-red-700" >Could not create view for unknown <b >type</b > {{ typeName }}</p >
5
+ </div >
6
+ <div v-else-if =" formStyle=='card'" :class =" panelClass" >
7
+ <div :class =" formClass" >
8
+ <div >
9
+ <div v-if =" $slots['heading']" ><slot name =" heading" ></slot ></div >
10
+ <h3 v-else :class =" headingClass" >{{ title }}</h3 >
11
+
12
+ <div v-if =" $slots['subheading']" ><slot name =" subheading" ></slot ></div >
13
+ <p v-else-if =" subHeading" :class =" subHeadingClass" >{{ subHeading }}</p >
14
+ <p v-else-if =" metaType?.notes" :class =" ['notes',subHeadingClass]" v-html =" metaType?.notes" ></p >
15
+ </div >
16
+ <MarkupModel :value =" model" />
17
+ </div >
18
+ </div >
19
+ <div v-else class =" relative z-10" aria-labelledby =" slide-over-title" role =" dialog" aria-modal =" true" >
20
+ <div class =" fixed inset-0" ></div >
21
+ <div class =" fixed inset-0 overflow-hidden" >
22
+ <div @mousedown =" close" class =" absolute inset-0 overflow-hidden" >
23
+ <div @mousedown.stop =" " class =" pointer-events-none fixed inset-y-0 right-0 flex pl-10" >
24
+ <div :class =" ['pointer-events-auto w-screen xl:max-w-3xl md:max-w-xl max-w-lg',transition1]" >
25
+ <div :class =" formClass" >
26
+ <div class =" flex min-h-0 flex-1 flex-col overflow-auto" >
27
+ <div class =" flex-1" >
28
+ <!-- Header -->
29
+ <div class =" bg-gray-50 dark:bg-gray-900 px-4 py-6 sm:px-6" >
30
+ <div class =" flex items-start justify-between space-x-3" >
31
+ <div class =" space-y-1" >
32
+ <div v-if =" $slots['heading']" ><slot name =" heading" ></slot ></div >
33
+ <h3 v-else :class =" headingClass" >{{ title }}</h3 >
34
+
35
+ <div v-if =" $slots['subheading']" ><slot name =" subheading" ></slot ></div >
36
+ <p v-else-if =" subHeading" :class =" subHeadingClass" >{{ subHeading }}</p >
37
+ <p v-else-if =" metaType?.notes" :class =" ['notes',subHeadingClass]" v-html =" metaType?.notes" ></p >
38
+ </div >
39
+ <div class =" flex h-7 items-center" >
40
+ <CloseButton button-class =" bg-gray-50 dark:bg-gray-900" @close =" close" />
41
+ </div >
42
+ </div >
43
+ </div >
44
+ <MarkupModel :value =" model" />
45
+ </div >
46
+ </div >
47
+ </div >
48
+ </div >
49
+ </div >
50
+ </div >
51
+ </div >
52
+ </div >
53
+ </div >
54
+ </template >
55
+
56
+ <script setup lang="ts">
57
+ import { useMetadata , Apis } from ' @/use/metadata'
58
+ import { form } from ' ./css'
59
+ import { computed , onMounted , onUnmounted , ref , watch } from ' vue'
60
+ import { transition } from ' @/use/utils'
61
+ import { Sole } from ' @/use/config'
62
+ import { humanize } from ' @servicestack/client'
63
+
64
+ const props = withDefaults (defineProps <{
65
+ model: any
66
+ apis? : Apis ,
67
+ typeName? : string ,
68
+ done? : Function ,
69
+ formStyle? : " slideOver" | " card"
70
+ panelClass? : string
71
+ formClass? : string
72
+ headingClass? : string
73
+ subHeadingClass? : string
74
+ heading? : string
75
+ subHeading? : string
76
+ }>(), {
77
+ formStyle: " slideOver" ,
78
+ })
79
+
80
+ const emit = defineEmits <{
81
+ (e : ' done' ): void
82
+ }>()
83
+
84
+ const { typeOf } = useMetadata ()
85
+
86
+ const typeName = computed (() => props .typeName ?? props .apis ! .dataModel ! .name )
87
+ const metaType = computed (() => typeOf (typeName .value ))
88
+ const panelClass = computed (() => props .panelClass || form .panelClass (props .formStyle ))
89
+ const formClass = computed (() => props .formClass || form .formClass (props .formStyle ))
90
+ const headingClass = computed (() => props .headingClass || form .headingClass (props .formStyle ))
91
+ const subHeadingClass = computed (() => props .subHeadingClass || form .subHeadingClass (props .formStyle ))
92
+
93
+ const title = computed (() => props .heading || typeOf (typeName .value )?.description ||
94
+ (props .model ?.id ? ` ${humanize (typeName .value )} ${props .model .id } ` : ' View ' + humanize (typeName .value )))
95
+
96
+ if (Sole .interceptors .has (' AutoViewForm.new' )) Sole .interceptors .invoke (' AutoViewForm.new' , { props })
97
+
98
+ function done() {
99
+ if (props .done ) {
100
+ props .done ()
101
+ }
102
+ }
103
+
104
+ /* SlideOver */
105
+ const show = ref (false )
106
+ const transition1 = ref (' ' )
107
+ const rule1 = {
108
+ entering: { cls: ' transform transition ease-in-out duration-500 sm:duration-700' , from: ' translate-x-full' , to: ' translate-x-0' },
109
+ leaving: { cls: ' transform transition ease-in-out duration-500 sm:duration-700' , from: ' translate-x-0' , to: ' translate-x-full' }
110
+ }
111
+ watch (show , () => {
112
+ transition (rule1 , transition1 , show .value )
113
+ if (! show .value ) setTimeout (done , 700 )
114
+ })
115
+ show .value = true
116
+ function close() {
117
+ if (props .formStyle == ' slideOver' ) {
118
+ show .value = false
119
+ } else {
120
+ done ()
121
+ }
122
+ }
123
+
124
+ const globalKeyHandler = (e : KeyboardEvent ) => { if (e .key === ' Escape' ) close () }
125
+ onMounted (() => window .addEventListener (' keydown' , globalKeyHandler ))
126
+ onUnmounted (() => window .removeEventListener (' keydown' , globalKeyHandler ))
127
+ </script >
0 commit comments