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

Created missing BAW services #227

Merged
merged 31 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1760afa
Created analysis jobs service
Allcharles Apr 26, 2020
9c48e52
Created audio event service
Allcharles Apr 27, 2020
1c4a709
Created audio event comment service
Allcharles Apr 27, 2020
64f16b0
Created bookmark service
Allcharles Apr 27, 2020
458c009
Created saved search service
Allcharles Apr 27, 2020
b944b59
Created studies service
Allcharles Apr 27, 2020
a944dde
Created question services
Allcharles Apr 27, 2020
5fc5253
Created response services
Allcharles Apr 27, 2020
2437c11
Merge branch 'additional-services' into new-services
Allcharles Apr 27, 2020
3f3c9a3
Extracted service tests to folder
Allcharles Apr 27, 2020
9919fb7
Created progress event services
Allcharles Apr 27, 2020
1c8c537
Created dataset services
Allcharles Apr 29, 2020
93f3e69
Cleanup AnalysisJob review comments
Allcharles Apr 29, 2020
23dce4a
Cleanup AnalysisJobItem review comments
Allcharles Apr 29, 2020
0845eea
Cleanup AudioEvent models review comments
Allcharles Apr 29, 2020
78dfd4f
Cleanup AudioRecording review comments
Allcharles Apr 29, 2020
41241be
Cleanup viewUrl review comments
Allcharles Apr 29, 2020
c9d6dfa
Reduce persisted User keys
Allcharles Apr 29, 2020
8e104be
Cleanup missing associations
Allcharles Apr 29, 2020
7e11dad
Cleanup AbstractModel test files
Allcharles Apr 29, 2020
a8d8b91
Convert model attributes to symbol
Allcharles Apr 29, 2020
cf246c7
Default account associations
Allcharles Apr 29, 2020
528ceb3
Created audio recording service
Allcharles Apr 29, 2020
f1591f7
Cleanup service declarations
Allcharles Apr 29, 2020
4d60cad
Created tagging service
Allcharles Apr 29, 2020
af3947b
Created audio event tags service
Allcharles Apr 30, 2020
d4f2bc4
Created AnalysisJobItem service
Allcharles Apr 30, 2020
d87a7e5
Added model injectors
Allcharles Apr 30, 2020
ad8dcb5
Cleanup review comments
Allcharles May 5, 2020
c75ba90
Fix remaining review comments
Allcharles May 5, 2020
75f5290
Merge branch 'master' into new-services
Allcharles May 5, 2020
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
607 changes: 5 additions & 602 deletions src/app/models/AbstractModel.spec.ts

Large diffs are not rendered by default.

