-
Notifications
You must be signed in to change notification settings - Fork 0
/
webview-modal-survey.js
228 lines (205 loc) · 9.68 KB
/
webview-modal-survey.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/********************************************************
Copyright (c) 2024 Cisco and/or its affiliates.
This software is licensed to you under the terms of the Cisco Sample
Code License, Version 1.1 (the "License"). You may obtain a copy of the
License at
https://developer.cisco.com/docs/licenses
All use of the material herein must be in accordance with the terms of
the License. All rights not expressly granted by the License are
reserved. Unless required by applicable law or agreed to separately 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.
*********************************************************
* Author(s): Robert(Bobby) McGonigle Jr
* Technical Marketing Engineer
* Cisco Systems
*
* Jon Miranda
* Technical Solutions Architect
* Cisco Systems
*
* Jacob Munson
* Collaboration Architect
* CMAD Systems
*
* Description:
* - Customize and Open a Webview Display Modal on Button Clicks or Call Disconnects with cache clear and display panel close after duration.
*/
import xapi from 'xapi';
const config = {
WebModal: { // Set Values pertaining to a Web Based Modal
Title: 'Survey', //Set a user facing title for the Web Modal
Url: 'https://cisco.com', // Set the URL you want to open
OSDToolTip: { // If the modal is prompted by a trigger without user interaction, this tooltip will show to help guide the user
Mode: true,
Message: 'Tell us about your experience on the Touch Panel 🙂',
Duration: 20,
Location: 'Top-Right', // Top-Right, Top-Left, Center, Bottom-Right, Bottom-Left
},
Triggers: { // Choose how the WebModal should be prompted to open
PanelClicked: true, // If true, will generate a user facing panel to open the WebModal when clicked
CallDisconnect: true // If true, the WebModal will open when a call disonnects
},
ClearCacheOnExit: {
Mode: true, // If true, it will clear cache for Webapps
Target: 'WebApps' // All, Signage, WebApps, PersistentWebApp
},
WebViewTimoutDuration: { // Choose how long the Survey Form stays on screen
Mode: true, // If true, it will close Webview Panel after duration timer
Duration: 18 //Number of seconds
}
},
UserInterface: {
Panel: {
Name: 'Survey', // Set the Name of the WebApps Panel
Location: 'HomeScreen', // HomeScreen, HomeScreenAndCallControls, CallControls, Never, ControlPanel
Order: 1, // Set the Position where this panel will render amongst other Custom Panels. Does not effect Native Panels
Icon: {
Type: 'Language', // Choose an Option from the list Below. Note, Custom expect a the CustomIconURL to be provided
/*
"Blinds", "Briefing", "Camera", "Concierge",
"Custom", "Disc", "Handset", "Help", "Helpdesk",
"Home", "Hvac", "Info", "Input", "Language",
"Laptop", "Lightbulb", "Media", "Microphone",
"Power", "Proximity", "Record", "Sliders", "Tv"
*/
Color: 'cf7900', // Set a Background Color using a Hexadecimal Value. Does not apply to Custom Icons or Icons located in the Control Panel
CustomIconURL: 'https://avatars.githubusercontent.com/u/159071680?s=200&v=4' // Must be a .ico, .jpg or .png file that's between 60x60px to 1200x1200px in size. If the image fails to download, the icon above will be used
}
}
}
}
const panelId = 'webModal';
async function buildUserInterface() {
const xml = `<Extensions>
<Panel>
<Order>${config.UserInterface.Panel.Order}</Order>
<Location>${config.UserInterface.Panel.Location}</Location>
<Icon>${config.UserInterface.Panel.Icon.Type.toLowerCase() == 'custom' ? 'Blinds' : config.UserInterface.Panel.Icon.Type}</Icon>
<Name>${config.UserInterface.Panel.Name}</Name>
<ActivityType>Custom</ActivityType>
</Panel>
</Extensions>`
console.info({ Info: 'Buiding UserInterface...', Properties: config.UserInterface.Panel })
if (config.WebModal.Triggers.PanelClicked) {
await xapi.Command.UserInterface.Extensions.Panel.Save({ PanelId: panelId }, xml)
if (config.UserInterface.Panel.Icon.Type.toLowerCase() == 'custom' && config.UserInterface.Panel.Icon.CustomIconURL != '') {
try {
let getIconAndId = (await xapi.Command.UserInterface.Extensions.Icon.Download({ Url: config.UserInterface.Panel.Icon.CustomIconURL })).IconId
console.info({ Info: `Custom Icon fetched, ID: ${getIconAndId}` })
let uploadIcon = await xapi.Command.UserInterface.Extensions.Panel.Update({ IconId: getIconAndId, Icon: 'Custom', PanelId: panelId });
console.info({ Info: `Custom Icon Uploaded!` })
} catch (e) {
console.error(e)
}
}
console.info({ Info: 'UserInterface Built!' })
} else {
await xapi.Command.UserInterface.Extensions.Panel.Remove({ PanelId: panelId })
console.info({ Info: 'UserInterface Removed! PanelClicked Trigger Not Enabled.' })
}
}
let modalLocation = 'Controller';
const handle = {
PanelClicked: async function (event) {
if (event.PanelId == panelId) {
try {
await xapi.Command.UserInterface.WebView.Display({ Title: `${config.WebModal.Title}`, Url: config.WebModal.Url, Target: modalLocation, Mode: 'Modal' })
console.log({ Message: `WebModal Opened [${config.WebModal.Title}] via Panel Clicked Event on [${modalLocation}]` })
} catch (e) {
e.Context = 'Failed to open Webview Display on Panel Clicked'
console.error(e)
}
}
},
CallDisconnect: async function (event) {
if (config.WebModal.OSDToolTip.Mode && modalLocation == 'Controller') {
let x = 1000;
let y = 1000;
switch (config.WebModal.OSDToolTip.Location) {
case 'Top-Right':
x = 9000;
break;
case 'Center':
x = 5000; y = 5000;
break;
case 'Bottom-Left':
y = 9000;
break;
case 'Bottom-Right':
x = 9000; y = 9000;
break;
}
xapi.Command.UserInterface.Message.TextLine.Display({ Text: config.WebModal.OSDToolTip.Message, Duration: config.WebModal.OSDToolTip.Duration, X: x, Y: y })
}
try {
await xapi.Command.UserInterface.WebView.Display({ Title: `${config.WebModal.Title}`, Url: config.WebModal.Url, Target: modalLocation, Mode: 'Modal' })
console.log({ Message: `WebModal Opened [${config.WebModal.Title}] via Call Disconnect Event on [${modalLocation}]` })
} catch (e) {
e.Context = 'Failed to open Webview Display on Call Disonnect'
console.error(e)
}
},
WebViewClear: async function (event) {
if (event?.Status && event.Status == 'NotVisible') {
try {
await xapi.Command.WebEngine.DeleteStorage({ Type: config.WebModal.ClearCacheOnExit.Target })
console.warn({ Warning: `Webview Storage Deleted, Type: [${config.WebModal.ClearCacheOnExit.Target}]` })
} catch (e) {
e.Context = 'Failed to delete Storage on Webview Clear'
console.error(e)
}
}
},
WebViewTimout: async function (event) {
if (event?.Status && event.Status == 'Visible') {
try {
setTimeout(() => {
xapi.Command.UserInterface.WebView.Clear({ Target: modalLocation })
console.log({ Message: `Webview Panel Clear, Type: [${modalLocation}]` })
}, config.WebModal.WebViewTimoutDuration.Duration * 1000);
} catch (e) {
e.Context = 'Failed to close panel on Webview Clear'
console.error(e)
}
}
}
}
async function init() {
console.log({ Info: 'Initializing Macro...' })
const product = await xapi.Status.SystemUnit.ProductPlatform.get()
const peripherals = await xapi.Status.Peripherals.ConnectedDevice.get()
let cause = ''
if (product.includes('Desk') || product.includes('Board')) {
modalLocation = 'OSD'
cause = 'Touch enabled product found without a controller connected'
}
peripherals.forEach(element => {
if (element.Name.includes('Navigator') && element.Location == 'InsideRoom') {
modalLocation = 'Controller'
cause = 'Controller connected inside the room'
}
})
console.info({ Info: `Product Identified [${product}], the WebModal with render on the [${modalLocation}]`, Cause: cause })
await buildUserInterface()
if (config.WebModal.Triggers.PanelClicked) {
xapi.Event.UserInterface.Extensions.Panel.Clicked.on(handle.PanelClicked)
console.info({ Info: 'Subscribed to Panel Clicked Event' })
}
if (config.WebModal.Triggers.CallDisconnect) {
xapi.Event.CallDisconnect.on(handle.CallDisconnect)
console.info({ Info: 'Subscribed to Call Disconnect Event' })
}
if (config.WebModal.ClearCacheOnExit.Mode) {
console.warn({ Warning: `ClearCacheOnExit is enabled, this may interfere with Web Based Solutions on the device outside this macro. Consider Disabling` })
xapi.Status.UserInterface.WebView['*'].on(handle.WebViewClear)
console.info({ Info: 'Subscribed to Webview Cleared Event' })
}
if (config.WebModal.WebViewTimoutDuration.Mode) {
xapi.Status.UserInterface.WebView['*'].on(handle.WebViewTimout)
console.info({ Info: 'Subscribed to Webview Timeout Event' })
}
console.log({ Info: 'Macro Initialized!' })
}
init()