1
1
import { ref } from "vue" ;
2
- import {
3
- fetchStopAreaDetails ,
4
- fetchStops ,
5
- type FullyDescribedStopArea ,
6
- type StopArea ,
7
- type StopPoint ,
8
- } from "./TBM" ;
2
+ import { fetchStopAreaDetails , type StopAreaDetails , type StopArea , type StopPoint } from "./TBM" ;
9
3
import router from "@/router" ;
10
4
import { type LocationQuery , type RouteLocationNormalized } from "vue-router" ;
11
5
import { unique } from "." ;
12
6
13
- const selectedStops = ref < FullyDescribedStopArea [ ] > ( [ ] ) ;
7
+ const selectedStopAreas = ref < StopAreaDetails [ ] > ( [ ] ) ;
14
8
const excludedStopPoints = ref < [ StopArea [ "id" ] , StopPoint [ "id" ] ] [ ] > ( [ ] ) ;
15
9
16
- const stops = ref < StopArea [ ] > ( [ ] ) ;
10
+ const stopAreas = ref < StopArea [ ] > ( [ ] ) ;
17
11
18
12
let query : LocationQuery = { } ;
19
13
let queryInternallyUpdated = false ;
@@ -22,38 +16,41 @@ function provideQuery(q: LocationQuery) {
22
16
query = { ...q } ;
23
17
}
24
18
19
+ // In ascending order
20
+ function getStopAreaKeysFromQuery ( q : LocationQuery ) {
21
+ return Object . keys ( q )
22
+ . filter ( ( k ) => ! isNaN ( parseInt ( k ) ) )
23
+ . sort ( ( a , b ) => parseInt ( a ) - parseInt ( b ) ) ;
24
+ }
25
+
25
26
async function queryUpdated ( to : RouteLocationNormalized ) {
26
27
if ( queryInternallyUpdated ) {
27
28
queryInternallyUpdated = false ;
28
29
return ;
29
30
}
30
31
query = { ...to . query } ;
31
32
32
- for ( const k of Object . keys ( to . query )
33
- . filter ( ( k ) => ! isNaN ( parseInt ( k ) ) )
34
- . sort ( ( a , b ) => parseInt ( a ) - parseInt ( b ) ) ) {
35
- const providenStop = to . query [ k ] as string ;
33
+ const stopAreaKeys = getStopAreaKeysFromQuery ( to . query ) ;
34
+ for ( const k of stopAreaKeys ) {
35
+ const providedStopAreaId = to . query [ k ] as string ;
36
36
37
- if ( selectedStops . value . find ( ( s ) => s . name === providenStop ) ) continue ;
38
- const found = ( await fetchStops ( providenStop ) ) . find ( ( s ) => s . name === providenStop ) ;
39
- if ( ! found ) {
40
- delete query [ k ] ;
41
- queryInternallyUpdated = true ;
42
- router . push ( { query } ) ;
43
- continue ;
44
- }
45
- const fullyDescribedStopArea = await fetchStopAreaDetails ( found ) ;
46
- if ( ! fullyDescribedStopArea ) {
37
+ const deserializedStopAreaId = deserializeStopAreaId ( providedStopAreaId ) ;
38
+ if ( selectedStopAreas . value . find ( ( sa ) => sa . id === deserializedStopAreaId ) ) continue ;
39
+
40
+ const StopAreaDetails = await fetchStopAreaDetails ( { id : deserializedStopAreaId } ) ;
41
+ if ( ! StopAreaDetails ) {
47
42
delete query [ k ] ;
48
43
queryInternallyUpdated = true ;
49
44
router . push ( { query } ) ;
50
45
continue ;
51
46
}
52
- selectedStops . value = [ ...selectedStops . value , fullyDescribedStopArea ] ;
47
+ selectedStopAreas . value = [ ...selectedStopAreas . value , StopAreaDetails ] ;
53
48
}
54
49
55
- const providenStops = Object . keys ( query ) . map ( ( k ) => query [ k ] ) ;
56
- selectedStops . value = selectedStops . value . filter ( ( s ) => providenStops . includes ( s . name ) ) ;
50
+ selectedStopAreas . value = selectedStopAreas . value . filter ( ( sa ) => {
51
+ const serializedStopAreaId = serializeStopAreaId ( sa . id ) ;
52
+ return stopAreaKeys . find ( ( k ) => query [ k ] === serializedStopAreaId ) ;
53
+ } ) ;
57
54
58
55
excludedStopPoints . value = deserializeExcludedStopPoints (
59
56
typeof query [ "eSP" ] === "string" ? query [ "eSP" ] : "" ,
@@ -73,16 +70,16 @@ function deserializeExcludedStopPoints(serializedExcludedStopPoints: string) {
73
70
const stopAreaName = query [ stopAreaNumber ] ;
74
71
if ( ! stopAreaName ) continue ;
75
72
76
- const stopArea = selectedStops . value . find ( ( s ) => s . name === stopAreaName ) ;
77
- if ( ! stopArea ) continue ;
73
+ const StopAreaDetails = selectedStopAreas . value . find ( ( s ) => s . name === stopAreaName ) ;
74
+ if ( ! StopAreaDetails ) continue ;
78
75
79
76
const stopPoints = stopAreaString . split ( "-" ) ;
80
77
81
78
for ( let i = 1 ; i < stopPoints . length ; i ++ ) {
82
- const stopPoint = stopArea . details . stopPoints . find ( ( s ) => s . id . endsWith ( stopPoints [ i ] ) ) ;
79
+ const stopPoint = StopAreaDetails . stopPoints . find ( ( s ) => s . id . endsWith ( stopPoints [ i ] ) ) ;
83
80
if ( ! stopPoint ) continue ;
84
81
85
- excludedStopPoints . push ( [ stopArea . id , stopPoint . id ] ) ;
82
+ excludedStopPoints . push ( [ StopAreaDetails . id , stopPoint . id ] ) ;
86
83
}
87
84
}
88
85
@@ -93,7 +90,7 @@ function serializeExcludedStopPoints(excludedStopPoints: [StopArea["id"], StopPo
93
90
const partialExcludedStopPoints = [ ] as string [ ] ;
94
91
95
92
for ( const stopAreaId of excludedStopPoints . map ( ( [ stopArea ] ) => stopArea ) . filter ( unique ) ) {
96
- const stopArea = selectedStops . value . find ( ( s ) => s . id === stopAreaId ) ;
93
+ const stopArea = selectedStopAreas . value . find ( ( s ) => s . id === stopAreaId ) ;
97
94
if ( ! stopArea ) continue ;
98
95
99
96
const stopAreaNumber = Object . keys ( query ) . find ( ( k ) => query [ k ] === stopArea . name ) ;
@@ -110,11 +107,19 @@ function serializeExcludedStopPoints(excludedStopPoints: [StopArea["id"], StopPo
110
107
return partialExcludedStopPoints . join ( "," ) ;
111
108
}
112
109
113
- async function addStopArea ( stop : string ) {
114
- const alreadySelected = selectedStops . value . find ( ( s ) => s . name === stop ) ;
110
+ function serializeStopAreaId ( stopAreaId : StopArea [ "id" ] ) {
111
+ return stopAreaId . substring ( "stop_area:" . length ) ;
112
+ }
113
+
114
+ function deserializeStopAreaId ( stopAreaId : string ) : StopArea [ "id" ] {
115
+ return `stop_area:${ stopAreaId } ` ;
116
+ }
117
+
118
+ async function addStopArea ( stopArea : StopArea ) {
119
+ const alreadySelected = selectedStopAreas . value . find ( ( s ) => s . id === stopArea . id ) ;
115
120
if ( alreadySelected ) {
116
121
if ( excludedStopPoints . value . find ( ( [ sa ] ) => sa === alreadySelected . id ) ) {
117
- excludedStopPoints . value = excludedStopPoints . value . filter ( ( [ sp ] ) => sp != alreadySelected . id ) ;
122
+ excludedStopPoints . value = excludedStopPoints . value . filter ( ( [ sa ] ) => sa != alreadySelected . id ) ;
118
123
query [ "eSP" ] = serializeExcludedStopPoints ( excludedStopPoints . value ) ;
119
124
if ( ! query [ "eSP" ] . length ) delete query [ "eSP" ] ;
120
125
queryInternallyUpdated = true ;
@@ -123,22 +128,69 @@ async function addStopArea(stop: string) {
123
128
} else return - 1 ; //display error
124
129
}
125
130
126
- const found = stops . value . find ( ( s ) => s . name === stop ) ;
127
- if ( ! found ) return - 2 ; // display error
131
+ const StopAreaDetails = await fetchStopAreaDetails ( stopArea ) ;
132
+ if ( ! StopAreaDetails ) return - 2 ; // display error
128
133
129
- const fullyDescribedStopArea = await fetchStopAreaDetails ( found ) ;
130
- if ( ! fullyDescribedStopArea ) return - 3 ; // display error
131
-
132
- query [ Object . keys ( query ) . length + 1 ] = fullyDescribedStopArea . name ;
134
+ query [ getStopAreaKeysFromQuery ( query ) . length + 1 ] = serializeStopAreaId ( StopAreaDetails . id ) ;
133
135
queryInternallyUpdated = true ;
134
136
router . push ( { query } ) ;
135
137
136
- selectedStops . value . push ( fullyDescribedStopArea ) ;
138
+ selectedStopAreas . value . push ( StopAreaDetails ) ;
137
139
138
140
return 0 ;
139
141
}
140
142
141
- async function addStopPoint ( stopArea : StopArea , stopPointId : StopPoint [ "id" ] ) {
143
+ function removeStopArea ( stopArea : StopAreaDetails ) {
144
+ selectedStopAreas . value = selectedStopAreas . value . filter ( ( s ) => s . id != stopArea . id ) ;
145
+
146
+ let queryNeedUpdate = false ;
147
+
148
+ if ( excludedStopPoints . value . find ( ( [ stopAreaId ] ) => stopAreaId === stopArea . id ) ) {
149
+ queryNeedUpdate = true ;
150
+ excludedStopPoints . value = excludedStopPoints . value . filter ( ( [ stopAreaId ] ) => stopAreaId !== stopArea . id ) ;
151
+ query [ "eSP" ] = serializeExcludedStopPoints ( excludedStopPoints . value ) ;
152
+ if ( ! query [ "eSP" ] . length ) delete query [ "eSP" ] ;
153
+ }
154
+
155
+ const serializedStopAreaId = serializeStopAreaId ( stopArea . id ) ;
156
+ Object . keys ( query ) . forEach ( ( k ) => {
157
+ if ( query [ k ] === serializedStopAreaId ) {
158
+ queryNeedUpdate = true ;
159
+ delete query [ k ] ;
160
+ }
161
+ } ) ;
162
+
163
+ let gap = 0 ;
164
+ getStopAreaKeysFromQuery ( query ) . forEach ( ( k , i , arr ) => {
165
+ const intK = parseInt ( k ) ;
166
+
167
+ // Init, full rename case
168
+ if ( i === 0 ) gap = intK - 1 ;
169
+
170
+ if ( gap ) {
171
+ query [ ( intK - gap ) . toString ( ) ] = query [ k ] ;
172
+ delete query [ k ] ;
173
+ }
174
+
175
+ // End of array, do not compute next gap
176
+ if ( i === arr . length - 1 ) return ;
177
+ const intK2 = parseInt ( arr [ i + 1 ] ) ;
178
+
179
+ // Next gap
180
+ gap += intK2 - intK - 1 ;
181
+ } ) ;
182
+ if ( gap ) queryNeedUpdate = true ;
183
+
184
+ if ( queryNeedUpdate ) {
185
+ queryInternallyUpdated = true ;
186
+ router . push ( { query } ) ;
187
+ }
188
+ }
189
+
190
+ async function addStopPoint (
191
+ stopArea : Parameters < typeof fetchStopAreaDetails > [ 0 ] ,
192
+ stopPointId : StopPoint [ "id" ] ,
193
+ ) {
142
194
if ( excludedStopPoints . value . find ( ( [ _ , sp ] ) => sp === stopPointId ) ) {
143
195
excludedStopPoints . value = excludedStopPoints . value . filter ( ( [ _ , sp ] ) => sp != stopPointId ) ;
144
196
query [ "eSP" ] = serializeExcludedStopPoints ( excludedStopPoints . value ) ;
@@ -148,18 +200,19 @@ async function addStopPoint(stopArea: StopArea, stopPointId: StopPoint["id"]) {
148
200
return 1 ;
149
201
}
150
202
151
- const fullyDescribedStopArea = await fetchStopAreaDetails ( stopArea ) ;
152
- if ( ! fullyDescribedStopArea ) return - 3 ; // display error
203
+ // Add stop area, exclude all stop points except stopPointId
204
+ const StopAreaDetails = await fetchStopAreaDetails ( stopArea ) ;
205
+ if ( ! StopAreaDetails ) return - 3 ; // display error
153
206
154
- for ( const stopPoint of fullyDescribedStopArea . details . stopPoints )
207
+ for ( const stopPoint of StopAreaDetails . stopPoints )
155
208
excludedStopPoints . value . push ( [ stopArea . id , stopPoint . id ] ) ;
156
209
157
- selectedStops . value . push ( fullyDescribedStopArea ) ;
210
+ selectedStopAreas . value . push ( StopAreaDetails ) ;
158
211
159
212
return 0 ;
160
213
}
161
214
162
- function removeStopPoint ( stopArea : FullyDescribedStopArea , stopPoint : StopPoint ) {
215
+ function removeStopPoint ( stopArea : StopAreaDetails , stopPoint : StopPoint ) {
163
216
if (
164
217
excludedStopPoints . value . find (
165
218
( [ stopAreaId , stopPointId ] ) => stopArea . id === stopAreaId && stopPoint . id === stopPointId ,
@@ -174,40 +227,15 @@ function removeStopPoint(stopArea: FullyDescribedStopArea, stopPoint: StopPoint)
174
227
queryInternallyUpdated = true ;
175
228
router . push ( { query } ) ;
176
229
177
- if ( stopArea . details . stopPoints . every ( ( s ) => excludedStopPoints . value . find ( ( esp ) => s . id === esp [ 1 ] ) ) )
230
+ if ( stopArea . stopPoints . every ( ( s ) => excludedStopPoints . value . find ( ( esp ) => s . id === esp [ 1 ] ) ) )
178
231
removeStopArea ( stopArea ) ;
179
232
}
180
233
181
- function removeStopArea ( stopArea : FullyDescribedStopArea ) {
182
- selectedStops . value = selectedStops . value . filter ( ( s ) => s . id != stopArea . id ) ;
183
-
184
- let queryNeedUpdate = false ;
185
-
186
- if ( excludedStopPoints . value . find ( ( [ stopAreaId ] ) => stopAreaId === stopArea . id ) ) {
187
- queryNeedUpdate = true ;
188
- excludedStopPoints . value = excludedStopPoints . value . filter ( ( [ stopAreaId ] ) => stopAreaId !== stopArea . id ) ;
189
- query [ "eSP" ] = serializeExcludedStopPoints ( excludedStopPoints . value ) ;
190
- if ( ! query [ "eSP" ] . length ) delete query [ "eSP" ] ;
191
- }
192
-
193
- Object . keys ( query ) . forEach ( ( k ) => {
194
- if ( query [ k ] === stopArea . name ) {
195
- queryNeedUpdate = true ;
196
- delete query [ k ] ;
197
- }
198
- } ) ;
199
-
200
- if ( queryNeedUpdate ) {
201
- queryInternallyUpdated = true ;
202
- router . push ( { query } ) ;
203
- }
204
- }
205
-
206
- function getWantedStops ( stops : typeof selectedStops . value ) {
207
- return stops . reduce (
208
- ( acc , stopArea : FullyDescribedStopArea ) => [
234
+ function getWantedStops ( stopAreas : typeof selectedStopAreas . value ) {
235
+ return stopAreas . reduce (
236
+ ( acc , stopArea : StopAreaDetails ) => [
209
237
...acc ,
210
- ...stopArea . details . stopPoints
238
+ ...stopArea . stopPoints
211
239
. filter (
212
240
( sp ) =>
213
241
! excludedStopPoints . value . find (
@@ -223,9 +251,9 @@ function getWantedStops(stops: typeof selectedStops.value) {
223
251
}
224
252
225
253
export {
226
- selectedStops ,
254
+ selectedStopAreas ,
227
255
excludedStopPoints ,
228
- stops ,
256
+ stopAreas ,
229
257
addStopArea ,
230
258
addStopPoint ,
231
259
removeStopPoint ,
0 commit comments