@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/package.json +1 -1
- package/src/lib/components/ChipInput.svelte +12 -13
- package/src/lib/components/GPSTracker.svelte +202 -0
- package/src/lib/components/InlineEdit.svelte +7 -9
- package/src/lib/components/KeyboardShortcutsOverlay.svelte +296 -0
- package/src/lib/components/LocationMap.svelte +186 -0
- package/src/lib/components/MapView.svelte +341 -0
- package/src/lib/components/linked-columns/LinkedColumns.svelte +520 -0
- package/src/lib/components/replay/ChapterTimeline.svelte +326 -0
- package/src/lib/components/session-nav/transcriptModel.ts +352 -0
- package/src/lib/index.ts +47 -0
- package/src/lib/types/googleMaps.d.ts +51 -0
- package/src/lib/types/maps.ts +43 -0
- package/src/lib/utils/googleMapsLoader.ts +84 -0
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
|
+
}
|