@citizenplane/pimp 18.10.2 → 18.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/CpSeatMap.vue.d.ts +29 -0
- package/dist/components/CpSeatMap.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapEmergencyExitDialog.vue.d.ts +21 -0
- package/dist/components/CpSeatMapEmergencyExitDialog.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapGrid.vue.d.ts +17 -0
- package/dist/components/CpSeatMapGrid.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapPlane.vue.d.ts +24 -0
- package/dist/components/CpSeatMapPlane.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapRow.vue.d.ts +22 -0
- package/dist/components/CpSeatMapRow.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapRowFacility.vue.d.ts +16 -0
- package/dist/components/CpSeatMapRowFacility.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapSeat.vue.d.ts +21 -0
- package/dist/components/CpSeatMapSeat.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapSeatWrapper.vue.d.ts +23 -0
- package/dist/components/CpSeatMapSeatWrapper.vue.d.ts.map +1 -0
- package/dist/components/CpSeatMapZone.vue.d.ts +16 -0
- package/dist/components/CpSeatMapZone.vue.d.ts.map +1 -0
- package/dist/components/CpTabs.vue.d.ts.map +1 -1
- package/dist/components/icons/IconPlaneNose.vue.d.ts +3 -0
- package/dist/components/icons/IconPlaneNose.vue.d.ts.map +1 -0
- package/dist/components/icons/IconPlaneWing.vue.d.ts +3 -0
- package/dist/components/icons/IconPlaneWing.vue.d.ts.map +1 -0
- package/dist/components/icons/IconSparkle.vue.d.ts +3 -0
- package/dist/components/icons/IconSparkle.vue.d.ts.map +1 -0
- package/dist/components/index.d.ts +14 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/constants/seatMap/CpSeatMapConfig.d.ts +22 -0
- package/dist/constants/seatMap/CpSeatMapConfig.d.ts.map +1 -0
- package/dist/constants/seatMap/CpSeatMapSeatSelection.d.ts +12 -0
- package/dist/constants/seatMap/CpSeatMapSeatSelection.d.ts.map +1 -0
- package/dist/constants/seatMap/CpSeatMapTransitionDirections.d.ts +5 -0
- package/dist/constants/seatMap/CpSeatMapTransitionDirections.d.ts.map +1 -0
- package/dist/constants/seatMap/IataTravelerTypes.d.ts +7 -0
- package/dist/constants/seatMap/IataTravelerTypes.d.ts.map +1 -0
- package/dist/constants/seatMap/Seat.d.ts +18 -0
- package/dist/constants/seatMap/Seat.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatAncillary.d.ts +9 -0
- package/dist/constants/seatMap/SeatAncillary.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatCharacteristic.d.ts +7 -0
- package/dist/constants/seatMap/SeatCharacteristic.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatCharacteristicCodes.d.ts +10 -0
- package/dist/constants/seatMap/SeatCharacteristicCodes.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatMap.d.ts +10 -0
- package/dist/constants/seatMap/SeatMap.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatMapZone.d.ts +6 -0
- package/dist/constants/seatMap/SeatMapZone.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatRow.d.ts +15 -0
- package/dist/constants/seatMap/SeatRow.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatRowFacilities.d.ts +10 -0
- package/dist/constants/seatMap/SeatRowFacilities.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatRowFacilityFlags.d.ts +8 -0
- package/dist/constants/seatMap/SeatRowFacilityFlags.d.ts.map +1 -0
- package/dist/constants/seatMap/SeatStatuses.d.ts +8 -0
- package/dist/constants/seatMap/SeatStatuses.d.ts.map +1 -0
- package/dist/constants/seatMap/index.d.ts +16 -0
- package/dist/constants/seatMap/index.d.ts.map +1 -0
- package/dist/helpers/seatMap.d.ts +28 -0
- package/dist/helpers/seatMap.d.ts.map +1 -0
- package/dist/pimp.es.js +4633 -4130
- package/dist/pimp.umd.js +40 -40
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpSeatMap.vue +226 -0
- package/src/components/CpSeatMapEmergencyExitDialog.vue +87 -0
- package/src/components/CpSeatMapGrid.vue +41 -0
- package/src/components/CpSeatMapPlane.vue +221 -0
- package/src/components/CpSeatMapRow.vue +183 -0
- package/src/components/CpSeatMapRowFacility.vue +88 -0
- package/src/components/CpSeatMapSeat.vue +138 -0
- package/src/components/CpSeatMapSeatWrapper.vue +189 -0
- package/src/components/CpSeatMapZone.vue +60 -0
- package/src/components/CpTabs.vue +25 -15
- package/src/components/icons/IconPlaneNose.vue +39 -0
- package/src/components/icons/IconPlaneWing.vue +11 -0
- package/src/components/icons/IconSparkle.vue +8 -0
- package/src/components/index.ts +51 -0
- package/src/constants/seatMap/CpSeatMapConfig.ts +47 -0
- package/src/constants/seatMap/CpSeatMapSeatSelection.ts +12 -0
- package/src/constants/seatMap/CpSeatMapTransitionDirections.ts +4 -0
- package/src/constants/seatMap/IataTravelerTypes.ts +6 -0
- package/src/constants/seatMap/Seat.ts +18 -0
- package/src/constants/seatMap/SeatAncillary.ts +8 -0
- package/src/constants/seatMap/SeatCharacteristic.ts +7 -0
- package/src/constants/seatMap/SeatCharacteristicCodes.ts +9 -0
- package/src/constants/seatMap/SeatMap.ts +10 -0
- package/src/constants/seatMap/SeatMapZone.ts +5 -0
- package/src/constants/seatMap/SeatRow.ts +15 -0
- package/src/constants/seatMap/SeatRowFacilities.ts +10 -0
- package/src/constants/seatMap/SeatRowFacilityFlags.ts +7 -0
- package/src/constants/seatMap/SeatStatuses.ts +7 -0
- package/src/constants/seatMap/index.ts +16 -0
- package/src/helpers/seatMap.ts +76 -0
- package/src/stories/CpSeatMap.stories.ts +357 -0
|
@@ -184,17 +184,6 @@ const getUnderlineElement = () => {
|
|
|
184
184
|
return underlineElement
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
// NOTE: fix mimatch width between active underline & focus outline of active tab
|
|
188
|
-
const getUnderlineInset = () => {
|
|
189
|
-
if (props.variant !== 'underline') return 0
|
|
190
|
-
|
|
191
|
-
const rootStyle = getComputedStyle(document.documentElement)
|
|
192
|
-
const rootFontSize = Number.parseFloat(rootStyle.fontSize)
|
|
193
|
-
const insetRem = Number.parseFloat(rootStyle.getPropertyValue('--cp-dimensions-0_5'))
|
|
194
|
-
|
|
195
|
-
return rootFontSize * insetRem
|
|
196
|
-
}
|
|
197
|
-
|
|
198
187
|
const setUnderlineStyle = () => {
|
|
199
188
|
const activeTabElement = getActiveTabElement()
|
|
200
189
|
const underlineElement = getUnderlineElement()
|
|
@@ -202,10 +191,12 @@ const setUnderlineStyle = () => {
|
|
|
202
191
|
|
|
203
192
|
if (!activeTabElement || !underlineElement || !containerElement) return
|
|
204
193
|
|
|
205
|
-
const
|
|
194
|
+
const containerRect = containerElement.getBoundingClientRect()
|
|
195
|
+
const tabRect = activeTabElement.getBoundingClientRect()
|
|
196
|
+
const left = tabRect.left - containerRect.left + containerElement.scrollLeft
|
|
206
197
|
|
|
207
|
-
underlineElement.style.width = `${
|
|
208
|
-
underlineElement.style.transform = `translate3d(${
|
|
198
|
+
underlineElement.style.width = `${tabRect.width}px`
|
|
199
|
+
underlineElement.style.transform = `translate3d(${left}px, 0, 0)`
|
|
209
200
|
}
|
|
210
201
|
|
|
211
202
|
const scrollToActiveElement = (behavior: ScrollBehavior = 'smooth') => {
|
|
@@ -298,7 +289,7 @@ watch(
|
|
|
298
289
|
opacity 300ms ease;
|
|
299
290
|
|
|
300
291
|
&:focus-visible {
|
|
301
|
-
outline-offset:
|
|
292
|
+
outline-offset: 0;
|
|
302
293
|
}
|
|
303
294
|
|
|
304
295
|
&--isLoading {
|
|
@@ -349,6 +340,25 @@ watch(
|
|
|
349
340
|
.cpTabs__tab:focus-visible {
|
|
350
341
|
border-bottom-left-radius: 0;
|
|
351
342
|
border-bottom-right-radius: 0;
|
|
343
|
+
outline: none;
|
|
344
|
+
|
|
345
|
+
&::before {
|
|
346
|
+
position: absolute;
|
|
347
|
+
border: var(--cp-dimensions-0_5) solid var(--cp-border-accent-solid);
|
|
348
|
+
border-radius: inherit;
|
|
349
|
+
border-bottom: none;
|
|
350
|
+
content: '';
|
|
351
|
+
inset: 0;
|
|
352
|
+
pointer-events: none;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
&.cpTabs__tab--isActive::before {
|
|
356
|
+
border-bottom: var(--cp-dimensions-0_5) solid var(--cp-border-accent-solid);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.cpTabs__tab--isActive:focus-visible ~ .cpTabs__activeUnderline--isUnderline {
|
|
361
|
+
opacity: 0;
|
|
352
362
|
}
|
|
353
363
|
}
|
|
354
364
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg fill="none" viewBox="0 0 504 433" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<g filter="url(#filter0_i_23228_86232)">
|
|
4
|
+
<path
|
|
5
|
+
d="M171.634 43.4901C209.521 -14.4961 294.478 -14.497 332.366 43.4891L462.309 242.364C489.513 283.999 504 332.657 504 382.391L504 432.666H0.00012207L0 382.391C5.19025e-05 332.657 14.4874 283.999 41.6914 242.364L171.634 43.4901Z"
|
|
6
|
+
fill="white"
|
|
7
|
+
/>
|
|
8
|
+
</g>
|
|
9
|
+
<path
|
|
10
|
+
d="M172.053 43.7637C209.743 -13.9203 294.257 -13.9212 331.947 43.7627L461.89 242.638C489.041 284.191 503.5 332.754 503.5 382.392V432.166H0.5V382.392C0.500052 332.754 14.9595 284.191 42.1104 242.638L172.053 43.7637Z"
|
|
11
|
+
stroke="#E9EAF6"
|
|
12
|
+
/>
|
|
13
|
+
<defs>
|
|
14
|
+
<filter
|
|
15
|
+
id="filter0_i_23228_86232"
|
|
16
|
+
color-interpolation-filters="sRGB"
|
|
17
|
+
filterUnits="userSpaceOnUse"
|
|
18
|
+
height="432.666"
|
|
19
|
+
width="504"
|
|
20
|
+
x="0"
|
|
21
|
+
y="0"
|
|
22
|
+
>
|
|
23
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
|
24
|
+
<feBlend in="SourceGraphic" in2="BackgroundImageFix" mode="normal" result="shape" />
|
|
25
|
+
<feColorMatrix
|
|
26
|
+
in="SourceAlpha"
|
|
27
|
+
result="hardAlpha"
|
|
28
|
+
type="matrix"
|
|
29
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
30
|
+
/>
|
|
31
|
+
<feOffset />
|
|
32
|
+
<feGaussianBlur stdDeviation="20" />
|
|
33
|
+
<feComposite in2="hardAlpha" k2="-1" k3="1" operator="arithmetic" />
|
|
34
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0.917647 0 0 0 0 0.92549 0 0 0 0 1 0 0 0 1 0" />
|
|
35
|
+
<feBlend in2="shape" mode="normal" result="effect1_innerShadow_23228_86232" />
|
|
36
|
+
</filter>
|
|
37
|
+
</defs>
|
|
38
|
+
</svg>
|
|
39
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg fill="none" preserveAspectRatio="xMaxYMid meet" viewBox="0 0 180 509" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M0 87.8 L180 0 L180 490.1 L0 508.7 Z" fill="url(#paint0_linear_23056_30266)" />
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="paint0_linear_23056_30266" x1="1" x2="0" y1="0.5" y2="0.5">
|
|
6
|
+
<stop offset="0.5" stop-color="white" />
|
|
7
|
+
<stop offset="1" stop-color="white" stop-opacity="0" />
|
|
8
|
+
</linearGradient>
|
|
9
|
+
</defs>
|
|
10
|
+
</svg>
|
|
11
|
+
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg fill="none" height="13" viewBox="0 0 13 13" width="13" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path
|
|
4
|
+
d="M5.64966 0.826416C5.81077 0.391202 6.42605 0.3912 6.58716 0.826416L7.65063 3.70044C7.80258 4.11068 8.12614 4.43424 8.53638 4.58618L11.4104 5.64966C11.8456 5.81077 11.8456 6.42605 11.4104 6.58716L8.53638 7.65063C8.12614 7.80258 7.80258 8.12614 7.65063 8.53638L6.58716 11.4104C6.42605 11.8456 5.81077 11.8456 5.64966 11.4104L4.58618 8.53638C4.43424 8.12614 4.11068 7.80258 3.70044 7.65063L0.826416 6.58716C0.391202 6.42605 0.3912 5.81077 0.826416 5.64966L3.70044 4.58618C4.05951 4.45319 4.35244 4.18883 4.52173 3.84985L4.58618 3.70044L5.64966 0.826416Z"
|
|
5
|
+
stroke="#D1D3E6"
|
|
6
|
+
/>
|
|
7
|
+
</svg>
|
|
8
|
+
</template>
|
package/src/components/index.ts
CHANGED
|
@@ -43,6 +43,15 @@ import CpMultiselect from './CpMultiselect.vue'
|
|
|
43
43
|
import CpRadio from './CpRadio.vue'
|
|
44
44
|
import CpRadioGroup from './CpRadioGroup.vue'
|
|
45
45
|
import CpRadioNew from './CpRadioNew.vue'
|
|
46
|
+
import CpSeatMap from './CpSeatMap.vue'
|
|
47
|
+
import CpSeatMapEmergencyExitDialog from './CpSeatMapEmergencyExitDialog.vue'
|
|
48
|
+
import CpSeatMapGrid from './CpSeatMapGrid.vue'
|
|
49
|
+
import CpSeatMapPlane from './CpSeatMapPlane.vue'
|
|
50
|
+
import CpSeatMapRow from './CpSeatMapRow.vue'
|
|
51
|
+
import CpSeatMapRowFacility from './CpSeatMapRowFacility.vue'
|
|
52
|
+
import CpSeatMapSeat from './CpSeatMapSeat.vue'
|
|
53
|
+
import CpSeatMapSeatWrapper from './CpSeatMapSeatWrapper.vue'
|
|
54
|
+
import CpSeatMapZone from './CpSeatMapZone.vue'
|
|
46
55
|
import CpSelect from './CpSelect.vue'
|
|
47
56
|
import CpSelectableButton from './CpSelectableButton.vue'
|
|
48
57
|
import CpSelectMenu from './CpSelectMenu.vue'
|
|
@@ -132,6 +141,15 @@ const Components = {
|
|
|
132
141
|
CpTransitionSlide,
|
|
133
142
|
CpTransitionTabContent,
|
|
134
143
|
CpTrip,
|
|
144
|
+
CpSeatMap,
|
|
145
|
+
CpSeatMapEmergencyExitDialog,
|
|
146
|
+
CpSeatMapGrid,
|
|
147
|
+
CpSeatMapPlane,
|
|
148
|
+
CpSeatMapRow,
|
|
149
|
+
CpSeatMapRowFacility,
|
|
150
|
+
CpSeatMapSeat,
|
|
151
|
+
CpSeatMapSeatWrapper,
|
|
152
|
+
CpSeatMapZone,
|
|
135
153
|
}
|
|
136
154
|
|
|
137
155
|
const Pimp: Plugin = {
|
|
@@ -152,6 +170,30 @@ const Pimp: Plugin = {
|
|
|
152
170
|
},
|
|
153
171
|
}
|
|
154
172
|
|
|
173
|
+
export type {
|
|
174
|
+
CpSeatMapConfig,
|
|
175
|
+
CpSeatMapSeatSelection,
|
|
176
|
+
Seat,
|
|
177
|
+
SeatAncillary,
|
|
178
|
+
SeatCharacteristic,
|
|
179
|
+
SeatMap,
|
|
180
|
+
SeatMapZone,
|
|
181
|
+
SeatRow,
|
|
182
|
+
SeatRowFacilityFlags,
|
|
183
|
+
} from '@/constants/seatMap'
|
|
184
|
+
export type { CpSeatMapSeatSelection as CpSeatMapSelection } from '@/constants/seatMap/CpSeatMapSeatSelection'
|
|
185
|
+
|
|
186
|
+
export {
|
|
187
|
+
CpSeatMapTransitionDirections,
|
|
188
|
+
DEFAULT_CP_SEAT_MAP_CONFIG,
|
|
189
|
+
IataTravelerTypes,
|
|
190
|
+
SeatCharacteristicCodes,
|
|
191
|
+
SeatRowFacilities,
|
|
192
|
+
SeatRowFacilityPosition,
|
|
193
|
+
SeatStatuses,
|
|
194
|
+
} from '@/constants/seatMap'
|
|
195
|
+
// Consumers key `selections` with this, so it has to be the very same helper.
|
|
196
|
+
export { displaySeat } from '@/helpers/seatMap'
|
|
155
197
|
export {
|
|
156
198
|
CpAccordion,
|
|
157
199
|
CpAccordionGroup,
|
|
@@ -182,6 +224,15 @@ export {
|
|
|
182
224
|
CpRadio,
|
|
183
225
|
CpRadioGroup,
|
|
184
226
|
CpRadioNew,
|
|
227
|
+
CpSeatMap,
|
|
228
|
+
CpSeatMapEmergencyExitDialog,
|
|
229
|
+
CpSeatMapGrid,
|
|
230
|
+
CpSeatMapPlane,
|
|
231
|
+
CpSeatMapRow,
|
|
232
|
+
CpSeatMapRowFacility,
|
|
233
|
+
CpSeatMapSeat,
|
|
234
|
+
CpSeatMapSeatWrapper,
|
|
235
|
+
CpSeatMapZone,
|
|
185
236
|
CpSelect,
|
|
186
237
|
CpSelectableButton,
|
|
187
238
|
CpSelectMenu,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { SeatStatuses } from './SeatStatuses'
|
|
2
|
+
|
|
3
|
+
export interface CpSeatMapConfig {
|
|
4
|
+
emergencyExit: {
|
|
5
|
+
close: string
|
|
6
|
+
confirm: string
|
|
7
|
+
disclaimerContent: string
|
|
8
|
+
disclaimerTitle: string
|
|
9
|
+
subtitle: string
|
|
10
|
+
title: string
|
|
11
|
+
}
|
|
12
|
+
facility: {
|
|
13
|
+
galley: string
|
|
14
|
+
lavatory: string
|
|
15
|
+
}
|
|
16
|
+
seatStatuses: Record<SeatStatuses, string> & {
|
|
17
|
+
selected: string
|
|
18
|
+
selectedForLinkedTraveler: string
|
|
19
|
+
selectTravelerFirst: string
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const DEFAULT_CP_SEAT_MAP_CONFIG: CpSeatMapConfig = {
|
|
24
|
+
seatStatuses: {
|
|
25
|
+
[SeatStatuses.FREE]: 'Available',
|
|
26
|
+
[SeatStatuses.OCCUPIED]: 'Occupied',
|
|
27
|
+
[SeatStatuses.OCCUPIED_BY_CURRENT_PAX]: 'Selected',
|
|
28
|
+
[SeatStatuses.BLOCKED]: 'Unavailable',
|
|
29
|
+
[SeatStatuses.PAYABLE]: 'Extra fee',
|
|
30
|
+
selected: 'Selected',
|
|
31
|
+
selectedForLinkedTraveler: 'Selected for this traveler and their linked traveler',
|
|
32
|
+
selectTravelerFirst: 'Select a traveler first',
|
|
33
|
+
},
|
|
34
|
+
facility: {
|
|
35
|
+
galley: 'Galley',
|
|
36
|
+
lavatory: 'Lavatory',
|
|
37
|
+
},
|
|
38
|
+
emergencyExit: {
|
|
39
|
+
close: 'Close',
|
|
40
|
+
confirm: 'Confirm',
|
|
41
|
+
disclaimerContent:
|
|
42
|
+
'You must be able to assist the crew in an evacuation. Passengers who cannot are not allowed in these rows.',
|
|
43
|
+
disclaimerTitle: 'Emergency exit row requirements',
|
|
44
|
+
subtitle: 'This seat is located in an emergency exit row.',
|
|
45
|
+
title: 'Emergency exit row',
|
|
46
|
+
},
|
|
47
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IataTravelerTypes } from './IataTravelerTypes'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What the consumer knows about a seat it has assigned. Pimp holds no selection
|
|
5
|
+
* state of its own — it only renders what it is handed.
|
|
6
|
+
*/
|
|
7
|
+
export interface CpSeatMapSeatSelection {
|
|
8
|
+
hasLinkedTraveler?: boolean
|
|
9
|
+
initials: string
|
|
10
|
+
/** Drives the linked-traveler badge icon; without it the badge falls back to infant. */
|
|
11
|
+
linkedTravelerType?: IataTravelerTypes
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SeatAncillary } from './SeatAncillary'
|
|
2
|
+
import type { SeatCharacteristic } from './SeatCharacteristic'
|
|
3
|
+
import type { SeatStatuses } from './SeatStatuses'
|
|
4
|
+
|
|
5
|
+
export interface Seat {
|
|
6
|
+
blocking_code?: string
|
|
7
|
+
characteristics: SeatCharacteristic[]
|
|
8
|
+
column: string
|
|
9
|
+
eligible_ancillaries: SeatAncillary[]
|
|
10
|
+
has_specific_message: boolean
|
|
11
|
+
id: number
|
|
12
|
+
is_exit_row: boolean
|
|
13
|
+
occupied_traveler_id: number
|
|
14
|
+
selected_ancillary?: SeatAncillary
|
|
15
|
+
status: SeatStatuses
|
|
16
|
+
traveler_eligibility?: Record<string, boolean>
|
|
17
|
+
type: string
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SeatMapZone } from './SeatMapZone'
|
|
2
|
+
import type { SeatRow } from './SeatRow'
|
|
3
|
+
|
|
4
|
+
export interface SeatMap {
|
|
5
|
+
aircraft: string
|
|
6
|
+
exit_row_warning_child_max_age?: number
|
|
7
|
+
ref_id_segment: string
|
|
8
|
+
rows: SeatRow[]
|
|
9
|
+
zones: Record<string, SeatMapZone>
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Seat } from './Seat'
|
|
2
|
+
import type { SeatRowFacilityFlags } from './SeatRowFacilityFlags'
|
|
3
|
+
|
|
4
|
+
export interface SeatRow {
|
|
5
|
+
bottom?: SeatRowFacilityFlags
|
|
6
|
+
has_exit_back: boolean
|
|
7
|
+
has_exit_front: boolean
|
|
8
|
+
has_exit_left: boolean
|
|
9
|
+
has_exit_right: boolean
|
|
10
|
+
is_exit: boolean
|
|
11
|
+
number: number
|
|
12
|
+
seats: Record<string, Seat>
|
|
13
|
+
top?: SeatRowFacilityFlags
|
|
14
|
+
zone: string
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type { CpSeatMapConfig } from './CpSeatMapConfig'
|
|
2
|
+
export type { CpSeatMapSeatSelection } from './CpSeatMapSeatSelection'
|
|
3
|
+
export type { Seat } from './Seat'
|
|
4
|
+
export type { SeatAncillary } from './SeatAncillary'
|
|
5
|
+
export type { SeatCharacteristic } from './SeatCharacteristic'
|
|
6
|
+
export type { SeatMap } from './SeatMap'
|
|
7
|
+
export type { SeatMapZone } from './SeatMapZone'
|
|
8
|
+
export type { SeatRow } from './SeatRow'
|
|
9
|
+
export type { SeatRowFacilityFlags } from './SeatRowFacilityFlags'
|
|
10
|
+
|
|
11
|
+
export { DEFAULT_CP_SEAT_MAP_CONFIG } from './CpSeatMapConfig'
|
|
12
|
+
export { CpSeatMapTransitionDirections } from './CpSeatMapTransitionDirections'
|
|
13
|
+
export { IataTravelerTypes } from './IataTravelerTypes'
|
|
14
|
+
export { SeatCharacteristicCodes } from './SeatCharacteristicCodes'
|
|
15
|
+
export { SeatRowFacilities, SeatRowFacilityPosition } from './SeatRowFacilities'
|
|
16
|
+
export { SeatStatuses } from './SeatStatuses'
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { SeatMap } from '@/constants/seatMap/SeatMap'
|
|
2
|
+
import type { SeatRow } from '@/constants/seatMap/SeatRow'
|
|
3
|
+
|
|
4
|
+
import { IataTravelerTypes } from '@/constants/seatMap/IataTravelerTypes'
|
|
5
|
+
|
|
6
|
+
export type SeatMapLayout = (string | null)[]
|
|
7
|
+
|
|
8
|
+
export interface FormattedSeatMapZone {
|
|
9
|
+
id: string
|
|
10
|
+
layout: SeatMapLayout
|
|
11
|
+
title: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** A zone wider than this many columns switches the map to its compact treatment. */
|
|
15
|
+
const LARGE_PLANE_COLUMNS = 6
|
|
16
|
+
|
|
17
|
+
export const displaySeat = (seat: { column: string; row: number }) => `${seat.row}${seat.column}`
|
|
18
|
+
|
|
19
|
+
export const getSeatMapZones = (seatMap: SeatMap): FormattedSeatMapZone[] => {
|
|
20
|
+
return Object.keys(seatMap.zones).map((zoneId) => {
|
|
21
|
+
const zone = seatMap.zones[zoneId]
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
id: zoneId,
|
|
25
|
+
title: zone?.title || '',
|
|
26
|
+
layout: zone?.layout || [],
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getZoneRows = (seatMap: SeatMap, zoneId: string): SeatRow[] => {
|
|
32
|
+
return seatMap.rows.filter((row) => row.zone === zoneId).sort((a, b) => a.number - b.number)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const isLargeSeatMap = (zones: FormattedSeatMapZone[]) => {
|
|
36
|
+
return zones.some((zone) => zone.layout.length > LARGE_PLANE_COLUMNS)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A `null` column is an aisle; it gets a named grid area so row numbers can sit in it. */
|
|
40
|
+
export const getGridTemplateAreas = (layout: SeatMapLayout) => {
|
|
41
|
+
let hallwayIndex = 0
|
|
42
|
+
|
|
43
|
+
return layout
|
|
44
|
+
.map((column) => {
|
|
45
|
+
if (column === null) {
|
|
46
|
+
hallwayIndex++
|
|
47
|
+
return `HALLWAY-${hallwayIndex}`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return column
|
|
51
|
+
})
|
|
52
|
+
.join(' ')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const getGridTemplateColumns = (layout: SeatMapLayout) => {
|
|
56
|
+
return layout.map((column) => (column === null ? 'var(--hallway-width)' : 'var(--seat-width)')).join(' ')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Number of columns before the first aisle, used to span row facilities. */
|
|
60
|
+
export const getSeatBlockSize = (layout: SeatMapLayout) => {
|
|
61
|
+
const firstNullIndex = layout.indexOf(null)
|
|
62
|
+
return firstNullIndex > 0 ? firstNullIndex + 1 : layout.length
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const hasHallway = (layout: SeatMapLayout) => layout.includes(null)
|
|
66
|
+
|
|
67
|
+
export const getHallways = (layout: SeatMapLayout) => {
|
|
68
|
+
return layout.filter((column) => column === null).map((column, index) => ({ column, index: index + 1 }))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const getTravelerIcon = (passengerType?: IataTravelerTypes) => {
|
|
72
|
+
if (!passengerType || passengerType === IataTravelerTypes.ADULT) return ''
|
|
73
|
+
if ([IataTravelerTypes.CHILD, IataTravelerTypes.UNACCOMPANIED_MINOR].includes(passengerType)) return 'child'
|
|
74
|
+
|
|
75
|
+
return 'infant'
|
|
76
|
+
}
|