Commit d24e8a6d authored by Moises Sacal's avatar Moises Sacal
Browse files

listing labarchives notebooks via api

parent ad14d794
......@@ -8,6 +8,7 @@
# dependencies
node_modules
redbox-portal
# IDEs and editors
.idea
......
{"version":3,"sources":["webpack/bootstrap c6470057ba362df2d5f3"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t\"inline\": 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c6470057ba362df2d5f3"],"sourceRoot":"webpack:///"}
\ No newline at end of file
{"version":3,"sources":["webpack/bootstrap dc7a5ffb2d3940551b4d"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t\"inline\": 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap dc7a5ffb2d3940551b4d"],"sourceRoot":"webpack:///"}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -164251,6 +164251,22 @@ __WEBPACK_IMPORTED_MODULE_0__Observable__["Observable"].prototype._catch = __WEB
//# sourceMappingURL=catch.js.map
 
 
/***/ }),
/***/ "./node_modules/rxjs/_esm5/add/operator/delay.js":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Observable__ = __webpack_require__("./node_modules/rxjs/_esm5/Observable.js");
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__operator_delay__ = __webpack_require__("./node_modules/rxjs/_esm5/operator/delay.js");
/** PURE_IMPORTS_START .._.._Observable,.._.._operator_delay PURE_IMPORTS_END */
__WEBPACK_IMPORTED_MODULE_0__Observable__["Observable"].prototype.delay = __WEBPACK_IMPORTED_MODULE_1__operator_delay__["a" /* delay */];
//# sourceMappingURL=delay.js.map
/***/ }),
 
/***/ "./node_modules/rxjs/_esm5/add/operator/do.js":
......@@ -166298,6 +166314,66 @@ function _catch(selector) {
//# sourceMappingURL=catch.js.map
 
 
/***/ }),
/***/ "./node_modules/rxjs/_esm5/operator/delay.js":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = delay;
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__scheduler_async__ = __webpack_require__("./node_modules/rxjs/_esm5/scheduler/async.js");
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__operators_delay__ = __webpack_require__("./node_modules/rxjs/_esm5/operators/delay.js");
/** PURE_IMPORTS_START .._scheduler_async,.._operators_delay PURE_IMPORTS_END */
/**
* Delays the emission of items from the source Observable by a given timeout or
* until a given Date.
*
* <span class="informal">Time shifts each item by some specified amount of
* milliseconds.</span>
*
* <img src="./img/delay.png" width="100%">
*
* If the delay argument is a Number, this operator time shifts the source
* Observable by that amount of time expressed in milliseconds. The relative
* time intervals between the values are preserved.
*
* If the delay argument is a Date, this operator time shifts the start of the
* Observable execution until the given date occurs.
*
* @example <caption>Delay each click by one second</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var delayedClicks = clicks.delay(1000); // each click emitted after 1 second
* delayedClicks.subscribe(x => console.log(x));
*
* @example <caption>Delay all clicks until a future date happens</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var date = new Date('March 15, 2050 12:00:00'); // in the future
* var delayedClicks = clicks.delay(date); // click emitted only after that date
* delayedClicks.subscribe(x => console.log(x));
*
* @see {@link debounceTime}
* @see {@link delayWhen}
*
* @param {number|Date} delay The delay duration in milliseconds (a `number`) or
* a `Date` until which the emission of the source items is delayed.
* @param {Scheduler} [scheduler=async] The IScheduler to use for
* managing the timers that handle the time-shift for each item.
* @return {Observable} An Observable that delays the emissions of the source
* Observable by the specified timeout or Date.
* @method delay
* @owner Observable
*/
function delay(delay, scheduler) {
if (scheduler === void 0) {
scheduler = __WEBPACK_IMPORTED_MODULE_0__scheduler_async__["a" /* async */];
}
return Object(__WEBPACK_IMPORTED_MODULE_1__operators_delay__["a" /* delay */])(delay, scheduler)(this);
}
//# sourceMappingURL=delay.js.map
/***/ }),
 
