Added notifcations subjects

Added small test project
This commit is contained in:
Mathias Beaulieu-Duncan
2019-09-13 09:46:09 -05:00
parent 9ec3000b85
commit 833798d6ad
12 changed files with 206 additions and 556 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@poweredsoft/data",
"version": "0.0.20",
"version": "0.0.21",
"peerDependencies": {
"rxjs": "^6.5.3"
}
+69 -18
View File
@@ -1,22 +1,27 @@
import { Observable, of, Observer, BehaviorSubject } from 'rxjs';
import { Observable, of, Observer, BehaviorSubject, throwError, Subject } from 'rxjs';
import { IDataSource } from './IDataSource';
import { IQueryExecutionResult, IQueryExecutionGroupResult, IFilter, ISort, IAggregate, IGroup, IQueryCriteria } from './models';
import { finalize } from 'rxjs/operators';
import { finalize, catchError, map } from 'rxjs/operators';
import { IDataSourceOptions, IResolveCommandModelEvent } from '../public-api';
import { IDataSourceErrorMessage } from './IDataSourceErrorMessage';
import { IDataSourceValidationError } from './IDataSourceValidationError';
import { IDataSourceError } from './IDataSourceError';
import { IDataSourceNotifyMessage } from './IDataSourceNotifyMessage';
export class DataSource<TModel> implements IDataSource<TModel>
{
data: IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel> = null;
protected _dataSubject: BehaviorSubject<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel>> = new BehaviorSubject(null);
protected _loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject(false);
protected _validationSubject: Subject<IDataSourceValidationError> = new Subject();
protected _notifyMessageSubject: Subject<IDataSourceNotifyMessage> = new Subject();
protected _data$: Observable<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel>>;
protected _loading$: Observable<boolean>;
// TODO: Validation error subject
// TODO: Message error subject
protected _validationError$: Observable<IDataSourceValidationError>;
protected _notifyMessage$: Observable<IDataSourceNotifyMessage>;
public manageNotificationMessage: boolean;
protected _criteria: IQueryCriteria = {
page: null,
@@ -28,23 +33,43 @@ export class DataSource<TModel> implements IDataSource<TModel>
};
get data$() {
if (!this._data$)
this._data$ = this._dataSubject.asObservable();
return this._data$;
}
get loading$() {
if (!this._loading$)
this._loading$ = this._loadingSubject.asObservable();
return this._loading$;
}
get validationError$() {
if (!this._validationError$)
this._validationError$ = this._validationSubject.asObservable();
return this._validationError$;
}
get notifyMessage$() {
if (!this._notifyMessage$)
this._notifyMessage$ = this._notifyMessageSubject.asObservable();
return this._notifyMessage$;
}
constructor(public options: IDataSourceOptions<TModel>) {
this._initCriteria();
this._initSubjectObservables();
}
protected _initCriteria() {
if (!this.options.defaultCriteria)
return;
this.manageNotificationMessage = (null == this.options.manageNotificationMessage || !this.options.manageNotificationMessage) ? false : true;
const copy: IQueryCriteria = JSON.parse(JSON.stringify(this.options.defaultCriteria));
this._criteria.page = copy.page || this._criteria.page;
this._criteria.pageSize = copy.pageSize || this._criteria.pageSize;
@@ -54,13 +79,7 @@ export class DataSource<TModel> implements IDataSource<TModel>
this._criteria.sorts = copy.sorts || this._criteria.sorts;
}
protected _initSubjectObservables() {
this._loading$ = this._loadingSubject.asObservable();
this._data$ = this._dataSubject.asObservable();
}
resolveCommandModelByName<T extends any>(event: IResolveCommandModelEvent<TModel>) : Observable<T> {
if (!this.options.transport.commands.hasOwnProperty(name))
return Observable.throw(`command with name ${name} not found`);
@@ -72,11 +91,33 @@ export class DataSource<TModel> implements IDataSource<TModel>
}
executeCommandByName<TCommand, TResult>(name: string, command: TCommand) : Observable<TResult> {
if (!this.options.transport.commands.hasOwnProperty(name))
return Observable.throw(`command with name ${name} not found`);
return this.options.transport.commands[name].adapter.handle(command);
return this.options.transport.commands[name].adapter.handle(command).pipe(
map(t => {
let message = `{command} was executed successfully..`;
if (!this.manageNotificationMessage)
message = message.replace('{command}', name);
this._notifyMessageSubject.next({
type: 'success',
message: message
});
return t;
}),
catchError((err: IDataSourceError) => {
if (err.type == 'message')
this._notifyMessageSubject.next({
type: 'error',
message: (err as IDataSourceErrorMessage).message
});
else if(err.type == 'validation')
this._validationSubject.next(err as IDataSourceValidationError);
return throwError(err);
})
);
}
private _query() : Observable<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel>> {
@@ -92,10 +133,20 @@ export class DataSource<TModel> implements IDataSource<TModel>
.subscribe(
result => {
this.data = result;
o.next(result);
this._dataSubject.next(this.data);
o.next(result)
this._notifyMessageSubject.next({
message: 'New data has been read succesfully..',
type: 'info'
});
},
err => o.error(err)
err => {
o.error(err);
this._notifyMessageSubject.next({
message: 'Something unexpected as occured during the query',
type: 'error'
});
}
);
});
}
@@ -1,6 +1,8 @@
import { Observable } from "rxjs";
import { ISort, IFilter, IGroup, IAggregate, IQueryExecutionResult, IQueryExecutionGroupResult, IQueryCriteria } from "./models";
import { IResolveCommandModelEvent } from "./IResolveCommandModelEvent";
import { IDataSourceValidationError } from './IDataSourceValidationError';
import { IDataSourceNotifyMessage } from './IDataSourceNotifyMessage';
export interface IDataSource<TModel>
{
@@ -11,6 +13,8 @@ export interface IDataSource<TModel>
data$: Observable<IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel>>;
loading$: Observable<boolean>;
validationError$: Observable<IDataSourceValidationError>;
notifyMessage$: Observable<IDataSourceNotifyMessage>;
data: IQueryExecutionResult<TModel> & IQueryExecutionGroupResult<TModel>;
@@ -0,0 +1,4 @@
export interface IDataSourceError {
type: 'message' | 'validation';
}
@@ -0,0 +1,7 @@
import { IDataSourceError } from './IDataSourceError';
export interface IDataSourceErrorMessage extends IDataSourceError {
message: string;
}
@@ -0,0 +1,4 @@
export interface IDataSourceNotifyMessage {
type: 'warning' | 'info' | 'success' | 'error';
message: string;
}
@@ -6,6 +6,7 @@ import { IQueryCriteria } from "./models";
export interface IDataSourceOptions<TModel> {
transport: IDataSourceTransportOptions<TModel>;
defaultCriteria: IQueryCriteria;
manageNotificationMessage?: boolean;
}
export interface IDataSourceTransportOptions<TModel> {
@@ -0,0 +1,6 @@
import { IDataSourceError } from './IDataSourceError';
export interface IDataSourceValidationError extends IDataSourceError
{
errors: { [field: string]: string[]; }
}
@@ -12,4 +12,7 @@ export * from './lib/IDataSourceQueryAdapterOptions';
export * from './lib/IQueryAdapter';
export * from './lib/IResolveCommandModelEvent';
export * from './lib/IDataSourceCommandAdapterOptions';
export * from './lib/IDataSourceValidationError';
export * from './lib/IDataSourceError';
export * from './lib/IDataSourceErrorMessage';