|
|
import Memory = require("dojo/store/Memory");
|
|
|
import Observable = require("dojo/store/Observable");
|
|
|
import { Appointment, Member } from "./Appointment";
|
|
|
import { Contact } from "./Contact";
|
|
|
import { Uuid } from "@implab/core-amd/Uuid";
|
|
|
import { Observable as RxjsObservable } from "rxjs";
|
|
|
import { QueryResultUpdate } from "@implab/djx/tsx";
|
|
|
import {isPromise} from "@implab/core-amd/safe";
|
|
|
|
|
|
type AppointmentRecord = Omit<Appointment, "getMembers"> & {id: string};
|
|
|
|
|
|
type ContactRecord = Contact;
|
|
|
|
|
|
type MemberRecord = Member & { appointmentId: string; };
|
|
|
|
|
|
export interface ObservableResults<T> {
|
|
|
/**
|
|
|
* Allows observation of results
|
|
|
*/
|
|
|
observe(listener: (object: T, previousIndex: number, newIndex: number) => void, includeUpdates?: boolean): {
|
|
|
remove(): void;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
export function isObservable<T>(v: unknown): v is ObservableResults<T> {
|
|
|
return !!v && (typeof (v as {observe?: unknown}).observe === "function");
|
|
|
}
|
|
|
|
|
|
export function observe<T>(results: T[], includeObjectUpdates?: boolean): RxjsObservable<QueryResultUpdate<T>>;
|
|
|
export function observe<T>(results: PromiseLike<T[]>, includeObjectUpdates?: boolean): PromiseLike<RxjsObservable<QueryResultUpdate<T>>>;
|
|
|
export function observe(results: unknown[] | PromiseLike<unknown[]>, includeObjectUpdates = true) {
|
|
|
// results может быть асинхронным, т.е. до завершения
|
|
|
// получения результатов store может быть обновлен. В любом
|
|
|
// случае, если между подключением хотя бы одного наблюдателя
|
|
|
// была выполнена команда обновления, results считается устаревшим
|
|
|
// и не может быть использован для отслеживания обновлений.
|
|
|
// Конкретно с dojo/store/Observable тут вообще возникает проблема:
|
|
|
// 1. Синхронные store типа Memory будут давать ошибку на методах
|
|
|
// обновления (add,put,remove)
|
|
|
// 2. Асинхронные store типа JsonRest будут выдавать предупреждения
|
|
|
// о необработанной ошибке в Promise при обращении к методам
|
|
|
// обновления (add,put,remove)
|
|
|
|
|
|
const _subscribe = (items: unknown[]) => new RxjsObservable<QueryResultUpdate<unknown>>(subscriber => {
|
|
|
items
|
|
|
.forEach((value, newIndex) => subscriber.next({ item: value, newIndex, prevIndex: -1}));
|
|
|
|
|
|
try {
|
|
|
if (isObservable(results)) {
|
|
|
const h = results.observe(
|
|
|
(value, prevIndex, newIndex) => subscriber.next({
|
|
|
item: value,
|
|
|
prevIndex,
|
|
|
newIndex
|
|
|
}),
|
|
|
includeObjectUpdates
|
|
|
);
|
|
|
|
|
|
return () => { h.remove(); };
|
|
|
}
|
|
|
} catch (err) {
|
|
|
subscriber.error(err);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return isPromise(results) ?
|
|
|
results.then(_subscribe) :
|
|
|
_subscribe(results || []);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class MainContext {
|
|
|
private readonly _appointments = new Observable(new Memory<AppointmentRecord>());
|
|
|
|
|
|
private readonly _contacts = new Observable(new Memory<ContactRecord>());
|
|
|
|
|
|
private readonly _members = new Observable(new Memory<MemberRecord>());
|
|
|
|
|
|
createAppointment(title: string, startAt: Date, duration: number, members: Member[]) {
|
|
|
const id = Uuid();
|
|
|
this._appointments.add({
|
|
|
id: Uuid(),
|
|
|
startAt,
|
|
|
duration,
|
|
|
title
|
|
|
});
|
|
|
|
|
|
members.forEach(member =>
|
|
|
this._members.add({
|
|
|
appointmentId: id,
|
|
|
...member
|
|
|
}, {id: Uuid()}) as void
|
|
|
);
|
|
|
}
|
|
|
|
|
|
queryAppointments(dateFrom: Date, dateTo: Date) {
|
|
|
//this._appointments.query().map()
|
|
|
}
|
|
|
|
|
|
private readonly _mapAppointment = ({startAt, title, duration, id}: AppointmentRecord) => ({
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|