Skip to content
This repository was archived by the owner on Aug 29, 2024. It is now read-only.

Commit b5b7aeb

Browse files
committed
🐛🚧 Add stop area from its id, not name
Clarify names
1 parent e1330c1 commit b5b7aeb

File tree

3 files changed

+150
-104
lines changed

3 files changed

+150
-104
lines changed

src/components/StopArea.vue

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
removeStopPoint,
1919
removeStopArea,
2020
getWantedStops,
21-
selectedStops,
21+
selectedStopAreas,
2222
excludedStopPoints,
2323
} from "@/store/StopsManager";
2424
import {
@@ -50,7 +50,7 @@ const restoreStopComp = ref<InstanceType<typeof BaseModal> | null>(null);
5050
5151
const excludedStopPointsToRestore = ref<(StopPoint & { routes: FullyDescribedRoute[] })[]>([]);
5252
53-
async function getExcludedStopPoints() {
53+
async function getExcludedStopPointsToRestore() {
5454
excludedStopPointsToRestore.value = await mapAsync(
5555
excludedStopPoints.value
5656
.filter(([stopAreaId]) => stopAreaId === props.stopArea.id)
@@ -89,7 +89,7 @@ async function getExcludedStopPoints() {
8989
restoreStopComp.value.show(false);
9090
}
9191
92-
watch(excludedStopPoints, getExcludedStopPoints);
92+
watch(excludedStopPoints, getExcludedStopPointsToRestore);
9393
9494
fetchMinimized();
9595
</script>
@@ -159,7 +159,7 @@ fetchMinimized();
159159
class="mx-2 my-3 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 overflow-hidden transition-margin"
160160
>
161161
<StopPointComp
162-
v-for="stopPoint of getWantedStops(selectedStops).filter(
162+
v-for="stopPoint of getWantedStops(selectedStopAreas).filter(
163163
(stopPoint) => stopPoint.stopAreaId === stopArea.id,
164164
)"
165165
:key="stopPoint.id"
@@ -176,7 +176,7 @@ fetchMinimized();
176176
ref="restoreStopComp"
177177
@update:shown="
178178
(s) => {
179-
if (s) getExcludedStopPoints();
179+
if (s) getExcludedStopPointsToRestore();
180180
}
181181
"
182182
>

src/store/StopsManager.ts

+107-79
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
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";
93
import router from "@/router";
104
import { type LocationQuery, type RouteLocationNormalized } from "vue-router";
115
import { unique } from ".";
126

13-
const selectedStops = ref<FullyDescribedStopArea[]>([]);
7+
const selectedStopAreas = ref<StopAreaDetails[]>([]);
148
const excludedStopPoints = ref<[StopArea["id"], StopPoint["id"]][]>([]);
159

16-
const stops = ref<StopArea[]>([]);
10+
const stopAreas = ref<StopArea[]>([]);
1711

1812
let query: LocationQuery = {};
1913
let queryInternallyUpdated = false;
@@ -22,38 +16,41 @@ function provideQuery(q: LocationQuery) {
2216
query = { ...q };
2317
}
2418

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+
2526
async function queryUpdated(to: RouteLocationNormalized) {
2627
if (queryInternallyUpdated) {
2728
queryInternallyUpdated = false;
2829
return;
2930
}
3031
query = { ...to.query };
3132

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;
3636

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) {
4742
delete query[k];
4843
queryInternallyUpdated = true;
4944
router.push({ query });
5045
continue;
5146
}
52-
selectedStops.value = [...selectedStops.value, fullyDescribedStopArea];
47+
selectedStopAreas.value = [...selectedStopAreas.value, StopAreaDetails];
5348
}
5449

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+
});
5754

