Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
@use '@angular/material' as mat;

@mixin color($theme) {
.job-name, .loi-name {
.job-name, .loi-name, .loi-submission-count {
color: mat.get-theme-color($theme, on-surface-variant);
}

.loi-submission-count.empty {
color: mat.get-theme-color($theme, neutral-variant, 50);
}

.tree-node-selected {
background-color: rgba(mat.get-theme-color($theme, on-surface), 0.12);

Expand Down Expand Up @@ -35,6 +39,10 @@
font: mat.get-theme-typography($theme, label-large, font);
}

.loi-submission-count {
font: mat.get-theme-typography($theme, label-small, font);
}

.loi-tree-node.tree-node-selected .loi-name {
font-weight: 700;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
<mat-icon svgIcon="{{ node.iconName }}" class="loi-icon" [ngStyle]="{color: node.iconColor}"></mat-icon>

<div class="loi-name">{{ node.name }}</div>

<div
class="loi-submission-count"
[class.empty]="!node.loi?.submissionCount"
>
{{ node.loi?.submissionCount ?? 0 }}
</div>
</ng-container>

<ng-container *ngIf="!isSidePanelExpanded()">
Expand All @@ -56,7 +63,7 @@
</ng-container>

<ng-container *ngIf="!hasChild(node)">
<div style="width: 40px; visibility: hidden;"></div>
<div style="width: 40px; visibility: hidden"></div>
</ng-container>

<div class="job-tree-node-label">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@
white-space: normal;
word-wrap: break-word;
}

.loi-submission-count {
flex-shrink: 0;
padding: 0 16px;
min-width: 48px;
text-align: right;
font-variant-numeric: tabular-nums;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,21 @@ describe('JobListItemComponent', () => {

const surveyId = 'survey1';

function createLois(count: number): List<LocationOfInterest> {
function createLois(
count: number,
submissionCounts: number[] = []
): List<LocationOfInterest> {
const lois: LocationOfInterest[] = [];
for (let i = 0; i < count; i++) {
lois.push(
new LocationOfInterest(
/* id= */ 'loi' + i,
/* jobId= */ job.id,
/* geometry= */ new Point(new Coordinate(1.23, 4.56)),
/* properties= */ Map()
/* properties= */ Map(),
/* customId= */ '',
/* predefined= */ true,
/* submissionCount= */ submissionCounts[i] ?? 0
)
);
}
Expand Down Expand Up @@ -209,6 +215,31 @@ describe('JobListItemComponent', () => {
expect((await jobTree.getNodes()).length).toBe(4);
});

it('should render submission counts for each LOI', async () => {
navigationServiceSpy.getSidePanelExpanded.and.returnValue(true);
fixture.detectChanges();

fixture.componentRef.setInput('lois', createLois(3, [0, 4, 12]));
fixture.detectChanges();

const jobTree = await loader.getHarness(MatTreeHarness);
const jobNode = (await jobTree.getNodes())[0];
await jobNode.expand();
fixture.detectChanges();
await fixture.whenStable();

const counts = fixture.nativeElement.querySelectorAll(
'.loi-submission-count'
);
expect(counts.length).toBe(3);
expect(counts[0].textContent.trim()).toBe('0');
expect(counts[0].classList).toContain('empty');
expect(counts[1].textContent.trim()).toBe('4');
expect(counts[1].classList).not.toContain('empty');
expect(counts[2].textContent.trim()).toBe('12');
expect(counts[2].classList).not.toContain('empty');
});

it('should select LOI when LOI is clicked', async () => {
const jobTree = await loader.getHarness(MatTreeHarness);
const jobNode = (await jobTree.getNodes())[0];
Expand Down
20 changes: 20 additions & 0 deletions web/src/app/converters/loi-data-converter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@ describe('loiDocToModel', () => {
])
),
},
{
expectation: 'converts submission count when set',
inputId: 'id0',
inputData: {
[lo.jobId]: 'jobId0',
[lo.geometry]: geoPointData,
[lo.properties]: {},
[lo.source]: Pb.LocationOfInterest.Source.IMPORTED,
[lo.submissionCount]: 3,
},
want: new LocationOfInterest(
'id0',
'jobId0',
geoPoint,
Map<string, string | number>(),
'',
true,
3
),
},
];

for (const t of testData) {
Expand Down
3 changes: 2 additions & 1 deletion web/src/app/converters/loi-data-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export function loiDocToModel(
geometry,
properties,
pb.customTag,
pb.source === Pb.LocationOfInterest.Source.IMPORTED
pb.source === Pb.LocationOfInterest.Source.IMPORTED,
pb.submissionCount ?? 0
);
} catch (e) {
return new Error(`Invalid LOI data for ${id}`, {cause: e});
Expand Down
3 changes: 2 additions & 1 deletion web/src/app/models/loi.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export class LocationOfInterest {
readonly geometry: Geometry,
readonly properties: Map<string, string | number>,
readonly customId: string = '',
readonly predefined: boolean = true
readonly predefined: boolean = true,
readonly submissionCount: number = 0
) {}

static getSmallestByArea(
Expand Down
Loading