Commit 1ceb7c6e authored by Moises Sacal's avatar Moises Sacal
Browse files

added check link for issue #17

parent b0803235
This diff is collapsed.
......@@ -124,14 +124,8 @@ export class LabarchivesLinkField extends FieldBase<any> {
<p *ngFor="let item of field.workspaceDefinition">{{ item.label }} :
{{ field.currentWorkspace[item.name]}}</p>
<h5>{{ field.processingLabel }}</h5>
<p>{{ field.processingMessage }}&nbsp;<span
*ngIf="field.checks.master; then isDone; else isSpinning"></span></p>
<p *ngIf="field.checks.comparing">{{ field.comparingLabel }}&nbsp;<span
*ngIf="field.checks.link; then isDone; else isSpinning"></span></p>
<p *ngIf="field.checks.link == false">{{ field.statusLabel }}&nbsp;<span
*ngIf="field.checks.rdmp; then isDone; else isSpinning"></span></p>
<p>{{ field.processingMessage }}&nbsp;</p>
<p class="alert alert-success" *ngIf="field.checks.linkCreated">{{ field.processingSuccess }}</p>
<p class="alert alert-danger" *ngIf="field.checks.linkWithOther">{{ field.processingFail }}</p>
<p class="alert alert-danger" *ngIf="field.processingStatus === 'done' && field.processingFail">
{{ field.processingFail }}</p>
<ng-template #isDone>
......
......@@ -2,6 +2,7 @@ import {Output, EventEmitter, Component, OnInit, Inject, Injector, Input} from '
import {FormGroup, FormControl, Validators, NgForm} from '@angular/forms';
import {SimpleComponent} from '../shared/form/field-simple.component';
import {FieldBase} from '../shared/form/field-base';
import {LabarchivesService} from "../labarchives.service";
export class LabarchivesListField extends FieldBase<any> {
......@@ -12,40 +13,59 @@ export class LabarchivesListField extends FieldBase<any> {
rdmpLinkLabel: string;
loading: boolean;
labUser: any = {};
rdmp: string;
workspaces: any;
linkedLabel: string;
linkedAnotherLabel: string;
linkLabel: string;
linkProblem: string;
@Input() user: any;
@Output() link: EventEmitter<any> = new EventEmitter<any>();
labarchivesService: LabarchivesService;
constructor(options: any, injector: any) {
super(options, injector);
this.labarchivesService = this.getFromInjector(LabarchivesService);
this.columns = [
{'label': 'Name', 'property': 'name'},
{'label': 'Default', 'property': 'isDefault'},
{'label': 'Location', 'property': 'web_url', 'link': 'true'}
{'label': 'Default', 'property': 'isDefault'}
];
this.rdmpLinkLabel = 'Plan';
this.syncLabel = 'Sync';
this.linkedLabel = options['linkedLabel'] || 'Linked';
this.linkedAnotherLabel = options['linkedAnotherLabel'] || 'Linked to another workspace';
this.linkLabel = options['linkLabel'] || 'Link Workspace';
this.linkProblem = options['linkProblem'] || 'There was a problem checking the link';
}
registerEvents() {
this.fieldMap['Login'].field['userLogin'].subscribe(this.listWorkspaces.bind(this));
this.fieldMap['Login'].field['userLogin'].subscribe(this.bindUser.bind(this));
//this.fieldMap['Link'].field['linkItem'].subscribe(this.listWorkspaces.bind(this));
}
listWorkspaces(labUser: any) {
bindUser(labUser: any) {
console.log(labUser);
if (labUser && labUser.notebooks) {
this.workspaces = labUser.notebooks.map((nb) => {
this.labUser = labUser;
this.listWorkspaces();
}
}
listWorkspaces() {
if (this.labUser && this.labUser.notebooks) {
this.workspaces = this.labUser.notebooks.map((nb) => {
const isDefault = nb['isDefault'] ? 'default' : '';
return {
id: nb['id'],
name: nb['name'],
description: isDefault,
web_url: '',
isDefault: isDefault ? 'Default Notebook' : '',
rdmp: {info: ''}
}
});
this.checkLinks();
} else {
this.workspaces = [];
}
......@@ -55,6 +75,29 @@ export class LabarchivesListField extends FieldBase<any> {
this.link.emit(item);
}
checkLinks() {
//this.workspaces[index]['linkedState'] == 'check'; // Possible values: linked, another, link
this.workspaces.map((w, index) => {
this.labarchivesService.checkLink(this.rdmp, w['id'])
.then((response) => {
if (!response.status) {
throw new Error('Error checking workspace');
} else {
const check = response['check'];
console.log(check);
if (check['link'] === 'linked') {
this.workspaces[index]['linkedState'] = 'linked';
} else {
this.workspaces[index]['linkedState'] = 'link';
}
}
})
.catch((error) => {
console.log(error);
this.workspaces[index]['linkedState'] = 'problem';
});
});
}
}
......@@ -63,7 +106,7 @@ export class LabarchivesListField extends FieldBase<any> {
selector: 'ws-labarchiveslist',
template: `
<div class="row">
<div *ngIf="field.workspaces" class="col-lg-10">
<div *ngIf="field.workspaces" class="col-lg-12">
<div class="">
<table class="table">
<thead>
......@@ -87,15 +130,26 @@ export class LabarchivesListField extends FieldBase<any> {
</td>
</ng-container>
<td>
<span *ngIf="item.rdmp.info && item.rdmp.info.rdmp; else isNotLinked ">
<button disabled type="button" class="btn btn-success btn-block"
*ngIf="item.rdmp.info.rdmp === field.rdmp"> Linked </button>
<button disabled type="button" class="btn btn-info btn-block"
*ngIf="item.rdmp.info.rdmp != field.rdmp"> Linked to another RDMP</button>
</span>
<ng-template #isNotLinked>
<button type="button" class="btn btn-info btn-block" (click)="field.linkWorkspace(item)">Link</button>
</ng-template>
<span *ngIf="!item['linkedState']">
<button type="button" disabled class="btn btn-info btn-block" [name]="item['@id']">
<span><i class="fa fa-spinner fa-spin"></i></span></button>
</span>
<span *ngIf="item['linkedState'] === 'linked'">
<button type="button" disabled class="btn btn-success btn-block"
[name]="item['@id']">{{ field.linkedLabel }}</button>
</span>
<span *ngIf="item['linkedState'] === 'another'">
<button type="button" disabled class="btn btn-info btn-block"
[name]="item['@id']">{{ field.linkedAnotherLabel }}</button>
</span>
<span *ngIf="item['linkedState'] === 'link'">
<button type="button" class="btn btn-info btn-block" [name]="item['@id']"
(click)="field.linkWorkspace(item)">{{ field.linkLabel }}</button>
</span>
<span *ngIf="item['linkedState'] === 'problem'">
<button type="button" disabled class="btn btn-warning btn-block"
[name]="item['@id']">{{ field.linkProblem }}</button>
</span>
</td>
</tr>
</tbody>
......@@ -121,4 +175,9 @@ export class LabarchivesListComponent extends SimpleComponent {
ngOnInit() {
this.field.registerEvents();
}
ngAfterContentInit() {
this.field.listWorkspaces();
}
}
......@@ -63,4 +63,18 @@ export class LabarchivesService extends BaseService {
}
}
public async checkLink(rdmpId: string, nbId: string) {
const wsUrl = this.brandingAndPortalUrl + '/ws/labarchives/checkLink';
try {
const result = await this.http.post(
wsUrl,
{rdmp: rdmpId, nbId: nbId},
this.options
).toPromise();
return Promise.resolve(this.extractData(result));
} catch (e) {
return Promise.reject(new Error(e));
}
}
}
......@@ -12,7 +12,8 @@ var Controllers;
super();
this._exportedMethods = [
'login',
'link'
'link',
'checkLink'
];
this.config = new Config_1.Config(sails.config.workspaces);
}
......@@ -30,6 +31,7 @@ var Controllers;
const userInfo = response['users'];
if (userInfo) {
info = new UserInfo_1.UserInfo(userInfo['id'], userInfo['orcid'], userInfo['fullname'], userInfo['notebooks']);
sails.log.debug(info);
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName);
}
else {
......@@ -58,6 +60,30 @@ var Controllers;
this.ajaxFail(req, res, message, { status: false, message: message });
}
}
list(req, res) {
sails.log.debug('list');
const userId = req.user.id;
this.config.brandingAndPortalUrl = BrandingService.getFullPath(req);
let info = {};
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName)
.flatMap(response => {
const user = response['users'] || null;
if (user) {
const userInfo = LabarchivesService.userInfo(this.config.key, user['id']);
return Rx_1.Observable.fromPromise(userInfo);
}
else {
return Rx_1.Observable.throw('');
}
})
.subscribe(response => {
this.ajaxOk(req, res, null, { status: true, labUser: response, message: 'list' });
}, error => {
sails.log.error('list: error');
sails.log.error(error);
this.ajaxFail(req, res, error.message, { status: false, message: error.message });
});
}
link(req, res) {
const userId = req.user.id;
const username = req.user.username;
......@@ -142,6 +168,43 @@ var Controllers;
this.ajaxFail(req, res, error.message, { status: false, message: error.message });
});
}
checkLink(req, res) {
sails.log.debug('checkLink');
const userId = req.user.id;
const username = req.user.username;
const rdmp = req.param('rdmp');
const nbId = req.param('nbId');
const workspace = req.param('workspace');
let info = {};
let check = {
link: ''
};
this.config.brandingAndPortalUrl = BrandingService.getFullPath(req);
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName)
.flatMap(response => {
info = response.info;
const nbTree = LabarchivesService.getNotebookTree(this.config.key, info['id'], nbId, 0);
return Rx_1.Observable.fromPromise(nbTree);
})
.subscribe(response => {
if (response['tree-tools'] && response['tree-tools']['level-nodes']) {
const lvlNodes = response['tree-tools']['level-nodes'];
const nodes = lvlNodes['level-node'];
if (Array.isArray(nodes)) {
nodes.map(node => {
if (node['display-text'] === 'stash.workspace') {
check.link = 'linked';
}
});
}
}
this.ajaxOk(req, res, null, { status: true, check: check, message: 'checkLink' });
}, error => {
sails.log.error('checkLink: error');
sails.log.error(error);
this.ajaxFail(req, res, error.message, { status: false, message: error.message });
});
}
}
Controllers.LabarchivesController = LabarchivesController;
})(Controllers = exports.Controllers || (exports.Controllers = {}));
......
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Rx_1 = require("rxjs/Rx");
const _ = require('lodash');
var Services;
(function (Services) {
var Core;
......@@ -44,26 +45,6 @@ var Services;
}
return exportedMethods;
}
metTriggerCondition(oid, record, options) {
const triggerCondition = _.get(options, "triggerCondition", "");
const forceRun = _.get(options, "forceRun", false);
const variables = {
imports: {
record: record,
oid: oid
}
};
if (!_.isUndefined(triggerCondition) && !_.isEmpty(triggerCondition)) {
const compiled = _.template(triggerCondition, variables);
return compiled();
}
else if (forceRun) {
return "true";
}
else {
return "false";
}
}
}
Core.Service = Service;
})(Core = Services.Core || (Services.Core = {}));
......
......@@ -19,7 +19,9 @@ var Services;
this._exportedMethods = [
'login',
'insertNode',
'addEntry'
'addEntry',
'getNotebookInfo',
'getNotebookTree'
];
this.config = new Config_1.Config(sails.config.workspaces);
}
......@@ -68,6 +70,36 @@ var Services;
}
});
}
getNotebookInfo(key, userId, nbId) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (key && key['akid'] && key['password']) {
return yield la.getNotebookInfo(key, userId, nbId);
}
else {
return Promise.reject(new Error('missing keys for accessing lab archives APIs'));
}
}
catch (e) {
return Promise.reject(new Error(e));
}
});
}
getNotebookTree(key, userId, nbId, treeLevel = 0) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (key && key['akid'] && key['password']) {
return yield la.getTree(key, userId, nbId, treeLevel);
}
else {
return Promise.reject(new Error('missing keys for accessing lab archives APIs'));
}
}
catch (e) {
return Promise.reject(new Error(e));
}
});
}
}
Services.LabarchivesService = LabarchivesService;
})(Services = exports.Services || (exports.Services = {}));
......
......@@ -31,7 +31,7 @@ module.exports = {
appId: 'labarchives',
recordType: 'labarchives',
workspaceFileName: 'README.md',
key: {"akid": "utech_sydney", "password": "***REMOVED***"}
key: {"akid": "utech_sydney", "password": ***REMOVED***}
}
}
};
......@@ -57,8 +57,8 @@ module.exports = function (sails) {
before: {},
after: {
'post /:branding/:portal/ws/labarchives/login': LabarchivesController.login,
'post /:branding/:portal/ws/labarchives/link': LabarchivesController.link
'post /:branding/:portal/ws/labarchives/link': LabarchivesController.link,
'post /:branding/:portal/ws/labarchives/checkLink': LabarchivesController.checkLink
}
},
configure: function () {
......
......@@ -16,6 +16,12 @@
"integrity": "sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==",
"dev": true
},
"@types/node": {
"version": "10.12.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
"dev": true
},
"@uts-eresearch/provision-labarchives": {
"version": "git+https://code.research.uts.edu.au/eresearch/provision-labarchives.git#4ffeaecca42e5af57cc5557fb545818e9c01ef1a",
"requires": {
......
......@@ -24,6 +24,7 @@
"author": "Moises Sacal",
"license": "GPL-3.0",
"devDependencies": {
"@types/node": "^10.12.18",
"@types/lodash": "^4.14.118",
"mocha": "^5.1.1",
"sails": "^1.0.2",
......
{
"compilerOptions": {
"target": "es2015",
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"isolatedModules": false,
......@@ -22,20 +22,23 @@
"node_modules/**",
"typings/browser/**",
"typings/browser.d.ts",
"test/integration/**/*.ts",
"angular/**"
"test/integration/**/*.ts"
],
"include": [
"typescript/**/*.ts"
"typescript/**/*.ts",
"api/**/*.ts",
"core/**/*.ts",
"assets/angular/**/*.ts"
],
"compileOnSave": true,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
},
"paths": {
"lodash/*": [
"node_modules/@types/lodash-es/*"
"typeAcquisition": {
"include": [
"lodash"
]
}
}
......@@ -23,7 +23,8 @@ export module Controllers {
protected _exportedMethods: any = [
'login',
'link'
'link',
'checkLink'
];
_config: any;
......@@ -48,6 +49,7 @@ export module Controllers {
const userInfo = response['users'];
if (userInfo) {
info = new UserInfo(userInfo['id'], userInfo['orcid'], userInfo['fullname'], userInfo['notebooks']);
sails.log.debug(info);
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName);
} else {
console.log(response);
......@@ -77,6 +79,30 @@ export module Controllers {
}
}
list(req, res) {
sails.log.debug('list');
const userId = req.user.id;
this.config.brandingAndPortalUrl = BrandingService.getFullPath(req);
let info = {};
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName)
.flatMap(response => {
const user = response['users'] || null;
if (user) {
const userInfo = LabarchivesService.userInfo(this.config.key, user['id']);
return Observable.fromPromise(userInfo);
} else {
return Observable.throw('');
}
})
.subscribe(response => {
this.ajaxOk(req, res, null, {status: true, labUser: response, message: 'list'});
}, error => {
sails.log.error('list: error');
sails.log.error(error);
this.ajaxFail(req, res, error.message, {status: false, message: error.message});
});
}
link(req, res) {
const userId = req.user.id;
const username = req.user.username;
......@@ -170,7 +196,43 @@ export module Controllers {
});
}
checkLink(req, res) {
sails.log.debug('checkLink');
const userId = req.user.id;
const username = req.user.username;
const rdmp = req.param('rdmp');
const nbId = req.param('nbId');
const workspace = req.param('workspace');
let info = {};
let check = {
link: ''
};
this.config.brandingAndPortalUrl = BrandingService.getFullPath(req);
return WorkspaceService.workspaceAppFromUserId(userId, this.config.appName)
.flatMap(response => {
info = response.info;
const nbTree = LabarchivesService.getNotebookTree(this.config.key, info['id'], nbId, 0);
return Observable.fromPromise(nbTree);
})
.subscribe(response => {
if (response['tree-tools'] && response['tree-tools']['level-nodes']) {
const lvlNodes = response['tree-tools']['level-nodes'];
const nodes = lvlNodes['level-node'];
if (Array.isArray(nodes)) {
nodes.map(node => {
if (node['display-text'] === 'stash.workspace') {
check.link = 'linked';
}
});
}
}
this.ajaxOk(req, res, null, {status: true, check: check, message: 'checkLink'});
}, error => {
sails.log.error('checkLink: error');
sails.log.error(error);
this.ajaxFail(req, res, error.message, {status: false, message: error.message});
});
}
}
}
module.exports = new Controllers.LabarchivesController().exports();
</
declare namespace _ {}
import { Observable } from 'rxjs/Rx';
declare var sails: Sails;
const _ = require('lodash');
export module Services.Core {
export class Service {
......@@ -64,34 +63,5 @@ export module Services.Core {
return exportedMethods;
}
/**
* returns a string that is 'true' or 'false' (literal) depending on whether the 'options.triggerCondition' is met!
*
* @author <a target='_' href='https://github.com/shilob'>Shilo Banihit</a>
* @param oid
* @param record
* @param options
* @return
*/
protected metTriggerCondition(oid, record, options) {
const triggerCondition = _.get(options, "triggerCondition", "");
const forceRun = _.get(options, "forceRun", false);
const variables = {
imports: {
record: record,
oid: oid
}
};
if (!_.isUndefined(triggerCondition) && !_.isEmpty(triggerCondition)) {
const compiled = _.template(triggerCondition, variables);
return compiled();
} else if (forceRun) {
return "true";
} else {
// if trigger condition is not set, fail fast!
return "false";