@joewinke/jatui 0.1.19 → 0.1.20

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/src/lib/index.ts CHANGED
@@ -2,6 +2,31 @@
2
2
  export { railNav, createRailNav, cycle } from './actions/railNav';
3
3
  export type { RailNavOptions, RailNavController } from './actions/railNav';
4
4
 
5
+ // Components — Session primitives (from JAT IDE, jat-jj79f.16 G1)
6
+ export { default as LinkedColumns } from './components/linked-columns/LinkedColumns.svelte';
7
+ export type { ColumnLink } from './components/linked-columns/LinkedColumns.svelte';
8
+
9
+ export { default as ChapterTimeline } from './components/replay/ChapterTimeline.svelte';
10
+ export type { ChapterBlock } from './components/replay/ChapterTimeline.svelte';
11
+
12
+ // Data models — Session transcript (from JAT IDE, jat-jj79f.16 G1)
13
+ export {
14
+ buildLinkedSession,
15
+ buildLinkedSessionFromWork,
16
+ rawTypeToState,
17
+ sampleLinkedSession,
18
+ SAMPLE_TRANSCRIPT_LINES,
19
+ } from './components/session-nav/transcriptModel';
20
+ export type {
21
+ ItemKind,
22
+ TranscriptItem,
23
+ FileTouchedEntry,
24
+ SignalNode,
25
+ LinkedSession,
26
+ WorkBlockClient,
27
+ WorkTranscriptItemClient,
28
+ } from './components/session-nav/transcriptModel';
29
+
5
30
  // Components — Universal
6
31
  export { default as UserAvatar } from './components/UserAvatar.svelte';
7
32
  export { default as SidebarUserFooter } from './components/SidebarUserFooter.svelte';
@@ -353,3 +378,25 @@ export type {
353
378
  AnnotationThread,
354
379
  AnnotationCallbacks,
355
380
  } from './types/annotation';
