Skip to content

Commit

Permalink
5710 add breadcrumbs to tasks lists (#7757)
Browse files Browse the repository at this point in the history
This commit adds a third line of text to tasks to display the additional contextual information.
This new line of text should display breadcrumbs showing where the person/place the task is about belongs to.
The functionality should match how we display breadcrumbs elsewhere on the app.
  • Loading branch information
elvisdorkenoo authored Sep 22, 2022
1 parent 6dfc69e commit e0ef002
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 50 deletions.
2 changes: 1 addition & 1 deletion tests/page-objects/tasks/tasks.wdio.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const noSelectedTaskSelector = '.empty-selection';

const tasksList = () => $(taskListSelector);
const getTaskById = (emissionId) => $(`${taskListSelector} li[data-record-id="${emissionId}"`);
const getTasks = () => $$(`${taskListSelector} li`);
const getTasks = () => $$(`${taskListSelector} li.content-row`);

const getTaskInfo = async (taskElement) => {
const contactName = await (await taskElement.$('h4 span')).getText();
Expand Down
1 change: 1 addition & 0 deletions webapp/src/ts/modules/tasks/tasks.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ <h4>
</div>

<div *ngIf="task.priorityLabel" class="warning">{{task.priorityLabel}}</div>
<div *ngIf="task.lineage?.length" class="detail" [innerHTML]="task.lineage | lineage"></div>
</div>
</a>
</li>
Expand Down
124 changes: 86 additions & 38 deletions webapp/src/ts/modules/tasks/tasks.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,25 @@ import { Selectors } from '@mm-selectors/index';
import { TelemetryService } from '@mm-services/telemetry.service';
import { TourService } from '@mm-services/tour.service';
import { GlobalActions } from '@mm-actions/global';
import { LineageModelGeneratorService } from '@mm-services/lineage-model-generator.service';
import { UserContactService } from '@mm-services/user-contact.service';
import { SessionService } from '@mm-services/session.service';

@Component({
templateUrl: './tasks.component.html',
})
export class TasksComponent implements OnInit, OnDestroy {
constructor(
private store:Store,
private changesService:ChangesService,
private contactTypesService:ContactTypesService,
private rulesEngineService:RulesEngineService,
private telemetryService:TelemetryService,
private tourService:TourService,
private route:ActivatedRoute,
private store: Store,
private changesService: ChangesService,
private contactTypesService: ContactTypesService,
private rulesEngineService: RulesEngineService,
private telemetryService: TelemetryService,
private tourService: TourService,
private route: ActivatedRoute,
private lineageModelGeneratorService: LineageModelGeneratorService,
private userContactService: UserContactService,
private sessionService: SessionService,
) {
this.tasksActions = new TasksActions(store);
this.globalActions = new GlobalActions(store);
Expand All @@ -41,6 +47,7 @@ export class TasksComponent implements OnInit, OnDestroy {
hasTasks;
loading;
tasksDisabled;
currentLevel;

private tasksLoaded;
private debouncedReload;
Expand Down Expand Up @@ -97,6 +104,9 @@ export class TasksComponent implements OnInit, OnDestroy {
this.hasTasks = false;
this.loading = true;
this.debouncedReload = _debounce(this.refreshTasks.bind(this), 1000, { maxWait: 10 * 1000 });

this.currentLevel = this.sessionService.isOnlineOnly() ? Promise.resolve() : this.getCurrentLineageLevel();

this.refreshTasks();

this.tourService.startIfNeeded(this.route.snapshot);
Expand Down Expand Up @@ -128,40 +138,78 @@ export class TasksComponent implements OnInit, OnDestroy {
});
}

private refreshTasks() {
const telemetryData:any = {
start: Date.now(),
};

return this.rulesEngineService
.isEnabled()
.then(isEnabled => {
this.tasksDisabled = !isEnabled;
return isEnabled ? this.rulesEngineService.fetchTaskDocsForAllContacts() : [];
})
.then(taskDocs => {
this.hasTasks = taskDocs.length > 0;
this.loading = false;
this.tasksActions.setTasksList(this.hydrateEmissions(taskDocs));
if (!this.tasksLoaded) {
this.tasksActions.setTasksLoaded(true);
}

telemetryData.end = Date.now();
const telemetryEntryName = !this.tasksLoaded ? `tasks:load`: `tasks:refresh`;
this.telemetryService.record(telemetryEntryName, telemetryData.end - telemetryData.start);
})
.catch(err => {
console.error('Error getting tasks for all contacts', err);

this.error = true;
this.loading = false;
this.hasTasks = false;
this.tasksActions.setTasksList([]);
});
private async refreshTasks() {
try {
const telemetryData: any = {
start: Date.now(),
};

const isEnabled = await this.rulesEngineService.isEnabled();
this.tasksDisabled = !isEnabled;
const taskDocs = isEnabled ? await this.rulesEngineService.fetchTaskDocsForAllContacts() : [];

this.hasTasks = taskDocs.length > 0;
this.loading = false;

const hydratedTasks = await this.hydrateEmissions(taskDocs) || [];
const subjects = await this.getLineagesFromTaskDocs(hydratedTasks);
if (subjects?.size) {
const userLineageLevel = await this.currentLevel;
hydratedTasks.forEach(task => {
task.lineage = this.getTaskLineage(subjects, task, userLineageLevel);
});
}

this.tasksActions.setTasksList(hydratedTasks);

if (!this.tasksLoaded) {
this.tasksActions.setTasksLoaded(true);
}

telemetryData.end = Date.now();
const telemetryEntryName = !this.tasksLoaded ? `tasks:load` : `tasks:refresh`;
this.telemetryService.record(telemetryEntryName, telemetryData.end - telemetryData.start);

} catch (exception) {
console.error('Error getting tasks for all contacts', exception);
this.error = true;
this.loading = false;
this.hasTasks = false;
this.tasksActions.setTasksList([]);
}
}

listTrackBy(index, task) {
return task?._id;
}

private getCurrentLineageLevel() {
return this.userContactService.get().then(user => user?.parent?.name);
}

private getLineagesFromTaskDocs(taskDocs) {
const ids = [...new Set(taskDocs.map(task => task.owner))];
return this.lineageModelGeneratorService
.reportSubjects(ids)
.then(subjects => new Map(subjects.map(subject => [subject._id, subject.lineage])));
}

private getTaskLineage(subjects, task, userLineageLevel) {
const lineage = subjects
.get(task.owner)
?.map(lineage => lineage?.name);
return this.cleanAndRemoveCurrentLineage(lineage, userLineageLevel);
}

private cleanAndRemoveCurrentLineage(lineage, userLineageLevel) {
if (!lineage?.length) {
return;
}
lineage = lineage.filter(level => level);
const item = lineage[lineage.length - 1];
if (item === userLineageLevel) {
lineage.pop();
}
return lineage;
}
}
Loading

0 comments on commit e0ef002

Please sign in to comment.