@websy/websy-designs 1.2.31 → 1.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,11 +6,13 @@
6
6
  WebsyPubSub
7
7
  WebsyForm
8
8
  WebsyDatePicker
9
+ WebsyDragDrop
9
10
  WebsyDropdown
10
11
  WebsyRouter
11
12
  WebsyResultList
12
13
  WebsyTable
13
14
  WebsyTable2
15
+ WebsyTable3
14
16
  WebsyChart
15
17
  WebsyChartTooltip
16
18
  WebsyLegend
@@ -372,7 +374,7 @@ class WebsyDatePicker {
372
374
  console.log('No element found with Id', elementId)
373
375
  }
374
376
  }
375
- close (confirm) {
377
+ close (confirm, isRange = false) {
376
378
  const maskEl = document.getElementById(`${this.elementId}_mask`)
377
379
  const contentEl = document.getElementById(`${this.elementId}_content`)
378
380
  const el = document.getElementById(this.elementId)
@@ -401,7 +403,7 @@ class WebsyDatePicker {
401
403
  this.options.onChange(hoursOut, true)
402
404
  }
403
405
  else {
404
- this.options.onChange(this.currentselection, false)
406
+ this.options.onChange(this.currentselection, isRange)
405
407
  }
406
408
  }
407
409
  }
@@ -951,7 +953,7 @@ class WebsyDatePicker {
951
953
  }
952
954
  this.highlightRange()
953
955
  this.updateRange()
954
- this.close(confirm)
956
+ this.close(confirm, true)
955
957
  }
956
958
  }