50 changes: 40 additions & 10 deletions src/app/models/AbstractModel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injector, Optional } from "@angular/core";
import { ApiFilter, ApiShow, IdOr } from "@baw-api/api-common";
import { ServiceToken } from "@baw-api/ServiceTokens";
import { ACCOUNT, ServiceToken } from "@baw-api/ServiceTokens";
import { DateTime, Duration } from "luxon";
import { BehaviorSubject, Observable, of } from "rxjs";
import { map } from "rxjs/operators";
Expand All @@ -20,6 +20,13 @@ export abstract class AbstractModel {
*/
private static metaKey = Symbol("meta");

/**
* Hidden attributes symbol.
* This stores the list of model attributes which are used to
* generate the toJSON() output.
*/
public static attributeKey = Symbol("meta");

/**
* Model ID
*/
Expand All @@ -30,11 +37,6 @@ export abstract class AbstractModel {
*/
public readonly kind: string;

/**
* Model attributes. This is used to generate the toJSON() output of the model.
*/
private _attributes: string[];

/**
* Redirect path to view model on website. This is a string which can be
* used by `Router.navigateByUrl()` without any processing. For example,
Expand All @@ -57,7 +59,7 @@ export abstract class AbstractModel {
*/
public toJSON() {
const output = {};
this._attributes.forEach((attribute) => {
this[AbstractModel.attributeKey].forEach((attribute) => {
const value = this[attribute];
if (value instanceof Set) {
output[attribute] = Array.from(value);
Expand Down Expand Up @@ -88,6 +90,34 @@ export abstract class AbstractModel {
}
}

/**
* Creates an association between the ownerId and its user model
*/
export function Owner<M extends AbstractModel & { ownerId?: Id }>() {
return HasOne(ACCOUNT, (m: M) => m.ownerId);
}

/**
* Creates an association between the creatorId and its user model
*/
export function Creator<M extends AbstractModel & { creatorId?: Id }>() {
return HasOne(ACCOUNT, (m: M) => m.creatorId);
}

/**
* Creates an association between the updaterId and its user model
*/
export function Updater<M extends AbstractModel & { updaterId?: Id }>() {
return HasOne(ACCOUNT, (m: M) => m.updaterId);
}

/**
* Creates an association between the deleterId and its user model
*/
export function Deleter<M extends AbstractModel & { deleterId?: Id }>() {
return HasOne(ACCOUNT, (m: M) => m.deleterId);
}

/**
* Associate models with list of IDs
* @param serviceToken Injection token for API Service
Expand Down Expand Up @@ -243,11 +273,11 @@ function createModelDecorator<S>(
* Add key to the models attributes
*/
export function BawPersistAttr(model: AbstractModel, key: string) {
if (!model["_attributes"]) {
model["_attributes"] = [];
if (!model[AbstractModel.attributeKey]) {
model[AbstractModel.attributeKey] = [];
}

model["_attributes"].push(key);
model[AbstractModel.attributeKey].push(key);
}

/**
Expand Down
44 changes: 26 additions & 18 deletions src/app/models/AnalysisJob.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ACCOUNT, SCRIPT } from "@baw-api/ServiceTokens";
import { Injector } from "@angular/core";
import { SAVED_SEARCH, SCRIPT } from "@baw-api/ServiceTokens";
import { Duration } from "luxon";
import { Observable } from "rxjs";
import {
Expand All @@ -12,8 +13,12 @@ import {
BawDateTime,
BawDuration,
BawPersistAttr,
Creator,
Deleter,
HasOne,
Updater,
} from "./AbstractModel";
import type { SavedSearch } from "./SavedSearch";
import type { Script } from "./Script";
import type { User } from "./User";

Expand All @@ -24,7 +29,7 @@ export interface IAnalysisJob {
id?: Id;
name?: Param;
annotationName?: string;
customSettings?: Blob | any;
customSettings?: Blob;
scriptId?: Id;
creatorId?: Id;
updaterId?: Id;
Expand All @@ -37,7 +42,7 @@ export interface IAnalysisJob {
startedAt?: DateTimeTimezone | string;
overallStatus?: Status;
overallStatusModifiedAt?: DateTimeTimezone | string;
overallProgress?: Blob | any;
overallProgress?: object;
overallProgressModifiedAt?: DateTimeTimezone | string;
overallCount?: number;
overallDurationSeconds?: number;
Expand Down Expand Up @@ -72,7 +77,7 @@ export class AnalysisJob extends AbstractModel implements IAnalysisJob {
public readonly overallStatus?: Status;
@BawDateTime()
public readonly overallStatusModifiedAt?: DateTimeTimezone;
public readonly overallProgress?: Blob;
public readonly overallProgress?: object;
@BawDateTime()
public readonly overallProgressModifiedAt?: DateTimeTimezone;
public readonly overallCount?: number;
Expand All @@ -82,27 +87,30 @@ export class AnalysisJob extends AbstractModel implements IAnalysisJob {
public readonly overallDataLengthBytes?: number;

// Associations
@HasOne(SCRIPT, (m: AnalysisJob) => m.scriptId)
public script?: Observable<Script>;
@HasOne(ACCOUNT, (m: AnalysisJob) => m.creatorId)
@Creator<AnalysisJob>()
public creator?: Observable<User>;
@HasOne(ACCOUNT, (m: AnalysisJob) => m.updaterId)
@Updater<AnalysisJob>()
public updater?: Observable<User>;
@HasOne(ACCOUNT, (m: AnalysisJob) => m.deleterId)
@Deleter<AnalysisJob>()
public deleter?: Observable<User>;
// TODO Add SavedSearch Association

constructor(analysisJob: IAnalysisJob) {
super(analysisJob);
@HasOne(SCRIPT, (m: AnalysisJob) => m.scriptId)
public script?: Observable<Script>;
@HasOne(SAVED_SEARCH, (m: AnalysisJob) => m.savedSearchId)
public savedSearch?: Observable<SavedSearch>;

this.customSettings = new Blob([analysisJob.customSettings]);
this.overallProgress = new Blob([analysisJob.overallProgress]);
constructor(analysisJob: IAnalysisJob, injector?: Injector) {
super(analysisJob, injector);
}

public get viewUrl(): string {
return "/BROKEN_LINK";
throw new Error("AnalysisJob viewUrl not implemented.");
}
}

// TODO
type Status = "??? Anthony";
type Status =
| "before_save"
| "new"
| "preparing"
| "processing"
| "suspended"
| "completed";
35 changes: 23 additions & 12 deletions src/app/models/AnalysisJobItem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Injector } from "@angular/core";
import { ANALYSIS_JOB, AUDIO_RECORDING } from "@baw-api/ServiceTokens";
import { DateTimeTimezone, Id } from "@interfaces/apiInterfaces";
import { AbstractModel, BawDateTime, BawPersistAttr } from "./AbstractModel";
import { Observable } from "rxjs";
import { AbstractModel, BawDateTime, HasOne } from "./AbstractModel";
import type { AnalysisJob } from "./AnalysisJob";
import type { AudioRecording } from "./AudioRecording";

export interface IAnalysisJobItem {
id?: Id;
Expand All @@ -11,18 +16,14 @@ export interface IAnalysisJobItem {
queuedAt?: DateTimeTimezone | string;
workStartedAt?: DateTimeTimezone | string;
completedAt?: DateTimeTimezone | string;
cancelStartedAt?: DateTimeTimezone | String;
cancelStartedAt?: DateTimeTimezone | string;
}

export class AnalysisJobItem extends AbstractModel implements IAnalysisJobItem {
public readonly kind: "AnalysisJobItem" = "AnalysisJobItem";
@BawPersistAttr
public readonly id?: Id;
@BawPersistAttr
public readonly analysisJobId?: Id;
@BawPersistAttr
public readonly audioRecordingId?: Id;
@BawPersistAttr
public readonly queueId?: string;
public readonly status?: Status;
@BawDateTime()
Expand All @@ -37,16 +38,26 @@ export class AnalysisJobItem extends AbstractModel implements IAnalysisJobItem {
public readonly cancelStartedAt?: DateTimeTimezone;

// Associations
// TODO Add AnalysisJob, AudioRecording, Queue associations
@HasOne(ANALYSIS_JOB, (m: AnalysisJobItem) => m.analysisJobId)
public analysisJob?: Observable<AnalysisJob>;
@HasOne(AUDIO_RECORDING, (m: AnalysisJobItem) => m.audioRecordingId)
public audioRecording?: Observable<AudioRecording>;

constructor(analysisJobItem: IAnalysisJobItem) {
super(analysisJobItem);
constructor(analysisJobItem: IAnalysisJobItem, injector?: Injector) {
super(analysisJobItem, injector);
}

public get viewUrl(): string {
return "/BROKEN_LINK";
throw new Error("AnalysisJobItem viewUrl not implemented.");
}
}

// TODO
export type Status = "new" | "??? Anthony";
export type Status =
| "successful"
| "new"
| "queued"
| "working"
| "failed"
| "timed_out"
| "cancelling"
| "cancelled";
Loading