From 4afd9ec3d1dba0bec61f225d4f1d13b07a720462 Mon Sep 17 00:00:00 2001 From: Jack Greenlee Date: Sat, 4 Nov 2023 01:00:36 -0400 Subject: [PATCH 1/5] remove js/diary/diaryTypes.ts not needed since we are now keeping diaryTypes as js/types/diaryTypes.ts --- www/js/diary/diaryTypes.ts | 72 -------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 www/js/diary/diaryTypes.ts diff --git a/www/js/diary/diaryTypes.ts b/www/js/diary/diaryTypes.ts deleted file mode 100644 index 5755c91ab..000000000 --- a/www/js/diary/diaryTypes.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* These type definitions are a work in progress. The goal is to have a single source of truth for - the types of the trip / place / untracked objects and all properties they contain. - Since we are using TypeScript now, we should strive to enforce type safety and also benefit from - IntelliSense and other IDE features. */ - -// Since it is WIP, these types are not used anywhere yet. - -type ConfirmedPlace = any; // TODO - -/* These are the properties received from the server (basically matches Python code) - This should match what Timeline.readAllCompositeTrips returns (an array of these objects) */ -export type CompositeTrip = { - _id: { $oid: string }; - additions: any[]; // TODO - cleaned_section_summary: any; // TODO - cleaned_trip: { $oid: string }; - confidence_threshold: number; - confirmed_trip: { $oid: string }; - distance: number; - duration: number; - end_confirmed_place: ConfirmedPlace; - end_fmt_time: string; - end_loc: { type: string; coordinates: number[] }; - end_local_dt: any; // TODO - end_place: { $oid: string }; - end_ts: number; - expectation: any; // TODO "{to_label: boolean}" - expected_trip: { $oid: string }; - inferred_labels: any[]; // TODO - inferred_section_summary: any; // TODO - inferred_trip: { $oid: string }; - key: string; - locations: any[]; // TODO - origin_key: string; - raw_trip: { $oid: string }; - sections: any[]; // TODO - source: string; - start_confirmed_place: ConfirmedPlace; - start_fmt_time: string; - start_loc: { type: string; coordinates: number[] }; - start_local_dt: any; // TODO - start_place: { $oid: string }; - start_ts: number; - user_input: any; // TODO -}; - -/* These properties aren't received from the server, but are derived from the above properties. - They are used in the UI to display trip/place details and are computed by the useDerivedProperties hook. */ -export type DerivedProperties = { - displayDate: string; - displayStartTime: string; - displayEndTime: string; - displayTime: string; - displayStartDateAbbr: string; - displayEndDateAbbr: string; - formattedDistance: string; - formattedSectionProperties: any[]; // TODO - distanceSuffix: string; - detectedModes: { mode: string; icon: string; color: string; pct: number | string }[]; -}; - -/* These are the properties that are still filled in by some kind of 'populate' mechanism. - It would simplify the codebase to just compute them where they're needed - (using memoization when apt so performance is not impacted). */ -export type PopulatedTrip = CompositeTrip & { - additionsList?: any[]; // TODO - finalInference?: any; // TODO - geojson?: any; // TODO - getNextEntry?: () => PopulatedTrip | ConfirmedPlace; - userInput?: any; // TODO - verifiability?: string; -}; From 8cb369173abab4d4638f74a4a03cb3b9c499340a Mon Sep 17 00:00:00 2001 From: Jack Greenlee Date: Sat, 4 Nov 2023 01:02:14 -0400 Subject: [PATCH 2/5] expand diaryTypes d96ff8d0d7c785f6914b2d080885df9030f6d033 --- www/js/diary/diaryHelper.ts | 4 +- www/js/types/diaryTypes.ts | 131 ++++++++++++++++++++++++------------ 2 files changed, 90 insertions(+), 45 deletions(-) diff --git a/www/js/diary/diaryHelper.ts b/www/js/diary/diaryHelper.ts index 48f40322d..5b060a236 100644 --- a/www/js/diary/diaryHelper.ts +++ b/www/js/diary/diaryHelper.ts @@ -24,7 +24,7 @@ type BaseMode = { }; // parallels the server-side MotionTypes enum: https://github.com/e-mission/e-mission-server/blob/94e7478e627fa8c171323662f951c611c0993031/emission/core/wrapper/motionactivity.py#L12 -type MotionTypeKey = +export type MotionTypeKey = | 'IN_VEHICLE' | 'BICYCLING' | 'ON_FOOT' @@ -64,7 +64,7 @@ const BaseModes: { [k: string]: BaseMode } = { OTHER: { name: 'OTHER', icon: 'pencil-circle', color: modeColors.taupe }, }; -type BaseModeKey = keyof typeof BaseModes; +export type BaseModeKey = keyof typeof BaseModes; /** * @param motionName A string like "WALKING" or "MotionTypes.WALKING" * @returns A BaseMode object containing the name, icon, and color of the motion type diff --git a/www/js/types/diaryTypes.ts b/www/js/types/diaryTypes.ts index 14d8acc07..2c901df00 100644 --- a/www/js/types/diaryTypes.ts +++ b/www/js/types/diaryTypes.ts @@ -1,75 +1,120 @@ -import { LocalDt, ServerData } from './serverData'; +/* This file provides typings for use in '/diary', including timeline objects (trips and places) + and user input objects. + As much as possible, these types parallel the types used in the server code. */ -export type UserInput = ServerData; +import { BaseModeKey, MotionTypeKey } from '../diary/diaryHelper'; +import { LocalDt } from './serverData'; -export type UserInputData = { - end_ts: number; - start_ts: number; - label: string; - start_local_dt?: LocalDt; - end_local_dt?: LocalDt; - status?: string; - match_id?: string; +type ObjectId = { $oid: string }; +type ConfirmedPlace = { + _id: ObjectId; + additions: UserInputEntry[]; + cleaned_place: ObjectId; + ending_trip: ObjectId; + enter_fmt_time: string; // ISO string 2023-10-31T12:00:00.000-04:00 + enter_local_dt: LocalDt; + enter_ts: number; // Unix timestamp + key: string; + location: { type: string; coordinates: number[] }; + origin_key: string; + raw_places: ObjectId[]; + source: string; + user_input: { + /* for keys ending in 'user_input' (e.g. 'trip_user_input'), the server gives us the raw user + input object with 'data' and 'metadata' */ + [k: `${string}user_input`]: UserInputEntry; + /* for keys ending in 'confirm' (e.g. 'mode_confirm'), the server just gives us the user input value + as a string (e.g. 'walk', 'drove_alone') */ + [k: `${string}confirm`]: string; + }; }; -type ConfirmedPlace = any; // TODO - +/* These are the properties received from the server (basically matches Python code) + This should match what Timeline.readAllCompositeTrips returns (an array of these objects) */ export type CompositeTrip = { - _id: { $oid: string }; - additions: any[]; // TODO - cleaned_section_summary: any; // TODO - cleaned_trip: { $oid: string }; + _id: ObjectId; + additions: UserInputEntry[]; + cleaned_section_summary: SectionSummary; + cleaned_trip: ObjectId; confidence_threshold: number; - confirmed_trip: { $oid: string }; + confirmed_trip: ObjectId; distance: number; duration: number; end_confirmed_place: ConfirmedPlace; end_fmt_time: string; end_loc: { type: string; coordinates: number[] }; end_local_dt: LocalDt; - end_place: { $oid: string }; + end_place: ObjectId; end_ts: number; expectation: any; // TODO "{to_label: boolean}" - expected_trip: { $oid: string }; + expected_trip: ObjectId; inferred_labels: any[]; // TODO - inferred_section_summary: any; // TODO - inferred_trip: { $oid: string }; + inferred_section_summary: SectionSummary; + inferred_trip: ObjectId; key: string; locations: any[]; // TODO origin_key: string; - raw_trip: { $oid: string }; + raw_trip: ObjectId; sections: any[]; // TODO source: string; start_confirmed_place: ConfirmedPlace; start_fmt_time: string; start_loc: { type: string; coordinates: number[] }; start_local_dt: LocalDt; - start_place: { $oid: string }; + start_place: ObjectId; start_ts: number; - user_input: UserInput; + user_input: { + /* for keys ending in 'user_input' (e.g. 'trip_user_input'), the server gives us the raw user + input object with 'data' and 'metadata' */ + [k: `${string}user_input`]: UserInputEntry; + /* for keys ending in 'confirm' (e.g. 'mode_confirm'), the server just gives us the user input value + as a string (e.g. 'walk', 'drove_alone') */ + [k: `${string}confirm`]: string; + }; }; -export type PopulatedTrip = CompositeTrip & { - additionsList?: any[]; // TODO - finalInference?: any; // TODO - geojson?: any; // TODO - getNextEntry?: () => PopulatedTrip | ConfirmedPlace; - userInput?: UserInput; - verifiability?: string; +/* The 'timeline' for a user is a list of their trips and places, + so a 'timeline entry' is either a trip or a place. */ +export type TimelineEntry = ConfirmedPlace | CompositeTrip; + +/* These properties aren't received from the server, but are derived from the above properties. + They are used in the UI to display trip/place details and are computed by the useDerivedProperties hook. */ +export type DerivedProperties = { + displayDate: string; + displayStartTime: string; + displayEndTime: string; + displayTime: string; + displayStartDateAbbr: string; + displayEndDateAbbr: string; + formattedDistance: string; + formattedSectionProperties: any[]; // TODO + distanceSuffix: string; + detectedModes: { mode: string; icon: string; color: string; pct: number | string }[]; }; -export type Trip = { - end_ts: number; - start_ts: number; +export type SectionSummary = { + count: { [k: MotionTypeKey | BaseModeKey]: number }; + distance: { [k: MotionTypeKey | BaseModeKey]: number }; + duration: { [k: MotionTypeKey | BaseModeKey]: number }; }; -export type TlEntry = { - key: string; - origin_key: string; - start_ts: number; - end_ts: number; - enter_ts: number; - exit_ts: number; - duration: number; - getNextEntry?: () => PopulatedTrip | ConfirmedPlace; +export type UserInputEntry = { + data: { + end_ts: number; + start_ts: number; + label: string; + start_local_dt?: LocalDt; + end_local_dt?: LocalDt; + status?: string; + match_id?: string; + }; + metadata: { + time_zone: string; + plugin: string; + write_ts: number; + platform: string; + read_ts: number; + key: string; + }; + key?: string; }; From 12e80295e2600439d714cb0131cae98e252bb811 Mon Sep 17 00:00:00 2001 From: Katie Rischpater <98350084+the-bay-kay@users.noreply.github.com> Date: Tue, 7 Nov 2023 14:55:44 -0800 Subject: [PATCH 3/5] Expanded diaryTypes - these types are used by timelineHelper --- www/js/types/diaryTypes.ts | 85 ++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 9 deletions(-) diff --git a/www/js/types/diaryTypes.ts b/www/js/types/diaryTypes.ts index 14d8acc07..4f10fb50f 100644 --- a/www/js/types/diaryTypes.ts +++ b/www/js/types/diaryTypes.ts @@ -12,39 +12,71 @@ export type UserInputData = { match_id?: string; }; -type ConfirmedPlace = any; // TODO +export type TripTransition = { + currstate: string; + transition: string; + ts: number; +}; + +export type ObjId = { + $oid: string; // objIds have len 24 +}; + +export type LocationCoord = { + type: string; // e.x., "Point" + coordinates: [number, number]; +}; + +type ConfirmedPlace = { + cleaned_place: { + string; + }; + additions: Array; // Todo + ender_local_dt: LocalDt; + starting_trip: ObjId; + exit_fmt_time: string; // ISO + exit_local_dt: LocalDt; + enter_ts: number; + source: string; + enter_fmt_time: string; + raw_places: Array; + location: LocationCoord; + exit_ts: number; + ending_trip: ObjId; + user_input: {}; //todo +}; export type CompositeTrip = { - _id: { $oid: string }; + _id: ObjId; additions: any[]; // TODO cleaned_section_summary: any; // TODO - cleaned_trip: { $oid: string }; + cleaned_trip: ObjId; confidence_threshold: number; - confirmed_trip: { $oid: string }; + confirmed_trip: ObjId; distance: number; duration: number; end_confirmed_place: ConfirmedPlace; end_fmt_time: string; end_loc: { type: string; coordinates: number[] }; end_local_dt: LocalDt; - end_place: { $oid: string }; + end_place: ObjId; end_ts: number; expectation: any; // TODO "{to_label: boolean}" - expected_trip: { $oid: string }; + expected_trip: ObjId; inferred_labels: any[]; // TODO inferred_section_summary: any; // TODO - inferred_trip: { $oid: string }; + inferred_trip: ObjId; key: string; locations: any[]; // TODO origin_key: string; - raw_trip: { $oid: string }; + raw_trip: ObjId; sections: any[]; // TODO source: string; start_confirmed_place: ConfirmedPlace; start_fmt_time: string; start_loc: { type: string; coordinates: number[] }; start_local_dt: LocalDt; - start_place: { $oid: string }; + start_place: ObjId; start_ts: number; user_input: UserInput; }; @@ -73,3 +105,38 @@ export type TlEntry = { duration: number; getNextEntry?: () => PopulatedTrip | ConfirmedPlace; }; + +export type Location = { + speed: number; + heading: number; + local_dt: LocalDt; + idx: number; + section: ObjId; + longitude: number; + latitude: number; + fmt_time: string; // ISO + mode: number; + loc: LocationCoord; + ts: number; // Unix + altitude: number; + distance: number; +}; + +// used in readAllCompositeTrips +export type SectionData = { + end_ts: number; // Unix time, e.x. 1696352498.804 + end_loc: LocationCoord; + start_fmt_time: string; // ISO time + end_fmt_time: string; + trip_id: ObjId; + sensed_mode: number; + source: string; // e.x., "SmoothedHighConfidenceMotion" + start_ts: number; // Unix + start_loc: LocationCoord; + cleaned_section: ObjId; + start_local_dt: LocalDt; + end_local_dt: LocalDt; + sensed_mode_str: string; //e.x., "CAR" + duration: number; + distance: number; +}; From 4a96b9d146e549549ace56156ac9829af16d5c98 Mon Sep 17 00:00:00 2001 From: Katie Rischpater <98350084+the-bay-kay@users.noreply.github.com> Date: Thu, 9 Nov 2023 10:37:05 -0800 Subject: [PATCH 4/5] Minor adjustments to diaryTypes --- www/js/types/diaryTypes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/js/types/diaryTypes.ts b/www/js/types/diaryTypes.ts index cfde363d6..938b06851 100644 --- a/www/js/types/diaryTypes.ts +++ b/www/js/types/diaryTypes.ts @@ -3,7 +3,7 @@ As much as possible, these types parallel the types used in the server code. */ import { BaseModeKey, MotionTypeKey } from '../diary/diaryHelper'; -import { LocalDt } from './serverData'; +import { ServerData, LocalDt } from './serverData'; type ObjectId = { $oid: string }; type ConfirmedPlace = { @@ -51,7 +51,7 @@ export type CompositeTrip = { confirmed_trip: ObjectId; distance: number; duration: number; - end_confirmed_place: ConfirmedPlace; + end_confirmed_place: ServerData; end_fmt_time: string; end_loc: { type: string; coordinates: number[] }; end_local_dt: LocalDt; @@ -68,7 +68,7 @@ export type CompositeTrip = { raw_trip: ObjectId; sections: any[]; // TODO source: string; - start_confirmed_place: ConfirmedPlace; + start_confirmed_place: ServerData; start_fmt_time: string; start_loc: { type: string; coordinates: number[] }; start_local_dt: LocalDt; From 361cc280f0e51c8737c8f38741154480cfb0992e Mon Sep 17 00:00:00 2001 From: Katie Rischpater <98350084+the-bay-kay@users.noreply.github.com> Date: Wed, 15 Nov 2023 13:44:39 -0800 Subject: [PATCH 5/5] Separated `labelTypes` into separate file --- www/js/diary/LabelTabContext.ts | 2 +- www/js/diary/diaryHelper.ts | 3 ++- www/js/survey/multilabel/confirmHelper.ts | 26 +---------------------- www/js/types/labelTypes.ts | 24 +++++++++++++++++++++ 4 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 www/js/types/labelTypes.ts diff --git a/www/js/diary/LabelTabContext.ts b/www/js/diary/LabelTabContext.ts index 24d7ade41..717a4980d 100644 --- a/www/js/diary/LabelTabContext.ts +++ b/www/js/diary/LabelTabContext.ts @@ -1,6 +1,6 @@ import { createContext } from 'react'; import { TimelineEntry, UserInputEntry } from '../types/diaryTypes'; -import { LabelOption } from '../survey/multilabel/confirmHelper'; +import { LabelOption } from '../types/labelTypes'; export type TimelineMap = Map; export type TimelineLabelMap = { diff --git a/www/js/diary/diaryHelper.ts b/www/js/diary/diaryHelper.ts index 616974b7b..2fee7eccd 100644 --- a/www/js/diary/diaryHelper.ts +++ b/www/js/diary/diaryHelper.ts @@ -3,8 +3,9 @@ import moment from 'moment'; import { DateTime } from 'luxon'; -import { LabelOptions, readableLabelToKey } from '../survey/multilabel/confirmHelper'; +import { readableLabelToKey } from '../survey/multilabel/confirmHelper'; import { CompositeTrip } from '../types/diaryTypes'; +import { LabelOptions } from '../types/labelTypes'; export const modeColors = { pink: '#c32e85', // oklch(56% 0.2 350) // e-car diff --git a/www/js/survey/multilabel/confirmHelper.ts b/www/js/survey/multilabel/confirmHelper.ts index 51674b0c3..4c2be1012 100644 --- a/www/js/survey/multilabel/confirmHelper.ts +++ b/www/js/survey/multilabel/confirmHelper.ts @@ -4,31 +4,7 @@ import { getAngularService } from '../../angular-react-helper'; import { fetchUrlCached } from '../../services/commHelper'; import i18next from 'i18next'; import { logDebug } from '../../plugin/logger'; - -type InputDetails = { - [k in T]?: { - name: string; - labeltext: string; - choosetext: string; - key: string; - }; -}; -export type LabelOption = { - value: string; - baseMode: string; - met?: { range: any[]; mets: number }; - met_equivalent?: string; - kgCo2PerKm: number; - text?: string; -}; -export type MultilabelKey = 'MODE' | 'PURPOSE' | 'REPLACED_MODE'; -export type LabelOptions = { - [k in T]: LabelOption[]; -} & { - translations: { - [lang: string]: { [translationKey: string]: string }; - }; -}; +import { LabelOption, LabelOptions, MultilabelKey, InputDetails } from '../../types/labelTypes'; let appConfig; export let labelOptions: LabelOptions; diff --git a/www/js/types/labelTypes.ts b/www/js/types/labelTypes.ts new file mode 100644 index 000000000..8ac720adc --- /dev/null +++ b/www/js/types/labelTypes.ts @@ -0,0 +1,24 @@ +export type InputDetails = { + [k in T]?: { + name: string; + labeltext: string; + choosetext: string; + key: string; + }; +}; +export type LabelOption = { + value: string; + baseMode: string; + met?: { range: any[]; mets: number }; + met_equivalent?: string; + kgCo2PerKm: number; + text?: string; +}; +export type MultilabelKey = 'MODE' | 'PURPOSE' | 'REPLACED_MODE'; +export type LabelOptions = { + [k in T]: LabelOption[]; +} & { + translations: { + [lang: string]: { [translationKey: string]: string }; + }; +};