Skip to content

Commit

Permalink
Merge branch 'service_rewrite_2023' into diaryServices-rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
the-bay-kay authored Nov 9, 2023
2 parents bf91301 + edafd98 commit 7e1790e
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 100 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: prettier
on:
pull_request:

jobs:
run-prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npx prettier --check www

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ www/dist
www/manual_lib
www/json

# Ignore all HTML files:
**/*.html

# This is the pattern to check only www directory
# Ignore all
/*
Expand Down
5 changes: 5 additions & 0 deletions www/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,14 @@
"errors": {
"registration-check-token": "User registration error. Please check your token and try again.",
"not-registered-cant-contact": "User is not registered, so the server cannot be contacted.",
"while-initializing-label": "While initializing Label tab: ",
"while-populating-composite": "Error while populating composite trips",
"while-loading-another-week": "Error while loading travel of {{when}} week",
"while-loading-specific-week": "Error while loading travel for the week of {{day}}",
"while-updating-timeline": "While updating timeline: ",
"while-refreshing-label": "While refreshing Label tab: ",
"while-repopulating-entry": "While repopulating timeline entry: ",
"while-loading-metrics": "While loading metrics: ",
"while-log-messages": "While getting messages from the log ",
"while-max-index": "While getting max index "
},
Expand Down
7 changes: 4 additions & 3 deletions www/js/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { setServerConnSettings } from './config/serverConn';
import AppStatusModal from './control/AppStatusModal';
import usePermissionStatus from './usePermissionStatus';
import { withErrorBoundary } from './plugin/ErrorBoundary';

const defaultRoutes = (t) => [
{
Expand Down Expand Up @@ -55,9 +56,9 @@ const App = () => {
}, [appConfig, t]);

const renderScene = BottomNavigation.SceneMap({
label: LabelTab,
metrics: MetricsTab,
control: ProfileSettings,
label: withErrorBoundary(LabelTab),
metrics: withErrorBoundary(MetricsTab),
control: withErrorBoundary(ProfileSettings),
});

const refreshOnboardingState = () => getPendingOnboardingState().then(setOnboardingState);
Expand Down
8 changes: 7 additions & 1 deletion www/js/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Chart as ChartJS, registerables } from 'chart.js';
import { Chart as ChartJSChart } from 'react-chartjs-2';
import Annotation, { AnnotationOptions, LabelPosition } from 'chartjs-plugin-annotation';
import { dedupColors, getChartHeight, darkenOrLighten } from './charting';
import { logDebug } from '../plugin/logger';

ChartJS.register(...registerables, Annotation);

Expand Down Expand Up @@ -134,6 +135,9 @@ const Chart = ({
? {}
: {
callback: (value, i) => {
logDebug(`Horizontal axis callback: i = ${i};
chartDatasets = ${JSON.stringify(chartDatasets)};
chartDatasets[0].data = ${JSON.stringify(chartDatasets[0].data)}`);
const label = chartDatasets[0].data[i].y;
if (typeof label == 'string' && label.includes('\n'))
return label.split('\n');
Expand Down Expand Up @@ -168,7 +172,9 @@ const Chart = ({
? {}
: {
callback: (value, i) => {
console.log('testing vertical', chartData, i);
logDebug(`Vertical axis callback: i = ${i};
chartDatasets = ${JSON.stringify(chartDatasets)};
chartDatasets[0].data = ${JSON.stringify(chartDatasets[0].data)}`);
const label = chartDatasets[0].data[i].x;
if (typeof label == 'string' && label.includes('\n'))
return label.split('\n');
Expand Down
201 changes: 116 additions & 85 deletions www/js/diary/LabelTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
import { fillLocationNamesOfTrip, resetNominatimLimiter } from './addressNamesHelper';
import { SurveyOptions } from '../survey/survey';
import { getLabelOptions } from '../survey/multilabel/confirmHelper';
import { displayError } from '../plugin/logger';
import { displayError, displayErrorMsg, logDebug, logWarn } from '../plugin/logger';
import { useTheme } from 'react-native-paper';
import { getPipelineRangeTs } from '../commHelper';

Expand Down Expand Up @@ -59,55 +59,66 @@ const LabelTab = () => {

// initialization, once the appConfig is loaded
useEffect(() => {
if (!appConfig) return;
const surveyOptKey = appConfig.survey_info['trip-labels'];
const surveyOpt = SurveyOptions[surveyOptKey];
setSurveyOpt(surveyOpt);
showPlaces = appConfig.survey_info?.buttons?.['place-notes'];
getLabelOptions(appConfig).then((labelOptions) => setLabelOptions(labelOptions));
labelPopulateFactory = getAngularService(surveyOpt.service);
const tripSurveyName = appConfig.survey_info?.buttons?.['trip-notes']?.surveyName;
const placeSurveyName = appConfig.survey_info?.buttons?.['place-notes']?.surveyName;
enbs.initConfig(tripSurveyName, placeSurveyName);
try {
if (!appConfig) return;
const surveyOptKey = appConfig.survey_info['trip-labels'];
const surveyOpt = SurveyOptions[surveyOptKey];
setSurveyOpt(surveyOpt);
showPlaces = appConfig.survey_info?.buttons?.['place-notes'];
getLabelOptions(appConfig).then((labelOptions) => setLabelOptions(labelOptions));
labelPopulateFactory = getAngularService(surveyOpt.service);
const tripSurveyName = appConfig.survey_info?.buttons?.['trip-notes']?.surveyName;
const placeSurveyName = appConfig.survey_info?.buttons?.['place-notes']?.surveyName;
enbs.initConfig(tripSurveyName, placeSurveyName);

// we will show filters if 'additions' are not configured
// https://github.com/e-mission/e-mission-docs/issues/894
if (appConfig.survey_info?.buttons == undefined) {
// initalize filters
const tripFilter = surveyOpt.filter;
const allFalseFilters = tripFilter.map((f, i) => ({
...f,
state: i == 0 ? true : false, // only the first filter will have state true on init
}));
setFilterInputs(allFalseFilters);
// we will show filters if 'additions' are not configured
// https://github.com/e-mission/e-mission-docs/issues/894
if (appConfig.survey_info?.buttons == undefined) {
// initalize filters
const tripFilter = surveyOpt.filter;
const allFalseFilters = tripFilter.map((f, i) => ({
...f,
state: i == 0 ? true : false, // only the first filter will have state true on init
}));
setFilterInputs(allFalseFilters);
}
loadTimelineEntries();
} catch (e) {
displayError(e, t('errors.while-initializing-label'));
}
loadTimelineEntries();
}, [appConfig, refreshTime]);

// whenever timelineMap is updated, update the displayedEntries
// according to the active filter
useEffect(() => {
if (!timelineMap) return setDisplayedEntries(null);
const allEntries = Array.from<any>(timelineMap.values());
const activeFilter = filterInputs?.find((f) => f.state == true);
let entriesToDisplay = allEntries;
if (activeFilter) {
const entriesAfterFilter = allEntries.filter(
(t) => t.justRepopulated || activeFilter?.filter(t),
);
/* next, filter out any untracked time if the trips that came before and
try {
if (!timelineMap) return setDisplayedEntries(null);
const allEntries = Array.from<any>(timelineMap.values());
const activeFilter = filterInputs?.find((f) => f.state == true);
let entriesToDisplay = allEntries;
if (activeFilter) {
const entriesAfterFilter = allEntries.filter(
(t) => t.justRepopulated || activeFilter?.filter(t),
);
/* next, filter out any untracked time if the trips that came before and
after it are no longer displayed */
entriesToDisplay = entriesAfterFilter.filter((tlEntry) => {
if (!tlEntry.origin_key.includes('untracked')) return true;
const prevTrip = allEntries[allEntries.indexOf(tlEntry) - 1];
const nextTrip = allEntries[allEntries.indexOf(tlEntry) + 1];
const prevTripDisplayed = entriesAfterFilter.includes(prevTrip);
const nextTripDisplayed = entriesAfterFilter.includes(nextTrip);
// if either the trip before or after is displayed, then keep the untracked time
return prevTripDisplayed || nextTripDisplayed;
});
entriesToDisplay = entriesAfterFilter.filter((tlEntry) => {
if (!tlEntry.origin_key.includes('untracked')) return true;
const prevTrip = allEntries[allEntries.indexOf(tlEntry) - 1];
const nextTrip = allEntries[allEntries.indexOf(tlEntry) + 1];
const prevTripDisplayed = entriesAfterFilter.includes(prevTrip);
const nextTripDisplayed = entriesAfterFilter.includes(nextTrip);
// if either the trip before or after is displayed, then keep the untracked time
return prevTripDisplayed || nextTripDisplayed;
});
logDebug('After filtering, entriesToDisplay = ' + JSON.stringify(entriesToDisplay));
} else {
logDebug('No active filter, displaying all entries');
}
setDisplayedEntries(entriesToDisplay);
} catch (e) {
displayError(e, t('errors.while-updating-timeline'));
}
setDisplayedEntries(entriesToDisplay);
}, [timelineMap, filterInputs]);

