1
1
import type { ValidationMode } from '@jsonforms/core' ;
2
- import { reactive , ref , watch } from 'vue' ;
2
+ import { reactive , ref , watch , type Ref , type UnwrapRef } from 'vue' ;
3
+
4
+ export const appstoreLayouts = [ '' , 'demo-and-data' ] as const ;
5
+ export type AppstoreLayouts = ( typeof appstoreLayouts ) [ number ] ;
3
6
4
7
const appstore = reactive ( {
5
8
exampleName : useHistoryHash ( '' ) ,
6
9
rtl : false ,
7
- formOnly : false ,
10
+ layout : useLocalStorage ( 'vuetify-example-layout' , '' ) ,
11
+ formOnly : useHistoryHashQuery ( 'form-only' , false as boolean ) ,
12
+ activeTab : useHistoryHashQuery ( 'active-tab' , 0 as number ) ,
8
13
dark : useLocalStorage ( 'vuetify-example-dark' , false ) ,
9
14
theme : useLocalStorage ( 'vuetify-example-theme' , 'light' ) ,
10
- drawer : true ,
15
+ drawer : useHistoryHashQuery ( 'drawer' , true as boolean ) ,
11
16
settings : false ,
12
17
variant : useLocalStorage ( 'vuetify-example-variant' , '' ) ,
13
18
iconset : useLocalStorage ( 'vuetify-example-iconset' , 'mdi' ) ,
14
19
blueprint : useLocalStorage ( 'vuetify-example-blueprint' , 'md1' ) ,
15
20
jsonforms : {
16
- readonly : false ,
21
+ readonly : useHistoryHashQuery ( 'read-only' , false as boolean ) ,
17
22
validationMode : 'ValidateAndShow' as ValidationMode ,
18
23
config : {
19
24
restrict : true ,
@@ -26,7 +31,6 @@ const appstore = reactive({
26
31
hideAvatar : false ,
27
32
hideArraySummaryValidation : false ,
28
33
enableFilterErrorsBeforeTouch : false ,
29
- vuetify : { } ,
30
34
} ,
31
35
locale : useLocalStorage ( 'vuetify-example-locale' , 'en' ) ,
32
36
} ,
@@ -36,12 +40,13 @@ export const useAppStore = () => {
36
40
return appstore ;
37
41
} ;
38
42
39
- export function useHistoryHash ( initialValue : string ) {
43
+ function useHistoryHash ( initialValue : string ) {
40
44
const data = ref ( initialValue ) ;
41
45
42
46
// Function to update data based on URL hash
43
47
const updateDataFromHash = ( ) => {
44
- const hash = window . location . hash . slice ( 1 ) ;
48
+ const hashAndQuery = window . location . hash . slice ( 1 ) ; // Remove the leading '#'
49
+ const [ hash , _ ] = hashAndQuery . split ( '?' ) ; // Split hash and query string
45
50
if ( hash ) {
46
51
try {
47
52
data . value = decodeURIComponent ( hash ) ;
@@ -51,17 +56,83 @@ export function useHistoryHash(initialValue: string) {
51
56
}
52
57
} ;
53
58
54
- // Update data from URL hash on component mount
59
+ // Initial update from URL hash
55
60
updateDataFromHash ( ) ;
56
61
57
- watch (
58
- data ,
59
- ( newValue ) => {
60
- const encodedData = encodeURIComponent ( newValue ) ;
61
- window . history . replaceState ( null , '' , `#${ encodedData } ` ) ;
62
- } ,
63
- { deep : true } ,
64
- ) ;
62
+ watch ( data , ( newValue ) => {
63
+ const encodedData = encodeURIComponent ( newValue ) ;
64
+
65
+ const currentHash = window . location . hash . slice ( 1 ) ;
66
+ const [ , currentQueryString ] = currentHash . split ( '?' ) ; // Extract the query part after ?
67
+
68
+ window . history . replaceState (
69
+ null ,
70
+ '' ,
71
+ `#${ encodedData } ${ currentQueryString ? '?' + currentQueryString : '' } ` , // Keep the query parameters intact
72
+ ) ;
73
+ } ) ;
74
+
75
+ return data ;
76
+ }
77
+
78
+ function useHistoryHashQuery < T extends string | boolean | number > (
79
+ queryParam : string ,
80
+ initialValue : T ,
81
+ ) {
82
+ const data : Ref < UnwrapRef < T > > = ref < T > ( initialValue ) ;
83
+
84
+ // Function to update data based on URL hash
85
+ const updateDataFromHash = ( ) => {
86
+ const hashAndQuery = window . location . hash . slice ( 1 ) ; // Remove the leading '#'
87
+ const [ _ , query ] = hashAndQuery . split ( '?' ) ; // Split hash and query string
88
+
89
+ const searchParams = new URLSearchParams ( query ) ;
90
+ if ( searchParams ) {
91
+ try {
92
+ const value = searchParams . has ( queryParam )
93
+ ? searchParams . get ( queryParam )
94
+ : `${ initialValue } ` ;
95
+
96
+ // Convert the value based on the type of initialValue
97
+ if ( typeof initialValue === 'boolean' ) {
98
+ // Handle boolean conversion
99
+ data . value = ( value === 'true' ) as UnwrapRef < T > ;
100
+ } else if ( typeof initialValue === 'number' ) {
101
+ data . value = ( value ? parseFloat ( value ) : 0 ) as UnwrapRef < T > ;
102
+ } else if ( typeof initialValue === 'string' ) {
103
+ // Handle string conversion
104
+ data . value = value as UnwrapRef < T > ;
105
+ }
106
+ } catch ( error ) {
107
+ console . error ( 'Error parsing hash:' , error ) ;
108
+ }
109
+ }
110
+ } ;
111
+
112
+ // Initial update from URL hash
113
+ updateDataFromHash ( ) ;
114
+
115
+ watch ( data , ( newValue ) => {
116
+ const encodedData = encodeURIComponent ( newValue ) ;
117
+
118
+ const hashAndQuery = window . location . hash . slice ( 1 ) ; // Remove the leading '#'
119
+ const [ hash , query ] = hashAndQuery . split ( '?' ) ; // Split hash and query string
120
+
121
+ const searchParams = new URLSearchParams ( query ) ;
122
+
123
+ if ( newValue === initialValue ) {
124
+ // it is the default value so no need to preserve the query paramter
125
+ searchParams . delete ( queryParam ) ;
126
+ } else {
127
+ searchParams . set ( queryParam , encodedData ) ;
128
+ }
129
+
130
+ window . history . replaceState (
131
+ null ,
132
+ '' ,
133
+ `#${ hash } ${ searchParams . size > 0 ? '?' + searchParams : '' } ` , // Keep the query parameters intact
134
+ ) ;
135
+ } ) ;
65
136
66
137
return data ;
67
138
}
0 commit comments