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