11<script setup>
2- import { ref } from ' vue'
2+ import { ChevronDown , ChevronRight , Maximize2 , Minimize2 } from ' lucide-vue-next'
3+ import { computed , ref , watch } from ' vue'
34import OAMarkdown from ' ../Common/OAMarkdown.vue'
45import { Badge } from ' ../ui/badge'
6+ import { Button } from ' ../ui/button/index'
57import { Collapsible , CollapsibleContent , CollapsibleTrigger } from ' ../ui/collapsible'
8+ import { Tooltip , TooltipContent , TooltipProvider , TooltipTrigger } from ' ../ui/tooltip/index'
69import OASchemaPropertyAttributes from ' ./OASchemaPropertyAttributes.vue'
710
811const props = defineProps ({
@@ -26,13 +29,38 @@ const props = defineProps({
2629 type: Boolean ,
2730 default: undefined ,
2831 },
32+ expandAll: {
33+ type: Boolean ,
34+ default: undefined ,
35+ },
2936})
3037
3138const isOpen = ref (props .open !== undefined ? props .open : props .deep > 0 && props .level <= 10 )
3239
40+ const childrenExpandState = ref (undefined )
41+
42+ watch (() => props .expandAll , (newValue ) => {
43+ if (newValue !== undefined ) {
44+ isOpen .value = newValue
45+ childrenExpandState .value = newValue
46+ }
47+ }, { immediate: true })
48+
49+ const toggleAllChildren = (expand ) => {
50+ childrenExpandState .value = expand
51+ isOpen .value = expand
52+ }
53+
3354const isObject = props .property .types ? .includes (' object' )
3455const isArray = props .property .types ? .includes (' array' )
3556const isObjectOrArray = isObject || isArray || props .property .type === ' object' || props .property .type === ' array'
57+
58+ const hasExpandableProperties = computed (() => {
59+ return isObjectOrArray
60+ && props .property .properties
61+ && props .property .properties .length > 0
62+ && props .property .properties .some (p => (p .types ? .includes (' object' ) || p .types ? .includes (' array' ) || p .type === ' object' || p .type === ' array' ) && p .properties )
63+ })
3664< / script>
3765
3866< template>
@@ -51,30 +79,26 @@ const isObjectOrArray = isObject || isArray || props.property.type === 'object'
5179 {{ props .property .name }}
5280 < / span>
5381
54- < div
55- v- if = " isObjectOrArray && props.property.properties"
56- class = " flex-shrink-0 w-4 h-4 cursor-pointer"
57- >
58- < svg
59- v- if = " !isOpen"
60- xmlns= " http://www.w3.org/2000/svg"
61- width= " 100%"
62- height= " 100%"
63- viewBox= " 0 0 24 24"
64- >< path
65- fill= " currentColor"
66- d= " M8.59 16.58L13.17 12L8.59 7.41L10 6l6 6l-6 6z"
67- / ></ s vg>
68- < svg
69- v- if = " isOpen"
70- xmlns= " http://www.w3.org/2000/svg"
71- width= " 100%"
72- height= " 100%"
73- viewBox= " 0 0 24 24"
74- >< path
75- fill= " currentColor"
76- d= " M7.41 8.58L12 13.17l4.59-4.59L18 10l-6 6l-6-6z"
77- / ></ s vg>
82+ < div class = " flex items-center" >
83+ < TooltipProvider>
84+ < Tooltip delay- duration= " 200" >
85+ < TooltipTrigger as- child>
86+ < Button
87+ v- if = " isObjectOrArray && props.property.properties"
88+ size= " icon"
89+ variant= " icon"
90+ : aria- label= " isOpen ? $t('Collapse') : $t('Expand')"
91+ class = " flex-shrink-0 w-4 h-4 cursor-pointer"
92+ >
93+ < ChevronDown v- if = " isOpen" / >
94+ < ChevronRight v- else / >
95+ < / Button>
96+ < / TooltipTrigger>
97+ < TooltipContent>
98+ < p> {{ isOpen ? $t (' Collapse' ) : $t (' Expand' ) }}< / p>
99+ < / TooltipContent>
100+ < / Tooltip>
101+ < / TooltipProvider>
78102 < / div>
79103
80104 < div class = " flex flex-row items-center gap-1 text-muted-foreground" >
@@ -102,6 +126,30 @@ const isObjectOrArray = isObject || isArray || props.property.type === 'object'
102126 < / template>
103127 < / div>
104128
129+ < div
130+ v- if = " hasExpandableProperties"
131+ class = " flex items-center"
132+ >
133+ < TooltipProvider>
134+ < Tooltip delay- duration= " 200" >
135+ < TooltipTrigger as- child>
136+ < Button
137+ size= " icon"
138+ variant= " icon"
139+ : aria- label= " isOpen ? $t('Collapse all') : $t('Expand all')"
140+ @click .stop .prevent = " toggleAllChildren(!isOpen)"
141+ >
142+ < Minimize2 v- if = " isOpen" / >
143+ < Maximize2 v- else / >
144+ < / Button>
145+ < / TooltipTrigger>
146+ < TooltipContent>
147+ < p> {{ isOpen ? $t (' Collapse all' ) : $t (' Expand all' ) }}< / p>
148+ < / TooltipContent>
149+ < / Tooltip>
150+ < / TooltipProvider>
151+ < / div>
152+
105153 < div class = " flex-grow mx-2" >
106154 < div
107155 v- if = " props.property.required === true"
@@ -144,7 +192,8 @@ const isObjectOrArray = isObject || isArray || props.property.type === 'object'
144192 : schema= " props.schema"
145193 : deep= " props.deep - 1"
146194 : level= " props.level + 1"
147- : open= " subProperty?.meta?.isOneOf === true"
195+ : open= " childrenExpandState !== undefined ? childrenExpandState : subProperty?.meta?.isOneOf === true"
196+ : expand- all= " childrenExpandState"
148197 / >
149198 < / div>
150199 < / CollapsibleContent>
0 commit comments