blob: 558502911b95f24f6ad788cb4538e7d7f375834e [file] [log] [blame]
Simon Hunt8d28a552016-01-11 14:01:02 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Simon Hunt8d28a552016-01-11 14:01:02 -08003 *
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 */
16
17/*
18 ONOS GUI -- Layer -- Dialog Service
19
20 Builds on the panel service to provide dialog functionality.
21 */
22(function () {
23 'use strict';
24
25 // injected refs
Simon Hunt5198f082016-02-04 13:41:17 -080026 var $log, $window, fs, ps, bns, ks;
Simon Hunt8d28a552016-01-11 14:01:02 -080027
28 // configuration
29 var defaultSettings = {
30 width: 300,
31 edge: 'left'
32 };
33
34 // internal state
Simon Hunt5198f082016-02-04 13:41:17 -080035 var pApi, panel, dApi,
36 keyBindings = {};
Simon Hunt8d28a552016-01-11 14:01:02 -080037
38 // create the dialog; return its API
39 function createDialog(id, opts) {
40 var header, body, footer,
41 settings = angular.extend({}, defaultSettings, opts),
42 p = ps.createPanel(id, settings),
43 cls = opts && opts.cssCls;
44
45 p.classed('dialog', true);
46 if (cls) {
47 p.classed(cls, true);
48 }
49 panel = p;
50
51 function reset() {
52 p.empty();
53 p.append('div').classed('header', true);
54 p.append('div').classed('body', true);
55 p.append('div').classed('footer', true);
56
57 header = p.el().select('.header');
58 body = p.el().select('.body');
59 footer = p.el().select('.footer');
60 }
61
62 function hAppend(x) {
63 if (typeof x === 'string') {
64 return header.append(x);
65 }
66 header.node().appendChild(x.node());
67 return header;
68 }
69
70 function bAppend(x) {
71 if (typeof x === 'string') {
72 return body.append(x);
73 }
74 body.node().appendChild(x.node());
75 return body;
76 }
77
78 function fAppend(x) {
79 if (typeof x === 'string') {
80 return footer.append(x);
81 }
82 footer.node().appendChild(x.node());
83 return footer;
84 }
85
86 function destroy() {
87 ps.destroyPanel(id);
88 }
89
90 return {
91 reset: reset,
92 appendHeader: hAppend,
93 appendBody: bAppend,
94 appendFooter: fAppend,
95 destroy: destroy
96 };
97 }
98
Simon Hunte75cf182016-02-05 09:39:45 -080099 function makeButton(callback, text, keyName) {
Simon Hunt5198f082016-02-04 13:41:17 -0800100 var cb = fs.isF(callback),
101 key = fs.isS(keyName);
Simon Hunt8d28a552016-01-11 14:01:02 -0800102
103 function invoke() {
104 cb && cb();
Simon Hunt5198f082016-02-04 13:41:17 -0800105 clearBindings();
Simon Hunt8d28a552016-01-11 14:01:02 -0800106 panel.hide();
107 }
Simon Hunt5198f082016-02-04 13:41:17 -0800108
109 if (key) {
110 keyBindings[key] = invoke;
111 }
112
Simon Hunt8d28a552016-01-11 14:01:02 -0800113 return createDiv('dialog-button')
114 .text(text)
115 .on('click', invoke);
116 }
117
118 function setTitle(title) {
119 if (pApi) {
120 pApi.appendHeader('h2').text(title);
121 }
122 return dApi;
123 }
124
125 function addContent(content) {
126 if (pApi) {
127 pApi.appendBody(content);
128 }
129 return dApi;
130 }
131
Simon Hunte75cf182016-02-05 09:39:45 -0800132 function addButton(cb, text, key) {
Simon Hunt8d28a552016-01-11 14:01:02 -0800133 if (pApi) {
Simon Hunte75cf182016-02-05 09:39:45 -0800134 pApi.appendFooter(makeButton(cb, text, key));
Simon Hunt8d28a552016-01-11 14:01:02 -0800135 }
136 return dApi;
137 }
138
Simon Hunte75cf182016-02-05 09:39:45 -0800139 function addOk(cb, text) {
140 return addButton(cb, text || 'OK', 'enter');
Simon Hunt5198f082016-02-04 13:41:17 -0800141 }
142
Simon Hunte75cf182016-02-05 09:39:45 -0800143 function addCancel(cb, text) {
144 return addButton(cb, text || 'Cancel', 'esc');
Simon Hunt5198f082016-02-04 13:41:17 -0800145 }
146
147 function clearBindings() {
148 keyBindings = {};
149 ks.dialogKeys();
150 }
151
Simon Hunt8d28a552016-01-11 14:01:02 -0800152 // opens the dialog (creates if necessary)
153 function openDialog(id, opts) {
154 $log.debug('Open DIALOG', id, opts);
155 if (!pApi) {
156 pApi = createDialog(id, opts);
157 }
158 pApi.reset();
159 panel.show();
160
161 // return the dialog object API
162 dApi = {
163 setTitle: setTitle,
164 addContent: addContent,
Simon Hunt5198f082016-02-04 13:41:17 -0800165 addButton: addButton,
166 addOk: addOk,
167 addCancel: addCancel,
168 bindKeys: function () {
169 ks.dialogKeys(keyBindings);
170 }
Simon Hunt8d28a552016-01-11 14:01:02 -0800171 };
172 return dApi;
173 }
174
175 // closes the dialog (destroying panel)
176 function closeDialog() {
177 $log.debug('Close DIALOG');
178 if (pApi) {
Simon Hunt5198f082016-02-04 13:41:17 -0800179 clearBindings();
Simon Hunt8d28a552016-01-11 14:01:02 -0800180 panel.hide();
181 pApi.destroy();
182 pApi = null;
183 dApi = null;
184 }
185 }
186
187 // creates a detached div, returning D3 selection
188 // optional CSS class may be provided
189 function createDiv(cls) {
190 var div = d3.select(document.createElement('div'));
191 if (cls) {
192 div.classed(cls, true);
193 }
194 return div;
195 }
196
197 angular.module('onosLayer')
198 .factory('DialogService',
199 ['$log', '$window', 'FnService', 'PanelService', 'ButtonService',
Simon Hunt5198f082016-02-04 13:41:17 -0800200 'KeyService',
Simon Hunt8d28a552016-01-11 14:01:02 -0800201
202 // TODO: for now, $window is not used, but we should provide an option
203 // to center the dialog on the window.
204
Simon Hunt5198f082016-02-04 13:41:17 -0800205 function (_$log_, _$window_, _fs_, _ps_, _bns_, _ks_) {
Simon Hunt8d28a552016-01-11 14:01:02 -0800206 $log = _$log_;
207 $window = _$window_;
208 fs = _fs_;
209 ps = _ps_;
210 bns = _bns_;
Simon Hunt5198f082016-02-04 13:41:17 -0800211 ks = _ks_;
Simon Hunt8d28a552016-01-11 14:01:02 -0800212
213 return {
214 openDialog: openDialog,
215 closeDialog: closeDialog,
216 createDiv: createDiv
217 };
218 }]);
219
220}());