From bb8d5b6b7c55fde8c411ed0a530a90133274b6a6 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Mon, 2 Oct 2023 11:39:03 -0400 Subject: [PATCH] Fix broken statistics by adding timestamp on new entries (#2659) Also make words-per-day-per-user more robust --- Backend/Services/StatisticsService.cs | 33 ++++++++++--------- .../DataEntry/DataEntryTable/index.tsx | 4 ++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Backend/Services/StatisticsService.cs b/Backend/Services/StatisticsService.cs index 6cb12777bc..60cccf1789 100644 --- a/Backend/Services/StatisticsService.cs +++ b/Backend/Services/StatisticsService.cs @@ -89,27 +89,30 @@ public async Task> GetWordsPerDayPerUserCounts(str // The created timestamp may not exist for some model if (!string.IsNullOrEmpty(sd.Created)) { - DateTime tempDate = ParseDateTimePermissivelyWithException(sd.Created); - var userName = userNameIdDictionary.GetValueOrDefault(sd.UserId, ""); - // WordsPerDayPerUserCount exist for particular day - if (shortTimeDictionary.ContainsKey(tempDate.ToISO8601TimeFormatDateOnlyString()) && - !string.IsNullOrEmpty(userName)) - { - var chartNode = shortTimeDictionary[tempDate.ToISO8601TimeFormatDateOnlyString()]; - chartNode.UserNameCountDictionary[userName] = chartNode - .UserNameCountDictionary.GetValueOrDefault(userName, 0) + 1; - } - // WordsPerDayPerUserCount NOT exist, create one and update to the Dictionary - else + var dateKey = ParseDateTimePermissivelyWithException(sd.Created) + .ToISO8601TimeFormatDateOnlyString(); + if (!shortTimeDictionary.ContainsKey(dateKey)) { var tempBarChartNode = new WordsPerDayPerUserCount(sd.Created); foreach (User u in projectUsers) { tempBarChartNode.UserNameCountDictionary.Add(u.Username, 0); } - tempBarChartNode.UserNameCountDictionary[userName] = 1; - shortTimeDictionary.Add( - tempBarChartNode.DateTime.ToISO8601TimeFormatDateOnlyString(), tempBarChartNode); + shortTimeDictionary.Add(dateKey, tempBarChartNode); + } + + var chartNode = shortTimeDictionary[dateKey]; + var username = userNameIdDictionary.GetValueOrDefault(sd.UserId, "?"); + // A semantic domain shouldn't usually have `.Created` without a valid `.UserId`; + // this case is a safe-guard to allow a project owner to see statistics even if there's an + // error in the user reckoning (e.g., if a user is removed from the project mid-workshop). + if (!chartNode.UserNameCountDictionary.ContainsKey(username)) + { + chartNode.UserNameCountDictionary.Add(username, 1); + } + else + { + chartNode.UserNameCountDictionary[username] += 1; } } } diff --git a/src/components/DataEntry/DataEntryTable/index.tsx b/src/components/DataEntry/DataEntryTable/index.tsx index 55445b8c76..bfd161daff 100644 --- a/src/components/DataEntry/DataEntryTable/index.tsx +++ b/src/components/DataEntry/DataEntryTable/index.tsx @@ -691,7 +691,9 @@ export default function DataEntryTable( const addNewEntry = async (): Promise => { const word = newWord(state.newVern); const lang = analysisLang.bcp47; - word.senses.push(newSense(state.newGloss, lang, props.semanticDomain)); + word.senses.push( + newSense(state.newGloss, lang, makeSemDomCurrent(props.semanticDomain)) + ); word.note = newNote(state.newNote, lang); await addNewWord(word, state.newAudioUrls); };