957
959
  selectCustomRange (rangeInput) {
@@ -1109,6 +1111,278 @@ Date.prototype.floor = function () {
1109
1111
  return new Date(`${this.getMonth() + 1}/${this.getDate()}/${this.getFullYear()}`)
1110
1112
  }
1111
1113
 
1114
+ /* global WebsyDesigns GlobalPubSub */
1115
+ class WebsyDragDrop {
1116
+ constructor (elementId, options) {
1117
+ const DEFAULTS = {
1118
+ items: [],
1119
+ orientation: 'horizontal',
1120
+ dropPlaceholder: 'Drop item here'
1121
+ }
1122
+ this.busy = false
1123
+ this.options = Object.assign({}, DEFAULTS, options)
1124
+ this.elementId = elementId
1125
+ if (!elementId) {
1126
+ console.log('No element Id provided for Websy DragDrop')
1127
+ return
1128
+ }
1129
+ const el = document.getElementById(elementId)
1130
+ if (el) {
1131
+ el.innerHTML = `
1132
+ <div id='${this.elementId}_container' class='websy-drag-drop-container ${this.options.orientation}'>
1133
+ <div>
1134
+ </div>
1135
+ `
1136
+ el.addEventListener('click', this.handleClick.bind(this))
1137
+ el.addEventListener('dragstart', this.handleDragStart.bind(this))
1138
+ el.addEventListener('dragover', this.handleDragOver.bind(this))
1139
+ el.addEventListener('dragleave', this.handleDragLeave.bind(this))
1140
+ el.addEventListener('drop', this.handleDrop.bind(this))
1141
+ window.addEventListener('dragend', this.handleDragEnd.bind(this))
1142
+ }
1143
+ else {
1144
+ console.error(`No element found with ID ${this.elementId}`)
1145
+ }
1146
+ GlobalPubSub.subscribe(this.elementId, 'requestForDDItem', this.handleRequestForItem.bind(this))
1147
+ console.log('constructor dd')
1148
+ console.trace()
1149
+ GlobalPubSub.subscribe(this.elementId, 'add', this.addItem.bind(this))
1150
+ this.render()
1151
+ }
1152
+ addItem (data) {
1153
+ if (data.target === this.elementId && this.busy === false) {
1154
+ this.busy = true
1155
+ console.log('adding item to dd')
1156
+ // check that an item with the same id doesn't already exist
1157
+ let index = this.getItemIndex(data.item.id)
1158
+ if (index === -1) {
1159
+ this.options.items.splice(data.index, 0, data.item)
1160
+ const startEl = document.getElementById(`${this.elementId}start_item`)
1161
+ if (startEl) {
1162
+ if (this.options.items.length === 0) {
1163
+ startEl.classList.add('empty')
1164
+ }
1165
+ else {
1166
+ startEl.classList.remove('empty')
1167
+ }
1168
+ }
1169
+ if (this.options.onItemAdded) {
1170
+ this.options.onItemAdded()
1171
+ }
1172
+ }
1173
+ this.busy = false
1174
+ }
1175
+ }
1176
+ createItemHtml (elementId, index, item) {
1177
+ if (!item.id) {
1178
+ item.id = WebsyDesigns.Utils.createIdentity()
1179
+ }
1180
+ let html = `
1181
+ <div id='${item.id}_item' class='websy-dragdrop-item' draggable='true' data-id='${item.id}'>
1182
+ <div id='${item.id}_itemInner' class='websy-dragdrop-item-inner' data-id='${item.id}'>
1183
+ `
1184
+ if (item.component) {
1185
+ html += `<div id='${item.id}_component'></div>`
1186
+ }
1187
+ else {
1188
+ html += `${item.html || item.label || ''}`
1189
+ }
1190
+ html += `
1191
+ </div>
1192
+ <div id='${item.id}_dropZone' class='websy-drop-zone droppable' data-index='${item.id}' data-side='right' data-id='${item.id}' data-placeholder='${this.options.dropPlaceholder}'></div>
1193
+ </div>
1194
+ `
1195
+ return html
1196
+ }
1197
+ getItemIndex (id) {
1198
+ for (let i = 0; i < this.options.items.length; i++) {
1199
+ if (this.options.items[i].id === id) {
1200
+ return i
1201
+ }
1202
+ }
1203
+ return -1
1204
+ }
1205
+ handleClick (event) {
1206
+
1207
+ }
1208
+ handleDragStart (event) {
1209
+ this.draggedId = event.target.getAttribute('data-id')
1210
+ event.dataTransfer.effectAllowed = 'move'
1211
+ event.dataTransfer.setData('application/wd-item', JSON.stringify({el: event.target.id, id: this.elementId, itemId: this.draggedId}))
1212
+ console.log('drag start', event)
1213
+ event.target.style.opacity = 0.5
1214
+ this.dragging = true
1215
+ }
1216
+ handleDragOver (event) {
1217
+ console.log('drag over', event.target.classList)
1218
+ if (event.preventDefault) {
1219
+ event.preventDefault()
1220
+ }
1221
+ if (!event.target.classList.contains('droppable')) {
1222
+ return
1223
+ }
1224
+ event.target.classList.add('drag-over')
1225
+ }
1226
+ handleDragLeave (event) {
1227
+ console.log('drag leave', event.target.classList)
1228
+ if (!event.target.classList.contains('droppable')) {
1229
+ return
1230
+ }
1231
+ event.target.classList.remove('drag-over')
1232
+ // let side = event.target.getAttribute('data-side')
1233
+ // let id = event.target.getAttribute('data-id')
1234
+ // let droppedItem = this.options.items[id]
1235
+ // this.removeExpandedDrop(side, id, droppedItem)
1236
+ }
1237
+ handleDrop (event) {
1238
+ console.log('drag drop')
1239
+ console.log(event.dataTransfer.getData('application/wd-item'))
1240
+ const data = JSON.parse(event.dataTransfer.getData('application/wd-item'))
1241
+ if (event.preventDefault) {
1242
+ event.preventDefault()
1243
+ }
1244
+ if (!event.target.classList.contains('droppable')) {
1245
+ return
1246
+ }
1247
+ let side = event.target.getAttribute('data-side')
1248
+ let id = event.target.getAttribute('data-id')
1249
+ let index = this.getItemIndex(id)
1250
+ let draggedIndex = this.getItemIndex(data.id)
1251
+ let droppedItem = this.options.items[index]
1252
+ if (side === 'right') {
1253
+ index += 1
1254
+ }
1255
+ if (draggedIndex === -1) {
1256
+ console.log('requestForDDItem')
1257
+ GlobalPubSub.publish(data.id, 'requestForDDItem', {
1258
+ group: this.options.group,
1259
+ source: data.id,
1260
+ target: this.elementId,
1261
+ index,
1262
+ id: data.itemId
1263
+ })
1264
+ }
1265
+ else if (index > draggedIndex) {
1266
+ // insert and then remove
1267
+ this.options.items.splice(index, 0, droppedItem)
1268
+ this.options.items.splice(draggedIndex, 1)
1269
+ if (this.options.onOrderUpdated) {
1270
+ this.options.onOrderUpdated()
1271
+ }
1272
+ }
1273
+ else {
1274
+ // remove and then insert
1275
+ this.options.items.splice(draggedIndex, 1)
1276
+ this.options.items.splice(index, 0, droppedItem)
1277
+ if (this.options.onOrderUpdated) {
1278
+ this.options.onOrderUpdated()
1279
+ }
1280
+ }
1281
+ // this.removeExpandedDrop(side, id, droppedItem)
1282
+ // const draggedEl = document.getElementById(`${this.elementId}_${this.draggedId}_item`)
1283
+ const draggedEl = document.getElementById(data.el)
1284
+ const droppedEl = document.getElementById(`${id}_item`)
1285
+ if (draggedEl) {
1286
+ droppedEl.insertAdjacentElement('afterend', draggedEl)
1287
+ }
1288
+ let dragOverEl = droppedEl.querySelector('.drag-over')
1289
+ if (dragOverEl) {
1290
+ dragOverEl.classList.remove('drag-over')
1291
+ }
1292
+ }
1293
+ handleDragEnd (event) {
1294
+ console.log('drag end')
1295
+ event.target.style.opacity = 1
1296
+ this.draggedId = null
1297
+ this.dragging = false
1298
+ const startEl = document.getElementById(`${this.elementId}start_item`)
1299
+ if (startEl) {
1300
+ if (this.options.items.length === 0) {
1301
+ startEl.classList.add('empty')
1302
+ }
1303
+ else {
1304
+ startEl.classList.remove('empty')
1305
+ }
1306
+ }
1307
+ }
1308
+ handleRequestForItem (data) {
1309
+ if (data.group === this.options.group) {
1310
+ let index = this.getItemIndex(data.id)
1311
+ if (index !== -1) {
1312
+ let itemToAdd = this.options.items.splice(index, 1)
1313
+ GlobalPubSub.publish(data.target, 'add', {
1314
+ target: data.target,
1315
+ index: data.index,
1316
+ item: itemToAdd[0]
1317
+ })
1318
+ }
1319
+ }
1320
+ }
1321
+ measureItems () {
1322
+ const el = document.getElementById(`${this.elementId}_container`)
1323
+ this.options.items.forEach(d => {
1324
+
1325
+ })
1326
+ }
1327
+ // removeExpandedDrop (side, id, droppedItem) {
1328
+ // let dropEl
1329
+ // const dropImageEl = document.getElementById(`${id}_itemInner`)
1330
+ // // const placeholderEl = document.getElementById(`${this.elementId}_${id}_dropZonePlaceholder`)
1331
+ // if (side === 'left') {
1332
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneLeft`)
1333
+ // dropImageEl.style.left = `0px`
1334
+ // }
1335
+ // else if (side === 'right') {
1336
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneRight`)
1337
+ // }
1338
+ // else {
1339
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneEnd`)
1340
+ // }
1341
+ // if (dropEl) {
1342
+ // const dropElSize = dropEl.getBoundingClientRect()
1343
+ // dropEl.style.width = `${(dropElSize.width / 2)}px`
1344
+ // dropEl.style.marginLeft = null
1345
+ // dropEl.style.border = null
1346
+ // }
1347
+ // if (placeholderEl) {
1348
+ // placeholderEl.classList.remove('active')
1349
+ // placeholderEl.style.left = null
1350
+ // placeholderEl.style.right = null
1351
+ // placeholderEl.style.width = null
1352
+ // placeholderEl.style.height = null
1353
+ // }
1354
+ // }
1355
+ removeItem (id) {
1356
+
1357
+ }
1358
+ render () {
1359
+ const el = document.getElementById(`${this.elementId}_container`)
1360
+ if (el) {
1361
+ this.measureItems()
1362
+ let html = `
1363
+ <div id='${this.elementId}start_item' class='websy-dragdrop-item ${this.options.items.length === 0 ? 'empty' : ''}' data-id='${this.elementId}start'>
1364
+ <div id='${this.elementId}start_dropZone' class='websy-drop-zone droppable' data-index='start' data-side='start' data-id='${this.elementId}start' data-placeholder='${this.options.dropPlaceholder}'></div>
1365
+ </div>
1366
+ `
1367
+ html += this.options.items.map((d, i) => this.createItemHtml(this.elementId, i, d)).join('')
1368
+ el.innerHTML = html
1369
+ this.options.items.forEach((item, i) => {
1370
+ if (item.component) {
1371
+ if (item.isQlikPlugin && WebsyDesigns.QlikPlugin[item.component]) {
1372
+ item.instance = new WebsyDesigns.QlikPlugin[item.component](`${item.id}_component`, item.options)
1373
+ }
1374
+ else if (WebsyDesigns[item.component]) {
1375
+ item.instance = new WebsyDesigns[item.component](`${item.id}_component`, item.options)
1376
+ }
1377
+ else {
1378
+ console.error(`Component ${item.component} not found.`)
1379
+ }
1380
+ }
1381
+ })
1382
+ }
1383
+ }
1384
+ }
1385
+
1112
1386
  /* global WebsyUtils */
1113
1387
  class WebsyDropdown {
1114
1388
  constructor (elementId, options) {
@@ -1224,7 +1498,11 @@ class WebsyDropdown {
1224
1498
  d.index = i
1225
1499
  }
1226
1500
  return d
1227
- })
1501
+ })
1502
+ const headerEl = document.getElementById(`${this.elementId}_header`)
1503
+ if (headerEl) {
1504
+ headerEl.classList[`${this.options.allowClear === true ? 'add' : 'remove'}`]('allow-clear')
1505
+ }
1228
1506
  const el = document.getElementById(`${this.elementId}_items`)
1229
1507
  if (el.childElementCount === 0) {
1230
1508
  this.render()
@@ -1545,10 +1823,11 @@ class WebsyDropdown {
1545
1823
  }
1546
1824
  }
1547
1825
  }
1548
- const item = this.options.items[index]
1826
+ // const item = this.options.items[index]
1827
+ const item = this._originalData[index] || this.options.items[index]
1549
1828
  this.updateHeader(item)
1550
1829
  if (item && this.options.onItemSelected) {
1551
- this.options.onItemSelected(item, this.selectedItems, this.options.items, this.options)
1830
+ this.options.onItemSelected(item, this.selectedItems, this._originalData || this.options.items, this.options)
1552
1831
  }
1553
1832
  if (this.options.closeAfterSelection === true) {
1554
1833
  this.close()
@@ -2469,18 +2748,35 @@ class WebsyPubSub {
2469
2748
  this.elementId = elementId
2470
2749
  this.subscriptions = {}
2471
2750
  }
2472
- publish (method, data) {
2473
- if (this.subscriptions[method]) {
2474
- this.subscriptions[method].forEach(fn => {
2475
- fn(data)
2476
- })
2751
+ publish (id, method, data) {
2752
+ if (arguments.length === 3) {
2753
+ if (this.subscriptions[id] && this.subscriptions[id][method]) {
2754
+ this.subscriptions[id][method](data)
2755
+ }
2756
+ }
2757
+ else {
2758
+ if (this.subscriptions[method]) {
2759
+ this.subscriptions[method].forEach(fn => {
2760
+ fn(data)
2761
+ })
2762
+ }
2477
2763
  }
2478
2764
  }
2479
- subscribe (method, fn) {
2480
- if (!this.subscriptions[method]) {
2481
- this.subscriptions[method] = []
2765
+ subscribe (id, method, fn) {
2766
+ if (arguments.length === 3) {
2767
+ if (!this.subscriptions[id]) {
2768
+ this.subscriptions[id] = {}
2769
+ }
2770
+ if (!this.subscriptions[id][method]) {
2771
+ this.subscriptions[id][method] = fn
2772
+ }
2773
+ }
2774
+ else {
2775
+ if (!this.subscriptions[method]) {
2776
+ this.subscriptions[method] = []
2777
+ }
2778
+ this.subscriptions[method].push(fn)
2482
2779
  }
2483
- this.subscriptions[method].push(fn)
2484
2780
  }
2485
2781
  }
2486
2782
 
@@ -4583,7 +4879,12 @@ class WebsyTable2 {
4583
4879
  }
4584
4880
  }
4585
4881
  hideLoading () {
4586
- this.loadingDialog.hide()
4882
+ if (this.options.onLoading) {
4883
+ this.options.onLoading(false)
4884
+ }
4885
+ else {
4886
+ this.loadingDialog.hide()
4887
+ }
4587
4888
  }
4588
4889
  internalSort (column, colIndex) {
4589
4890
  this.options.columns.forEach((c, i) => {
@@ -4658,7 +4959,8 @@ class WebsyTable2 {
4658
4959
  class="tableHeaderField ${['asc', 'desc'].indexOf(c.sort) !== -1 ? 'sortable-column' : ''}"
4659
4960
  data-sort-index="${c.sortIndex || i}"
4660
4961
  data-index="${i}"
4661
- data-sort="${c.sort}"
4962
+ data-sort="${c.sort}"
4963
+ style="${c.style || ''}"
4662
4964
  >
4663
4965
  ${c.name}
4664
4966
  </div>
@@ -4760,7 +5062,12 @@ class WebsyTable2 {
4760
5062
  }
4761
5063
  }
4762
5064
  showLoading (options) {
4763
- this.loadingDialog.show(options)
5065
+ if (this.options.onLoading) {
5066
+ this.options.onLoading(true)
5067
+ }
5068
+ else {
5069
+ this.loadingDialog.show(options)
5070
+ }
4764
5071
  }
4765
5072
  getColumnParameters (values) {
4766
5073
  const tableEl = document.getElementById(`${this.elementId}_table`)
@@ -4824,6 +5131,555 @@ class WebsyTable2 {
4824
5131
  }
4825
5132
  }
4826
5133
 
5134
+ /* global WebsyDesigns */
5135
+ class WebsyTable3 {
5136
+ constructor (elementId, options) {
5137
+ this.elementId = elementId
5138
+ const DEFAULTS = {
5139
+ virtualScroll: false,
5140
+ showTotalsAbove: true,
5141
+ minHandleSize: 20,
5142
+ maxColWidth: '50%',
5143
+ allowPivoting: false
5144
+ }
5145
+ this.options = Object.assign({}, DEFAULTS, options)
5146
+ this.sizes = {}
5147
+ this.scrollDragging = false
5148
+ this.cellDragging = false
5149
+ this.vScrollRequired = false
5150
+ this.hScrollRequired = false
5151
+ this.pinnedColumns = 0
5152
+ this.startRow = 0
5153
+ this.endRow = 0
5154
+ this.startCol = 0
5155
+ this.endCol = 0
5156
+ this.mouseYStart = 0
5157
+ this.mouseYStart = 0
5158
+ if (!elementId) {
5159
+ console.log('No element Id provided for Websy Table')
5160
+ return
5161
+ }
5162
+ const el = document.getElementById(this.elementId)
5163
+ if (el) {
5164
+ let html = `
5165
+ <div id='${this.elementId}_tableContainer' class='websy-vis-table-3 ${this.options.paging === 'pages' ? 'with-paging' : ''} ${this.options.virtualScroll === true ? 'with-virtual-scroll' : ''}'>
5166
+ <!--<div class="download-button">
5167
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 11h5l-9 10-9-10h5v-11h8v11zm1 11h-10v2h10v-2z"/></svg>
5168
+ </div>-->
5169
+ <div id="${this.elementId}_tableInner" class="websy-table-inner-container">
5170
+ <table id="${this.elementId}_tableHeader" class="websy-table-header"></table>
5171
+ <table id="${this.elementId}_tableBody" class="websy-table-body"></table>
5172
+ <table id="${this.elementId}_tableFooter" class="websy-table-footer"></table>
5173
+ <div id="${this.elementId}_vScrollContainer" class="websy-v-scroll-container">
5174
+ <div id="${this.elementId}_vScrollHandle" class="websy-scroll-handle websy-scroll-handle-y"></div>
5175
+ </div>
5176
+ <div id="${this.elementId}_hScrollContainer" class="websy-h-scroll-container">
5177
+ <div id="${this.elementId}_hScrollHandle" class="websy-scroll-handle websy-scroll-handle-x"></div>
5178
+ </div>
5179
+ </div>
5180
+ <div id="${this.elementId}_errorContainer" class='websy-vis-error-container'>
5181
+ <div>
5182
+ <div id="${this.elementId}_errorTitle"></div>
5183
+ <div id="${this.elementId}_errorMessage"></div>
5184
+ </div>
5185
+ </div>
5186
+ <div id="${this.elementId}_dropdownContainer"></div>
5187
+ <div id="${this.elementId}_loadingContainer"></div>
5188
+ </div>
5189
+ `
5190
+ if (this.options.paging === 'pages') {
5191
+ html += `
5192
+ <div class="websy-table-paging-container">
5193
+ Show <div id="${this.elementId}_pageSizeSelector" class="websy-vis-page-selector"></div> rows
5194
+ <ul id="${this.elementId}_pageList" class="websy-vis-page-list"></ul>
5195
+ </div>
5196
+ `
5197
+ }
5198
+ el.innerHTML = html
5199
+ el.addEventListener('click', this.handleClick.bind(this))
5200
+ el.addEventListener('mousedown', this.handleMouseDown.bind(this))
5201
+ window.addEventListener('mousemove', this.handleMouseMove.bind(this))
5202
+ window.addEventListener('mouseup', this.handleMouseUp.bind(this))
5203
+ let scrollEl = document.getElementById(`${this.elementId}_tableBody`)
5204
+ if (scrollEl) {
5205
+ scrollEl.addEventListener('wheel', this.handleScrollWheel.bind(this))
5206
+ }
5207
+ this.loadingDialog = new WebsyDesigns.LoadingDialog(`${this.elementId}_loadingContainer`)
5208
+ this.render(this.options.data)
5209
+ }
5210
+ else {
5211
+ console.error(`No element found with ID ${this.elementId}`)
5212
+ }
5213
+ }
5214
+ set columns (columns) {
5215
+ this.options.columns = columns
5216
+ this.renderColumnHeaders()
5217
+ }
5218
+ set totals (totals) {
5219
+ this.options.totals = totals
5220
+ this.renderTotals()
5221
+ }
5222
+ appendRows (data) {
5223
+ this.hideError()
5224
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5225
+ if (bodyEl) {
5226
+ if (this.options.virtualScroll === true) {
5227
+ bodyEl.innerHTML = this.buildBodyHtml(data, true)
5228
+ }
5229
+ else {
5230
+ bodyEl.innerHTML += this.buildBodyHtml(data, true)
5231
+ }
5232
+ }
5233
+ // this.data = this.data.concat(data)
5234
+ // this.rowCount = this.data.length
5235
+ }
5236
+ buildBodyHtml (data = [], useWidths = false) {
5237
+ if (data.length === 0) {
5238
+ return ''
5239
+ }
5240
+ let bodyHtml = ``
5241
+ let sizingColumns = this.options.columns[this.options.columns.length - 1]
5242
+ if (useWidths === true) {
5243
+ bodyHtml += '<colgroup>'
5244
+ bodyHtml += sizingColumns.map(c => `
5245
+ <col
5246
+ style='width: ${c.width || c.actualWidth}px!important'
5247
+ ></col>
5248
+ `).join('')
5249
+ bodyHtml += '</colgroup>'
5250
+ }
5251
+ data.forEach(row => {
5252
+ bodyHtml += `<tr class="websy-table-row">`
5253
+ row.forEach((cell, cellIndex) => {
5254
+ bodyHtml += `<td
5255
+ class='websy-table-cell'
5256
+ style='${cell.style}'
5257
+ data-info='${cell.value}'
5258
+ colspan='${cell.colspan || 1}'
5259
+ rowspan='${cell.rowspan || 1}'
5260
+ `
5261
+ // if (useWidths === true) {
5262
+ // bodyHtml += `
5263
+ // style='width: ${sizingColumns[cellIndex].width || sizingColumns[cellIndex].actualWidth}px!important'
5264
+ // width='${sizingColumns[cellIndex].width || sizingColumns[cellIndex].actualWidth}'
5265
+ // `
5266
+ // }
5267
+ bodyHtml += `
5268
+ >
5269
+ ${cell.value}
5270
+ </td>`
5271
+ })
5272
+ bodyHtml += `</tr>`
5273
+ })
5274
+ // bodyHtml += `</div>`
5275
+ return bodyHtml
5276
+ }
5277
+ buildHeaderHtml (useWidths = false) {
5278
+ let headerHtml = ''
5279
+ let sizingColumns = this.options.columns[this.options.columns.length - 1]
5280
+ if (useWidths === true) {
5281
+ headerHtml += '<colgroup>'
5282
+ headerHtml += sizingColumns.map(c => `
5283
+ <col
5284
+ style='width: ${c.width || c.actualWidth}px!important'
5285
+ ></col>
5286
+ `).join('')
5287
+ headerHtml += '</colgroup>'
5288
+ }
5289
+ this.options.columns.forEach((row, rowIndex) => {
5290
+ if (useWidths === false && rowIndex !== this.options.columns.length - 1) {
5291
+ // if we're calculating the size we only want to render the last row of column headers
5292
+ return
5293
+ }
5294
+ headerHtml += `<tr class="websy-table-row websy-table-header-row">`
5295
+ row.forEach(col => {
5296
+ headerHtml += `<td
5297
+ class='websy-table-cell'
5298
+ style='${col.style}'
5299
+ colspan='${col.colspan || 1}'
5300
+ rowspan='${col.rowspan || 1}'
5301
+ `
5302
+ // if (useWidths === true && rowIndex === this.options.columns.length - 1) {
5303
+ // headerHtml += `
5304
+ // style='width: ${col.width || col.actualWidth}px'
5305
+ // width='${col.width || col.actualWidth}'
5306
+ // `
5307
+ // }
5308
+ headerHtml += `
5309
+ >
5310
+ ${col.name}
5311
+ </td>`
5312
+ })
5313
+ headerHtml += `</tr>`
5314
+ })
5315
+ return headerHtml
5316
+ }
5317
+ buildTotalHtml (useWidths = false) {
5318
+ if (!this.options.totals) {
5319
+ return ''
5320
+ }
5321
+ let totalHtml = `<tr class="websy-table-row websy-table-total-row">`
5322
+ this.options.totals.forEach((col, colIndex) => {
5323
+ totalHtml += `<td
5324
+ class='websy-table-cell'
5325
+ colspan='${col.colspan || 1}'
5326
+ rowspan='${col.rowspan || 1}'
5327
+ `
5328
+ if (useWidths === true) {
5329
+ totalHtml += `
5330
+ style='width: ${this.options.columns[this.options.columns.length - 1][colIndex].width || this.options.columns[this.options.columns.length - 1][colIndex].actualWidth}px'
5331
+ width='${col.width || col.actualWidth}'
5332
+ `
5333
+ }
5334
+ totalHtml += `
5335
+ >
5336
+ ${col.value}
5337
+ </td>`
5338
+ })
5339
+ totalHtml += `</tr>`
5340
+ return totalHtml
5341
+ }
5342
+ calculateSizes (sample = [], totalRowCount, totalColumnCount, pinnedColumns) {
5343
+ this.totalRowCount = totalRowCount // probably need some error handling here if no value is passed in
5344
+ this.totalColumnCount = totalColumnCount // probably need some error handling here if no value is passed in
5345
+ this.pinnedColumns = pinnedColumns // probably need some error handling here if no value is passed in
5346
+ let outerEl = document.getElementById(this.elementId)
5347
+ let tableEl = document.getElementById(`${this.elementId}_tableContainer`)
5348
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5349
+ headEl.style.width = 'auto'
5350
+ headEl.innerHTML = this.buildHeaderHtml()
5351
+ this.sizes.outer = outerEl.getBoundingClientRect()
5352
+ this.sizes.table = tableEl.getBoundingClientRect()
5353
+ this.sizes.header = headEl.getBoundingClientRect()
5354
+ let maxWidth
5355
+ if (typeof this.options.maxColWidth === 'number') {
5356
+ maxWidth = this.options.maxColWidth
5357
+ }
5358
+ else if (this.options.maxColWidth.indexOf('%') !== -1) {
5359
+ maxWidth = this.sizes.outer.width * (+(this.options.maxColWidth.replace('%', '')) / 100)
5360
+ }
5361
+ else if (this.options.maxColWidth.indexOf('px') !== -1) {
5362
+ maxWidth = +this.options.maxColWidth.replace('px', '')
5363
+ }
5364
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5365
+ bodyEl.style.width = 'auto'
5366
+ bodyEl.innerHTML = this.buildBodyHtml([sample])
5367
+ let footerEl = document.getElementById(`${this.elementId}_tableFooter`)
5368
+ footerEl.innerHTML = this.buildTotalHtml()
5369
+ this.sizes.total = footerEl.getBoundingClientRect()
5370
+ const rows = Array.from(tableEl.querySelectorAll('.websy-table-row'))
5371
+ let totalWidth = 0
5372
+ this.sizes.scrollableWidth = this.sizes.outer.width
5373
+ rows.forEach((row, rowIndex) => {
5374
+ Array.from(row.children).forEach((col, colIndex) => {
5375
+ let colSize = col.getBoundingClientRect()
5376
+ this.sizes.cellHeight = colSize.height
5377
+ if (this.options.columns[this.options.columns.length - 1][colIndex]) {
5378
+ if (!this.options.columns[this.options.columns.length - 1][colIndex].actualWidth) {
5379
+ this.options.columns[this.options.columns.length - 1][colIndex].actualWidth = 0
5380
+ }
5381
+ this.options.columns[this.options.columns.length - 1][colIndex].actualWidth = Math.min(Math.max(this.options.columns[this.options.columns.length - 1][colIndex].actualWidth, colSize.width), maxWidth)
5382
+ this.options.columns[this.options.columns.length - 1][colIndex].cellHeight = colSize.height
5383
+ }
5384
+ })
5385
+ })
5386
+ this.options.columns[this.options.columns.length - 1].forEach((col, colIndex) => {
5387
+ if (colIndex < this.pinnedColumns) {
5388
+ this.sizes.scrollableWidth -= col.actualWidth
5389
+ }
5390
+ })
5391
+ this.sizes.totalWidth = this.options.columns[this.options.columns.length - 1].reduce((a, b) => a + (b.width || b.actualWidth), 0)
5392
+ const outerSize = outerEl.getBoundingClientRect()
5393
+ if (this.sizes.totalWidth < outerSize.width) {
5394
+ this.sizes.totalWidth = 0
5395
+ let equalWidth = outerSize.width / this.options.columns[this.options.columns.length - 1].length
5396
+ this.options.columns[this.options.columns.length - 1].forEach((c, i) => {
5397
+ if (!c.width) {
5398
+ if (c.actualWidth < equalWidth) {
5399
+ // adjust the width
5400
+ c.actualWidth = equalWidth
5401
+ }
5402
+ }
5403
+ this.sizes.totalWidth += c.width || c.actualWidth
5404
+ equalWidth = (outerSize.width - this.sizes.totalWidth) / (this.options.columns[this.options.columns.length - 1].length - (i + 1))
5405
+ })
5406
+ }
5407
+ // take the height of the last cell as the official height for data cells
5408
+ // this.sizes.dataCellHeight = this.options.columns[this.options.columns.length - 1].cellHeight
5409
+ headEl.innerHTML = ''
5410
+ bodyEl.innerHTML = ''
5411
+ footerEl.innerHTML = ''
5412
+ headEl.style.width = 'initial'
5413
+ bodyEl.style.width = 'initial'
5414
+ this.sizes.bodyHeight = this.sizes.table.height - (this.sizes.header.height + this.sizes.total.height)
5415
+ this.sizes.rowsToRender = Math.ceil(this.sizes.bodyHeight / this.sizes.cellHeight)
5416
+ this.sizes.rowsToRenderPrecise = this.sizes.bodyHeight / this.sizes.cellHeight
5417
+ this.startRow = 0
5418
+ this.endRow = this.sizes.rowsToRender
5419
+ this.startCol = 0
5420
+ this.endCol = this.options.columns[this.options.columns.length - 1].length
5421
+ if (this.sizes.rowsToRender < this.totalRowCount) {
5422
+ this.vScrollRequired = true
5423
+ }
5424
+ if (this.sizes.totalWidth > this.sizes.outer.width) {
5425
+ this.hScrollRequired = true
5426
+ }
5427
+ this.options.allColumns = this.options.columns.map(c => c)
5428
+ console.log('sizes', this.sizes)
5429
+ return this.sizes
5430
+ }
5431
+ createSample (data) {
5432
+ let output = []
5433
+ this.options.columns[this.options.columns.length - 1].forEach((col, colIndex) => {
5434
+ if (col.maxLength) {
5435
+ output.push({value: new Array(col.maxLength).fill('W').join('')})
5436
+ }
5437
+ else if (data) {
5438
+ let longest = ''
5439
+ for (let i = 0; i < Math.min(data.length, 1000); i++) {
5440
+ if (longest.length < data[i][colIndex].value.length) {
5441
+ longest = data[i][colIndex].value
5442
+ }
5443
+ }
5444
+ output.push({value: longest})
5445
+ }
5446
+ else {
5447
+ output.push({value: ''})
5448
+ }
5449
+ })
5450
+ return output
5451
+ }
5452
+ handleClick (event) {
5453
+
5454
+ }
5455
+ handleMouseDown (event) {
5456
+ if (event.target.classList.contains('websy-scroll-handle-y')) {
5457
+ // set up the scroll start values
5458
+ this.scrollDragging = true
5459
+ this.scrollDirection = 'y'
5460
+ const scrollHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5461
+ this.handleYStart = scrollHandleEl.offsetTop
5462
+ this.mouseYStart = event.pageY
5463
+ console.log('mouse down', this.handleYStart, this.mouseYStart)
5464
+ console.log(scrollHandleEl.offsetTop)
5465
+ }
5466
+ else if (event.target.classList.contains('websy-scroll-handle-x')) {
5467
+ this.scrollDragging = true
5468
+ this.scrollDirection = 'x'
5469
+ const scrollHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5470
+ this.handleXStart = scrollHandleEl.offsetLeft
5471
+ this.mouseXStart = event.pageX
5472
+ }
5473
+ }
5474
+ handleMouseMove (event) {
5475
+ // event.preventDefault()
5476
+ if (this.scrollDragging === true) {
5477
+ if (this.scrollDirection === 'y') {
5478
+ const diff = event.pageY - this.mouseYStart
5479
+ this.scrollY(diff)
5480
+ }
5481
+ else if (this.scrollDirection === 'x') {
5482
+ const diff = event.pageX - this.mouseXStart
5483
+ this.scrollX(diff)
5484
+ }
5485
+ }
5486
+ }
5487
+ handleMouseUp (event) {
5488
+ this.scrollDragging = false
5489
+ this.cellDragging = false
5490
+ this.handleYStart = null
5491
+ this.mouseYStart = null
5492
+ this.handleXStart = null
5493
+ this.mouseXStart = null
5494
+ }
5495
+ handleScrollWheel (event) {
5496
+ event.preventDefault()
5497
+ console.log('scrollwheel', event)
5498
+ if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
5499
+ this.scrollX(Math.max(-5, Math.min(5, event.deltaX)))
5500
+ }
5501
+ else {
5502
+ this.scrollY(Math.max(-5, Math.min(5, event.deltaY)))
5503
+ }
5504
+ }
5505
+ hideError () {
5506
+ const el = document.getElementById(`${this.elementId}_tableContainer`)
5507
+ if (el) {
5508
+ el.classList.remove('has-error')
5509
+ }
5510
+ const tableEl = document.getElementById(`${this.elementId}_tableInner`)
5511
+ tableEl.classList.remove('hidden')
5512
+ const containerEl = document.getElementById(`${this.elementId}_errorContainer`)
5513
+ if (containerEl) {
5514
+ containerEl.classList.remove('active')
5515
+ }
5516
+ }
5517
+ hideLoading () {
5518
+ this.loadingDialog.hide()
5519
+ }
5520
+ render (data, calcSizes = true) {
5521
+ if (!this.options.columns) {
5522
+ console.log(`No columns provided for table with ID ${this.elementId}`)
5523
+ return
5524
+ }
5525
+ if (this.options.columns.length === 0) {
5526
+ console.log(`No columns provided for table with ID ${this.elementId}`)
5527
+ return
5528
+ }
5529
+ // this.data = []
5530
+ // Adjust the sizing of the header/body/footer
5531
+ if (calcSizes === true) {
5532
+ const sample = this.createSample(data)
5533
+ this.calculateSizes(sample, data.length, (data[0] || []).length, 0)
5534
+ }
5535
+ console.log(this.options.columns)
5536
+ const tableInnerEl = document.getElementById(`${this.elementId}_tableInner`)
5537
+ if (tableInnerEl) {
5538
+ tableInnerEl.style.width = `${this.sizes.totalWidth}px`
5539
+ }
5540
+ this.renderColumnHeaders()
5541
+ this.renderTotals()
5542
+ if (data) {
5543
+ this.appendRows(data)
5544
+ }
5545
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5546
+ // bodyEl.innerHTML = this.buildBodyHtml(data, true)
5547
+ bodyEl.style.height = `calc(100% - ${this.sizes.header.height}px - ${this.sizes.total.height}px)`
5548
+ if (this.options.virtualScroll === true) {
5549
+ // set the scroll element positions
5550
+ if (this.vScrollRequired === true) {
5551
+ let vScrollEl = document.getElementById(`${this.elementId}_vScrollContainer`)
5552
+ let vHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5553
+ vScrollEl.style.top = `${this.sizes.header.height + this.sizes.total.height}px`
5554
+ vScrollEl.style.height = `${this.sizes.bodyHeight}px`
5555
+ vHandleEl.style.height = Math.max(this.options.minHandleSize, this.sizes.bodyHeight * (this.sizes.rowsToRenderPrecise / this.totalRowCount)) + 'px'
5556
+ }
5557
+ if (this.hScrollRequired === true) {
5558
+ let hScrollEl = document.getElementById(`${this.elementId}_hScrollContainer`)
5559
+ let hHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5560
+ hScrollEl.style.left = `${this.sizes.table.width - this.sizes.scrollableWidth}px`
5561
+ hScrollEl.style.width = `${this.sizes.scrollableWidth - 20}px`
5562
+ hHandleEl.style.width = Math.max(this.options.minHandleSize, this.sizes.scrollableWidth * (this.sizes.scrollableWidth / this.sizes.totalWidth)) + 'px'
5563
+ }
5564
+ }
5565
+ }
5566
+ renderColumnHeaders () {
5567
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5568
+ if (headEl) {
5569
+ headEl.innerHTML = this.buildHeaderHtml(true)
5570
+ }
5571
+ }
5572
+ renderTotals () {
5573
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5574
+ let totalHtml = this.buildTotalHtml(true)
5575
+ if (this.options.showTotalsAbove === true) {
5576
+ headEl.innerHTML += totalHtml
5577
+ }
5578
+ else {
5579
+ const footerEl = document.getElementById(`${this.elementId}_tableFooter`)
5580
+ if (footerEl) {
5581
+ footerEl.innerHTML = totalHtml
5582
+ }
5583
+ }
5584
+ }
5585
+ resize () {
5586
+
5587
+ }
5588
+ showError (options) {
5589
+ const el = document.getElementById(`${this.elementId}_tableContainer`)
5590
+ if (el) {
5591
+ el.classList.add('has-error')
5592
+ }
5593
+ const tableEl = document.getElementById(`${this.elementId}_tableInner`)
5594
+ tableEl.classList.add('hidden')
5595
+ const containerEl = document.getElementById(`${this.elementId}_errorContainer`)
5596
+ if (containerEl) {
5597
+ containerEl.classList.add('active')
5598
+ }
5599
+ if (options.title) {
5600
+ const titleEl = document.getElementById(`${this.elementId}_errorTitle`)
5601
+ if (titleEl) {
5602
+ titleEl.innerHTML = options.title
5603
+ }
5604
+ }
5605
+ if (options.message) {
5606
+ const messageEl = document.getElementById(`${this.elementId}_errorMessage`)
5607
+ if (messageEl) {
5608
+ messageEl.innerHTML = options.message
5609
+ }
5610
+ }
5611
+ }
5612
+ scrollX (diff) {
5613
+ const scrollContainerEl = document.getElementById(`${this.elementId}_hScrollContainer`)
5614
+ const scrollHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5615
+ let handlePos
5616
+ if (typeof this.handleXStart !== 'undefined' && this.handleXStart !== null) {
5617
+ handlePos = this.handleXStart + diff
5618
+ }
5619
+ else {
5620
+ handlePos = scrollHandleEl.offsetLeft + diff
5621
+ }
5622
+ const scrollableSpace = scrollContainerEl.getBoundingClientRect().width - scrollHandleEl.getBoundingClientRect().width
5623
+ console.log('dragging x', diff, scrollContainerEl.getBoundingClientRect().width - scrollHandleEl.getBoundingClientRect().width)
5624
+ scrollHandleEl.style.left = Math.min(scrollableSpace, Math.max(0, handlePos)) + 'px'
5625
+ if (this.options.onScroll) {
5626
+ let actualLeft = (this.sizes.totalWidth - this.sizes.scrollableWidth) * (Math.min(scrollableSpace, Math.max(0, handlePos)) / scrollableSpace)
5627
+ let cumulativeWidth = 0
5628
+ this.startCol = 0
5629
+ this.endCol = 0
5630
+ for (let i = 0; i < this.options.allColumns[this.options.allColumns.length - 1].length; i++) {
5631
+ cumulativeWidth += this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth
5632
+ console.log(actualLeft, this.sizes.totalWidth, cumulativeWidth, cumulativeWidth + this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth)
5633
+ if (actualLeft < cumulativeWidth) {
5634
+ this.startCol = i
5635
+ break
5636
+ }
5637
+ }
5638
+ cumulativeWidth = 0
5639
+ for (let i = this.startCol; i < this.options.allColumns[this.options.allColumns.length - 1].length; i++) {
5640
+ cumulativeWidth += this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth
5641
+ if (cumulativeWidth < this.sizes.scrollableWidth) {
5642
+ this.endCol = i
5643
+ }
5644
+ }
5645
+ if (this.endCol < this.options.allColumns[this.options.allColumns.length - 1].length - 1) {
5646
+ this.endCol += 1
5647
+ }
5648
+ if (this.endCol === this.options.allColumns[this.options.allColumns.length - 1].length - 1 && cumulativeWidth > this.sizes.totalWidth) {
5649
+ this.startCol += 1
5650
+ }
5651
+ this.endCol = Math.max(this.startCol, this.endCol)
5652
+ this.options.onScroll('y', this.startRow, this.endRow, this.startCol, this.endCol)
5653
+ }
5654
+ }
5655
+ scrollY (diff) {
5656
+ const scrollContainerEl = document.getElementById(`${this.elementId}_vScrollContainer`)
5657
+ const scrollHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5658
+ let handlePos
5659
+ if (typeof this.handleYStart !== 'undefined' && this.handleYStart !== null) {
5660
+ handlePos = this.handleYStart + diff
5661
+ }
5662
+ else {
5663
+ console.log('appending not resetting')
5664
+ handlePos = scrollHandleEl.offsetTop + diff
5665
+ }
5666
+ const scrollableSpace = scrollContainerEl.getBoundingClientRect().height - scrollHandleEl.getBoundingClientRect().height
5667
+ console.log('dragging y', (diff), scrollContainerEl.getBoundingClientRect().height - scrollHandleEl.getBoundingClientRect().height)
5668
+ scrollHandleEl.style.top = Math.min(scrollableSpace, Math.max(0, handlePos)) + 'px'
5669
+ if (this.options.onScroll) {
5670
+ this.startRow = Math.min(this.totalRowCount - this.sizes.rowsToRender, Math.max(0, Math.round((this.totalRowCount - this.sizes.rowsToRender) * (handlePos / scrollableSpace))))
5671
+ this.endRow = this.startRow + this.sizes.rowsToRender
5672
+ if (this.endRow === this.totalRowCount) {
5673
+ this.startRow += 1
5674
+ }
5675
+ this.options.onScroll('y', this.startRow, this.endRow, this.startCol, this.endCol)
5676
+ }
5677
+ }
5678
+ showLoading (options) {
5679
+ this.loadingDialog.show(options)
5680
+ }
5681
+ }
5682
+
4827
5683
  /* global d3 include WebsyDesigns */
