blob: b2bb38bb90002c19aa59a31419ee9dfbda127840 [file] [log] [blame]
Sean Condon83fc39f2018-04-19 18:56:13 +01001/*
2 * Copyright 2015-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the 'License');
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an 'AS IS' BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sean Condon2bd11b72018-06-15 08:00:48 +010016import { Component, OnInit, OnDestroy } from '@angular/core';
Sean Condon83fc39f2018-04-19 18:56:13 +010017import { DialogService } from '../../fw/layer/dialog.service';
18import { FnService } from '../../fw/util/fn.service';
19import { IconService } from '../../fw/svg/icon.service';
20import { KeyService } from '../../fw/util/key.service';
21import { LionService } from '../../fw/util/lion.service';
Sean Condon2bd11b72018-06-15 08:00:48 +010022import { LoadingService } from '../../fw/layer/loading.service';
Sean Condon83fc39f2018-04-19 18:56:13 +010023import { LogService } from '../../log.service';
24import { PanelService } from '../../fw/layer/panel.service';
Sean Condon2bd11b72018-06-15 08:00:48 +010025import { TableBaseImpl, TableResponse } from '../../fw/widget/tablebase';
Sean Condon83fc39f2018-04-19 18:56:13 +010026import { UrlFnService } from '../../fw/remote/urlfn.service';
27import { WebSocketService } from '../../fw/remote/websocket.service';
28
Sean Condon2bd11b72018-06-15 08:00:48 +010029const INSTALLED = 'INSTALLED';
30const ACTIVE = 'ACTIVE';
31const appMgmtReq = 'appManagementRequest';
32const topPdg = 60;
33const panelWidth = 540;
34const pName = 'application-details-panel';
35const detailsReq = 'appDetailsRequest';
36const detailsResp = 'appDetailsResponse';
37const fileUploadUrl = 'applications/upload';
38const activateOption = '?activate=true';
39const appUrlPrefix = 'rs/applications/';
40const iconUrlSuffix = '/icon';
41const downloadSuffix = '/download';
42const dialogId = 'app-dialog';
43const dialogOpts = {
44 edge: 'right',
45 width: 400,
46};
47const strongWarning = {
48 'org.onosproject.drivers': true,
49};
50const propOrder = ['id', 'state', 'category', 'version', 'origin', 'role'];
51
52interface AppTableResponse extends TableResponse {
53 apps: Apps[];
54}
55
56interface Apps {
57 category: string;
58 desc: string;
59 features: string;
60 icon: string;
61 id: string;
62 origin: string;
63 permissions: string;
64 readme: string;
65 required_apps: string;
66 role: string;
67 state: string;
68 title: string;
69 url: string;
70 version: string;
71 _iconid_state: string;
72}
73
74interface CtrlBtnState {
75 installed: boolean;
76 selection: string;
77 active: boolean;
78}
79
Sean Condon83fc39f2018-04-19 18:56:13 +010080/**
81 * ONOS GUI -- Apps View Component
82 */
83@Component({
84 selector: 'onos-apps',
85 templateUrl: './apps.component.html',
Sean Condon2bd11b72018-06-15 08:00:48 +010086 styleUrls: [
87 './apps.component.css', './apps.theme.css',
88 '../../fw/widget/table.css', '../../fw/widget/table-theme.css'
89 ]
Sean Condon83fc39f2018-04-19 18:56:13 +010090})
Sean Condon2bd11b72018-06-15 08:00:48 +010091export class AppsComponent extends TableBaseImpl implements OnInit, OnDestroy {
92
93 // deferred localization strings
94 lionFn; // Function
95 warnDeactivate: string;
96 warnOwnRisk: string;
97 friendlyProps: string[];
98 ctrlBtnState: CtrlBtnState;
99 detailsPanel: any;
Sean Condon83fc39f2018-04-19 18:56:13 +0100100
101 constructor(
Sean Condon2bd11b72018-06-15 08:00:48 +0100102 protected fs: FnService,
Sean Condon83fc39f2018-04-19 18:56:13 +0100103 private ds: DialogService,
104 private is: IconService,
105 private ks: KeyService,
Sean Condon2bd11b72018-06-15 08:00:48 +0100106 private lion: LionService,
107 protected ls: LoadingService,
108 protected log: LogService,
Sean Condon83fc39f2018-04-19 18:56:13 +0100109 private ps: PanelService,
Sean Condon83fc39f2018-04-19 18:56:13 +0100110 private ufs: UrlFnService,
Sean Condon2bd11b72018-06-15 08:00:48 +0100111 protected wss: WebSocketService,
112 private window: Window,
Sean Condon83fc39f2018-04-19 18:56:13 +0100113 ) {
Sean Condon2bd11b72018-06-15 08:00:48 +0100114 super(fs, null, log, wss, 'app');
115 this.responseCallback = this.appResponseCb;
116 this.sortParams = {
117 firstCol: 'state',
118 firstDir: 'desc',
119 secondCol: 'title',
120 secondDir: 'asc',
121 };
122 // We want doLion() to be called only after the Lion service is populated (from the WebSocket)
123 this.lion.loadCb = (() => this.doLion());
124 this.ctrlBtnState = <CtrlBtnState>{
125 installed: false,
126 active: false
127 };
128 if (this.lion.ubercache.length === 0) {
129 this.lionFn = this.dummyLion;
130 } else {
131 this.doLion();
132 }
Sean Condon83fc39f2018-04-19 18:56:13 +0100133 }
134
135 ngOnInit() {
Sean Condon2bd11b72018-06-15 08:00:48 +0100136 this.init();
137 this.log.debug('AppComponent initialized');
Sean Condon83fc39f2018-04-19 18:56:13 +0100138 }
139
Sean Condon2bd11b72018-06-15 08:00:48 +0100140 ngOnDestroy() {
141 this.destroy();
142 this.log.debug('AppComponent destroyed');
143 }
144
145 /**
146 * The callback called when App data returns from WSS
147 */
148 appResponseCb(data: AppTableResponse) {
149 this.log.debug('App response received for ', data.apps.length, 'apps');
150 }
151
152 refreshCtrls() {
153 let row;
154 let rowIdx;
155 if (this.ctrlBtnState.selection) {
156 rowIdx = this.fs.find(this.selId, this.tableData);
157 row = rowIdx >= 0 ? this.tableData[rowIdx] : null;
158
159 this.ctrlBtnState.installed = row && row.state === INSTALLED;
160 this.ctrlBtnState.active = row && row.state === ACTIVE;
161 } else {
162 this.ctrlBtnState.installed = false;
163 this.ctrlBtnState.active = false;
164 }
165 }
166
167 createConfirmationText(action, itemId) {
168// let content = this.ds.createDiv();
169// content.append('p').text(this.lionFn(action) + ' ' + itemId);
170// if (strongWarning[itemId]) {
171// content.append('p').html(
172// this.fs.sanitize(this.warnDeactivate) +
173// '<br>' +
174// this.fs.sanitize(this.warnOwnRisk)
175// ).classed('strong', true);
176// }
177// return content;
178 }
179
180 confirmAction(action): void {
181 const itemId = this.selId;
182 const spar = this.sortParams;
183
184 function dOk() {
185 this.log.debug('Initiating', action, 'of', itemId);
186 this.wss.sendEvent(appMgmtReq, {
187 action: action,
188 name: itemId,
189 sortCol: spar.sortCol,
190 sortDir: spar.sortDir,
191 });
192 if (action === 'uninstall') {
193 this.detailsPanel.hide();
194 } else {
195 this.wss.sendEvent(detailsReq, { id: itemId });
196 }
197 }
198
199 function dCancel() {
200 this.log.debug('Canceling', action, 'of', itemId);
201 }
202
203// this.ds.openDialog(dialogId, dialogOpts)
204// .setTitle(this.lionFn('dlg_confirm_action'))
205// .addContent(this.createConfirmationText(action, itemId))
206// .addOk(dOk)
207// .addCancel(dCancel)
208// .bindKeys();
209 }
210
211 appAction(action) {
212 if (this.ctrlBtnState.selection) {
213 this.confirmAction(action);
214 }
215 }
216
217 downloadApp() {
218 if (this.ctrlBtnState.selection) {
219 (<any>this.window).location = appUrlPrefix + this.selId + downloadSuffix;
220 }
221 }
222
223 /**
224 * Read the LION bundle for App - this should replace the dummyLion implementation
225 * of lionFn with a function from the LION Service
226 */
227 doLion() {
228 this.lionFn = this.lion.bundle('core.view.App');
229
230 this.warnDeactivate = this.lionFn('dlg_warn_deactivate');
231 this.warnOwnRisk = this.lionFn('dlg_warn_own_risk');
232
233 this.friendlyProps = [
234 this.lionFn('app_id'), this.lionFn('state'),
235 this.lionFn('category'), this.lionFn('version'),
236 this.lionFn('origin'), this.lionFn('role'),
237 ];
238 }
239
240 /**
241 * A dummy implementation of the lionFn until the response is received and the LION
242 * bundle is received from the WebSocket
243 */
244 dummyLion(key: string): string {
245 return '%' + key + '%';
246 }
Sean Condon83fc39f2018-04-19 18:56:13 +0100247}