From ea374622b250cc56880a84240647de94205d2ccb Mon Sep 17 00:00:00 2001 From: Jesse Washburn <142361664+jessewashburn@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:42:54 -0500 Subject: [PATCH 1/8] courses: smoother titles (fixes #7664) (#7922) Co-authored-by: dogi --- package.json | 6 +++--- src/app/courses/courses.component.html | 5 +++-- src/app/courses/courses.scss | 4 ++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e480c6539f..c57a6351fd 100755 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.15.97", + "version": "0.15.98", "myplanet": { - "latest": "v0.21.34", - "min": "v0.20.34" + "latest": "v0.21.35", + "min": "v0.20.35" }, "scripts": { "ng": "ng", diff --git a/src/app/courses/courses.component.html b/src/app/courses/courses.component.html index 554f750401..586eb3df19 100644 --- a/src/app/courses/courses.component.html +++ b/src/app/courses/courses.component.html @@ -131,8 +131,9 @@

- {{ element.doc.courseTitle.length > 180 ? element.doc.courseTitle.slice(0, 180) + '...' : element.doc.courseTitle }} - {{ element.doc.courseTitle.length > 180 ? element.doc.courseTitle.slice(0, 180) + '...' : element.doc.courseTitle }} + {{ element.doc.courseTitle.length > 180 ? element.doc.courseTitle.slice(0, 180) + '...' : element.doc.courseTitle }} + {{ element.doc.courseTitle.length > 180 ? element.doc.courseTitle.slice(0, 180) + '...' : element.doc.courseTitle }} + bookmark bookmark_border diff --git a/src/app/courses/courses.scss b/src/app/courses/courses.scss index 6ec414dfe1..efe18f5943 100644 --- a/src/app/courses/courses.scss +++ b/src/app/courses/courses.scss @@ -55,6 +55,10 @@ $label-height: 1rem; height: $toolbar-height; } +.break-word { + word-break: break-word; +} + @media(max-width: $screen-md) { .mat-column-info { max-width: 120px; From 0f4a9ca715aab737fd8703cdde7184fdf54861bc Mon Sep 17 00:00:00 2001 From: Jesse Washburn <142361664+jessewashburn@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:45:52 -0500 Subject: [PATCH 2/8] dashboard: smoother tiles (fixes #7924) (#7926) Co-authored-by: dogi --- package.json | 2 +- src/app/dashboard/dashboard-tile.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c57a6351fd..dfdb51b2c3 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.15.98", + "version": "0.15.99", "myplanet": { "latest": "v0.21.35", "min": "v0.20.35" diff --git a/src/app/dashboard/dashboard-tile.component.html b/src/app/dashboard/dashboard-tile.component.html index 6cda7acb0e..9941b3c936 100644 --- a/src/app/dashboard/dashboard-tile.component.html +++ b/src/app/dashboard/dashboard-tile.component.html @@ -25,7 +25,7 @@ #dashboardTile >

{{item.firstLine}}

-

{{item.title | slice:0:80}}

+

{{item.title | slice:0:80}}

From 6e18f46b98e81df8d85c847b6d5f870746531abd Mon Sep 17 00:00:00 2001 From: Mutugi <48474421+Mutugiii@users.noreply.github.com> Date: Fri, 13 Dec 2024 23:55:37 +0300 Subject: [PATCH 3/8] manager: smoother myplanet logs (fixes #7634)(fixes #7816) (#7913) Co-authored-by: dogi --- package.json | 6 +-- src/app/home/home-router.module.ts | 2 - src/app/home/home.module.ts | 2 +- .../manager-dashboard-router.module.ts | 2 + .../manager-dashboard.component.html | 1 + .../reports}/logs-myplanet.component.html | 9 +++- .../reports}/logs-myplanet.component.ts | 47 ++++++++++++++--- .../reports/reports-myplanet.component.html | 6 +++ .../reports/reports-myplanet.component.ts | 52 ++++++++++++++++++- 9 files changed, 112 insertions(+), 15 deletions(-) rename src/app/{logs-myplanet => manager-dashboard/reports}/logs-myplanet.component.html (76%) rename src/app/{logs-myplanet => manager-dashboard/reports}/logs-myplanet.component.ts (58%) diff --git a/package.json b/package.json index dfdb51b2c3..2d26be0a9e 100755 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.15.99", + "version": "0.16.0", "myplanet": { - "latest": "v0.21.35", - "min": "v0.20.35" + "latest": "v0.21.40", + "min": "v0.20.40" }, "scripts": { "ng": "ng", diff --git a/src/app/home/home-router.module.ts b/src/app/home/home-router.module.ts index 7a4e71a88f..8eda6e64d8 100644 --- a/src/app/home/home-router.module.ts +++ b/src/app/home/home-router.module.ts @@ -6,7 +6,6 @@ import { NotificationsComponent } from '../notifications/notifications.component import { UpgradeComponent } from '../upgrade/upgrade.component'; import { UsersAchievementsComponent } from '../users/users-achievements/users-achievements.component'; import { UsersAchievementsUpdateComponent } from '../users/users-achievements/users-achievements-update.component'; -import { LogsMyPlanetComponent } from '../logs-myplanet/logs-myplanet.component'; import { TeamsViewComponent } from '../teams/teams-view.component'; import { HealthListComponent } from '../health/health-list.component'; import { CommunityComponent } from '../community/community.component'; @@ -35,7 +34,6 @@ const routes: Routes = [ { path: 'upgrade/myplanet', component: UpgradeComponent, data: { myPlanet: true } }, { path: 'teams', loadChildren: () => import('../teams/teams.module').then(m => m.TeamsModule) }, { path: 'enterprises', loadChildren: () => import('../teams/teams.module').then(m => m.TeamsModule), data: { mode: 'enterprise' } }, - { path: 'logs/myplanet', component: LogsMyPlanetComponent }, { path: 'health', component: HealthListComponent }, { path: 'health/profile/:id', loadChildren: () => import('../health/health.module').then(m => m.HealthModule) }, { path: 'nation', component: TeamsViewComponent, data: { mode: 'services' } }, diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts index cc9c52acae..8ee5378d75 100644 --- a/src/app/home/home.module.ts +++ b/src/app/home/home.module.ts @@ -17,7 +17,7 @@ import { UpgradeComponent } from '../upgrade/upgrade.component'; import { SharedComponentsModule } from '../shared/shared-components.module'; import { UsersAchievementsModule } from '../users/users-achievements/users-achievements.module'; import { NewsModule } from '../news/news.module'; -import { LogsMyPlanetComponent } from '../logs-myplanet/logs-myplanet.component'; +import { LogsMyPlanetComponent } from '../manager-dashboard/reports/logs-myplanet.component'; import { TeamsModule } from '../teams/teams.module'; import { CommunityComponent } from '../community/community.component'; import { PlanetCalendarModule } from '../shared/calendar.module'; diff --git a/src/app/manager-dashboard/manager-dashboard-router.module.ts b/src/app/manager-dashboard/manager-dashboard-router.module.ts index 9249544115..c5b7fd16e4 100644 --- a/src/app/manager-dashboard/manager-dashboard-router.module.ts +++ b/src/app/manager-dashboard/manager-dashboard-router.module.ts @@ -10,6 +10,7 @@ import { ReportsDetailComponent } from './reports/reports-detail.component'; import { ReportsPendingComponent } from './reports/reports-pending.component'; import { ReportsMyPlanetComponent } from './reports/reports-myplanet.component'; import { RequestsComponent } from './requests/requests.component'; +import { LogsMyPlanetComponent } from './reports/logs-myplanet.component'; const routes: Routes = [ { path: '', component: ManagerDashboardComponent }, @@ -27,6 +28,7 @@ const routes: Routes = [ { path: 'reports/detail', component: ReportsDetailComponent }, { path: 'reports/pending', component: ReportsPendingComponent }, { path: 'reports/myplanet', component: ReportsMyPlanetComponent }, + { path: 'logs/myplanet', component: LogsMyPlanetComponent }, { path: 'requests', component: RequestsComponent } ]; diff --git a/src/app/manager-dashboard/manager-dashboard.component.html b/src/app/manager-dashboard/manager-dashboard.component.html index c31840c7e0..85d2f7bb5b 100644 --- a/src/app/manager-dashboard/manager-dashboard.component.html +++ b/src/app/manager-dashboard/manager-dashboard.component.html @@ -10,6 +10,7 @@ Reports myPlanet Reports + myPlanet Logs Surveys Logs @@ -13,6 +13,10 @@ myPlanet + +
@@ -22,6 +26,9 @@ {{planet.nameDoc?.name || planet.doc?.name}} ({{planet.children.length}}) + diff --git a/src/app/logs-myplanet/logs-myplanet.component.ts b/src/app/manager-dashboard/reports/logs-myplanet.component.ts similarity index 58% rename from src/app/logs-myplanet/logs-myplanet.component.ts rename to src/app/manager-dashboard/reports/logs-myplanet.component.ts index c71a58706a..4e6443c94c 100644 --- a/src/app/logs-myplanet/logs-myplanet.component.ts +++ b/src/app/manager-dashboard/reports/logs-myplanet.component.ts @@ -1,12 +1,12 @@ import { Component, OnInit } from '@angular/core'; -import { CouchService } from '../shared/couchdb.service'; +import { CouchService } from '../../shared/couchdb.service'; import { forkJoin } from 'rxjs'; -import { StateService } from '../shared/state.service'; -import { PlanetMessageService } from '../shared/planet-message.service'; -import { ManagerService } from '../manager-dashboard/manager.service'; -import { filterSpecificFields } from '../shared/table-helpers'; -import { attachNamesToPlanets, areNoChildren } from '../manager-dashboard/reports/reports.utils'; - +import { StateService } from '../../shared/state.service'; +import { PlanetMessageService } from '../../shared/planet-message.service'; +import { ManagerService } from '../manager.service'; +import { filterSpecificFields } from '../../shared/table-helpers'; +import { attachNamesToPlanets, areNoChildren } from './reports.utils'; +import { CsvService } from '../../shared/csv.service'; @Component({ templateUrl: './logs-myplanet.component.html' @@ -23,6 +23,7 @@ export class LogsMyPlanetComponent implements OnInit { } constructor( + private csvService: CsvService, private couchService: CouchService, private stateService: StateService, private planetMessageService: PlanetMessageService, @@ -64,4 +65,36 @@ export class LogsMyPlanetComponent implements OnInit { }, (error) => this.planetMessageService.showAlert($localize`There was a problem getting myPlanet activity.`)); } + private mapToCsvData(children: any[], planetName?: string): any[] { + return children.map((data: any) => ({ + ...(planetName ? { 'Planet Name': planetName } : {}), + 'ID': data.androidId, + 'Name': data.deviceName || data.customDeviceName, + 'Type': data.type, + 'Time': new Date(Number(data.time)), + 'Version': data.version, + 'Error': data.error || 'N/A', + })); + } + + exportAll(): void { + const csvData: any[] = this.apklogs.flatMap((planet: any) => { + return this.mapToCsvData(planet.children, planet.name); + }); + + this.csvService.exportCSV({ + data: csvData, + title: 'myPlanet Logs', + }); + } + + exportSingle(planet: any): void { + const csvData = this.mapToCsvData(planet.children); + + this.csvService.exportCSV({ + data: csvData, + title: `myPlanet Logs for ${planet.name}`, + }); + } + } diff --git a/src/app/manager-dashboard/reports/reports-myplanet.component.html b/src/app/manager-dashboard/reports/reports-myplanet.component.html index e581313d35..8f10c8ea16 100755 --- a/src/app/manager-dashboard/reports/reports-myplanet.component.html +++ b/src/app/manager-dashboard/reports/reports-myplanet.component.html @@ -29,6 +29,9 @@ myPlanet on { planetType, select, center {Nations} other {Communities} } +
@@ -38,6 +41,9 @@ {{planet.nameDoc?.name || planet.doc?.name}} ({{planet.children.length}}) + diff --git a/src/app/manager-dashboard/reports/reports-myplanet.component.ts b/src/app/manager-dashboard/reports/reports-myplanet.component.ts index 8e4dc06efb..134c0e2255 100755 --- a/src/app/manager-dashboard/reports/reports-myplanet.component.ts +++ b/src/app/manager-dashboard/reports/reports-myplanet.component.ts @@ -11,6 +11,7 @@ import { ActivatedRoute } from '@angular/router'; import { switchMap, map } from 'rxjs/operators'; import { findDocuments } from '../../shared/mangoQueries'; import { DeviceInfoService, DeviceType } from '../../shared/device-info.service'; +import { CsvService } from '../../shared/csv.service'; @Component({ templateUrl: './reports-myplanet.component.html' @@ -33,13 +34,14 @@ export class ReportsMyPlanetComponent implements OnInit { hub = { spokes: [] }; constructor( + private csvService: CsvService, private couchService: CouchService, private stateService: StateService, private planetMessageService: PlanetMessageService, private managerService: ManagerService, private reportsService: ReportsService, private route: ActivatedRoute, - private deviceInfoService: DeviceInfoService, + private deviceInfoService: DeviceInfoService ) { this.deviceType = this.deviceInfoService.getDeviceType(); this.isMobile = this.deviceType === DeviceType.MOBILE; @@ -112,4 +114,52 @@ export class ReportsMyPlanetComponent implements OnInit { ); } + private formatTotalTime(totalMilliseconds: number): string { + if (!totalMilliseconds || totalMilliseconds === 0) { + return '00:00:00'; + } + const totalSeconds = Math.floor(totalMilliseconds / 1000); + const hours = Math.floor(totalSeconds / 3600); + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = totalSeconds % 60; + + return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + } + + private mapToCsvData(children: any[], planetName?: string): any[] { + return children.map((data: any) => ({ + ...(planetName ? { 'Planet Name': planetName } : {}), + 'ID': data.androidId.toString() || data.uniqueAndroidId.toString(), + 'Name': data.deviceName || data.customDeviceName, + 'Last Synced': data.time && data.time !== 0 ? + new Date(data.time).toDateString() : + data.last_synced && data.last_synced !== 0 ? + new Date(data.last_synced).toDateString() : + 'N/A', + 'Version': data.versionName, + 'No of Visits': data.count, + 'Used Time': this.formatTotalTime(data.totalUsedTime), + })); + } + + exportAll(): void { + const csvData: any[] = this.planets.flatMap((planet: any) => { + return this.mapToCsvData(planet.children, planet.name); + }); + + this.csvService.exportCSV({ + data: csvData, + title: 'myPlanet Reports', + }); + } + + exportSingle(planet: any): void { + const csvData = this.mapToCsvData(planet.children); + + this.csvService.exportCSV({ + data: csvData, + title: `myPlanet Reports for ${planet.name}`, + }); + } + } From 6a2f4ece25258e817d9c18003a49e002d7f02a55 Mon Sep 17 00:00:00 2001 From: Jesse Washburn <142361664+jessewashburn@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:11:57 -0500 Subject: [PATCH 4/8] teams: smoother calendar recursions (fixes #7858) (#7862) Co-authored-by: mutugiii Co-authored-by: dogi --- package.json | 2 +- .../add-meetups/meetups-add.component.html | 7 +- .../add-meetups/meetups-add.component.ts | 75 ++++++++++++------- src/app/shared/calendar.component.ts | 15 ++-- src/app/validators/custom-validators.ts | 11 +++ 5 files changed, 72 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 2d26be0a9e..625d9ddf90 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.16.0", + "version": "0.16.1", "myplanet": { "latest": "v0.21.40", "min": "v0.20.40" diff --git a/src/app/meetups/add-meetups/meetups-add.component.html b/src/app/meetups/add-meetups/meetups-add.component.html index cca2895936..f44c7ed018 100644 --- a/src/app/meetups/add-meetups/meetups-add.component.html +++ b/src/app/meetups/add-meetups/meetups-add.component.html @@ -53,8 +53,11 @@
-
- {{day}} +
+ {{ day }} + + Please select at least one day. +
diff --git a/src/app/meetups/add-meetups/meetups-add.component.ts b/src/app/meetups/add-meetups/meetups-add.component.ts index 9b26da9cee..9b22185699 100644 --- a/src/app/meetups/add-meetups/meetups-add.component.ts +++ b/src/app/meetups/add-meetups/meetups-add.component.ts @@ -103,22 +103,24 @@ export class MeetupsAddComponent implements OnInit { }, { validators: CustomValidators.meetupTimeValidator() }); - } +} - onSubmit() { - if (!this.meetupForm.valid) { - showFormErrors(this.meetupForm.controls); - return; - } - this.meetupForm.value.startTime = this.changeTimeFormat(this.meetupForm.value.startTime); - this.meetupForm.value.endTime = this.changeTimeFormat(this.meetupForm.value.endTime); - const meetup = { ...this.meetupForm.value, link: this.link, sync: this.sync }; - if (this.pageType === 'Update') { +onSubmit() { + if (!this.meetupForm.valid) { + showFormErrors(this.meetupForm.controls); + return; + } + const dayFormArray = this.meetupForm.get('day') as FormArray; + dayFormArray.updateValueAndValidity(); + this.meetupForm.value.startTime = this.changeTimeFormat(this.meetupForm.value.startTime); + this.meetupForm.value.endTime = this.changeTimeFormat(this.meetupForm.value.endTime); + const meetup = { ...this.meetupForm.value, link: this.link, sync: this.sync }; + if (this.pageType === 'Update') { this.updateMeetup(meetup); } else { this.addMeetup(meetup); - } } +} changeTimeFormat(time: string): string { if (time && time.length < 5) { @@ -174,35 +176,50 @@ export class MeetupsAddComponent implements OnInit { } } - isClassDay(day) { - return this.meetupFrequency.includes(day) ? true : false; - } - onDayChange(day: string, isChecked: boolean) { const dayFormArray = this.meetupForm.controls.day; if (isChecked) { // add to day array if checked dayFormArray.push(new FormControl(day)); } else { - // remove from day array if unchecked - const index = dayFormArray.controls.findIndex(x => x.value === day); - dayFormArray.removeAt(index); + // remove from day array if unchecked + const index = dayFormArray.controls.findIndex(x => x.value === day); + if (index >= 0) { + dayFormArray.removeAt(index); + } } - } + dayFormArray.updateValueAndValidity(); +} - toggleDaily(val, showCheckbox) { - // empty the array - this.meetupForm.setControl('day', this.fb.array([])); - switch (val) { +toggleDaily(val: string, showCheckbox: boolean) { + const dayFormArray = this.meetupForm.get('day') as FormArray; + dayFormArray.clear(); + dayFormArray.clearValidators(); + + switch (val) { + // add all days to the array if the course is daily case 'daily': - // add all days to the array if the course is daily - this.meetupForm.setControl('day', this.fb.array(this.days)); - break; + this.days.forEach((day) => { + dayFormArray.push(new FormControl(day)); + }); + break; case 'weekly': - this.meetupForm.setControl('day', this.fb.array(this.meetupFrequency)); - break; - } + dayFormArray.setValidators(CustomValidators.atLeastOneDaySelected()); + const startDate = this.meetupForm.controls.startDate.value; + if (startDate) { + const startDateObj = new Date(startDate); + const dayOfWeek = this.days[startDateObj.getDay()]; + if (dayOfWeek) { + dayFormArray.push(new FormControl(dayOfWeek)); + } + } + break; + + default: + break; } + dayFormArray.updateValueAndValidity(); +} meetupChangeNotifications(users, meetupInfo, meetupId) { return { docs: users.map((user) => ({ diff --git a/src/app/shared/calendar.component.ts b/src/app/shared/calendar.component.ts index 31cc504025..a45d582a21 100644 --- a/src/app/shared/calendar.component.ts +++ b/src/app/shared/calendar.component.ts @@ -171,13 +171,16 @@ export class PlanetCalendarComponent implements OnInit, OnChanges { } openAddEventDialog(event) { - let meetup; - if (event?.start) { - meetup = { - startDate: event?.start, - endDate: this.adjustEndDate(event?.end) - }; + const today = new Date(); + const meetup = event?.start + ? { + startDate: event.start, + endDate: this.adjustEndDate(event.end), } + : { + startDate: today, + endDate: today, + }; this.dialog.open(DialogsAddMeetupsComponent, { data: { meetup: meetup, link: this.link, sync: this.sync, onMeetupsChange: this.onMeetupsChange.bind(this), editable: this.editable } }); diff --git a/src/app/validators/custom-validators.ts b/src/app/validators/custom-validators.ts index c3c9311230..da950a37c8 100755 --- a/src/app/validators/custom-validators.ts +++ b/src/app/validators/custom-validators.ts @@ -255,4 +255,15 @@ export class CustomValidators { }); } + static atLeastOneDaySelected(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + if (!control.parent) { return null; } + const recurringControl = control.parent.get('recurring'); + if (!recurringControl || recurringControl.value !== 'weekly') { + return null; + } + const selectedDays = control.value; + return selectedDays && selectedDays.length > 0 ? null : { noDaysSelected: true }; + }; + } } From 432e29325b7056bdd34f0002a4791e19f1af815f Mon Sep 17 00:00:00 2001 From: sahilvunnam <118228103+sahilvunnam@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:23:30 -0800 Subject: [PATCH 5/8] resources: smoother collections display (fixes #7772) (#7776) Co-authored-by: Axel Lorens Co-authored-by: dogi --- package.json | 2 +- src/app/shared/forms/planet-tag-input-dialog.component.html | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 625d9ddf90..aaa098482b 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.16.1", + "version": "0.16.2", "myplanet": { "latest": "v0.21.40", "min": "v0.20.40" diff --git a/src/app/shared/forms/planet-tag-input-dialog.component.html b/src/app/shared/forms/planet-tag-input-dialog.component.html index 150940285e..eeb210d37a 100644 --- a/src/app/shared/forms/planet-tag-input-dialog.component.html +++ b/src/app/shared/forms/planet-tag-input-dialog.component.html @@ -54,8 +54,10 @@ All - - {{tag.name + ' (' + (tag.count || 0) + ')'}} + + {{ (tag.name + ' (' + (tag.count || 0) + ')') | slice:0:30 }}{{ (tag.name.length + tag.count.toString().length > 30) ? '...' : '' }} From 6d7e593461a19e44880828f03b5e58cc98712eb3 Mon Sep 17 00:00:00 2001 From: Jesse Washburn <142361664+jessewashburn@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:56:59 -0500 Subject: [PATCH 6/8] courses: smoother progress export (fixes #7811) (#7912) Co-authored-by: Mutugi <48474421+Mutugiii@users.noreply.github.com> Co-authored-by: dogi --- package.json | 2 +- .../courses-progress-leader.component.ts | 43 ++++++++++++++----- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index aaa098482b..e97348854d 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.16.2", + "version": "0.16.3", "myplanet": { "latest": "v0.21.40", "min": "v0.20.40" diff --git a/src/app/courses/progress-courses/courses-progress-leader.component.ts b/src/app/courses/progress-courses/courses-progress-leader.component.ts index c6a36c59d9..2a9faa7947 100644 --- a/src/app/courses/progress-courses/courses-progress-leader.component.ts +++ b/src/app/courses/progress-courses/courses-progress-leader.component.ts @@ -10,6 +10,7 @@ import { dedupeObjectArray } from '../../shared/utils'; import { DialogsLoadingService } from '../../shared/dialogs/dialogs-loading.service'; import { findDocuments } from '../../shared/mangoQueries'; import { UserProfileDialogComponent } from '../../users/users-profile/users-profile-dialog.component'; +import { StateService } from '../../shared/state.service'; import { DeviceInfoService, DeviceType } from '../../shared/device-info.service'; @Component({ @@ -31,6 +32,7 @@ export class CoursesProgressLeaderComponent implements OnInit, OnDestroy { submittedExamSteps: any[] = []; planetCodes: string[] = []; selectedPlanetCode: string; + configuration: any = {}; deviceType: DeviceType; deviceTypes = DeviceType; @@ -42,6 +44,7 @@ export class CoursesProgressLeaderComponent implements OnInit, OnDestroy { private csvService: CsvService, private dialogsLoadingService: DialogsLoadingService, private dialog: MatDialog, + private stateService: StateService, private deviceInfoService: DeviceInfoService ) { this.dialogsLoadingService.start(); @@ -221,23 +224,41 @@ export class CoursesProgressLeaderComponent implements OnInit, OnDestroy { } structureChartData(data) { - const dataArr = []; - data.forEach(element => { - const dataDict = {}; - dataDict['Username'] = element.label; - for (let i = 0; i < element.items.length; i++) { - dataDict[`Step ${(i + 1)}`] = element.items[i].number; - } + return data.map(element => { + let successfulSteps = 0; + let totalSteps = 0; + let totalErrors = 0; + const steps = {}; - dataArr.push(dataDict); + element.items.forEach((item, index) => { + const stepErrors = item.number || 0; + totalSteps++; + if (stepErrors === 0) { + successfulSteps++; + } + totalErrors += stepErrors; + steps[`Step ${(index + 1)}`] = stepErrors; + }); + + return { + 'Username': element.label, + 'Success Percentage': `${((successfulSteps / totalSteps) * 100).toFixed(2)}%`, + 'Total Errors': totalErrors, + ...steps + }; }); - return dataArr; } exportChartData() { + const planetName = this.stateService.configuration.name; + const courseTitle = this.course.courseTitle; + const entityLabel = this.configuration.planetType === 'nation' ? 'Nation' : 'Community'; + const title = $localize`${courseTitle} Course Progress for ${entityLabel} ${planetName}`; + + const structuredData = this.structureChartData(this.chartData); this.csvService.exportCSV({ - data: this.structureChartData(this.chartData), - title: $localize`Course Progress Data` + data: structuredData, + title: title }); } From dad08fdd8b65b27eab3c50dd2ec694363e0160b4 Mon Sep 17 00:00:00 2001 From: Jesse Washburn <142361664+jessewashburn@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:14:48 -0500 Subject: [PATCH 7/8] resources: smoother navigation (fixes #7927) (#7929) Co-authored-by: dogi --- package.json | 2 +- .../resources/view-resources/resources-view.component.html | 6 +++--- src/app/resources/view-resources/resources-view.scss | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e97348854d..e5e7f9ef39 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.16.3", + "version": "0.16.4", "myplanet": { "latest": "v0.21.40", "min": "v0.20.40" diff --git a/src/app/resources/view-resources/resources-view.component.html b/src/app/resources/view-resources/resources-view.component.html index cedf7e1f91..9c040b3a7f 100644 --- a/src/app/resources/view-resources/resources-view.component.html +++ b/src/app/resources/view-resources/resources-view.component.html @@ -43,11 +43,11 @@ - Open in new tab - - diff --git a/src/app/resources/view-resources/resources-view.scss b/src/app/resources/view-resources/resources-view.scss index 937c77f616..e33ad07cb0 100644 --- a/src/app/resources/view-resources/resources-view.scss +++ b/src/app/resources/view-resources/resources-view.scss @@ -34,6 +34,10 @@ max-height: 60vh; } } + + .toolbar-button { + flex-shrink: 0; + } @media (max-width: $screen-sm) { .view-container { From 56d4b398b9c8fd2732e60eb5ad926a5351f12c45 Mon Sep 17 00:00:00 2001 From: Axel Lo <54468493+RheuX@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:22:56 -0800 Subject: [PATCH 8/8] chat: smoother ux (fixes #7915) (#7931) Co-authored-by: dogi --- package.json | 2 +- .../chat/chat-window/chat-window.component.ts | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e5e7f9ef39..6cfbdb5399 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "planet", "license": "AGPL-3.0", - "version": "0.16.4", + "version": "0.16.5", "myplanet": { "latest": "v0.21.40", "min": "v0.20.40" diff --git a/src/app/chat/chat-window/chat-window.component.ts b/src/app/chat/chat-window/chat-window.component.ts index 85cdf7ce7d..2b987c78cf 100644 --- a/src/app/chat/chat-window/chat-window.component.ts +++ b/src/app/chat/chat-window/chat-window.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, OnDestroy, ViewChild, ElementRef, ChangeDetectorRef, Input, AfterViewInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { filter, takeUntil } from 'rxjs/operators'; import { CustomValidators } from '../../validators/custom-validators'; import { ConversationForm, AIProvider } from '../chat.model'; @@ -20,6 +20,7 @@ export class ChatWindowComponent implements OnInit, OnDestroy, AfterViewInit { spinnerOn = true; streaming: boolean; disabled = false; + clearChat = true; provider: AIProvider; conversations: any[] = []; selectedConversationId: any; @@ -71,8 +72,7 @@ export class ChatWindowComponent implements OnInit, OnDestroy, AfterViewInit { this.chatService.newChatSelected$ .pipe(takeUntil(this.onDestroy$)) .subscribe(() => { - this.selectedConversationId = null; - this.conversations = []; + this.resetConversation(); this.focusInput(); }, error => { console.error('Error subscribing to newChatSelected$', error); @@ -81,7 +81,16 @@ export class ChatWindowComponent implements OnInit, OnDestroy, AfterViewInit { subscribeToSelectedConversation() { this.chatService.selectedConversationId$ - .pipe(takeUntil(this.onDestroy$)) + .pipe( + takeUntil(this.onDestroy$), + filter(() => { + if (this.clearChat) { + this.clearChat = false; + return false; + } + return true; + }) + ) .subscribe((conversationId) => { this.selectedConversationId = conversationId; this.fetchConversation(this.selectedConversationId?._id); @@ -102,6 +111,11 @@ export class ChatWindowComponent implements OnInit, OnDestroy, AfterViewInit { })); } + resetConversation() { + this.conversations = []; + this.selectedConversationId = null; + } + createForm() { this.promptForm = this.formBuilder.group({ prompt: [ '', CustomValidators.required ],