5855
excludedStopPoints.value = deserializeExcludedStopPoints(
5956
typeof query["eSP"] === "string" ? query["eSP"] : "",
@@ -73,16 +70,16 @@ function deserializeExcludedStopPoints(serializedExcludedStopPoints: string) {
7370
const stopAreaName = query[stopAreaNumber];
7471
if (!stopAreaName) continue;
7572

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;
7875

7976
const stopPoints = stopAreaString.split("-");
8077

8178
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]));
8380
if (!stopPoint) continue;
8481

85-
excludedStopPoints.push([stopArea.id, stopPoint.id]);
82+
excludedStopPoints.push([StopAreaDetails.id, stopPoint.id]);
8683
}
8784
}
8885

@@ -93,7 +90,7 @@ function serializeExcludedStopPoints(excludedStopPoints: [StopArea["id"], StopPo
9390
const partialExcludedStopPoints = [] as string[];
9491

9592
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);
9794
if (!stopArea) continue;
9895

9996
const stopAreaNumber = Object.keys(query).find((k) => query[k] === stopArea.name);
@@ -110,11 +107,19 @@ function serializeExcludedStopPoints(excludedStopPoints: [StopArea["id"], StopPo
110107
return partialExcludedStopPoints.join(",");
111108
}
112109

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);
115120
if (alreadySelected) {
116121
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);
118123
query["eSP"] = serializeExcludedStopPoints(excludedStopPoints.value);
119124
if (!query["eSP"].length) delete query["eSP"];
120125
queryInternallyUpdated = true;
@@ -123,22 +128,69 @@ async function addStopArea(stop: string) {
123128
} else return -1; //display error
124129
}
125130

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
128133

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);
133135
queryInternallyUpdated = true;
134136
router.push({ query });
135137

136-
selectedStops.value.push(fullyDescribedStopArea);
138+
selectedStopAreas.value.push(StopAreaDetails);
137139

138140
return 0;
139141
}
140142

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+
) {
142194
if (excludedStopPoints.value.find(([_, sp]) => sp === stopPointId)) {
143195
excludedStopPoints.value = excludedStopPoints.value.filter(([_, sp]) => sp != stopPointId);
144196
query["eSP"] = serializeExcludedStopPoints(excludedStopPoints.value);
@@ -148,18 +200,19 @@ async function addStopPoint(stopArea: StopArea, stopPointId: StopPoint["id"]) {
148200
return 1;
149201
}
150202

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
153206

154-
for (const stopPoint of fullyDescribedStopArea.details.stopPoints)
207+
for (const stopPoint of StopAreaDetails.stopPoints)
155208
excludedStopPoints.value.push([stopArea.id, stopPoint.id]);
156209

157-
selectedStops.value.push(fullyDescribedStopArea);
210+
selectedStopAreas.value.push(StopAreaDetails);
158211

159212
return 0;
160213
}
161214

162-
function removeStopPoint(stopArea: FullyDescribedStopArea, stopPoint: StopPoint) {
215+
function removeStopPoint(stopArea: StopAreaDetails, stopPoint: StopPoint) {
163216
if (
164217
excludedStopPoints.value.find(
165218
([stopAreaId, stopPointId]) => stopArea.id === stopAreaId && stopPoint.id === stopPointId,
@@ -174,40 +227,15 @@ function removeStopPoint(stopArea: FullyDescribedStopArea, stopPoint: StopPoint)
174227
queryInternallyUpdated = true;
175228
router.push({ query });
176229

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])))
178231
removeStopArea(stopArea);
179232
}
180233

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) => [
209237
...acc,
210-
...stopArea.details.stopPoints
238+
...stopArea.stopPoints
211239
.filter(
212240
(sp) =>
213241
!excludedStopPoints.value.find(
@@ -223,9 +251,9 @@ function getWantedStops(stops: typeof selectedStops.value) {
223251
}
224252

225253
export {
226-
selectedStops,
254+
selectedStopAreas,
227255
excludedStopPoints,
228-
stops,
256+
stopAreas,
229257
addStopArea,
230258
addStopPoint,
231259
removeStopPoint,

0 commit comments

Comments
 (0)