/***/ "./node_modules/rxjs/_esm5/operator/do.js":
......@@ -166980,6 +167056,158 @@ var CatchSubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
//# sourceMappingURL=catchError.js.map
 
 
/***/ }),
/***/ "./node_modules/rxjs/_esm5/operators/delay.js":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["a"] = delay;
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__scheduler_async__ = __webpack_require__("./node_modules/rxjs/_esm5/scheduler/async.js");
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_isDate__ = __webpack_require__("./node_modules/rxjs/_esm5/util/isDate.js");
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Subscriber__ = __webpack_require__("./node_modules/rxjs/_esm5/Subscriber.js");
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Notification__ = __webpack_require__("./node_modules/rxjs/_esm5/Notification.js");
/** PURE_IMPORTS_START .._scheduler_async,.._util_isDate,.._Subscriber,.._Notification PURE_IMPORTS_END */
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b)
if (b.hasOwnProperty(p))
d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/**
* Delays the emission of items from the source Observable by a given timeout or
* until a given Date.
*
* <span class="informal">Time shifts each item by some specified amount of
* milliseconds.</span>
*
* <img src="./img/delay.png" width="100%">
*
* If the delay argument is a Number, this operator time shifts the source
* Observable by that amount of time expressed in milliseconds. The relative
* time intervals between the values are preserved.
*
* If the delay argument is a Date, this operator time shifts the start of the
* Observable execution until the given date occurs.
*
* @example <caption>Delay each click by one second</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var delayedClicks = clicks.delay(1000); // each click emitted after 1 second
* delayedClicks.subscribe(x => console.log(x));
*
* @example <caption>Delay all clicks until a future date happens</caption>
* var clicks = Rx.Observable.fromEvent(document, 'click');
* var date = new Date('March 15, 2050 12:00:00'); // in the future
* var delayedClicks = clicks.delay(date); // click emitted only after that date
* delayedClicks.subscribe(x => console.log(x));
*
* @see {@link debounceTime}
* @see {@link delayWhen}
*
* @param {number|Date} delay The delay duration in milliseconds (a `number`) or
* a `Date` until which the emission of the source items is delayed.
* @param {Scheduler} [scheduler=async] The IScheduler to use for
* managing the timers that handle the time-shift for each item.
* @return {Observable} An Observable that delays the emissions of the source
* Observable by the specified timeout or Date.
* @method delay
* @owner Observable
*/
function delay(delay, scheduler) {
if (scheduler === void 0) {
scheduler = __WEBPACK_IMPORTED_MODULE_0__scheduler_async__["a" /* async */];
}
var absoluteDelay = Object(__WEBPACK_IMPORTED_MODULE_1__util_isDate__["a" /* isDate */])(delay);
var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay);
return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); };
}
var DelayOperator = /*@__PURE__*/ (/*@__PURE__*/ function () {
function DelayOperator(delay, scheduler) {
this.delay = delay;
this.scheduler = scheduler;
}
DelayOperator.prototype.call = function (subscriber, source) {
return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler));
};
return DelayOperator;
}());
/**
* We need this JSDoc comment for affecting ESDoc.
* @ignore
* @extends {Ignored}
*/
var DelaySubscriber = /*@__PURE__*/ (/*@__PURE__*/ function (_super) {
__extends(DelaySubscriber, _super);
function DelaySubscriber(destination, delay, scheduler) {
_super.call(this, destination);
this.delay = delay;
this.scheduler = scheduler;
this.queue = [];
this.active = false;
this.errored = false;
}
DelaySubscriber.dispatch = function (state) {
var source = state.source;
var queue = source.queue;
var scheduler = state.scheduler;
var destination = state.destination;
while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) {
queue.shift().notification.observe(destination);
}
if (queue.length > 0) {
var delay_1 = Math.max(0, queue[0].time - scheduler.now());
this.schedule(state, delay_1);
}
else {
this.unsubscribe();
source.active = false;
}
};
DelaySubscriber.prototype._schedule = function (scheduler) {
this.active = true;
this.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, {
source: this, destination: this.destination, scheduler: scheduler
}));
};
DelaySubscriber.prototype.scheduleNotification = function (notification) {
if (this.errored === true) {
return;
}
var scheduler = this.scheduler;
var message = new DelayMessage(scheduler.now() + this.delay, notification);
this.queue.push(message);
if (this.active === false) {
this._schedule(scheduler);
}
};
DelaySubscriber.prototype._next = function (value) {
this.scheduleNotification(__WEBPACK_IMPORTED_MODULE_3__Notification__["a" /* Notification */].createNext(value));
};
DelaySubscriber.prototype._error = function (err) {
this.errored = true;
this.queue = [];
this.destination.error(err);
};
DelaySubscriber.prototype._complete = function () {
this.scheduleNotification(__WEBPACK_IMPORTED_MODULE_3__Notification__["a" /* Notification */].createComplete());
};
return DelaySubscriber;
}(__WEBPACK_IMPORTED_MODULE_2__Subscriber__["a" /* Subscriber */]));
var DelayMessage = /*@__PURE__*/ (/*@__PURE__*/ function () {
function DelayMessage(time, notification) {
this.time = time;
this.notification = notification;
}
return DelayMessage;
}());
//# sourceMappingURL=delay.js.map
/***/ }),
 
