blob: ed6d30a489ac87023714588dea043186c11c7925 [file] [log] [blame]
/*
* Copyright 2015-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
import { DialogService } from '../../fw/layer/dialog.service';
import { FnService } from '../../fw/util/fn.service';
import { IconService } from '../../fw/svg/icon.service';
import { KeyService } from '../../fw/util/key.service';
import { LionService } from '../../fw/util/lion.service';
import { LoadingService } from '../../fw/layer/loading.service';
import { LogService } from '../../log.service';
import { PanelService } from '../../fw/layer/panel.service';
import { TableBaseImpl, TableResponse } from '../../fw/widget/tablebase';
import { UrlFnService } from '../../fw/remote/urlfn.service';
import { WebSocketService } from '../../fw/remote/websocket.service';
const INSTALLED = 'INSTALLED';
const ACTIVE = 'ACTIVE';
const appMgmtReq = 'appManagementRequest';
const topPdg = 60;
const panelWidth = 540;
const pName = 'application-details-panel';
const detailsReq = 'appDetailsRequest';
const detailsResp = 'appDetailsResponse';
const fileUploadUrl = 'applications/upload';
const activateOption = '?activate=true';
const appUrlPrefix = 'rs/applications/';
const iconUrlSuffix = '/icon';
const downloadSuffix = '/download';
const dialogId = 'app-dialog';
const dialogOpts = {
edge: 'right',
width: 400,
};
const strongWarning = {
'org.onosproject.drivers': true,
};
const propOrder = ['id', 'state', 'category', 'version', 'origin', 'role'];
interface AppTableResponse extends TableResponse {
apps: Apps[];
}
interface Apps {
category: string;
desc: string;
features: string;
icon: string;
id: string;
origin: string;
permissions: string;
readme: string;
required_apps: string;
role: string;
state: string;
title: string;
url: string;
version: string;
_iconid_state: string;
}
interface CtrlBtnState {
installed: boolean;
selection: string;
active: boolean;
}
/**
* ONOS GUI -- Apps View Component
*/
@Component({
selector: 'onos-apps',
templateUrl: './apps.component.html',
styleUrls: [
'./apps.component.css', './apps.theme.css',
'../../fw/widget/table.css', '../../fw/widget/table-theme.css'
]
})
export class AppsComponent extends TableBaseImpl implements OnInit, OnDestroy {
// deferred localization strings
lionFn; // Function
warnDeactivate: string;
warnOwnRisk: string;
friendlyProps: string[];
ctrlBtnState: CtrlBtnState;
detailsPanel: any;
appFile: any;
activateImmediately = '';
uploadTip: string;
activateTip: string;
deactivateTip: string;
uninstallTip: string;
downloadTip: string;
constructor(
protected fs: FnService,
private ds: DialogService,
private is: IconService,
private ks: KeyService,
private lion: LionService,
protected ls: LoadingService,
protected log: LogService,
private ps: PanelService,
private ufs: UrlFnService,
protected wss: WebSocketService,
@Inject('Window') private window: Window,
) {
super(fs, null, log, wss, 'app');
this.responseCallback = this.appResponseCb;
this.sortParams = {
firstCol: 'state',
firstDir: 'desc',
secondCol: 'title',
secondDir: 'asc',
};
// We want doLion() to be called only after the Lion service is populated (from the WebSocket)
this.lion.loadCb = (() => this.doLion());
this.ctrlBtnState = <CtrlBtnState>{
installed: false,
active: false
};
if (this.lion.ubercache.length === 0) {
this.lionFn = this.dummyLion;
} else {
this.doLion();
}
this.uploadTip = this.lionFn('tt_ctl_upload');
this.activateTip = this.lionFn('tt_ctl_activate');
this.deactivateTip = this.lionFn('tt_ctl_deactivate');
this.uninstallTip = this.lionFn('tt_ctl_uninstall');
this.downloadTip = this.lionFn('tt_ctl_download');
}
ngOnInit() {
this.init();
this.log.debug('AppComponent initialized');
}
ngOnDestroy() {
this.destroy();
this.log.debug('AppComponent destroyed');
}
/**
* The callback called when App data returns from WSS
*/
appResponseCb(data: AppTableResponse) {
this.log.debug('App response received for ', data.apps.length, 'apps');
}
refreshCtrls() {
let row;
let rowIdx;
if (this.ctrlBtnState.selection) {
rowIdx = this.fs.find(this.selId, this.tableData);
row = rowIdx >= 0 ? this.tableData[rowIdx] : null;
this.ctrlBtnState.installed = row && row.state === INSTALLED;
this.ctrlBtnState.active = row && row.state === ACTIVE;
} else {
this.ctrlBtnState.installed = false;
this.ctrlBtnState.active = false;
}
}
createConfirmationText(action, itemId) {
// let content = this.ds.createDiv();
// content.append('p').text(this.lionFn(action) + ' ' + itemId);
// if (strongWarning[itemId]) {
// content.append('p').html(
// this.fs.sanitize(this.warnDeactivate) +
// '<br>' +
// this.fs.sanitize(this.warnOwnRisk)
// ).classed('strong', true);
// }
// return content;
}
confirmAction(action): void {
const itemId = this.selId;
const spar = this.sortParams;
function dOk() {
this.log.debug('Initiating', action, 'of', itemId);
this.wss.sendEvent(appMgmtReq, {
action: action,
name: itemId,
sortCol: spar.sortCol,
sortDir: spar.sortDir,
});
if (action === 'uninstall') {
this.detailsPanel.hide();
} else {
this.wss.sendEvent(detailsReq, { id: itemId });
}
}
function dCancel() {
this.log.debug('Canceling', action, 'of', itemId);
}
// this.ds.openDialog(dialogId, dialogOpts)
// .setTitle(this.lionFn('dlg_confirm_action'))
// .addContent(this.createConfirmationText(action, itemId))
// .addOk(dOk)
// .addCancel(dCancel)
// .bindKeys();
}
appAction(action) {
if (this.ctrlBtnState.selection) {
this.confirmAction(action);
}
}
downloadApp() {
if (this.ctrlBtnState.selection) {
(<any>this.window).location = appUrlPrefix + this.selId + downloadSuffix;
}
}
/**
* Read the LION bundle for App - this should replace the dummyLion implementation
* of lionFn with a function from the LION Service
*/
doLion() {
this.lionFn = this.lion.bundle('core.view.App');
this.warnDeactivate = this.lionFn('dlg_warn_deactivate');
this.warnOwnRisk = this.lionFn('dlg_warn_own_risk');
this.friendlyProps = [
this.lionFn('app_id'), this.lionFn('state'),
this.lionFn('category'), this.lionFn('version'),
this.lionFn('origin'), this.lionFn('role'),
];
}
/**
* A dummy implementation of the lionFn until the response is received and the LION
* bundle is received from the WebSocket
*/
dummyLion(key: string): string {
return '%' + key + '%';
}
appDropped() {
this.activateImmediately = activateOption;
// $scope.$emit('FileChanged'); // TODO: Implement this
this.appFile = null;
}
}