efficient-shell 4.126.4 → 4.131.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/README.md +972 -4
- package/dist/{Browser-IIVSJJIO.js → Browser-PSEMJFZE.js} +13 -9
- package/dist/Browser-PSEMJFZE.js.map +1 -0
- package/dist/{Calculator-HCKFTSJR.js → Calculator-ZXJPXG7F.js} +12 -8
- package/dist/Calculator-ZXJPXG7F.js.map +1 -0
- package/dist/ConfirmDialog-MTC7QMUJ.js +4 -0
- package/dist/{ConfirmDialog-LJXMB45A.js.map → ConfirmDialog-MTC7QMUJ.js.map} +1 -1
- package/dist/{CurrencyConverter-BKKORN6K.js → CurrencyConverter-WSJ2BBSX.js} +12 -8
- package/dist/CurrencyConverter-WSJ2BBSX.js.map +1 -0
- package/dist/{Documents-MIU3AWGL.js → Documents-PGMZR2MA.js} +14 -10
- package/dist/Documents-PGMZR2MA.js.map +1 -0
- package/dist/{Files-N2P2LJ5R.js → Files-2LKCJGYW.js} +17 -13
- package/dist/Files-2LKCJGYW.js.map +1 -0
- package/dist/{Notepad-L775LQBJ.js → Notepad-KW6WVABH.js} +15 -11
- package/dist/Notepad-KW6WVABH.js.map +1 -0
- package/dist/PdfViewer-M2YGZIYX.js +5 -0
- package/dist/{PdfViewer-LSP3YNFC.js.map → PdfViewer-M2YGZIYX.js.map} +1 -1
- package/dist/{PomodoroTimer-SVJ62RXM.js → PomodoroTimer-DG3LI5CX.js} +14 -10
- package/dist/PomodoroTimer-DG3LI5CX.js.map +1 -0
- package/dist/{Preview-G56SXZU4.js → Preview-E7EJJNXN.js} +16 -12
- package/dist/Preview-E7EJJNXN.js.map +1 -0
- package/dist/{Sidebar-J76PV4QF.js → Sidebar-BPU7RCZP.js} +5 -4
- package/dist/Sidebar-BPU7RCZP.js.map +1 -0
- package/dist/{Spreadsheet-ZP5KSNLJ.js → Spreadsheet-IDUODRZU.js} +14 -10
- package/dist/Spreadsheet-IDUODRZU.js.map +1 -0
- package/dist/{Stock-CDUS4VCZ.js → Stock-YMPOMUAW.js} +12 -8
- package/dist/Stock-YMPOMUAW.js.map +1 -0
- package/dist/{Weather-EEDBWBPQ.js → Weather-NZO3CWLH.js} +12 -8
- package/dist/Weather-NZO3CWLH.js.map +1 -0
- package/dist/{WorldClock-FFFULVTJ.js → WorldClock-HUC6D3AD.js} +12 -8
- package/dist/WorldClock-HUC6D3AD.js.map +1 -0
- package/dist/apps/index.js +26 -21
- package/dist/apps/index.js.map +1 -1
- package/dist/brand.css +1 -1
- package/dist/{chunk-N2CMEDSH.js → chunk-2GZQ352J.js} +4 -4
- package/dist/{chunk-N2CMEDSH.js.map → chunk-2GZQ352J.js.map} +1 -1
- package/dist/chunk-7IN7YZAL.js +547 -0
- package/dist/chunk-7IN7YZAL.js.map +1 -0
- package/dist/{chunk-YNGPTOL6.js → chunk-7MA5XBWD.js} +3 -3
- package/dist/{chunk-YNGPTOL6.js.map → chunk-7MA5XBWD.js.map} +1 -1
- package/dist/{chunk-4TVV2BIU.js → chunk-BJ34QOR3.js} +827 -624
- package/dist/chunk-BJ34QOR3.js.map +1 -0
- package/dist/{chunk-HNH7FOYB.js → chunk-CGXMWHQW.js} +7 -6
- package/dist/chunk-CGXMWHQW.js.map +1 -0
- package/dist/{chunk-N3CG5HG5.js → chunk-CLGNTGC5.js} +12 -11
- package/dist/chunk-CLGNTGC5.js.map +1 -0
- package/dist/chunk-D276EMXS.js +57 -0
- package/dist/chunk-D276EMXS.js.map +1 -0
- package/dist/{chunk-7KIOEKHS.js → chunk-E3TWIN7Z.js} +21 -135
- package/dist/chunk-E3TWIN7Z.js.map +1 -0
- package/dist/{chunk-2VM2FRZJ.js → chunk-EENVXIVU.js} +47 -67
- package/dist/chunk-EENVXIVU.js.map +1 -0
- package/dist/{chunk-YG45DAUT.js → chunk-FONEQRBH.js} +17 -11
- package/dist/chunk-FONEQRBH.js.map +1 -0
- package/dist/chunk-IPXN646P.js +14 -0
- package/dist/chunk-IPXN646P.js.map +1 -0
- package/dist/chunk-IRWSRJ4K.js +48 -0
- package/dist/chunk-IRWSRJ4K.js.map +1 -0
- package/dist/{chunk-JFQGPY7W.js → chunk-KWEX4ZAF.js} +20 -17
- package/dist/chunk-KWEX4ZAF.js.map +1 -0
- package/dist/chunk-LQTVTOSY.js +117 -0
- package/dist/chunk-LQTVTOSY.js.map +1 -0
- package/dist/{chunk-DMCFOWOJ.js → chunk-MQPX6ERJ.js} +4 -4
- package/dist/{chunk-DMCFOWOJ.js.map → chunk-MQPX6ERJ.js.map} +1 -1
- package/dist/{chunk-FQB24B42.js → chunk-SEWF4O3H.js} +3 -3
- package/dist/{chunk-FQB24B42.js.map → chunk-SEWF4O3H.js.map} +1 -1
- package/dist/{chunk-AXWC3332.js → chunk-TFXJRHJV.js} +3 -3
- package/dist/{chunk-AXWC3332.js.map → chunk-TFXJRHJV.js.map} +1 -1
- package/dist/{chunk-YNHLQ24V.js → chunk-TQURTLK2.js} +59 -143
- package/dist/chunk-TQURTLK2.js.map +1 -0
- package/dist/{chunk-6XQHH7D2.js → chunk-TRCWINHF.js} +5 -5
- package/dist/{chunk-6XQHH7D2.js.map → chunk-TRCWINHF.js.map} +1 -1
- package/dist/chunk-UHPWZ2F4.js +7 -0
- package/dist/{chunk-K6ZT6MWE.js.map → chunk-UHPWZ2F4.js.map} +1 -1
- package/dist/{chunk-32W6VY2J.js → chunk-VWZIGZFF.js} +4 -4
- package/dist/{chunk-32W6VY2J.js.map → chunk-VWZIGZFF.js.map} +1 -1
- package/dist/{chunk-HYZ5QMVO.js → chunk-XH3ELPQZ.js} +22 -19
- package/dist/chunk-XH3ELPQZ.js.map +1 -0
- package/dist/{chunk-W6XTG23K.js → chunk-ZKHD4J73.js} +8 -6
- package/dist/chunk-ZKHD4J73.js.map +1 -0
- package/dist/file-intake/index.js +3 -1
- package/dist/file-intake/index.js.map +1 -1
- package/dist/{index-dQia6NpB.d.ts → index-COwksV6G.d.ts} +699 -199
- package/dist/index.d.ts +2 -2
- package/dist/index.js +38 -31
- package/dist/index.js.map +1 -1
- package/dist/map/index.d.ts +329 -0
- package/dist/map/index.js +541 -0
- package/dist/map/index.js.map +1 -0
- package/dist/markdown/index.js +4 -3
- package/dist/markdown/index.js.map +1 -1
- package/dist/page-tabs/index.js +12 -8
- package/dist/page-tabs/index.js.map +1 -1
- package/dist/shell.css +17 -17
- package/dist/themes.css +15 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +17 -12
- package/dist/ui/index.js.map +1 -1
- package/dist/ui.css +673 -283
- package/package.json +11 -1
- package/dist/Browser-IIVSJJIO.js.map +0 -1
- package/dist/Calculator-HCKFTSJR.js.map +0 -1
- package/dist/ConfirmDialog-LJXMB45A.js +0 -3
- package/dist/CurrencyConverter-BKKORN6K.js.map +0 -1
- package/dist/Documents-MIU3AWGL.js.map +0 -1
- package/dist/Files-N2P2LJ5R.js.map +0 -1
- package/dist/Notepad-L775LQBJ.js.map +0 -1
- package/dist/PdfViewer-LSP3YNFC.js +0 -4
- package/dist/PomodoroTimer-SVJ62RXM.js.map +0 -1
- package/dist/Preview-G56SXZU4.js.map +0 -1
- package/dist/Sidebar-J76PV4QF.js.map +0 -1
- package/dist/Spreadsheet-ZP5KSNLJ.js.map +0 -1
- package/dist/Stock-CDUS4VCZ.js.map +0 -1
- package/dist/Weather-EEDBWBPQ.js.map +0 -1
- package/dist/WorldClock-FFFULVTJ.js.map +0 -1
- package/dist/chunk-2VM2FRZJ.js.map +0 -1
- package/dist/chunk-3CUSBZWG.js +0 -59
- package/dist/chunk-3CUSBZWG.js.map +0 -1
- package/dist/chunk-4TVV2BIU.js.map +0 -1
- package/dist/chunk-7KIOEKHS.js.map +0 -1
- package/dist/chunk-HNH7FOYB.js.map +0 -1
- package/dist/chunk-HYZ5QMVO.js.map +0 -1
- package/dist/chunk-JFQGPY7W.js.map +0 -1
- package/dist/chunk-K6ZT6MWE.js +0 -7
- package/dist/chunk-N3CG5HG5.js.map +0 -1
- package/dist/chunk-W6XTG23K.js.map +0 -1
- package/dist/chunk-YG45DAUT.js.map +0 -1
- package/dist/chunk-YNHLQ24V.js.map +0 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
|
+
import { QueryKey } from '@tanstack/react-query';
|
|
5
|
+
import * as _tanstack_query_core from '@tanstack/query-core';
|
|
6
|
+
import * as maplibre_gl from 'maplibre-gl';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Records on a map. One pin per placed record: a button carrying a glyph (or
|
|
10
|
+
* an icon) and, for a screen reader, the record's name in words, never the
|
|
11
|
+
* colour alone. The one map every EFFICIENT portal draws — the admin portal's
|
|
12
|
+
* Customer / Supplier maps and Trip Planner, the dealer portal's Address Book.
|
|
13
|
+
*
|
|
14
|
+
* Ported from Foyerboard's leads map, which draws its map the way
|
|
15
|
+
* whoson.today does: MapLibre over OpenFreeMap's vector tiles — free,
|
|
16
|
+
* keyless, OpenStreetMap data (the same data the backend geocodes against), a
|
|
17
|
+
* light and a dark style. The tiles load straight from tiles.openfreemap.org,
|
|
18
|
+
* so a host with a Content-Security-Policy must allow that origin.
|
|
19
|
+
*
|
|
20
|
+
* MapLibre is fetched only once the map mounts (`loadMapLibre`, which also
|
|
21
|
+
* says how the host serves its worker), and the map is made once per mount;
|
|
22
|
+
* pins, the selection, the theme and the fitted view are separate effects so
|
|
23
|
+
* a re-render never rebuilds the map.
|
|
24
|
+
*
|
|
25
|
+
* It also draws ROUTES — the Trip Planner's days, each a line under the pins
|
|
26
|
+
* (solid along the streets, dashed where it is only a straight-line estimate),
|
|
27
|
+
* again after a theme change, which replaces the style and every layer on it.
|
|
28
|
+
*/
|
|
29
|
+
interface MapPin {
|
|
30
|
+
key: string;
|
|
31
|
+
label: string;
|
|
32
|
+
lat: number;
|
|
33
|
+
lng: number;
|
|
34
|
+
/** One or two characters drawn on the pin (when it has no `icon`). */
|
|
35
|
+
glyph: string;
|
|
36
|
+
/** An icon drawn instead of the glyph: SVG path data, 24 × 24, stroked —
|
|
37
|
+
* the admin Trip Planner's stage icons. */
|
|
38
|
+
icon?: readonly string[];
|
|
39
|
+
/** A small tag on the pin's corner — a visit's place in the day's order. */
|
|
40
|
+
badge?: string;
|
|
41
|
+
/** Tone classes for the badge; white by default. */
|
|
42
|
+
badgeTone?: string;
|
|
43
|
+
/** Tone classes (background + text) — see `pinTone`. */
|
|
44
|
+
tone: string;
|
|
45
|
+
/** The pin marks an area, not the address: drawn dashed and faded. */
|
|
46
|
+
approximate?: boolean;
|
|
47
|
+
/** Shown for context only (another day's visits on the Trip Planner): drawn faint. */
|
|
48
|
+
faded?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** A line on the map: a day's road, or its straight-line estimate. */
|
|
51
|
+
interface MapRoute {
|
|
52
|
+
key: string;
|
|
53
|
+
/** [lng, lat] pairs, in order. */
|
|
54
|
+
coordinates: [number, number][];
|
|
55
|
+
/** Straight lines between the points, not the road: drawn dashed. */
|
|
56
|
+
estimate: boolean;
|
|
57
|
+
/** Context only (another day): drawn faint. */
|
|
58
|
+
faded?: boolean;
|
|
59
|
+
}
|
|
60
|
+
declare function EntityMap({ pins, selectedKey, focus, onSelect, ariaLabel, className, children, routes, fitTo, attribution, }: {
|
|
61
|
+
pins: MapPin[];
|
|
62
|
+
selectedKey: string | null;
|
|
63
|
+
/** Bump `n` to fly to a pin (the list's "show on map"). */
|
|
64
|
+
focus: {
|
|
65
|
+
key: string;
|
|
66
|
+
n: number;
|
|
67
|
+
} | null;
|
|
68
|
+
onSelect: (key: string) => void;
|
|
69
|
+
ariaLabel: string;
|
|
70
|
+
className?: string;
|
|
71
|
+
/** Drawn over the map: the selected record's card, the legend. */
|
|
72
|
+
children?: ReactNode;
|
|
73
|
+
/** Lines under the pins — the Trip Planner's day routes. */
|
|
74
|
+
routes?: MapRoute[];
|
|
75
|
+
/** Fit the view to these pins only (the day being planned); all pins when unset. */
|
|
76
|
+
fitTo?: string[] | null;
|
|
77
|
+
/** Extra credit line for the attribution (HTML), e.g. the router's. Read once, at mount. */
|
|
78
|
+
attribution?: string;
|
|
79
|
+
}): react_jsx_runtime.JSX.Element;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Map points — the wire shape every EFFICIENT map endpoint answers with, and
|
|
83
|
+
* the pure logic over it: what a point says about itself, how its pin looks,
|
|
84
|
+
* and the counts over a list of them. Kept free of React and MapLibre so it is
|
|
85
|
+
* testable without WebGL.
|
|
86
|
+
*
|
|
87
|
+
* The shape is efficient-backend's `logistics.serializers.MapPointsSerializer`
|
|
88
|
+
* (the `address-geocoding` capability): the admin portal's Customer / Supplier
|
|
89
|
+
* maps and Trip Planner, and the dealer portal's Address Book. Every record
|
|
90
|
+
* comes back, pinned or not — a point off the map has null `lat` / `lng` and a
|
|
91
|
+
* `placement` saying why, so a list beside the map can explain it instead of
|
|
92
|
+
* silently dropping the row. The backend never makes a request wait on the
|
|
93
|
+
* geocoder: an address it has not seen is `pending`, and the caller asks again
|
|
94
|
+
* while `pending > 0` (`mapPointsRefetchInterval`).
|
|
95
|
+
*
|
|
96
|
+
* Moved here from the admin portal (`src/components/map/mapPoints.ts`) so the
|
|
97
|
+
* dealer portal draws the same map rather than a second one.
|
|
98
|
+
*/
|
|
99
|
+
/**
|
|
100
|
+
* located — the geocoder matched the street
|
|
101
|
+
* approximate — only the suburb / postcode / city matched; the pin marks the area
|
|
102
|
+
* pending — still being looked up (poll again)
|
|
103
|
+
* not_found — the geocoder found nothing for this address
|
|
104
|
+
* failed — the map service could not answer; retried later
|
|
105
|
+
* no_address — too little to look up: no city or postcode (and none written into the street)
|
|
106
|
+
*/
|
|
107
|
+
type MapPlacement = 'located' | 'approximate' | 'pending' | 'not_found' | 'failed' | 'no_address';
|
|
108
|
+
/**
|
|
109
|
+
* One record on (or off) a map. `kind` is the record type the endpoint pinned
|
|
110
|
+
* (`customer`, `delivery_location`, `supplier`, `warehouse`, the Trip Planner's
|
|
111
|
+
* `office` / `trip_place` / `trip_stop` …); a portal narrows it to the kinds it
|
|
112
|
+
* reads with the type parameter.
|
|
113
|
+
*/
|
|
114
|
+
interface MapPoint<K extends string = string> {
|
|
115
|
+
kind: K;
|
|
116
|
+
id: string;
|
|
117
|
+
label: string;
|
|
118
|
+
/** CID / MID where the record has one. */
|
|
119
|
+
code: string;
|
|
120
|
+
/** What the pin is coloured by: the customer type, the supplier type, or the kind. */
|
|
121
|
+
category: string;
|
|
122
|
+
/** The address as one line. */
|
|
123
|
+
address: string;
|
|
124
|
+
placement: MapPlacement;
|
|
125
|
+
lat: number | null;
|
|
126
|
+
lng: number | null;
|
|
127
|
+
/** What the geocoder matched, when placed. */
|
|
128
|
+
matched: string;
|
|
129
|
+
}
|
|
130
|
+
interface MapPoints<P extends MapPoint = MapPoint> {
|
|
131
|
+
points: P[];
|
|
132
|
+
/** Points still being looked up — poll again while this is above zero. */
|
|
133
|
+
pending: number;
|
|
134
|
+
}
|
|
135
|
+
/** How often to ask again while addresses are still being located. */
|
|
136
|
+
declare const PENDING_POLL_MS = 3000;
|
|
137
|
+
/** A react-query `refetchInterval` for a map endpoint: every few seconds while
|
|
138
|
+
* the backend is still locating addresses, not at all once every point is settled. */
|
|
139
|
+
declare const mapPointsRefetchInterval: (data: Pick<MapPoints, "pending"> | undefined) => number | false;
|
|
140
|
+
/** A point's identity across kinds — a customer and one of its delivery
|
|
141
|
+
* locations are different pins even if two ids ever collided. */
|
|
142
|
+
declare const pointKey: (p: Pick<MapPoint, "kind" | "id">) => string;
|
|
143
|
+
/** On the map = placed by the geocoder AND carrying coordinates. */
|
|
144
|
+
declare const isOnMap: <P extends MapPoint>(p: P) => p is P & {
|
|
145
|
+
lat: number;
|
|
146
|
+
lng: number;
|
|
147
|
+
};
|
|
148
|
+
/** Why a point is not (exactly) where its address is — null when it is. */
|
|
149
|
+
declare function placementNote(placement: MapPlacement): string | null;
|
|
150
|
+
/** A pin colour and the legend's word for it. */
|
|
151
|
+
interface MapCategory {
|
|
152
|
+
label: string;
|
|
153
|
+
/** Tone classes (background + text) for the pin and its legend swatch. */
|
|
154
|
+
tone: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Pin colours by category. Customers follow the admin Customers list's Type
|
|
158
|
+
* badge families (importer, dealer purple, retail green); a record's
|
|
159
|
+
* secondary locations (delivery locations, warehouses) are amber.
|
|
160
|
+
*
|
|
161
|
+
* Importer and supplier are SKY, not blue: this package's themes remap
|
|
162
|
+
* `bg-blue-600` to the theme's accent (themes.css), so in the green theme
|
|
163
|
+
* importer pins came out the same green as retail. None of the other families
|
|
164
|
+
* here is remapped — a categorical colour must not follow the accent the way
|
|
165
|
+
* a button does.
|
|
166
|
+
*
|
|
167
|
+
* A portal that names a category differently passes its own map with the same
|
|
168
|
+
* tones (the dealer's own head office is its "Billing address", not "Dealer").
|
|
169
|
+
*/
|
|
170
|
+
declare const MAP_CATEGORIES: Readonly<Record<string, MapCategory>>;
|
|
171
|
+
/** Suppliers colour by the kind rather than their free-text type (Factory,
|
|
172
|
+
* Shipping Forwarder…), which has no fixed palette to map onto. */
|
|
173
|
+
declare function pinCategory(p: Pick<MapPoint, 'kind' | 'category'>): string;
|
|
174
|
+
declare const categoryTone: (category: string, categories?: Readonly<Record<string, MapCategory>>) => string;
|
|
175
|
+
declare const categoryLabel: (category: string, categories?: Readonly<Record<string, MapCategory>>) => string;
|
|
176
|
+
declare const pinTone: (p: Pick<MapPoint, "kind" | "category">, categories?: Readonly<Record<string, MapCategory>>) => string;
|
|
177
|
+
/**
|
|
178
|
+
* The character on a pin. A profile map numbers its extra locations (1, 2, 3 —
|
|
179
|
+
* the same numbers the list shows) and marks the head office with its
|
|
180
|
+
* category's initial; a list-wide map shows each record's category initial.
|
|
181
|
+
*/
|
|
182
|
+
declare function pinGlyph(p: MapPoint, number: number | null, categories?: Readonly<Record<string, MapCategory>>): string;
|
|
183
|
+
/** The kinds a profile map numbers: a record's secondary locations. */
|
|
184
|
+
declare const SECONDARY_KINDS: readonly string[];
|
|
185
|
+
/**
|
|
186
|
+
* The numbers a profile map gives its secondary locations, in list order; the
|
|
187
|
+
* record itself gets none. An unplaced location keeps its number, so the list
|
|
188
|
+
* and the pins never renumber as addresses resolve.
|
|
189
|
+
*/
|
|
190
|
+
declare function locationNumbers(points: MapPoint[], kinds?: readonly string[]): Map<string, number>;
|
|
191
|
+
interface MapSummary {
|
|
192
|
+
onMap: number;
|
|
193
|
+
approximate: number;
|
|
194
|
+
pending: number;
|
|
195
|
+
off: number;
|
|
196
|
+
}
|
|
197
|
+
declare function summarize(points: MapPoint[]): MapSummary;
|
|
198
|
+
/** "12 on the map · 2 approximate · 3 not on the map" — the list header. */
|
|
199
|
+
declare function summaryText(s: MapSummary): string;
|
|
200
|
+
/** The categories present among the placed points, in a stable order — the
|
|
201
|
+
* legend. Categories outside the palette follow, in the order first seen. */
|
|
202
|
+
declare function legendCategories(points: MapPoint[]): string[];
|
|
203
|
+
/**
|
|
204
|
+
* The records a compact map can't pin, each with its reason, for the notes
|
|
205
|
+
* drawn over the map (a map with no list beside it). Pending points are left
|
|
206
|
+
* out — they are counted as "Locating…" instead.
|
|
207
|
+
*/
|
|
208
|
+
declare function offMapNotes(points: MapPoint[], numbers?: ReadonlyMap<string, number>): {
|
|
209
|
+
key: string;
|
|
210
|
+
text: string;
|
|
211
|
+
}[];
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* A record's Locations map — compact, with no list beside it, because the
|
|
215
|
+
* page it sits on already lists the locations. The admin portal puts it on the
|
|
216
|
+
* customer / supplier Details tab beside the score (a customer's head office
|
|
217
|
+
* and delivery locations, a supplier's address and warehouses); the dealer
|
|
218
|
+
* portal puts it on the Address Book (the billing address and the delivery
|
|
219
|
+
* addresses). What a list would say lives over the map: the legend,
|
|
220
|
+
* "Locating…" while addresses are looked up, and a note for each record that
|
|
221
|
+
* has no pin and why. Clicking a pin shows its card.
|
|
222
|
+
*
|
|
223
|
+
* `refreshSignal` changes when the records it pins change elsewhere on the
|
|
224
|
+
* page (a delivery location added or edited, the address edited), and the
|
|
225
|
+
* points are asked again; `staleTime: 0` does the same whenever it remounts.
|
|
226
|
+
*
|
|
227
|
+
* Moved from the admin portal's `ProfileLocationsMap`.
|
|
228
|
+
*/
|
|
229
|
+
declare function LocationsMap({ queryKey, queryFn, refreshSignal, onOpen, ariaLabel, title, palette, numbers: givenNumbers, className, mapClassName, }: {
|
|
230
|
+
queryKey: QueryKey;
|
|
231
|
+
queryFn: () => Promise<MapPoints>;
|
|
232
|
+
refreshSignal?: unknown;
|
|
233
|
+
/** Open a point's own page or window; null for points that have none. */
|
|
234
|
+
onOpen?: (point: MapPoint) => ((() => void) | null);
|
|
235
|
+
ariaLabel: string;
|
|
236
|
+
/** The heading over the map. */
|
|
237
|
+
title?: string;
|
|
238
|
+
/** How the portal names and colours each category (the legend, the card, the head-office initial). */
|
|
239
|
+
palette?: Readonly<Record<string, MapCategory>>;
|
|
240
|
+
/** The number each pin shows, by `pointKey` — the numbers the page's own list
|
|
241
|
+
* shows. Unset: the secondary locations numbered in the endpoint's order. */
|
|
242
|
+
numbers?: ReadonlyMap<string, number>;
|
|
243
|
+
className?: string;
|
|
244
|
+
/** Sizing for the map box (it grows to fill the section by default). */
|
|
245
|
+
mapClassName?: string;
|
|
246
|
+
}): react_jsx_runtime.JSX.Element;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* What sits over an `EntityMap` — the legend and the chosen record's card.
|
|
250
|
+
* Both take the portal's category map (`MAP_CATEGORIES` unless it names a
|
|
251
|
+
* category its own way), so the legend's words and the card's match the pins.
|
|
252
|
+
*/
|
|
253
|
+
/** Which colour means what; drawn only when the map shows more than one.
|
|
254
|
+
* `floating` pins it to the map's top-left corner; off, the caller places it
|
|
255
|
+
* (a compact map stacks its notes under it). */
|
|
256
|
+
declare function MapLegend({ categories, palette, floating }: {
|
|
257
|
+
categories: string[];
|
|
258
|
+
palette?: Readonly<Record<string, MapCategory>>;
|
|
259
|
+
floating?: boolean;
|
|
260
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
261
|
+
/** The chosen record's card, over the map's bottom edge. */
|
|
262
|
+
declare function SelectedCard({ point, number, onOpen, onClose, palette }: {
|
|
263
|
+
point: MapPoint;
|
|
264
|
+
number: number | null;
|
|
265
|
+
/** Open the record's own page or window; null when it has none. */
|
|
266
|
+
onOpen: (() => void) | null;
|
|
267
|
+
onClose: () => void;
|
|
268
|
+
palette?: Readonly<Record<string, MapCategory>>;
|
|
269
|
+
}): react_jsx_runtime.JSX.Element;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* A map endpoint's points, asked again every few seconds while the backend is
|
|
273
|
+
* still locating addresses (`pending > 0`) and not at all once every point is
|
|
274
|
+
* settled. The backend never makes the request wait on the geocoder, so a
|
|
275
|
+
* first visit shows the list at once and the pins arrive as they are found.
|
|
276
|
+
*/
|
|
277
|
+
declare function useMapPoints<T extends MapPoints>(queryKey: QueryKey, queryFn: () => Promise<T>, { staleTime }?: {
|
|
278
|
+
staleTime?: number;
|
|
279
|
+
}): _tanstack_react_query.UseQueryResult<_tanstack_query_core.NoInfer<T>, Error>;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Keep the map's credit line ("OpenFreeMap © OpenMapTiles Data from
|
|
283
|
+
* OpenStreetMap") folded behind its (i) button until someone clicks it —
|
|
284
|
+
* expanded, it runs across the bottom of a compact map.
|
|
285
|
+
*
|
|
286
|
+
* MapLibre's compact attribution control unfolds ITSELF once: the first time
|
|
287
|
+
* the attribution text arrives with the style's sources it adds
|
|
288
|
+
* `maplibregl-compact` together with `maplibregl-compact-show`, which can be
|
|
289
|
+
* well after the map's `load` (folding on `load` or `idle` lost that race). So
|
|
290
|
+
* this watches the control and removes `maplibregl-compact-show` the first
|
|
291
|
+
* time it appears — the same class MapLibre itself drops when the map is
|
|
292
|
+
* dragged — then stops watching. From then on the (i) toggles the text as
|
|
293
|
+
* usual: MapLibre only unfolds automatically while the control is not yet
|
|
294
|
+
* compact, and after this it always is.
|
|
295
|
+
*
|
|
296
|
+
* Returns the cleanup that disconnects the watcher if the map unmounts first.
|
|
297
|
+
*/
|
|
298
|
+
declare const COMPACT_SHOW = "maplibregl-compact-show";
|
|
299
|
+
declare function foldAttributionOnce(control: Element | null): () => void;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* MapLibre, fetched only when a map is on screen: `EntityMap` calls
|
|
303
|
+
* `loadMapLibre()` as it mounts, so its ~1 MB (and its stylesheet) never rides
|
|
304
|
+
* in a page that shows no map. `maplibre-gl` is an OPTIONAL peer of this
|
|
305
|
+
* package, installed by the portals that draw maps, and it must stay behind
|
|
306
|
+
* this dynamic import — `scripts/verify-dist.mjs` fails a build that reaches
|
|
307
|
+
* it statically.
|
|
308
|
+
*
|
|
309
|
+
* The worker. MapLibre 6 starts a MODULE worker from a URL it is given, and
|
|
310
|
+
* that worker (`maplibre-gl-worker.mjs`) imports `./maplibre-gl-shared.mjs`
|
|
311
|
+
* beside it — so the host serves both files, unhashed, next to each other,
|
|
312
|
+
* under the installed version:
|
|
313
|
+
*
|
|
314
|
+
* /maplibre-gl/<version>/maplibre-gl-worker.mjs
|
|
315
|
+
* /maplibre-gl/<version>/maplibre-gl-shared.mjs
|
|
316
|
+
*
|
|
317
|
+
* The versioned path means an upgrade can never pair a cached old worker with
|
|
318
|
+
* a new main thread. In the Next.js portals that is a static route handler,
|
|
319
|
+
* `app/maplibre-gl/[version]/[file]/route.ts`, copying the two files verbatim
|
|
320
|
+
* from `node_modules/maplibre-gl/dist` at export time.
|
|
321
|
+
*/
|
|
322
|
+
type MapLibre = typeof maplibre_gl;
|
|
323
|
+
declare const MAPLIBRE_WORKER_FILE = "maplibre-gl-worker.mjs";
|
|
324
|
+
/** Where the host serves the worker for a given MapLibre version. */
|
|
325
|
+
declare const mapLibreWorkerUrl: (version: string) => string;
|
|
326
|
+
/** MapLibre, loaded once per page; a failed load is retried by the next map. */
|
|
327
|
+
declare function loadMapLibre(): Promise<MapLibre>;
|
|
328
|
+
|
|
329
|
+
export { COMPACT_SHOW, EntityMap, LocationsMap, MAPLIBRE_WORKER_FILE, MAP_CATEGORIES, type MapCategory, MapLegend, type MapPin, type MapPlacement, type MapPoint, type MapPoints, type MapRoute, type MapSummary, PENDING_POLL_MS, SECONDARY_KINDS, SelectedCard, categoryLabel, categoryTone, foldAttributionOnce, isOnMap, legendCategories, loadMapLibre, locationNumbers, mapLibreWorkerUrl, mapPointsRefetchInterval, offMapNotes, pinCategory, pinGlyph, pinTone, placementNote, pointKey, summarize, summaryText, useMapPoints };
|