Create db_api service wrapper and OO classes
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
65de891fe8
commit
0378522e9a
@ -41,7 +41,6 @@
|
|||||||
</ion-list>
|
</ion-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer>
|
<ion-footer>
|
||||||
<!-- <ion-searchbar placeholder="Filter pages..." (ionChange)="onFilterChange($event)"></ion-searchbar>-->
|
|
||||||
<ion-item button lines="full" (click)="showOptions($event)">
|
<ion-item button lines="full" (click)="showOptions($event)">
|
||||||
<ion-icon name="list" slot="start"></ion-icon>
|
<ion-icon name="list" slot="start"></ion-icon>
|
||||||
<ion-label>Menu</ion-label>
|
<ion-label>Menu</ion-label>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Component, OnInit, ViewChild, HostListener, Host} from '@angular/core';
|
import {Component, OnInit, ViewChild, HostListener} from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AlertController,
|
AlertController,
|
||||||
@ -144,21 +144,6 @@ export class AppComponent implements OnInit {
|
|||||||
}).then(popover => popover.present());
|
}).then(popover => popover.present());
|
||||||
}
|
}
|
||||||
|
|
||||||
onFilterChange($event) {
|
|
||||||
const query = $event.detail.value.toLowerCase();
|
|
||||||
this.menuTree.treeModel.clearFilter();
|
|
||||||
if ( query ) {
|
|
||||||
this.menuTree.treeModel.filterNodes(node => {
|
|
||||||
if ( node.data.virtual ) {
|
|
||||||
// "Virtual" tree nodes should always be shown
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node.data.name.toLowerCase().indexOf(query) >= 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('document:keyup.control./', ['$event'])
|
@HostListener('document:keyup.control./', ['$event'])
|
||||||
async handleKeyboardEvent() {
|
async handleKeyboardEvent() {
|
||||||
if ( this.hasSearchOpen ) {
|
if ( this.hasSearchOpen ) {
|
||||||
|
@ -285,12 +285,27 @@ export class ApiService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public _build_url(endpoint) {
|
public _build_url(endpoint, base = this.baseEndpoint) {
|
||||||
if ( !endpoint.startsWith('/') ) {
|
if ( !endpoint.startsWith('/') ) {
|
||||||
endpoint = `/${endpoint}`;
|
endpoint = `/${endpoint}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${this.baseEndpoint.endsWith('/') ? this.baseEndpoint.slice(0, -1) : this.baseEndpoint}${endpoint}`;
|
return `${base.endsWith('/') ? base.slice(0, -1) : base}${endpoint}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getToken(): Promise<string> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
if ( this.isOffline ) {
|
||||||
|
return rej(new ResourceNotAvailableOfflineError());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get('token').subscribe({
|
||||||
|
next: response => {
|
||||||
|
return res(response.data);
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async syncOfflineData() {
|
public async syncOfflineData() {
|
||||||
|
139
src/app/service/db-api.service.ts
Normal file
139
src/app/service/db-api.service.ts
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {ApiService} from './api.service';
|
||||||
|
import {Observable} from 'rxjs';
|
||||||
|
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||||
|
import ApiResponse from '../structures/ApiResponse';
|
||||||
|
import {environment} from '../../environments/environment';
|
||||||
|
import {debug} from '../utility';
|
||||||
|
import * as Structures from '../structures/db-api';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class DbApiService {
|
||||||
|
protected token?: string;
|
||||||
|
protected tokenTime?: number;
|
||||||
|
protected databaseBase: string = environment.databaseBase;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected readonly api: ApiService,
|
||||||
|
protected readonly http: HttpClient,
|
||||||
|
) {
|
||||||
|
Structures._setDbApi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getDatabase(databaseId: string): Promise<Structures.Database> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
|
||||||
|
this._authRequest(`/${databaseId}`).subscribe({
|
||||||
|
next: async response => {
|
||||||
|
if ( response.status !== 200 ) {
|
||||||
|
debug('Invalid get database response.', response);
|
||||||
|
return rej(new Error('Invalid database ID.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res(new Structures.Database(response.data));
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getDatabases(): Promise<Structures.Database[]> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
|
||||||
|
this._authRequest('/').subscribe({
|
||||||
|
next: async response => {
|
||||||
|
return res(response.data.map(x => new Structures.Database(x)));
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getColumns(databaseId: string): Promise<Structures.DatabaseColumn[]> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
|
||||||
|
this._authRequest(`${databaseId}/columns`).subscribe({
|
||||||
|
next: async response => {
|
||||||
|
return res(response.data.map(x => new Structures.DatabaseColumn(x)));
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getColumnOrder(databaseId: string): Promise<string[]> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
this._authRequest(`${databaseId}/columns/order`).subscribe({
|
||||||
|
next: async response => {
|
||||||
|
return res(response.data);
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getData(databaseId: string): Promise<Structures.DatabaseRecord[]> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
this._authRequest(`${databaseId}/data`).subscribe({
|
||||||
|
next: async response => {
|
||||||
|
return res(response.data.map(x => new Structures.DatabaseRecord(x)));
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getDataRecord(databaseId: string, recordId: string): Promise<Structures.DatabaseRecord> {
|
||||||
|
return new Promise(async (res, rej) => {
|
||||||
|
this._authRequest(`${databaseId}/record/${recordId}`).subscribe({
|
||||||
|
next: async response => {
|
||||||
|
return res(new Structures.DatabaseRecord(response.data));
|
||||||
|
},
|
||||||
|
error: rej,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected _authRequest(endpoint, params = {}, method: 'get' | 'post' = 'get') {
|
||||||
|
return new Observable<ApiResponse>(sub => {
|
||||||
|
this.getToken().then(token => {
|
||||||
|
const headers = new HttpHeaders({
|
||||||
|
authorization: `bearer ${token}`
|
||||||
|
});
|
||||||
|
|
||||||
|
debug('Auth request headers', headers);
|
||||||
|
|
||||||
|
if ( method === 'get' ) {
|
||||||
|
const data = {
|
||||||
|
params,
|
||||||
|
headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.http.get(this.api._build_url(endpoint, this.databaseBase), data).subscribe({
|
||||||
|
next: (response: any) => {
|
||||||
|
return sub.next(new ApiResponse(response));
|
||||||
|
},
|
||||||
|
error: e => {
|
||||||
|
return sub.error(e);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getToken(): Promise<string> {
|
||||||
|
const now = (new Date()).getTime();
|
||||||
|
|
||||||
|
// 1 hour
|
||||||
|
if ( this.token && this.tokenTime && (now - this.tokenTime) < (60 * 60 * 1000) ) {
|
||||||
|
return this.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.token = await this.api.getToken();
|
||||||
|
this.tokenTime = now;
|
||||||
|
return this.token;
|
||||||
|
}
|
||||||
|
}
|
102
src/app/structures/db-api.ts
Normal file
102
src/app/structures/db-api.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import {DbApiService} from '../service/db-api.service';
|
||||||
|
|
||||||
|
let privDbApi!: DbApiService;
|
||||||
|
export function _setDbApi(dbApi: DbApiService) {
|
||||||
|
privDbApi = dbApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _getDbApi(): DbApiService {
|
||||||
|
return privDbApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Database {
|
||||||
|
public name!: string;
|
||||||
|
public uuid!: string;
|
||||||
|
public pageId!: string;
|
||||||
|
public columnIds: string[] = [];
|
||||||
|
public versionNum?: number;
|
||||||
|
|
||||||
|
static async all() {
|
||||||
|
return _getDbApi().getDatabases();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async one(databaseId: string) {
|
||||||
|
return _getDbApi().getDatabase(databaseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(record?: any) {
|
||||||
|
if ( record ) {
|
||||||
|
this.loadFrom(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFrom(record: any) {
|
||||||
|
this.name = record.name;
|
||||||
|
this.uuid = record.uuid;
|
||||||
|
this.pageId = record.page_id;
|
||||||
|
this.columnIds = record.column_ids;
|
||||||
|
|
||||||
|
if ( record.version_num ) {
|
||||||
|
this.versionNum = record.version_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async columns() {
|
||||||
|
const order = await this.columnOrder();
|
||||||
|
const columns = await _getDbApi().getColumns(this.uuid);
|
||||||
|
|
||||||
|
return order.map(x => columns.find(col => col.uuid === x));
|
||||||
|
}
|
||||||
|
|
||||||
|
async columnOrder() {
|
||||||
|
return _getDbApi().getColumnOrder(this.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
async data() {
|
||||||
|
return _getDbApi().getData(this.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
async record(id: string) {
|
||||||
|
return _getDbApi().getDataRecord(this.uuid, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DatabaseColumn {
|
||||||
|
public name!: string;
|
||||||
|
public databaseId!: string;
|
||||||
|
public uuid!: string;
|
||||||
|
public type!: string;
|
||||||
|
public metadata: any;
|
||||||
|
|
||||||
|
constructor(record?: any) {
|
||||||
|
if ( record ) {
|
||||||
|
this.loadFrom(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFrom(record: any) {
|
||||||
|
this.name = record.name;
|
||||||
|
this.databaseId = record.database_id;
|
||||||
|
this.uuid = record.uuid;
|
||||||
|
this.type = record.type;
|
||||||
|
this.metadata = record.metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DatabaseRecord {
|
||||||
|
public data: any = {};
|
||||||
|
public uuid!: string;
|
||||||
|
public databaseId!: string;
|
||||||
|
|
||||||
|
constructor(record?: any) {
|
||||||
|
if ( record ) {
|
||||||
|
this.loadFrom(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFrom(record: any) {
|
||||||
|
this.data = record.data;
|
||||||
|
this.uuid = record.uuid;
|
||||||
|
this.databaseId = record.database_id;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true,
|
production: true,
|
||||||
backendBase: '/api/v1',
|
backendBase: '/api/v1',
|
||||||
|
databaseBase: '/db_api/v1',
|
||||||
statUrl: '/stat?ngsw-bypass',
|
statUrl: '/stat?ngsw-bypass',
|
||||||
versionUrl: '/i/version.html?ngsw-bypass',
|
versionUrl: '/i/version.html?ngsw-bypass',
|
||||||
outputDebug: false,
|
outputDebug: false,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
backendBase: '/link_api/api/v1',
|
backendBase: '/link_api/api/v1',
|
||||||
|
databaseBase: '/link_api/db_api/v1',
|
||||||
statUrl: '/link_api/stat?ngsw-bypass',
|
statUrl: '/link_api/stat?ngsw-bypass',
|
||||||
versionUrl: '/link_api/assets/version.html?ngsw-bypass',
|
versionUrl: '/link_api/assets/version.html?ngsw-bypass',
|
||||||
outputDebug: true,
|
outputDebug: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user