Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display round data #170

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
53b2a1d
Create menu button to display dialog during round
UtkarshKr007 Dec 21, 2020
9496fb3
Display flowers visited for the entire round
UtkarshKr007 Dec 21, 2020
d2f2bda
Provide MatDialogModule to Large Display tests
UtkarshKr007 Dec 21, 2020
4188c6e
Move fields above methods to fix lint problems
UtkarshKr007 Dec 21, 2020
9085498
Merge branch 'master' into round-data
UtkarshKr007 Dec 21, 2020
baf4275
Apply suggestions from code review
UtkarshKr007 Dec 21, 2020
092fe82
Revert html and add shareReplay to allInteraactions Field
UtkarshKr007 Dec 22, 2020
e779ce8
Add 'return'
UtkarshKr007 Dec 22, 2020
0d9d95c
Create test-page/:sessionId for most recent session
UtkarshKr007 Dec 23, 2020
12bbaaa
Create Mat Cards with student names
UtkarshKr007 Dec 23, 2020
d4fd0a9
Connect round-data-test to session
UtkarshKr007 Dec 23, 2020
9900726
Replace dialog with link to test/:sessionId
UtkarshKr007 Dec 23, 2020
3d02bf3
Merge branch 'master' into round-data
UtkarshKr007 Dec 24, 2020
287af46
Switch display based on existence of roundId
UtkarshKr007 Dec 29, 2020
6a48212
Get round students & their doc id from firebase
UtkarshKr007 Dec 29, 2020
c283932
Create RoundPath observable to pass to firebase
UtkarshKr007 Dec 29, 2020
6990679
get all students in a round from firebase
UtkarshKr007 Dec 29, 2020
979e2ef
Combine session and round students by id
UtkarshKr007 Dec 29, 2020
a2b4e24
Create and use RoundTestData interface
UtkarshKr007 Dec 29, 2020
a026dad
Display raw intearction values during round
UtkarshKr007 Dec 29, 2020
3689f3f
Merge branch 'master' into round-data
UtkarshKr007 Dec 30, 2020
288e373
Get flower names from barcode value
UtkarshKr007 Dec 30, 2020
acb6a37
Add name to nest interactions too
UtkarshKr007 Dec 30, 2020
27034f0
Add flower and nest pics to interactions
UtkarshKr007 Jan 1, 2021
185ed1b
Move new interface to RoundDataTest
UtkarshKr007 Jan 1, 2021
6709277
Merge branch 'master' into round-data
UtkarshKr007 Jan 3, 2021
c9fda91
Store Nest or FlowerSpecies rather than properties
UtkarshKr007 Jan 5, 2021
ab6c520
Merge branch 'master' into round-data
UtkarshKr007 Jan 7, 2021
d775e22
Merge branch 'master' into round-data
UtkarshKr007 Jan 8, 2021
d9ccc4c
Add in pollen indicators
UtkarshKr007 Jan 8, 2021
ce15692
Merge branch 'master' into round-data
UtkarshKr007 Jan 8, 2021
2b1d869
Remove sentencecase from app module
UtkarshKr007 Jan 8, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { JoinSessionComponent } from './pages/join-session/join-session.componen
import { HostSessionComponent } from './pages/host-session/host-session.component';
import { TestPagesComponent } from './pages/test-pages/test-pages.component';
import { AboutComponent } from './pages/about/about.component';
import { RoundDataTestComponent } from './test-pages/round-data-test/round-data-test.component';


