anonymous-student
Version:
Anonymous student is used to retrieve and save information from our website users.
160 lines (125 loc) • 4.96 kB
text/typescript
import { DataStorage } from '@studyportals/data-storage';
import { IStudent, StudentField } from '@studyportals/studentdomain';
import merge from 'deepmerge';
import { Actor, AnonymousStudentProfileUpdated, InterestType, StudentRepositoryStateType } from '../../../interfaces';
import { WriteHistoryRecord } from '../../domain/dto/write-history-record';
import { AnonymousStudentEventBroadcaster } from '../anonymous-student-event-broadcaster';
import { StudentClient } from '../interfaces/student-client';
export class LocalStudentClient implements StudentClient {
private storageKeyWriteHistory: string;
// tslint:disable: typedef
constructor(
private storageKey: string,
private storageTTL: number,
private anonymousStudentEventBroadcaster: AnonymousStudentEventBroadcaster | null = null
) {
this.storageKeyWriteHistory = `${storageKey}/WriteHistory`;
}
private localStorage = DataStorage;
public cleanUp(): void {
this.localStorage.remove(this.storageKey);
this.localStorage.remove(this.storageKeyWriteHistory);
}
public async getData(studentFields: StudentField[]): Promise<IStudent> {
const dataFromLocalStorage = this.retrieveDataFromLocalStorage();
const studentData = {};
studentFields.forEach((studentField) => {
const dataField = dataFromLocalStorage[studentField];
if (dataField === undefined) {
return;
}
if (dataField === null) {
studentData[studentField] = undefined;
return;
}
studentData[studentField] = dataField;
});
return studentData;
}
public async setData(studentData: IStudent): Promise<void> {
const dataForLocalStorage = this.retrieveDataFromLocalStorage();
const newStudentData = merge(dataForLocalStorage, studentData, { arrayMerge: this.mergeArraysWithoutDuplicates });
Object.keys(newStudentData).forEach((key) => {
if (newStudentData[key] === null) {
newStudentData[key] = undefined;
}
});
this.setDataInLocalStorage(newStudentData);
this.broadcastChanges(newStudentData);
}
private mergeArraysWithoutDuplicates(destinationArray: number[], sourceArray: number[], options: any): number[] {
return [...new Set([...destinationArray, ...sourceArray])];
}
public async addToCollection(type: StudentField, items: any[]): Promise<void> {
this.addToIdListInLocalStorage(type, items);
}
public async removeFromCollection(type: StudentField, items: any[]): Promise<void> {
this.removeFromIdListInLocalStorage(type, items);
}
public async addToWriteHistory(studentFields: StudentField[], actor: Actor): Promise<void> {
let records: WriteHistoryRecord[] = [];
const jsonRecords = this.localStorage.retrieve(this.storageKeyWriteHistory);
if (jsonRecords) {
records = JSON.parse(jsonRecords);
}
for (const studentField of studentFields) {
const existingRecord = records.find((record) => record.field === studentField);
if (existingRecord) {
existingRecord.actor = actor;
} else {
records.push({
field: studentField,
actor
});
}
}
this.localStorage.store(this.storageKeyWriteHistory, JSON.stringify(records), this.storageTTL);
}
public async getWriteHistory(): Promise<WriteHistoryRecord[]> {
const jsonRecords = this.localStorage.retrieve(this.storageKeyWriteHistory);
if (!jsonRecords) {
return [];
}
return JSON.parse(jsonRecords);
}
private retrieveDataFromLocalStorage() {
const rawData = this.localStorage.retrieve(this.storageKey);
const data = rawData ? JSON.parse(rawData) : {};
return data;
}
private setDataInLocalStorage(data: object): any {
Object.keys(data).forEach((key) => {
if (data[key] === undefined) {
data[key] = null;
}
});
this.localStorage.store(this.storageKey, JSON.stringify(data), this.storageTTL);
}
private addToIdListInLocalStorage(key: StudentField | InterestType, ids: number[]): void {
const dataForLocalStorage = this.retrieveDataFromLocalStorage();
const savedItems = new Set(dataForLocalStorage[key]);
ids.forEach((id) => {
savedItems.add(id);
});
dataForLocalStorage[key] = Array.from(savedItems);
this.setDataInLocalStorage(dataForLocalStorage);
this.broadcastChanges({ [key]: dataForLocalStorage[key] });
}
private removeFromIdListInLocalStorage(key: StudentField | InterestType, ids: number[]): void {
const dataForLocalStorage = this.retrieveDataFromLocalStorage();
const savedItems = new Set(dataForLocalStorage[key]);
ids.forEach((id) => {
savedItems.delete(id);
});
dataForLocalStorage[key] = Array.from(savedItems);
this.setDataInLocalStorage(dataForLocalStorage);
this.broadcastChanges({ [key]: dataForLocalStorage[key] });
}
private broadcastChanges(changes: IStudent) {
if (!this.anonymousStudentEventBroadcaster) {
return;
}
const event = new AnonymousStudentProfileUpdated(new Date(), StudentRepositoryStateType.OFFLINE, changes, true);
this.anonymousStudentEventBroadcaster.broadcastProfileUpdatedEvent(event);
}
}