pinkmine/libs/event-emitter/src/dashboards/dashboards.service.ts

106 lines
3 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { Dashboards as DashboardsDb } from '../couchdb-datasources/dashboards';
import * as DashboardModel from '../models/dashboard';
import nano from 'nano';
import { randomUUID } from 'crypto';
import { createAppError } from '../utils/result';
@Injectable()
export class DashboardsService {
private logger = new Logger(DashboardsService.name);
constructor(private db: DashboardsDb) {}
async create(): Promise<DashboardModel.Dashboard> {
const id = randomUUID();
this.logger.debug(`Create new dashboard with id - ${id}`);
if (await this.isExists(id)) {
const err = createAppError('ALREADY_EXISTS');
this.logger.error(`Error - ${JSON.stringify(err)}`);
throw err;
}
const ds = await this.db.getDatasource();
const doc: nano.MaybeDocument & DashboardModel.Dashboard = {
_id: id,
id: id,
data: null,
};
await ds.insert(doc);
return await ds.get(id);
}
async loadRawData(
id: string,
): Promise<DashboardModel.Dashboard & nano.MaybeDocument> {
this.logger.debug(`Load raw data, dashboard id - ${id}`);
const ds = await this.db.getDatasource();
if (!(await this.isExists(id))) throw createAppError('NOT_EXISTS');
const res = await ds.get(id);
return res;
}
async load(id: string): Promise<DashboardModel.Data> {
this.logger.debug(`Load dashboard id - ${id}`);
const rawData = await this.loadRawData(id);
return rawData?.data || { widgets: [] };
}
async isExists(id: string): Promise<boolean> {
const ds = await this.db.getDatasource();
try {
await ds.get(id);
return true;
} catch (ex) {
return false;
}
}
async save(id: string, data: DashboardModel.Data): Promise<void> {
this.logger.debug(
`Save dashboard id - ${id}, data - ${JSON.stringify(data)}`,
);
const ds = await this.db.getDatasource();
const prevValue = await this.loadRawData(id);
const newValue = {
_id: prevValue._id,
_rev: prevValue._rev,
id: prevValue.id,
data: data,
};
await ds.insert(newValue);
return;
}
async publicList(limit: number): Promise<{ id: string; title: string }[]> {
const ds = await this.db.getDatasource();
const data = await ds.find({
selector: {
'data.title': {
$exists: true,
},
},
fields: ['id', 'data.title'],
limit: limit,
});
if (!data.docs) throw createAppError('DASHBOARDS_NOT_FOUND');
return data.docs.map((d) => ({ id: d.id, title: d.data.title }));
}
async findDashboardsByWidgetType(
widgetType: string,
): Promise<DashboardModel.Dashboard[]> {
const ds = await this.db.getDatasource();
const data = await ds.find({
selector: {
'data.widgets': {
$elemMatch: {
type: widgetType,
},
},
},
});
if (!data.docs) throw createAppError('DASHBOARDS_NOT_FOUND');
return data.docs;
}
}