4828
5684
  class WebsyChart {
4829
5685
  constructor (elementId, options) {
@@ -5748,7 +6604,7 @@ bars
5748
6604
  .attr('x', getBarX.bind(this))
5749
6605
  .attr('y', getBarY.bind(this))
5750
6606
  .transition(this.transition)
5751
- .attr('fill', series.color)
6607
+ .attr('fill', d => d.color || series.color)
5752
6608
 
5753
6609
  bars
5754
6610
  .enter()
@@ -5758,7 +6614,7 @@ bars
5758
6614
  .attr('x', getBarX.bind(this))
5759
6615
  .attr('y', getBarY.bind(this))
5760
6616
  // .transition(this.transition)
5761
- .attr('fill', series.color)
6617
+ .attr('fill', d => d.color || series.color)
5762
6618
  .attr('class', d => {
5763
6619
  return `bar bar_${series.key}`
5764
6620
  })
@@ -5788,7 +6644,7 @@ if (this.options.showLabels) {
5788
6644
  .attr('y', getLabelY.bind(this))
5789
6645
  .attr('class', `label_${series.key}`)
5790
6646
  .style('font-size', `${this.options.labelSize || this.options.fontSize}px`)
5791
- .style('fill', this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(series.color))
6647
+ .style('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.color || series.color))
5792
6648
  .transition(this.transition)
5793
6649
  .text(d => d.y.label || d.y.value)
5794
6650
 
@@ -5801,7 +6657,7 @@ if (this.options.showLabels) {
5801
6657
  .attr('alignment-baseline', 'central')
5802
6658
  .attr('text-anchor', this.options.orientation === 'horizontal' ? 'left' : 'middle')
5803
6659
  .style('font-size', `${this.options.labelSize || this.options.fontSize}px`)
5804
- .style('fill', this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(series.color))
6660
+ .style('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.color || series.color))
5805
6661
  .text(d => d.y.label || d.y.value)
5806
6662
  .each(function (d, i) {
5807
6663
  if (that.options.orientation === 'horizontal') {
@@ -6495,6 +7351,8 @@ const WebsyDesigns = {
6495
7351
  Form: WebsyForm,
6496
7352
  WebsyDatePicker,
6497
7353
  DatePicker: WebsyDatePicker,
7354
+ WebsyDragDrop,
7355
+ DragDrop: WebsyDragDrop,
6498
7356
  WebsyDropdown,
6499
7357
  Dropdown: WebsyDropdown,
6500
7358
  WebsyResultList,
@@ -6507,8 +7365,10 @@ const WebsyDesigns = {
6507
7365
  Router: WebsyRouter,
6508
7366
  WebsyTable,
6509
7367
  WebsyTable2,
7368
+ WebsyTable3,
6510
7369
  Table: WebsyTable,
6511
7370
  Table2: WebsyTable2,
7371
+ Table3: WebsyTable3,
6512
7372
  WebsyChart,
6513
7373
  Chart: WebsyChart,
6514
7374
  WebsyChartTooltip,
@@ -6535,5 +7395,6 @@ const WebsyDesigns = {
6535
7395
  }
6536
7396
 
6537
7397
  WebsyDesigns.service = new WebsyDesigns.APIService('')
7398
+ window.GlobalPubSub = new WebsyPubSub('empty', {})
6538
7399
 
6539
7400
  export default WebsyDesigns