Skip to content

Commit

Permalink
MB-47270 Upgrade the views page to angular
Browse files Browse the repository at this point in the history
New components added:
 - Codemirror Editor.



Change-Id: Ib886babc780f331052c095b6df86fbd1368f0b1b
Reviewed-on: http://review.couchbase.org/c/ns_server/+/157224
Well-Formed: Build Bot <build@couchbase.com>
Reviewed-by: Raluca Lupu <raluca.lupu@couchbase.com>
Tested-by: Matthew <matthew.dawber@couchbase.com>
  • Loading branch information
Matthew Dawber committed Oct 28, 2021
1 parent 3ab910f commit f8051fe
Show file tree
Hide file tree
Showing 58 changed files with 2,764 additions and 1,774 deletions.
52 changes: 0 additions & 52 deletions priv/public/ui/app/components/directives/mn_filter/mn_filter.js

This file was deleted.

8 changes: 7 additions & 1 deletion priv/public/ui/app/components/mn_tasks_details.js
@@ -1,5 +1,5 @@
/*
Copyright 2015-Present Couchbase, Inc.
Copyright 2021-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
Expand Down Expand Up @@ -63,6 +63,7 @@ function mnTasksDetailsFactory($http, $cacheFactory, mnTasksService) {
rv.tasksRebalance = _.detect(tasks, detectRebalanceTasks);
rv.tasksWarmingUp = _.filter(tasks, detectWarmupTask);
rv.tasksBucketCompaction = _.filter(tasks, detectBucketCompactionTask);
rv.tasksViewCompaction = _.filter(tasks, detectViewCompactionTask);
rv.inRebalance = !!(rv.tasksRebalance && rv.tasksRebalance.status === "running");
rv.inRecoveryMode = !!rv.tasksRecovery;
rv.isLoadingSamples = !!_.detect(tasks, detectLoadingSamples);
Expand All @@ -78,6 +79,7 @@ function mnTasksDetailsFactory($http, $cacheFactory, mnTasksService) {
mnTasksService.stream.tasksXDCRPlug.next(rv.tasksXDCR);
mnTasksService.stream.tasksWarmingUpPlug.next(rv.tasksWarmingUp);
mnTasksService.stream.tasksBucketCompactionPlug.next(rv.tasksBucketCompaction);
mnTasksService.stream.tasksViewCompactionPlug.next(rv.tasksBucketCompaction);

let noCollectInfoTask = {
nodesByStatus: {},
Expand Down Expand Up @@ -123,6 +125,10 @@ function mnTasksDetailsFactory($http, $cacheFactory, mnTasksService) {
return taskInfo.type === 'bucket_compaction';
}

function detectViewCompactionTask(taskInfo) {
return taskInfo.type === 'view_compaction';
}

function clearCache() {
$cacheFactory.get('$http').remove('/pools/default/tasks');
return this;
Expand Down
8 changes: 7 additions & 1 deletion priv/public/ui/app/mn.admin.service.js
Expand Up @@ -11,7 +11,8 @@ import {Injectable} from '@angular/core';

import {BehaviorSubject, combineLatest} from 'rxjs';
import {pluck, switchMap, shareReplay, map,
distinctUntilChanged, withLatestFrom} from 'rxjs/operators';
distinctUntilChanged, withLatestFrom,
filter} from 'rxjs/operators';
import {HttpClient, HttpParams} from '@angular/common/http';
import * as R from 'ramda';

Expand Down Expand Up @@ -137,6 +138,11 @@ class MnAdminService {
this.stream.thisNode =
this.stream.getPoolsDefault.pipe(pluck("nodes"),
map(R.find(R.propEq('thisNode', true))));

this.stream.capiBase = this.stream.thisNode
.pipe(filter(node => node != undefined),
map(node => node.addressFamily == 'inet6' ? node.couchApiBaseHTTPS : node.couchApiBase));

this.stream.memoryQuotas =
this.stream.getPoolsDefault.pipe(
withLatestFrom(mnPoolsService.stream.quotaServices),
Expand Down
2 changes: 1 addition & 1 deletion priv/public/ui/app/mn.app.imports.js
Expand Up @@ -107,7 +107,7 @@ let gsiState = {
let viewsState = {
name: "app.admin.views.**",
url: "/views",
lazyLoad: mnLazyload(() => import('./mn_admin/mn_views_controller.js'), "mnViews")
lazyLoad: mnLoadNgModule('./mn.views.module.js', "MnViewsModule")
};

let settingsState = {
Expand Down
8 changes: 8 additions & 0 deletions priv/public/ui/app/mn.app.module.js
Expand Up @@ -48,6 +48,10 @@ import {MnStatsService} from './mn.stats.service.js';
import {MnSettingsAlertsService} from './mn.settings.alerts.service.js';
import {MnLogsListService} from './mn.logs.list.service.js';
import {MnSessionService} from './mn.session.service.js';
import {MnViewsListService} from './mn.views.list.service.js';
import {MnViewsEditingService} from './mn.views.editing.service.js';
import {MnRouterService} from './mn.router.service.js';
import {MnDocumentsService} from './mn.documents.service.js';


export {MnAppModule};
Expand Down Expand Up @@ -94,6 +98,10 @@ class MnAppModule {
MnSettingsAlertsService,
MnLogsListService,
MnSessionService,
MnViewsListService,
MnViewsEditingService,
MnRouterService,
MnDocumentsService,
{
provide: HTTP_INTERCEPTORS,
useClass: MnHttpInterceptor,
Expand Down
2 changes: 1 addition & 1 deletion priv/public/ui/app/mn.app.service.js
Expand Up @@ -2,7 +2,7 @@
Copyright 2020-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
Expand Down
3 changes: 2 additions & 1 deletion priv/public/ui/app/mn.bucket.delete.dialog.component.js
Expand Up @@ -36,10 +36,11 @@ class MnBucketDeleteDialogComponent extends MnLifeCycleHooksToStream {
MnBucketsService
]}

constructor(activeModal, mnFormService, mnBucketsService) {
constructor(activeModal, mnFormService, mnBucketsService, uiRouter) {
super();

this.activeModal = activeModal;
this.uiRouter = uiRouter;

this.form = mnFormService.create(this)
.setFormGroup({})
Expand Down
8 changes: 7 additions & 1 deletion priv/public/ui/app/mn.buckets.service.js
Expand Up @@ -9,11 +9,12 @@ licenses/APL2.txt.
*/
import {Injectable} from '@angular/core';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

