Skip to content
Open
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,9 +2,9 @@ <h2 mat-dialog-title align="center">Add Evidence</h2>

<mat-dialog-content class="config-content">
<app-team-selector
[allTeams]="allTeams"
[(selectedTeams)]="selectedTeams"
[teamGroups]="teamGroups"
[allTeams]="teamSelection.allTeams()"
[selectedTeams]="selectedTeams"
[teamGroups]="teamSelection.teamGroups()"
(selectedTeamsChange)="onSelectedTeamsChange($event)"
[type]="'add-evidence-config'">
</app-team-selector>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, inject, ChangeDetectionStrategy } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
import { EvidenceEntry, EvidenceStore } from '../../model/evidence-store';
import { TeamGroups } from '../../model/types';
import { TeamSelectionService } from '../../service/team-selection.service';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatButtonModule } from '@angular/material/button';
Expand All @@ -16,8 +16,6 @@ import { TeamSelectorComponent } from '../team-selector/team-selector.component'

export interface AddEvidenceModalData {
activityUuid: string;
allTeams: string[];
teamGroups: TeamGroups;
}

@Component({
Expand All @@ -42,10 +40,9 @@ export interface AddEvidenceModalData {
export class AddEvidenceModalComponent {
dialogRef = inject<MatDialogRef<AddEvidenceModalComponent>>(MatDialogRef);
data = inject<AddEvidenceModalData>(MAT_DIALOG_DATA);
readonly teamSelection = inject(TeamSelectionService);

activityUuid: string;
allTeams: string[];
teamGroups: TeamGroups;

// Form fields
selectedTeams: string[] = [];
Expand All @@ -66,8 +63,7 @@ export class AddEvidenceModalComponent {
const data = this.data;

this.activityUuid = data.activityUuid;
this.allTeams = data.allTeams;
this.teamGroups = data.teamGroups || {};
this.selectedTeams = [...this.teamSelection.effectiveTeams()];
}

onSelectedTeamsChange(teams: string[]): void {
Expand Down
5 changes: 5 additions & 0 deletions src/app/component/evidence-panel/evidence-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@angular/core';
import { EvidenceEntry } from '../../model/evidence-store';
import { LoaderService } from '../../service/loader/data-loader.service';
import { TeamSelectionService } from '../../service/team-selection.service';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { DatePipe } from '@angular/common';
Expand All @@ -21,6 +22,7 @@ import { DatePipe } from '@angular/common';
})
export class EvidencePanelComponent implements OnChanges {
private loader = inject(LoaderService);
private teamSelection = inject(TeamSelectionService);

@Input() activityUuid: string = '';
@Input() expanded: boolean = false;
Expand Down Expand Up @@ -53,9 +55,12 @@ export class EvidencePanelComponent implements OnChanges {

this.evidenceEntries = evidenceStore.getEvidence(this.activityUuid);

const effectiveTeams = new Set(this.teamSelection.effectiveTeams());

// Group evidence entries by team name
for (const entry of this.evidenceEntries) {
for (const teamName of entry.teams) {
if (!effectiveTeams.has(teamName)) continue;
if (!this.evidenceByTeam.has(teamName)) {
this.evidenceByTeam.set(teamName, []);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,10 @@ <h3>Individual Activities</h3>
<!-- Teams -->
<app-team-selector
[allTeams]="allTeams"
[selectedTeams]="config().selectedTeams"
(selectedTeamsChange)="onTeamsChanged($event)"
[teamGroups]="teamGroups"></app-team-selector>
[selectedTeams]="selectedTeams"
(selectedTeamsChange)="onSelectedTeamsChange($event)"
[teamGroups]="teamGroups">
</app-team-selector>

<mat-divider></mat-divider>
</mat-dialog-content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle';

export interface ReportConfigModalData {
config: ReportConfig;
selectedTeams: string[];
allActivities: Activity[];
allTeams: string[];
allDimensions: string[];
Expand All @@ -31,6 +32,11 @@ export interface ReportConfigModalData {
teamGroups: TeamGroups;
}

export interface ReportConfigModalResult {
config: ReportConfig;
selectedTeams: string[];
}

@Component({
selector: 'app-report-config-modal',
templateUrl: './report-config-modal.component.html',
Expand All @@ -57,11 +63,12 @@ export class ReportConfigModalComponent {

config = signal<ReportConfig>(JSON.parse(JSON.stringify({})));
allActivities: Activity[];
allTeams: string[];
allTeams: string[] = [];
allDimensions: string[];
allSubdimensions: string[];
allProgressTitles: ProgressTitle[];
teamGroups: TeamGroups;
teamGroups: TeamGroups = {};
selectedTeams: string[] = [];
activitySearchQuery = signal('');
maxWordCap: number = MAX_DESCRIPTION_WORD_CAP;

Expand All @@ -86,11 +93,12 @@ export class ReportConfigModalComponent {
// Deep copy config to avoid mutating the original until save
this.config.set(JSON.parse(JSON.stringify(data.config)));
this.allActivities = data.allActivities;
this.allTeams = data.allTeams;
this.allTeams = [...data.allTeams];
this.allDimensions = data.allDimensions;
this.allSubdimensions = data.allSubdimensions;
this.allProgressTitles = data.allProgressTitles || [];
this.teamGroups = data.teamGroups || {};
this.teamGroups = { ...data.teamGroups };
this.selectedTeams = [...data.selectedTeams];
}

setColumnGrouping(grouping: ColumnGrouping): void {
Expand Down Expand Up @@ -172,13 +180,13 @@ export class ReportConfigModalComponent {
});
}

onTeamsChanged(teams: string[]): void {
this.config.update(c => ({ ...c, selectedTeams: teams }));
onSelectedTeamsChange(teams: string[]): void {
this.selectedTeams = teams;
}

// --- Actions ---
onSave(): void {
this.dialogRef.close(this.config());
this.dialogRef.close({ config: this.config(), selectedTeams: this.selectedTeams });
}

onCancel(): void {
Expand Down
39 changes: 21 additions & 18 deletions src/app/component/team-selector/team-selector.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,45 @@ export class TeamSelectorComponent {

@Output() selectedTeamsChange = new EventEmitter<string[]>();

selectedGroupName: string = '';

isTeamSelected(team: string): boolean {
return this.selectedTeams.includes(team);
}

toggleTeam(team: string): void {
const idx = this.selectedTeams.indexOf(team);
if (idx >= 0) {
this.selectedTeams.splice(idx, 1);
const teams = [...this.selectedTeams];
const index = teams.indexOf(team);
if (index >= 0) {
teams.splice(index, 1);
} else {
this.selectedTeams.push(team);
teams.push(team);
}
this.selectedGroupName = '';
this.selectedTeamsChange.emit([...this.selectedTeams]);
this.selectedTeamsChange.emit(teams);
}

selectAllTeams(): void {
this.selectedTeams = [...this.allTeams];
this.selectedGroupName = '';
this.selectedTeamsChange.emit([...this.selectedTeams]);
this.selectedTeamsChange.emit([...this.allTeams]);
}

deselectAllTeams(): void {
this.selectedTeams = [];
this.selectedGroupName = '';
this.selectedTeamsChange.emit([...this.selectedTeams]);
this.selectedTeamsChange.emit([]);
}

get groupNames(): string[] {
return Object.keys(this.teamGroups);
return Object.keys(this.teamGroups).filter(group => this.teamGroups[group].length > 0);
}

selectGroup(group: string): void {
this.selectedTeams = [...(this.teamGroups[group] || [])];
this.selectedGroupName = group;
this.selectedTeamsChange.emit([...this.selectedTeams]);
this.selectedTeamsChange.emit([...(this.teamGroups[group] || [])]);
}

get selectedGroupName(): string {
const selected = new Set(this.selectedTeams);
for (const group of this.groupNames) {
const teams = this.teamGroups[group];
if (teams.length === selected.size && teams.every(team => selected.has(team))) {
return group;
}
}
return '';
}
}
12 changes: 8 additions & 4 deletions src/app/model/report-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export interface ActivityAttributes {
export interface ReportConfig {
columnGrouping: ColumnGrouping;
descriptionWordCap: number;
selectedTeams: string[];
excludedDimensions: string[];
excludedSubdimensions: string[];
excludedActivities: string[];
Expand Down Expand Up @@ -66,7 +65,6 @@ export function getDefaultReportConfig(): ReportConfig {
return {
columnGrouping: 'byProgress',
descriptionWordCap: DEFAULT_DESCRIPTION_WORD_CAP,
selectedTeams: [],
excludedDimensions: [],
excludedSubdimensions: [],
excludedActivities: [],
Expand Down Expand Up @@ -118,15 +116,21 @@ export function getReportConfig(): ReportConfig {
showTags: parsedAttrs.showTags ?? defaultAttrs.showTags,
};

return {
const config: ReportConfig = {
columnGrouping: parsed.columnGrouping ?? defaults.columnGrouping,
descriptionWordCap: parsed.descriptionWordCap ?? defaults.descriptionWordCap,
selectedTeams: parsed.selectedTeams ?? defaults.selectedTeams,
excludedDimensions: parsed.excludedDimensions ?? defaults.excludedDimensions,
excludedSubdimensions: parsed.excludedSubdimensions ?? defaults.excludedSubdimensions,
excludedActivities: parsed.excludedActivities ?? defaults.excludedActivities,
activityAttributes,
};

// Remove the legacy team selection from saved report settings.
if ('selectedTeams' in parsed) {
saveReportConfig(config);
}

return config;
}
} catch (e) {
console.error('Error reading ReportConfig from localStorage:', e);
Expand Down
Loading
Loading