async function loadTimelineEntries() {
Expand All @@ -118,15 +129,12 @@ const LabelTab = () => {
labelPopulateFactory,
enbs,
);
Logger.log(
'After reading unprocessedInputs, labelsResultMap =' +
JSON.stringify(labelsResultMap) +
'; notesResultMap = ' +
JSON.stringify(notesResultMap),
);
logDebug(`LabelTab: After reading unprocessedInputs,
labelsResultMap = ${JSON.stringify(labelsResultMap)};
notesResultMap = ${JSON.stringify(notesResultMap)}`);
setPipelineRange(pipelineRange);
} catch (error) {
Logger.displayError('Error while loading pipeline range', error);
} catch (e) {
displayError(e, 'Error while loading pipeline range');
setIsLoading(false);
}
}
Expand All @@ -139,15 +147,22 @@ const LabelTab = () => {
}, [pipelineRange]);

function refresh() {
setIsLoading('replace');
resetNominatimLimiter();
setQueriedRange(null);
setTimelineMap(null);
setRefreshTime(new Date());
try {
logDebug('Refreshing LabelTab');
setIsLoading('replace');
resetNominatimLimiter();
setQueriedRange(null);
setTimelineMap(null);
setRefreshTime(new Date());
} catch (e) {
displayError(e, t('errors.while-refreshing-label'));
}
}