import {HttpClient, HttpParams} from '@angular/common/http';
import {pluck, switchMap, shareReplay,
distinctUntilChanged, map, withLatestFrom} from 'rxjs/operators';
import {BehaviorSubject, timer, combineLatest} from 'rxjs';
import {filter, anyPass, propEq} from 'ramda';
import {filter, anyPass, allPass, propEq} from 'ramda';

import {singletonGuard} from './mn.core.js'
import {MnAdminService} from './mn.admin.service.js';
Expand Down Expand Up @@ -65,6 +66,11 @@ class MnBucketsService {
}, {})),
shareReplay({refCount: true, bufferSize: 1}));

this.stream.bucketsMembaseCouchstore = this.stream.getBuckets
.pipe(map(filter(allPass([propEq('bucketType', 'membase'),
propEq('storageBackend', 'couchstore')]))),
shareReplay({refCount: true, bufferSize: 1}));

this.stream.bucketsMembaseEphemeral = this.stream.getBuckets
.pipe(map(filter(anyPass([propEq('bucketType', 'membase'),
propEq('bucketType', 'ephemeral')]))),
Expand Down
74 changes: 74 additions & 0 deletions priv/public/ui/app/mn.codemirror.editor.component.js
@@ -0,0 +1,74 @@
/*
Copyright 2021-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
*/

import { Component, ChangeDetectionStrategy, ViewChild } from '@angular/core';
import { MnLifeCycleHooksToStream } from './mn.core.js';
import { MnHelperService } from './mn.helper.service.js';
import '../libs/codemirror.javascript.js';

export { MnCodeMirrorEditorComponent };

class MnCodeMirrorEditorComponent extends MnLifeCycleHooksToStream {
static get annotations() { return [
new Component({
selector: "mn-codemirror-editor",
templateUrl: "app/mn.codemirror.editor.html",
changeDetection: ChangeDetectionStrategy.OnPush,
queries: {
editor: new ViewChild('editor')
},
inputs: ['mnText', 'mnReadOnly', 'mnControl']
})
]}

static get parameters() { return [
MnHelperService
]}

constructor(mnHelperService) {
super();

this.mnHelperService = mnHelperService;
}

/* Instantiate an instance of codeMirror, default options passed in as a second argument.
mnText input is set as the default text value. */
ngOnInit() {
this.codeMirror = this.mnHelperService.createCodeMirror(this.editor.nativeElement, {
lineNumbers: true,
lineWrapping: true,
matchBrackets: true,
tabSize: 2,
mode: { name: "javascript", json: true },
readOnly: this.mnReadOnly || false
});

this.codeMirror.instance.setValue(this.mnText || "");

if (this.mnControl) {
this.codeMirror.onChange.subscribe(val => {
let text = this.getValue(val);
this.mnControl.patchValue(text);
});
}
}

/* Useful for setting the input if it changes from the parent component. */
ngOnChanges() {
if (this.codeMirror) {
this.codeMirror.instance.setValue(this.mnText);
}
}

getValue(event) {
return event[0].getValue();
}
}

10 changes: 10 additions & 0 deletions priv/public/ui/app/mn.codemirror.editor.html
@@ -0,0 +1,10 @@
<!--
Copyright 2021-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
-->

<textarea #editor></textarea>
27 changes: 27 additions & 0 deletions priv/public/ui/app/mn.codemirror.editor.module.js
@@ -0,0 +1,27 @@
/*
Copyright 2021-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
*/

import { NgModule } from '@angular/core';
import { MnCodeMirrorEditorComponent } from './mn.codemirror.editor.component.js';

export { MnCodeMirrorEditorModule };

class MnCodeMirrorEditorModule {
static get annotations() { return [
new NgModule({
declarations: [
MnCodeMirrorEditorComponent,
],
exports: [
MnCodeMirrorEditorComponent
]
})
]}
}
83 changes: 83 additions & 0 deletions priv/public/ui/app/mn.documents.service.js
@@ -0,0 +1,83 @@
/*
Copyright 2021-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
*/

import { Injectable } from "/ui/web_modules/@angular/core.js";
import { HttpClient } from '/ui/web_modules/@angular/common/http.js';
import { UIRouter } from '/ui/web_modules/@uirouter/angular.js';
import { switchMap, shareReplay, pluck, withLatestFrom,
combineLatest, distinctUntilChanged } from '../web_modules/rxjs/operators.js';
import { Subject, BehaviorSubject } from '../web_modules/rxjs.js';

export { MnDocumentsService }

class MnDocumentsService {
static get annotations() { return [
new Injectable()
]}

static get parameters() { return [
HttpClient,
UIRouter
]}

constructor(http, uiRouter) {
this.http = http;
this.stream = {};

this.stream.recalculateRandomDocument = new BehaviorSubject();
this.stream.getManualDocument = new Subject();

this.commonBucket = uiRouter.globals.params$
.pipe(pluck('commonBucket'),
distinctUntilChanged());

this.stream.getDocuments = new BehaviorSubject()
.pipe(switchMap(this.getDocuments.bind(this)),
shareReplay({refCount: true, bufferSize: 1}));

this.stream.getDocument = this.stream.getManualDocument
.pipe(switchMap(this.getDocument.bind(this)),
shareReplay({refCount: true, bufferSize: 1}));

this.stream.getRandomDocument =
this.stream.recalculateRandomDocument
.pipe(combineLatest(this.commonBucket),
pluck(1),
switchMap(this.getRandomKey.bind(this)),
pluck('key'),
withLatestFrom(this.commonBucket),
switchMap(this.getDocument.bind(this)),
shareReplay({ bufferSize: 1, refCount: true }));
}

getDocumentsURI(params) {
let bucket = params.bucket || params.commonBucket;
let base = "/pools/default/buckets/" + encodeURIComponent(bucket);

return base + "/docs";
}

buildDocumentUrl(params) {
return this.getDocumentsURI(params) + '/' + encodeURIComponent(params.documentId);
}

getDocument([key, bucket]) {
let params = { bucket, documentId: key}
return this.http.get(this.buildDocumentUrl(params));
}

getDocuments(params) {
return this.http.get(this.getDocumentsURI(params));
}

getRandomKey(bucket) {
return this.http.get(`/pools/default/buckets/${encodeURIComponent(bucket)}/localRandomKey`);
}
}

0 comments on commit f8051fe

Please sign in to comment.