381
+
382
+ // Components — Keyboard Navigation
383
+ export { default as KeyboardShortcutsOverlay } from './components/KeyboardShortcutsOverlay.svelte';
384
+ export type {
385
+ KeyboardShortcut,
386
+ SectionEntry as KeyboardShortcutSectionEntry,
387
+ ShortcutSection as KeyboardShortcutSection,
388
+ } from './components/KeyboardShortcutsOverlay.svelte';
389
+
390
+ // Components — Google Maps (DispatchMap fork + location primitives)
391
+ export { default as MapView } from './components/MapView.svelte';
392
+ export { default as LocationMap } from './components/LocationMap.svelte';
393
+ export { default as GPSTracker } from './components/GPSTracker.svelte';
394
+ export type { MapJob, MapAgent } from './types/maps';
395
+
396
+ // Utilities — Google Maps loader
397
+ export {
398
+ loadGoogleMapsAPI,
399
+ isGoogleMapsLoaded,
400
+ isPlacesLoaded,
401
+ isGeometryLoaded,
402
+ } from './utils/googleMapsLoader';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Minimal ambient declarations for Google Maps JS API loaded at runtime.
3
+ * Prevents "Property 'google' does not exist on Window" TS errors.
4
+ * Components using the Google Maps API operate with `any` for advanced
5
+ * marker types until @types/google.maps is added as a dev dependency.
6
+ */
7
+
8
+ declare namespace google {
9
+ namespace maps {
10
+ class Map {
11
+ constructor(el: HTMLElement, options: object);
12
+ fitBounds(bounds: any): void;
13
+ getZoom(): number | undefined;
14
+ setZoom(zoom: number): void;
15
+ setCenter(center: object): void;
16
+ }
17
+ class InfoWindow {
18
+ constructor(options: object);
19
+ open(map: any, marker: any): void;
20
+ }
21
+ class Circle {
22
+ constructor(options: object);
23
+ setMap(map: any): void;
24
+ }
25
+ class LatLngBounds {
26
+ extend(position: object): void;
27
+ }
28
+ const MapTypeId: { ROADMAP: string };
29
+ const event: {
30
+ addListener(instance: any, event: string, fn: () => void): any;
31
+ removeListener(listener: any): void;
32
+ clearInstanceListeners(instance: any): void;
33
+ };
34
+ namespace marker {
35
+ class AdvancedMarkerElement {
36
+ constructor(options: object);
37
+ map: any;
38
+ position: any;
39
+ addListener(event: string, fn: () => void): void;
40
+ }
41
+ }
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ const places: any;
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ const geometry: any;
46
+ }
47
+ }
48
+
49
+ interface Window {
50
+ google?: typeof google;
51
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Types for MapView, LocationMap, and GPSTracker components.
3
+ */
4
+
5
+ export interface MapJob {
6
+ id: string;
7
+ status: string;
8
+ type?: string;
9
+ priority?: string;
10
+ description?: string;
11
+ scheduled_at?: string;
12
+ customer?: {
13
+ name?: string;
14
+ phone?: string;
15
+ };
16
+ location?: {
17
+ address?: string;
18
+ latitude?: number;
19
+ longitude?: number;
20
+ };
21
+ }
22
+
23
+ export interface MapAgent {
24
+ id: string;
25
+ name: string;
26
+ email?: string;
27
+ avatarUrl?: string;
28
+ status?: string;
29
+ capacity?: string;
30
+ specializations?: string[];
31
+ vehicle?: { name?: string };
32
+ /** Most recent GPS fix */
33
+ location?: {
34
+ latitude?: number;
35
+ longitude?: number;
36
+ age_seconds?: number;
37
+ };
38
+ /** Active dispatches used as fallback location */
39
+ dispatches?: Array<{
40
+ job_id: string;
41
+ status: string;
42
+ }>;
43
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Centralized Google Maps API loader for jatui.
3
+ *
4
+ * Prevents multiple script loads and ensures all required libraries are available.
5
+ * Pass the API key explicitly — jatui is SvelteKit-agnostic (no $env imports).
6
+ *
7
+ * Usage:
8
+ * await loadGoogleMapsAPI({ apiKey: 'YOUR_KEY', libraries: ['marker', 'geometry'] })
9
+ * if (isGoogleMapsLoaded()) { ... }
10
+ */
11
+
12
+ interface LoadOptions {
13
+ apiKey: string;
14
+ libraries?: string[];
15
+ }
16
+
17
+ let loadPromise: Promise<void> | null = null;
18
+ let isLoaded = false;
19
+
20
+ export async function loadGoogleMapsAPI(options: LoadOptions): Promise<void> {
21
+ if (typeof window === 'undefined') return;
22
+
23
+ const { apiKey, libraries = [] } = options;
24
+
25
+ if (!apiKey) {
26
+ console.warn('googleMapsLoader: No API key provided');
27
+ return;
28
+ }
29
+
30
+ // If already loaded and all required libraries are available, return
31
+ if (isLoaded && window.google?.maps) {
32
+ const allLibrariesAvailable = libraries.every((lib) => {
33
+ switch (lib) {
34
+ case 'places':
35
+ return window.google?.maps?.places;
36
+ case 'geometry':
37
+ return window.google?.maps?.geometry;
38
+ default:
39
+ return true;
40
+ }
41
+ });
42
+ if (allLibrariesAvailable) return;
43
+ }
44
+
45
+ // If already loading, return the existing promise
46
+ if (loadPromise) return loadPromise;
47
+
48
+ // Combine default libraries with requested ones
49
+ const allLibraries = Array.from(new Set(['geometry', 'places', 'marker', ...libraries]));
50
+
51
+ loadPromise = new Promise<void>((resolve, reject) => {
52
+ const script = document.createElement('script');
53
+ script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=${allLibraries.join(',')}`;
54
+ script.async = true;
55
+ script.defer = true;
56
+
57
+ script.onload = () => {
58
+ isLoaded = true;
59
+ loadPromise = null;
60
+ resolve();
61
+ };
62
+
63
+ script.onerror = (error) => {
64
+ loadPromise = null;
65
+ reject(error);
66
+ };
67
+
68
+ document.head.appendChild(script);
69
+ });
70
+
71
+ return loadPromise;
72
+ }
73
+
74
+ export function isGoogleMapsLoaded(): boolean {
75
+ return isLoaded && !!window.google?.maps;
76
+ }
77
+
78
+ export function isPlacesLoaded(): boolean {
79
+ return isGoogleMapsLoaded() && !!window.google?.maps?.places;
80
+ }
81
+
82
+ export function isGeometryLoaded(): boolean {
83
+ return isGoogleMapsLoaded() && !!window.google?.maps?.geometry;
84
+ }