async function loadAnotherWeek(when: 'past' | 'future') {
try {
logDebug('LabelTab: loadAnotherWeek into the ' + when);

const reachedPipelineStart =
queriedRange?.start_ts && queriedRange.start_ts <= pipelineRange.start_ts;
const reachedPipelineEnd =
Expand Down Expand Up @@ -184,6 +199,7 @@ const LabelTab = () => {

async function loadSpecificWeek(day: string) {
try {
logDebug('LabelTab: loadSpecificWeek for day ' + day);
if (!isLoading) setIsLoading('replace');
resetNominatimLimiter();
const threeDaysBefore = moment(day).subtract(3, 'days').unix();
Expand All @@ -198,6 +214,11 @@ const LabelTab = () => {
}

function handleFetchedTrips(ctList, utList, mode: 'prepend' | 'append' | 'replace') {
logDebug(`LabelTab: handleFetchedTrips with
mode = ${mode};
ctList = ${JSON.stringify(ctList)};
utList = ${JSON.stringify(utList)}`);

const tripsRead = ctList.concat(utList);
populateCompositeTrips(
tripsRead,
Expand All @@ -215,24 +236,24 @@ const LabelTab = () => {
fillLocationNamesOfTrip(trip);
});
const readTimelineMap = compositeTrips2TimelineMap(tripsRead, showPlaces);
logDebug(`LabelTab: after composite trips converted,
readTimelineMap = ${JSON.stringify(readTimelineMap)}`);
if (mode == 'append') {
setTimelineMap(new Map([...timelineMap, ...readTimelineMap]));
} else if (mode == 'prepend') {
setTimelineMap(new Map([...readTimelineMap, ...timelineMap]));
} else if (mode == 'replace') {
setTimelineMap(readTimelineMap);
} else {
return console.error('Unknown insertion mode ' + mode);
return displayErrorMsg('Unknown insertion mode ' + mode);
}
}

async function fetchTripsInRange(startTs: number, endTs: number) {
if (!pipelineRange.start_ts) {
console.warn('trying to read data too early, early return');
return;
}

const readCompositePromise = readAllCompositeTrips(startTs, endTs);
if (!pipelineRange.start_ts) return logWarn('No pipelineRange yet - early return');
logDebug('LabelTab: fetchTripsInRange from ' + startTs + ' to ' + endTs);
const readCompositePromise = Timeline.readAllCompositeTrips(startTs, endTs);
let readUnprocessedPromise;
if (endTs >= pipelineRange.end_ts) {
const nowTs = new Date().getTime() / 1000;
Expand All @@ -247,6 +268,8 @@ const LabelTab = () => {
readUnprocessedPromise = Promise.resolve([]);
}
const results = await Promise.all([readCompositePromise, readUnprocessedPromise]);
logDebug(`LabelTab: readCompositePromise resolved as: ${JSON.stringify(results[0])};
readUnprocessedPromise resolved as: ${JSON.stringify(results[1])}`);
return results;
}

Expand All @@ -258,33 +281,41 @@ const LabelTab = () => {

const timelineMapRef = useRef(timelineMap);
async function repopulateTimelineEntry(oid: string) {
if (!timelineMap.has(oid)) return console.error(`Item with oid: ${oid} not found in timeline`);
const [newLabels, newNotes] = await getLocalUnprocessedInputs(
pipelineRange,
labelPopulateFactory,
enbs,
);
const repopTime = new Date().getTime();
const newEntry = { ...timelineMap.get(oid), justRepopulated: repopTime };
labelPopulateFactory.populateInputsAndInferences(newEntry, newLabels);
enbs.populateInputsAndInferences(newEntry, newNotes);
const newTimelineMap = new Map(timelineMap).set(oid, newEntry);
setTimelineMap(newTimelineMap);
try {
logDebug('LabelTab: Repopulating timeline entry with oid ' + oid);
if (!timelineMap.has(oid))
return displayErrorMsg('Item with oid: ' + oid + ' not found in timeline');
const [newLabels, newNotes] = await getLocalUnprocessedInputs(
pipelineRange,
labelPopulateFactory,
enbs,
);
const repopTime = new Date().getTime();
logDebug('LabelTab: creating new entry for oid ' + oid + ' with repopTime ' + repopTime);
const newEntry = { ...timelineMap.get(oid), justRepopulated: repopTime };
labelPopulateFactory.populateInputsAndInferences(newEntry, newLabels);
enbs.populateInputsAndInferences(newEntry, newNotes);
logDebug('LabelTab: after repopulating, newEntry = ' + JSON.stringify(newEntry));
const newTimelineMap = new Map(timelineMap).set(oid, newEntry);
setTimelineMap(newTimelineMap);

// after 30 seconds, remove the justRepopulated flag unless it was repopulated again since then
/* ref is needed to avoid stale closure:
// after 30 seconds, remove the justRepopulated flag unless it was repopulated again since then
/* ref is needed to avoid stale closure:
https://legacy.reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function */
timelineMapRef.current = newTimelineMap;
setTimeout(() => {
const entry = { ...timelineMapRef.current.get(oid) };
if (entry.justRepopulated != repopTime)
return console.log('Entry ' + oid + ' was repopulated again, skipping');
const newTimelineMap = new Map(timelineMapRef.current).set(oid, {
...entry,
justRepopulated: false,
});
setTimelineMap(newTimelineMap);
}, 30000);
timelineMapRef.current = newTimelineMap;
setTimeout(() => {
const entry = { ...timelineMapRef.current.get(oid) };
if (entry.justRepopulated != repopTime)
return logDebug('Entry ' + oid + ' was repopulated again, skipping');
const newTimelineMap = new Map(timelineMapRef.current).set(oid, {
...entry,
justRepopulated: false,
});
setTimelineMap(newTimelineMap);
}, 30000);
} catch (e) {
displayError(e, t('errors.while-repopulating-entry'));
}
}

const contextVals = {
Expand Down
Loading

0 comments on commit 7e1790e

Please sign in to comment.