const testRoutes: Routes = [
{path: 'timer-test', component: TimerTestComponent},
Expand All @@ -20,7 +22,9 @@ const testRoutes: Routes = [
{path: 'session-test', component: SessionTestComponent},
{path: 'round-template-test', component: RoundTemplateTestComponent},
{path: 'prepare-round-test', component: PrepareRoundTestComponent},
{path: 'flower-test', component: FlowerTestComponent}
{path: 'flower-test', component: FlowerTestComponent},
{path: ':sessionId', component: RoundDataTestComponent}

];

const routes: Routes = [
Expand Down
3 changes: 3 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ import { RoundTemplateTestComponent } from './test-pages/round-template-test/rou
import { TestPagesComponent } from './pages/test-pages/test-pages.component';
import { RoundChooserDialogComponent } from './components/round-chooser-dialog/round-chooser-dialog.component';
import { AboutComponent } from './pages/about/about.component';
import { RoundDataTestComponent } from './test-pages/round-data-test/round-data-test.component';
import { SharedModule } from './shared.module';



const FIREBASE_MODULES = [
AngularFireModule.initializeApp(environment.firebase),
AngularFirestoreModule,
Expand Down Expand Up @@ -65,6 +67,7 @@ const FIREBASE_MODULES = [
TestPagesComponent,
RoundChooserDialogComponent,
AboutComponent,
RoundDataTestComponent,
ConfirmRemoveStudentDialogComponent,
RenameStudentDialogComponent,
],
Expand Down
7 changes: 6 additions & 1 deletion src/app/pages/large-display/large-display.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@
</div>

<div right>
<button mat-icon-button><mat-icon>more_vert</mat-icon></button>
<button mat-icon-button [matMenuTriggerFor]="roundMenu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #roundMenu="matMenu">
<button mat-menu-item [routerLink]="['/test', (this.teacherSessionService.currentSession$ | async)?.id]">Review Round Data</button>
</mat-menu>
</div>
</app-bottom-bar>
</ng-container>
Expand Down
6 changes: 5 additions & 1 deletion src/app/pages/test-pages/test-pages.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ <h2>Test</h2>
<li><a routerLink="/test/json-data-test">json-data-test</a></li>
<li><a routerLink="/test/session-test">session-test</a></li>
<li><a routerLink="/test/prepare-round-test">prepare-round-test</a></li>
<li><a routerLink="/test/round-template-test">round-template-test</a></li>
<li><a routerLink="/test/round-template-test">round-template-test</a></li>
Create a session to see a link to round-data-test
<li *ngIf="(this.teacherSessionService.mostRecentSession$ | async) as session">
<a [routerLink]="['/test', session.id]">round-data-test</a>
</li>
</ul>
</nav>
3 changes: 2 additions & 1 deletion src/app/pages/test-pages/test-pages.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { TeacherSessionService } from '../../services/teacher-session.service';

@Component({
selector: 'app-test-pages',
Expand All @@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core';
})
export class TestPagesComponent implements OnInit {

constructor() { }
constructor(public teacherSessionService: TeacherSessionService) { }

ngOnInit(): void {
}
Expand Down
3 changes: 3 additions & 0 deletions src/app/round.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { FlowerSpecies } from './flowers';
import { TimePeriod } from './time-period';
import { BeeSpecies } from './bees';
import { Nest } from './nests';
import * as firebase from 'firebase/app';
import firestore = firebase.firestore;

Expand Down Expand Up @@ -33,6 +35,7 @@ export class RoundFlower {
}

export interface RoundStudentData {
id?: string;
beeSpecies?: string;
}

Expand Down
10 changes: 10 additions & 0 deletions src/app/services/firebase.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ export class FirebaseService {
.update({currentRoundId: roundPath.roundId});
}

getStudentsInARound(roundPath: RoundPath): Observable<RoundStudentData[]> {
return this.getRoundDocument(roundPath)
.collection<RoundStudentData>('students')
.valueChanges({idField: 'id'});
}

/**
* Returns an observable of all student data as an array of JSON objects
* @param sessionID the ID of the session the students are in
Expand Down Expand Up @@ -202,6 +208,10 @@ export class FirebaseService {
return this.getRoundDocument(roundPath).collection('interactions').add({createdAt: firestore.FieldValue.serverTimestamp(), ...data});
}

getAllInteractions(roundPath: RoundPath): Observable<Interaction[]> {
return this.getRoundDocument(roundPath).collection<Interaction>('interactions', ref => ref.orderBy('createdAt', 'desc')).valueChanges();
}

getStudentInteractions(roundPath: RoundPath, studentId: string): Observable<Interaction[]> {
return this.angularFirestore.collection<Interaction>(
'sessions/' + roundPath.sessionId + '/rounds/' + roundPath.roundId + '/interactions',
Expand Down
46 changes: 46 additions & 0 deletions src/app/test-pages/round-data-test/round-data-test.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<app-hill-background cover></app-hill-background>
<ng-container *ngIf="(currentRound$ | async); else waitForRound">
<div class="list-container">
<mat-card *ngFor="let data of (roundData$ | async)" class="student-card">
<mat-card-header>
<img mat-card-avatar src="/assets/art/500w/bees/{{data.bee.art_file}}">
<mat-card-title>{{data.name | sentenceCase}}</mat-card-title>
<mat-card-subtitle>{{data.bee.name}}</mat-card-subtitle>
<div class="cards">
<div class="pollen">
<mat-icon
inline
color='accent'
*ngFor="let number of [1,2,3]"
>
{{number <= data.carryingPollen ? 'lens' : 'panorama_fish_eye'}}
</mat-icon>
</div>
<div class="nest">
Pollen in nest:
<span>
{{data.nestPollen}}
</span>
</div>
</div>
</mat-card-header>
<mat-card-content>
<mat-list class="interaction-list">
<mat-list-item *ngFor="let interaction of data.interactions">
<img matListAvatar src="/assets/art/500w/{{interaction.isNest ? 'nests': 'flowers'}}/{{interaction.type.art_file}}" />
<div matLine>Name: {{interaction.type.name}}</div>
<div matLine>TimePeriod: {{interaction.timePeriod}}</div>
</mat-list-item>
</mat-list>
</mat-card-content>
</mat-card>
</div>
</ng-container>

<ng-template #waitForRound>
<div class="centered-container">
<mat-card>
<mat-card-title>Waiting for round to begin&hellip;</mat-card-title>
</mat-card>
</div>
</ng-template>
53 changes: 53 additions & 0 deletions src/app/test-pages/round-data-test/round-data-test.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@import "../../../variables";


@mixin responsive-font-size(
$for-phone-portrait,
$for-tablet-portrait,
$for-tablet-landscape,
) {
font-size: $for-phone-portrait;
line-height: $for-phone-portrait;
@media (min-width: $tablet-portrait-min-width) {
font-size: $for-tablet-portrait;
line-height: $for-tablet-portrait;
}
@media (min-width: $tablet-landscape-min-width) {
font-size: $for-tablet-landscape;
line-height: $for-tablet-landscape;
}
}

.list-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: baseline;
}

.student-card {
margin: 8px;
}

.header-text {
margin: 0px 16px
}

.interaction-list {
max-height: 400px;
overflow: auto;
}

.cards {
display: flex;
flex-direction: column;
align-items: center;
}

.nest, .pollen {
@include responsive-font-size(1.1rem, 1.2rem, 1.3rem);
}

.nest {
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { RoundDataTestComponent } from './round-data-test.component';

xdescribe('RoundDataTestComponent', () => {
let component: RoundDataTestComponent;
let fixture: ComponentFixture<RoundDataTestComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RoundDataTestComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(RoundDataTestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
124 changes: 124 additions & 0 deletions src/app/test-pages/round-data-test/round-data-test.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { combineLatest, Observable, of } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators';
import { Interaction, RoundStudentData } from 'src/app/round';
import { FirebaseService, RoundPath } from 'src/app/services/firebase.service';
import { TeacherSessionService } from '../../services/teacher-session.service';
import { allBeeSpecies, BeeSpecies } from 'src/app/bees';
import { allFlowerSpecies, FlowerSpecies } from 'src/app/flowers';
import { Nest } from 'src/app/nests';

@Component({
selector: 'app-round-data-test',
templateUrl: './round-data-test.component.html',
styleUrls: ['./round-data-test.component.scss']
})
export class RoundDataTestComponent implements OnInit {

constructor(
private activatedRoute: ActivatedRoute,
public teacherSessionService: TeacherSessionService,
public firebaseService: FirebaseService) { }

currentRound$: Observable<RoundPath | null> = this.teacherSessionService.mostRecentSession$.pipe(
map(session =>
session.currentRoundId
? this.RoundPathFromSession(session.id, session.currentRoundId)
: null
)
);

roundStudents$: Observable<RoundStudentData[]> = this.currentRound$.pipe(
switchMap(currentRound =>
currentRound
? this.firebaseService.getStudentsInARound(currentRound)
: of([])
),
shareReplay(1)
);

sessionStudents$ = this.teacherSessionService.studentsInCurrentSession$;

allInteractions$: Observable<Interaction[]> = this.currentRound$.pipe(
switchMap(currentRound =>
currentRound
? this.firebaseService.getAllInteractions(currentRound)
: of([])
),
shareReplay(1)
);

roundFlowers$: Observable<string[]> = this.currentRound$.pipe(
switchMap(currentRound =>
currentRound
? this.firebaseService.getRound(currentRound).pipe(
map((round) => round.flowerSpeciesIds)
)
: of([])
)
);


roundData$: Observable<RoundTestData[]> =
combineLatest([this.roundStudents$, this.sessionStudents$, this.allInteractions$, this.roundFlowers$]).pipe(
map(([roundStudents, sessionStudents, allInteractions, roundFlowerNames]) =>
roundStudents.map(roundStudent => {
const matchingSessionStudent = sessionStudents.find(sessionStudent => sessionStudent.id === roundStudent.id);
const studentBee: BeeSpecies = allBeeSpecies[roundStudent.beeSpecies];
const matchingInteractions: Interaction[] = allInteractions.filter((interaction) => roundStudent.id === interaction.userId);
const interactionsWithType: InteractionWithType[] = matchingInteractions.map((interaction) => {
const flower: FlowerSpecies = allFlowerSpecies[roundFlowerNames[interaction.barcodeValue]];
return (
interaction.isNest
? ({type: studentBee.nest_type, ...interaction})
: ({type: flower, ...interaction})
);
});
const totalPollen = interactionsWithType.filter(interaction => !interaction.isNest).length;
const lastNestIndex = interactionsWithType.findIndex(interaction => interaction.isNest);
let nestPollen;

if (lastNestIndex === -1) {
nestPollen = 0;
} else {
nestPollen = totalPollen - lastNestIndex;
}
const beePollen = totalPollen - nestPollen;
const roundTestData: RoundTestData = {
name: matchingSessionStudent.name,
bee: studentBee,
interactions: interactionsWithType,
carryingPollen: beePollen,
nestPollen
};
return (roundTestData);
})
)
);

RoundPathFromSession(sessionId: string, roundId: string) {
const roundPath: RoundPath = {sessionId, roundId};
return(roundPath);
}

ngOnInit(): void {
this.activatedRoute.paramMap.subscribe(params => {
this.teacherSessionService.setCurrentSession(params.get('sessionId'));
});
}

}

export interface InteractionWithType extends Interaction {
type: Nest | FlowerSpecies;
}


export interface RoundTestData {
name: string;
bee: BeeSpecies;
interactions: InteractionWithType[];
carryingPollen: number;
nestPollen: number;
}