106 lines
3 KiB
TypeScript
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;
|
|
}
|
|
}
|