mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-22 12:51:09 +02:00
ONOS-2849: Refactored topo dialog to general DialogService. Implemented confirmation dialog in App view.
Change-Id: Ib20e98253b2d13f7d7debef2dea5a530b61ced99
This commit is contained in:
parent
76b30f7881
commit
8d28a55fe3
50
web/gui/src/main/webapp/app/fw/layer/dialog.css
Normal file
50
web/gui/src/main/webapp/app/fw/layer/dialog.css
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Open Networking Laboratory
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
ONOS GUI -- Dialog Service -- CSS file
|
||||||
|
*/
|
||||||
|
|
||||||
|
.dialog h2 {
|
||||||
|
padding: 0 4px;
|
||||||
|
margin: 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
display: inline-block;
|
||||||
|
width: 210px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.light .dialog h2 {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.dark .dialog h2 {
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .dialog-button {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 20px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
margin: 4px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light .dialog .dialog-button {
|
||||||
|
background-color: #fec;
|
||||||
|
}
|
||||||
|
.dark .dialog .dialog-button {
|
||||||
|
background-color: #369;
|
||||||
|
}
|
195
web/gui/src/main/webapp/app/fw/layer/dialog.js
Normal file
195
web/gui/src/main/webapp/app/fw/layer/dialog.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Open Networking Laboratory
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
ONOS GUI -- Layer -- Dialog Service
|
||||||
|
|
||||||
|
Builds on the panel service to provide dialog functionality.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// injected refs
|
||||||
|
var $log, $window, fs, ps, bns;
|
||||||
|
|
||||||
|
// configuration
|
||||||
|
var defaultSettings = {
|
||||||
|
width: 300,
|
||||||
|
edge: 'left'
|
||||||
|
};
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
var pApi, panel, dApi;
|
||||||
|
|
||||||
|
// TODO: ONOS-3741
|
||||||
|
// TODO: ESC key invokes Cancel callback
|
||||||
|
// TODO: Enter invokes OK callback
|
||||||
|
|
||||||
|
// create the dialog; return its API
|
||||||
|
function createDialog(id, opts) {
|
||||||
|
var header, body, footer,
|
||||||
|
settings = angular.extend({}, defaultSettings, opts),
|
||||||
|
p = ps.createPanel(id, settings),
|
||||||
|
cls = opts && opts.cssCls;
|
||||||
|
|
||||||
|
p.classed('dialog', true);
|
||||||
|
if (cls) {
|
||||||
|
p.classed(cls, true);
|
||||||
|
}
|
||||||
|
panel = p;
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
p.empty();
|
||||||
|
p.append('div').classed('header', true);
|
||||||
|
p.append('div').classed('body', true);
|
||||||
|
p.append('div').classed('footer', true);
|
||||||
|
|
||||||
|
header = p.el().select('.header');
|
||||||
|
body = p.el().select('.body');
|
||||||
|
footer = p.el().select('.footer');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hAppend(x) {
|
||||||
|
if (typeof x === 'string') {
|
||||||
|
return header.append(x);
|
||||||
|
}
|
||||||
|
header.node().appendChild(x.node());
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bAppend(x) {
|
||||||
|
if (typeof x === 'string') {
|
||||||
|
return body.append(x);
|
||||||
|
}
|
||||||
|
body.node().appendChild(x.node());
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fAppend(x) {
|
||||||
|
if (typeof x === 'string') {
|
||||||
|
return footer.append(x);
|
||||||
|
}
|
||||||
|
footer.node().appendChild(x.node());
|
||||||
|
return footer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy() {
|
||||||
|
ps.destroyPanel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
reset: reset,
|
||||||
|
appendHeader: hAppend,
|
||||||
|
appendBody: bAppend,
|
||||||
|
appendFooter: fAppend,
|
||||||
|
destroy: destroy
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeButton(text, callback) {
|
||||||
|
var cb = fs.isF(callback);
|
||||||
|
|
||||||
|
function invoke() {
|
||||||
|
cb && cb();
|
||||||
|
panel.hide();
|
||||||
|
}
|
||||||
|
return createDiv('dialog-button')
|
||||||
|
.text(text)
|
||||||
|
.on('click', invoke);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTitle(title) {
|
||||||
|
if (pApi) {
|
||||||
|
pApi.appendHeader('h2').text(title);
|
||||||
|
}
|
||||||
|
return dApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addContent(content) {
|
||||||
|
if (pApi) {
|
||||||
|
pApi.appendBody(content);
|
||||||
|
}
|
||||||
|
return dApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addButton(text, cb) {
|
||||||
|
if (pApi) {
|
||||||
|
pApi.appendFooter(makeButton(text, cb));
|
||||||
|
}
|
||||||
|
return dApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// opens the dialog (creates if necessary)
|
||||||
|
function openDialog(id, opts) {
|
||||||
|
$log.debug('Open DIALOG', id, opts);
|
||||||
|
if (!pApi) {
|
||||||
|
pApi = createDialog(id, opts);
|
||||||
|
}
|
||||||
|
pApi.reset();
|
||||||
|
panel.show();
|
||||||
|
|
||||||
|
// return the dialog object API
|
||||||
|
dApi = {
|
||||||
|
setTitle: setTitle,
|
||||||
|
addContent: addContent,
|
||||||
|
addButton: addButton
|
||||||
|
};
|
||||||
|
return dApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// closes the dialog (destroying panel)
|
||||||
|
function closeDialog() {
|
||||||
|
$log.debug('Close DIALOG');
|
||||||
|
if (pApi) {
|
||||||
|
panel.hide();
|
||||||
|
pApi.destroy();
|
||||||
|
pApi = null;
|
||||||
|
dApi = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a detached div, returning D3 selection
|
||||||
|
// optional CSS class may be provided
|
||||||
|
function createDiv(cls) {
|
||||||
|
var div = d3.select(document.createElement('div'));
|
||||||
|
if (cls) {
|
||||||
|
div.classed(cls, true);
|
||||||
|
}
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
angular.module('onosLayer')
|
||||||
|
.factory('DialogService',
|
||||||
|
['$log', '$window', 'FnService', 'PanelService', 'ButtonService',
|
||||||
|
|
||||||
|
// TODO: for now, $window is not used, but we should provide an option
|
||||||
|
// to center the dialog on the window.
|
||||||
|
|
||||||
|
function (_$log_, _$window_, _fs_, _ps_, _bns_) {
|
||||||
|
$log = _$log_;
|
||||||
|
$window = _$window_;
|
||||||
|
fs = _fs_;
|
||||||
|
ps = _ps_;
|
||||||
|
bns = _bns_;
|
||||||
|
|
||||||
|
return {
|
||||||
|
openDialog: openDialog,
|
||||||
|
closeDialog: closeDialog,
|
||||||
|
createDiv: createDiv
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
}());
|
@ -30,3 +30,8 @@
|
|||||||
#ov-app input#uploadFile {
|
#ov-app input#uploadFile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#app-dialog p {
|
||||||
|
color: darkred;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
@ -24,16 +24,20 @@
|
|||||||
// constants
|
// constants
|
||||||
var INSTALLED = 'INSTALLED',
|
var INSTALLED = 'INSTALLED',
|
||||||
ACTIVE = 'ACTIVE',
|
ACTIVE = 'ACTIVE',
|
||||||
APP_MGMENT_REQ = 'appManagementRequest',
|
appMgmtReq = 'appManagementRequest',
|
||||||
FILE_UPLOAD_URL = 'applications/upload';
|
fileUploadUrl = 'applications/upload',
|
||||||
|
dialogId = 'app-dialog',
|
||||||
|
dialogOpts = {
|
||||||
|
edge: 'right'
|
||||||
|
};
|
||||||
|
|
||||||
angular.module('ovApp', [])
|
angular.module('ovApp', [])
|
||||||
.controller('OvAppCtrl',
|
.controller('OvAppCtrl',
|
||||||
['$log', '$scope', '$http',
|
['$log', '$scope', '$http',
|
||||||
'FnService', 'TableBuilderService', 'WebSocketService', 'UrlFnService',
|
'FnService', 'TableBuilderService', 'WebSocketService', 'UrlFnService',
|
||||||
'KeyService',
|
'KeyService', 'DialogService',
|
||||||
|
|
||||||
function ($log, $scope, $http, fs, tbs, wss, ufs, ks) {
|
function ($log, $scope, $http, fs, tbs, wss, ufs, ks, ds) {
|
||||||
$scope.ctrlBtnState = {};
|
$scope.ctrlBtnState = {};
|
||||||
$scope.uploadTip = 'Upload an application (.oar file)';
|
$scope.uploadTip = 'Upload an application (.oar file)';
|
||||||
$scope.activateTip = 'Activate selected application';
|
$scope.activateTip = 'Activate selected application';
|
||||||
@ -77,15 +81,41 @@
|
|||||||
['scroll down', 'See more apps']
|
['scroll down', 'See more apps']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
function createConfirmationText(action, sid) {
|
||||||
|
var content = ds.createDiv();
|
||||||
|
content.append('p').text(action + ' ' + sid);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmAction(action) {
|
||||||
|
var sid = $scope.selId,
|
||||||
|
spar = $scope.sortParams;
|
||||||
|
|
||||||
|
function dOk() {
|
||||||
|
$log.debug('Initiating', action, 'of', sid);
|
||||||
|
wss.sendEvent(appMgmtReq, {
|
||||||
|
action: action,
|
||||||
|
name: sid,
|
||||||
|
sortCol: spar.sortCol,
|
||||||
|
sortDir: spar.sortDir
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dCancel() {
|
||||||
|
$log.debug('Canceling', action, 'of', sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.openDialog(dialogId, dialogOpts)
|
||||||
|
.setTitle('Confirm Action')
|
||||||
|
.addContent(createConfirmationText(action, sid))
|
||||||
|
.addButton('OK', dOk)
|
||||||
|
.addButton('Cancel', dCancel);
|
||||||
|
}
|
||||||
|
|
||||||
$scope.appAction = function (action) {
|
$scope.appAction = function (action) {
|
||||||
if ($scope.ctrlBtnState.selection) {
|
if ($scope.ctrlBtnState.selection) {
|
||||||
$log.debug('Initiating ' + action + ' of ' + $scope.selId);
|
confirmAction(action);
|
||||||
wss.sendEvent(APP_MGMENT_REQ, {
|
|
||||||
action: action,
|
|
||||||
name: $scope.selId,
|
|
||||||
sortCol: $scope.sortParams.sortCol,
|
|
||||||
sortDir: $scope.sortParams.sortDir
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +123,7 @@
|
|||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
if ($scope.appFile) {
|
if ($scope.appFile) {
|
||||||
formData.append('file', $scope.appFile);
|
formData.append('file', $scope.appFile);
|
||||||
$http.post(ufs.rsUrl(FILE_UPLOAD_URL), formData, {
|
$http.post(ufs.rsUrl(fileUploadUrl), formData, {
|
||||||
transformRequest: angular.identity,
|
transformRequest: angular.identity,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': undefined
|
'Content-Type': undefined
|
||||||
|
@ -96,23 +96,6 @@ html[data-platform='iPad'] #topo-p-detail {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Topo Dialog Panel --- */
|
|
||||||
|
|
||||||
#topo-p-dialog .dialog-button {
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 20px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
margin: 4px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.light #topo-p-dialog .dialog-button {
|
|
||||||
background-color: #fec;
|
|
||||||
}
|
|
||||||
.dark #topo-p-dialog .dialog-button {
|
|
||||||
background-color: #369;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- general topo-panel styling --- */
|
/* --- general topo-panel styling --- */
|
||||||
|
|
||||||
|
@ -16,175 +16,29 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
ONOS GUI -- Topology Dialog Module.
|
ONOS GUI -- Topology Dialog Module.
|
||||||
Defines functions for manipulating a dialog box.
|
Creates a dialog box for the topology view.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// injected refs
|
|
||||||
var $log, $window, $rootScope, fs, ps, bns;
|
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
var pCls = 'topo-p dialog',
|
var idDialog = 'topo-p-dialog',
|
||||||
idDialog = 'topo-p-dialog',
|
opts = {
|
||||||
panelOpts = {
|
cssCls: 'topo-p'
|
||||||
width: 300,
|
|
||||||
edge: 'left'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// internal state
|
|
||||||
var pApi, panel, dApi;
|
|
||||||
|
|
||||||
// TODO: ESC key invokes Cancel callback
|
|
||||||
// TODO: Enter invokes OK callback
|
|
||||||
|
|
||||||
// create the dialog; return its API
|
|
||||||
function createDialog() {
|
|
||||||
var header, body, footer,
|
|
||||||
p = ps.createPanel(idDialog, panelOpts);
|
|
||||||
p.classed(pCls, true);
|
|
||||||
panel = p;
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
p.empty();
|
|
||||||
p.append('div').classed('header', true);
|
|
||||||
p.append('div').classed('body', true);
|
|
||||||
p.append('div').classed('footer', true);
|
|
||||||
|
|
||||||
header = p.el().select('.header');
|
|
||||||
body = p.el().select('.body');
|
|
||||||
footer = p.el().select('.footer');
|
|
||||||
}
|
|
||||||
|
|
||||||
function hAppend(x) {
|
|
||||||
if (typeof x === 'string') {
|
|
||||||
return header.append(x);
|
|
||||||
}
|
|
||||||
header.node().appendChild(x.node());
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bAppend(x) {
|
|
||||||
if (typeof x === 'string') {
|
|
||||||
return body.append(x);
|
|
||||||
}
|
|
||||||
body.node().appendChild(x.node());
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fAppend(x) {
|
|
||||||
if (typeof x === 'string') {
|
|
||||||
return footer.append(x);
|
|
||||||
}
|
|
||||||
footer.node().appendChild(x.node());
|
|
||||||
return footer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy() {
|
|
||||||
ps.destroyPanel(idDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
reset: reset,
|
|
||||||
appendHeader: hAppend,
|
|
||||||
appendBody: bAppend,
|
|
||||||
appendFooter: fAppend,
|
|
||||||
destroy: destroy
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeButton(text, callback) {
|
|
||||||
var cb = fs.isF(callback);
|
|
||||||
|
|
||||||
function invoke() {
|
|
||||||
cb && cb();
|
|
||||||
panel.hide();
|
|
||||||
}
|
|
||||||
return createDiv('dialog-button')
|
|
||||||
.text(text)
|
|
||||||
.on('click', invoke);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTitle(title) {
|
|
||||||
if (pApi) {
|
|
||||||
pApi.appendHeader('h2').text(title);
|
|
||||||
}
|
|
||||||
return dApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addContent(content) {
|
|
||||||
if (pApi) {
|
|
||||||
pApi.appendBody(content);
|
|
||||||
}
|
|
||||||
return dApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addButton(text, cb) {
|
|
||||||
if (pApi) {
|
|
||||||
pApi.appendFooter(makeButton(text, cb));
|
|
||||||
}
|
|
||||||
return dApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
// opens the dialog (creates if necessary)
|
|
||||||
function openDialog() {
|
|
||||||
$log.debug('Open DIALOG');
|
|
||||||
if (!pApi) {
|
|
||||||
pApi = createDialog();
|
|
||||||
}
|
|
||||||
pApi.reset();
|
|
||||||
panel.show();
|
|
||||||
|
|
||||||
// return the dialog object API
|
|
||||||
dApi = {
|
|
||||||
setTitle: setTitle,
|
|
||||||
addContent: addContent,
|
|
||||||
addButton: addButton
|
|
||||||
};
|
|
||||||
return dApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
// closes the dialog (destroying panel)
|
|
||||||
function closeDialog() {
|
|
||||||
$log.debug('Close DIALOG');
|
|
||||||
if (pApi) {
|
|
||||||
panel.hide();
|
|
||||||
pApi.destroy();
|
|
||||||
pApi = null;
|
|
||||||
dApi = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a detached div, returning D3 selection
|
|
||||||
// optional CSS class may be provided
|
|
||||||
function createDiv(cls) {
|
|
||||||
var div = d3.select(document.createElement('div'));
|
|
||||||
if (cls) {
|
|
||||||
div.classed(cls, true);
|
|
||||||
}
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================
|
// ==========================
|
||||||
|
|
||||||
angular.module('ovTopo')
|
angular.module('ovTopo')
|
||||||
.factory('TopoDialogService',
|
.factory('TopoDialogService',
|
||||||
['$log', '$window', '$rootScope', 'FnService', 'PanelService', 'ButtonService',
|
['DialogService',
|
||||||
|
|
||||||
function (_$log_, _$window_, _$rootScope_,
|
|
||||||
_fs_, _ps_, _bns_) {
|
|
||||||
$log = _$log_;
|
|
||||||
$window = _$window_;
|
|
||||||
$rootScope = _$rootScope_;
|
|
||||||
fs = _fs_;
|
|
||||||
ps = _ps_;
|
|
||||||
bns = _bns_;
|
|
||||||
|
|
||||||
|
function (ds) {
|
||||||
return {
|
return {
|
||||||
openDialog: openDialog,
|
openDialog: function () { return ds.openDialog(idDialog, opts); },
|
||||||
closeDialog: closeDialog,
|
closeDialog: ds.closeDialog,
|
||||||
createDiv: createDiv
|
createDiv: ds.createDiv
|
||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
}());
|
}());
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
<script src="app/fw/layer/layer.js"></script>
|
<script src="app/fw/layer/layer.js"></script>
|
||||||
<script src="app/fw/layer/panel.js"></script>
|
<script src="app/fw/layer/panel.js"></script>
|
||||||
|
<script src="app/fw/layer/dialog.js"></script>
|
||||||
<script src="app/fw/layer/flash.js"></script>
|
<script src="app/fw/layer/flash.js"></script>
|
||||||
<script src="app/fw/layer/quickhelp.js"></script>
|
<script src="app/fw/layer/quickhelp.js"></script>
|
||||||
<script src="app/fw/layer/veil.js"></script>
|
<script src="app/fw/layer/veil.js"></script>
|
||||||
@ -86,6 +87,7 @@
|
|||||||
<link rel="stylesheet" href="app/fw/svg/glyph.css">
|
<link rel="stylesheet" href="app/fw/svg/glyph.css">
|
||||||
<link rel="stylesheet" href="app/fw/svg/icon.css">
|
<link rel="stylesheet" href="app/fw/svg/icon.css">
|
||||||
<link rel="stylesheet" href="app/fw/layer/panel.css">
|
<link rel="stylesheet" href="app/fw/layer/panel.css">
|
||||||
|
<link rel="stylesheet" href="app/fw/layer/dialog.css">
|
||||||
<link rel="stylesheet" href="app/fw/layer/flash.css">
|
<link rel="stylesheet" href="app/fw/layer/flash.css">
|
||||||
<link rel="stylesheet" href="app/fw/layer/quickhelp.css">
|
<link rel="stylesheet" href="app/fw/layer/quickhelp.css">
|
||||||
<link rel="stylesheet" href="app/fw/layer/veil.css">
|
<link rel="stylesheet" href="app/fw/layer/veil.css">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user