/***/ "./node_modules/rxjs/_esm5/operators/filter.js":
......@@ -20,6 +20,7 @@ export class LabarchivesListField extends FieldBase<any> {
constructor(options: any, injector: any) {
super(options, injector);
this.columns = [
{'show': false, 'property': 'id'},
{'label': 'Name', 'property': 'name'},
{'label': 'Description', 'property': 'description'},
{'label': 'Location', 'property': 'web_url', 'link': 'true'}
......@@ -29,19 +30,31 @@ export class LabarchivesListField extends FieldBase<any> {
}
listWorkspaces() {
return [
{name: 'notebook', description: 'notebook description', web_url: 'the route of the notebook', rdmp: {info:''}},
{name: 'notebook2', description: 'notebook description 2 ', web_url: 'the route of the notebook', rdmp: {info:''}}
];
registerEvents() {
this.fieldMap['Login'].field['userLogin'].subscribe(this.listWorkspaces.bind(this));
}
linkWorkspace(item: any) {
alert('linking')
listWorkspaces(labUser: any) {
const notebooks = labUser['notebooks'];
if (notebooks && notebooks['notebook']) {
const nbs = notebooks['notebook'];
console.log(nbs);
this.workspaces = nbs.map((nb) => {
const isDefault = nb['is-default'];
return {
name: nb['name'],
description: isDefault._ !== 'false' ? 'default' : '',
web_url: '',
rdmp: {info: '', id: nb['id']}
}
});
} else {
this.workspaces = [];
}
}
init() {
this.workspaces = this.listWorkspaces();
linkWorkspace(item: any) {
alert('linking')
}
}
......@@ -50,54 +63,60 @@ export class LabarchivesListField extends FieldBase<any> {
@Component({
selector: 'ws-labarchiveslist',
template: `
<div class="">
<table class="table">
<thead>
<tr>
<ng-container *ngFor="let header of field.columns">
<th>{{ header.label }}</th>
</ng-container>
<th>{{ field.rdmpLinkLabel }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of field.workspaces">
<ng-container *ngFor="let column of field.columns">
<td *ngIf="column.show != false">
<span *ngIf="column.link; else noProcessing "><a target="_blank" rel="noopener noreferrer"
href="{{ item[column.property] }}">{{ item[column.property]
}}</a></span>
<ng-template #multivalue></ng-template>
<ng-template #noProcessing><span>{{ item[column.property] }}</span></ng-template>
</td>
</ng-container>
<td>
<div class="row">
<div class="col-lg-10">
<div class="">
<table class="table">
<thead>
<tr>
<ng-container *ngFor="let header of field.columns">
<th>{{ header.label }}</th>
</ng-container>
<th>{{ field.rdmpLinkLabel }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of field.workspaces">
<ng-container *ngFor="let column of field.columns">
<td *ngIf="column.show != false">
<span *ngIf="column.link; else noProcessing ">
<a target="_blank" rel="noopener noreferrer"
href="{{ item[column.property] }}">{{ item[column.property]}}</a>
</span>
<ng-template #multivalue></ng-template>
<ng-template #noProcessing><span>{{ item[column.property] }}</span></ng-template>
</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>
</td>
</tr>
</tbody>
</table>
<div *ngIf="field.loading" class="">
<img class="center-block" src="/images/loading.svg">
</div>
<p *ngIf="field.failedObjects.length > 0">There were {{ field.failedObjects.length }} records that failed to
load</p>
<p *ngIf="field.accessDeniedObjects.length > 0">There were {{ field.accessDeniedObjects.length }} records that
you do not have access to</p>
<div class="">
<button type="button" class="btn btn-default" (click)="field.listWorkspaces()"><i
class="fa fa-refresh"></i>&nbsp;{{ field.syncLabel }}
</button>
</div>
<div>
<p></p>
<ng-template #isNotLinked>
<button type="button" class="btn btn-info btn-block" (click)="field.linkWorkspace(item)"> Link
</button>
</ng-template>
</td>
</tr>
</tbody>
</table>
<div *ngIf="field.loading" class="">
<img class="center-block" src="/images/loading.svg">
</div>
<p *ngIf="field.failedObjects.length > 0">There were {{ field.failedObjects.length }} records that failed to
load</p>
<p *ngIf="field.accessDeniedObjects.length > 0">There were {{ field.accessDeniedObjects.length }} records that
you do not have access to</p>
<div class="">
<button type="button" class="btn btn-default" (click)="field.listWorkspaces()"><i
class="fa fa-refresh"></i>&nbsp;{{ field.syncLabel }}
</button>
</div>
<div>
<p></p>
</div>
</div>
</div>
</div>
`
......@@ -106,6 +125,6 @@ export class LabarchivesListComponent extends SimpleComponent {
field: LabarchivesListField;
ngOnInit() {
this.field.init();
this.field.registerEvents();
}
}
......@@ -3,6 +3,8 @@ 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 LabarchivesLoginField extends FieldBase<any> {
valid = true;
......@@ -12,24 +14,46 @@ export class LabarchivesLoginField extends FieldBase<any> {
passwordLabel: string = 'Password';
submitted = false;
errorMessage: string = undefined;
user: any;
labarchivesService: LabarchivesService;
@Output() userLogin = new EventEmitter<any>();
constructor(options: any, injector: any) {
super(options, injector);
this.labarchivesService = this.getFromInjector(LabarchivesService);
}
onSubmit() {
this.user = {username: this.username, password: this.password};
this.user.loggedIn = true;
this.userLogin.emit(this.user);
this.submitted = true;
async login(form) {
const formValid = this.loginValid(form);
if (formValid === '') {
// TODO: Investigate this. Using this method to remove the trailing Base64 equals ==
form.password = form.password.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
this.user = {username: form.username, password: form.password};
const login = await this.labarchivesService.login(this.user.username, this.user.password);
if (login.status) {
this.user.loggedIn = true;
this.userLogin.emit(login.labUser);
this.submitted = true;
} else {
this.errorMessage = login.message;
}
} else {
this.errorMessage = formValid;
}
}
userIsValid() {
return true;
loginValid(form) {
if (!form.username) {
return 'Please include username';
}
if (!form.password) {
return 'Please include username';
}
return '';
}
}
......@@ -37,31 +61,37 @@ export class LabarchivesLoginField extends FieldBase<any> {
@Component({
selector: 'ws-labarchiveslogin',
template: `
<form (ngSubmit)="field.onSubmit()" #form="ngForm">
<div class="form-group">
<label>{{ field.usernameLabel }}</label>
<input type="text" class="form-control" ngModel name="username"
attr.aria-label="{{ field.usernameLabel }}">
</div>
<div class="form-group">
<label>{{ field.passwordLabel }}</label>
<input type="password" class="form-control" ngModel name="password"
attr.aria-label="{{ field.passwordLabel }}">
</div>
<div class="form-row">
<button type="submit" [disabled]="!field.valid" class="btn btn-primary">Login</button>
</div>
<div>
<p></p>
</div>
<div class="form-group">
<button type="submit" [disabled]="!field.valid" class="btn btn-primary">Login trough UTS</button>
</div>
<div class="errorMessage" *ngIf="!field.valid">Field is required</div>
<div>
<p></p>
<div class="row">
<div class="col-md-5 col-md-offset-2">
<form #form="ngForm">
<div class="form-group">
<label>{{ field.usernameLabel }}</label>
<input type="text" class="form-control" ngModel name="username"
attr.aria-label="{{ field.usernameLabel }}">
</div>
<div class="form-group">
<label>{{ field.passwordLabel }}</label>
<input type="password" class="form-control" ngModel name="password"
attr.aria-label="{{ field.passwordLabel }}">
</div>
<div class="form-row">
<button (click)="field.login(form.value)" type="submit" [disabled]="!field.valid" class="btn btn-primary">
Login
</button>
</div>
<div>
<p>or</p>
</div>
<div class="form-group">
<button type="submit" [disabled]="!field.valid" class="btn btn-primary">Login trough UTS</button>
</div>
<div class="alert alert-danger" *ngIf="field.errorMessage">{{ field.errorMessage }}</div>
<div>
<p></p>
</div>
</form>
</div>
</form>
</div>
`
})
export class LabarchivesLoginComponent extends SimpleComponent {
......
......@@ -3,6 +3,8 @@ import {ReactiveFormsModule, FormsModule} from '@angular/forms';
import {NgModule} from '@angular/core';
import {SharedModule} from './shared/shared.module';
import {LabarchivesService} from "./labarchives.service";
import {LabarchivesFormComponent} from './labarchives-form.component';
import {LabarchivesLoginComponent} from './components/labarchives-login.component';
import {LabarchivesListComponent} from './components/labarchives-list.component';
......@@ -15,7 +17,9 @@ import {LabarchivesListComponent} from './components/labarchives-list.component'
LabarchivesFormComponent, LabarchivesLoginComponent, LabarchivesListComponent
],
exports: [],
providers: [],
providers: [
LabarchivesService
],
bootstrap: [
LabarchivesFormComponent
],
......
import {Injectable, Inject} from '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/delay';
import {Observable} from 'rxjs/Observable';
import {BaseService} from './shared/base-service';
import {ConfigService} from './shared/config-service';
@Injectable()
export class LabarchivesService extends BaseService {
protected baseUrl: any;
public recordURL: string = this.brandingAndPortalUrl + '/record/view';
protected initSubject: any;
constructor(@Inject(Http) http: Http,
@Inject(ConfigService) protected configService: ConfigService) {
super(http, configService);
this.initSubject = new Subject();
this.emitInit();
}