@websy/websy-designs 1.9.14 → 1.10.0

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.
@@ -43,29 +43,45 @@ function APIRoutes (dbHelper, authHelper) {
43
43
  }
44
44
  }, err => res.json(err))
45
45
  })
46
+ router.post('/:entity/upsert', authHelper.checkPermissions, (req, res) => {
47
+ let user
48
+ if (req.session && req.session.user) {
49
+ user = req.session.user
50
+ }
51
+ const sql = dbHelper.buildUpsert(req.params.entity, req.body, user)
52
+ console.log('upsert sql', sql)
53
+ dbHelper.execute(sql).then(response => res.json(response), err => res.json(err))
54
+ })
46
55
  router.post('/:entity', authHelper.checkPermissions, (req, res) => {
47
56
  // const sql = dbHelper.buildInsert(req.params.entity, req.body, req.session.passport.user.id)
48
- console.log(req.body)
49
- console.log(req.session)
57
+ // console.log(req.body)
58
+ // console.log(req.session)
50
59
  let user
51
60
  if (req.session && req.session.user) {
52
61
  user = req.session.user
53
62
  }
54
63
  const sql = dbHelper.buildInsert(req.params.entity, req.body, user)
55
- console.log(sql)
64
+ // console.log(sql)
56
65
  dbHelper.execute(sql).then(response => res.json(response), err => {
57
66
  res.statusCode = 404
58
67
  res.json({err})
59
68
  })
60
- })
61
- console.log('defining put endpoint for /:entity/:id')
62
- router.put('/:entity/:id', (req, res) => {
63
- console.log('executing put')
64
- const sql = dbHelper.buildUpdateWithId(req.params.entity, req.params.id, req.body)
69
+ })
70
+ // console.log('defining put endpoint for /:entity/:id')
71
+ router.put('/:entity/:id', authHelper.checkPermissions, (req, res) => {
72
+ let user
73
+ if (req.session && req.session.user) {
74
+ user = req.session.user
75
+ }
76
+ const sql = dbHelper.buildUpdateWithId(req.params.entity, req.params.id, req.body, user)
65
77
  dbHelper.execute(sql).then(response => res.json(response), err => res.json(err))
66
78
  })
67
- router.put('/:entity', (req, res) => {
68
- const sql = dbHelper.buildUpdate(req.params.entity, req.query.where, req.body)
79
+ router.put('/:entity', authHelper.checkPermissions, (req, res) => {
80
+ let user
81
+ if (req.session && req.session.user) {
82
+ user = req.session.user
83
+ }
84
+ const sql = dbHelper.buildUpdate(req.params.entity, req.query.where, req.body, user)
69
85
  dbHelper.execute(sql).then(response => res.json(response), err => res.json(err))
70
86
  })
71
87
  return router
@@ -55,6 +55,10 @@ class APIService {
55
55
  const url = this.buildUrl(entity, id)
56
56
  return this.run('DELETE', url)
57
57
  }
58
+ deleteMany (entity, query) {
59
+ const url = this.buildUrl(entity, null, query)
60
+ return this.run('DELETE', url)
61
+ }
58
62
  get (entity, id, query, offset, limit) {
59
63
  let url = this.buildUrl(entity, id, query)
60
64
  if (offset) {
@@ -65,12 +69,12 @@ class APIService {
65
69
  url += `?offset=${offset}`
66
70
  }
67
71
  }
68
- if (limit) {
72
+ if (limit || this.options.rowLimit) {
69
73
  if (url.indexOf('?') !== -1) {
70
- url += `&limit=${limit}`
74
+ url += `&limit=${limit || this.options.rowLimit}`
71
75
  }
72
76
  else {
73
- url += `?limit=${limit}`
77
+ url += `?limit=${limit || this.options.rowLimit}`
74
78
  }
75
79
  }
76
80
  return this.run('GET', url)
@@ -188,16 +192,51 @@ class ButtonGroup {
188
192
  this.render()
189
193
  }
190
194
  }
195
+ get value () {
196
+ if (this.options.activeItem > -1) {
197
+ return [this.options.items[this.options.activeItem]]
198
+ }
199
+ else if (this.options.multiSelect === true) {
200
+ return this.options.items.filter(d => d.selected)
201
+ }
202
+ return []
203
+ }
204
+ set value (value) {
205
+ let activeIndex = -1
206
+ if (this.options.multiSelect === true) {
207
+ if (Array.isArray(value)) {
208
+ this.options.items.forEach(d => {
209
+ if (value.indexOf(d.value) !== -1) {
210
+ d.selected = true
211
+ }
212
+ else {
213
+ d.selected = false
214
+ }
215
+ })
216
+ }
217
+ }
218
+ else {
219
+ for (let i = 0; i < this.options.items.length; i++) {
220
+ if ((this.options.items[i].value || this.options.items[i].label) === value) {
221
+ activeIndex = i
222
+ }
223
+ }
224
+ this.options.activeItem = activeIndex
225
+ }
226
+ this.render()
227
+ }
191
228
  handleClick (event) {
192
229
  if (event.target.classList.contains('websy-button-group-item')) {
193
230
  const index = +event.target.getAttribute('data-index')
194
231
  if (this.options.multiSelect === true) {
195
232
  if (event.target.classList.contains('active')) {
233
+ this.options.items[index].selected = false
196
234
  this.options.onDeactivate(this.options.items[index], index, event)
197
235
  event.target.classList.remove('active')
198
236
  event.target.classList.add('inactive')
199
237
  }
200
238
  else {
239
+ this.options.items[index].selected = true
201
240
  this.options.onActivate(this.options.items[index], index, event)
202
241
  event.target.classList.add('active')
203
242
  event.target.classList.remove('inactive')
@@ -248,7 +287,10 @@ class ButtonGroup {
248
287
  let activeClass = ''
249
288
  if (this.options.activeItem !== -1) {
250
289
  activeClass = i === this.options.activeItem ? 'active' : 'inactive'
251
- }
290
+ }
291
+ else if (this.options.multiSelect === true) {
292
+ activeClass = t.selected === true ? 'active' : 'inactive'
293
+ }
252
294
  return `
253
295
  <${this.options.tag} ${(t.attributes || []).join(' ')} data-id="${t.id || t.label}" data-index="${i}" class="websy-button-group-item ${(t.classes || []).join(' ')} ${this.options.style}-style ${activeClass}">${t.label}</${this.options.tag}>
254
296
  `
@@ -1858,6 +1900,7 @@ class WebsyDropdown {
1858
1900
  const contentPos = WebsyUtils.getElementPos(contentEl)
1859
1901
  if (this.options.style === 'plain' && headerPos.width > 0 && headerPos.height > 0) {
1860
1902
  contentEl.style.right = `calc(100vw - ${headerPos.right}px)`
1903
+ contentEl.style.width = `${headerEl.clientWidth}px`
1861
1904
  if (headerPos.bottom + contentPos.height > window.innerHeight) {
1862
1905
  // contentEl.classList.add('on-top')
1863
1906
  contentEl.style.bottom = `calc(100vh - ${headerPos.top}px)`
@@ -1869,6 +1912,7 @@ class WebsyDropdown {
1869
1912
  else if (this.options.style === 'plain' && headerPos.width === 0 && headerPos.height === 0) {
1870
1913
  const targetPos = WebsyUtils.getElementPos(event.target)
1871
1914
  contentEl.style.right = `calc(100vw - ${targetPos.right}px)`
1915
+ contentEl.style.width = `${targetPos.width}px`
1872
1916
  }
1873
1917
  if (this.options.disableSearch !== true) {
1874
1918
  const searchEl = document.getElementById(`${this.elementId}_search`)
@@ -1880,6 +1924,19 @@ class WebsyDropdown {
1880
1924
  this.options.onOpen(this.elementId)
1881
1925
  }
1882
1926
  }
1927
+ set items (items) {
1928
+ this.options.items = [...items]
1929
+ if (this.options.items.length > 0) {
1930
+ this.options.items = this.options.items.map((d, i) => {
1931
+ if (typeof d.index === 'undefined') {
1932
+ d.index = i
1933
+ }
1934
+ return d
1935
+ })
1936
+ }
1937
+ this._originalData = [...this.options.items]
1938
+ this.render()
1939
+ }
1883
1940
  render () {
1884
1941
  if (!this.elementId) {
1885
1942
  console.log('No element Id provided for Websy Dropdown')
@@ -2078,9 +2135,7 @@ class WebsyForm {
2078
2135
  }
2079
2136
  GlobalPubSub.subscribe('recaptchaready', this.recaptchaReady.bind(this))
2080
2137
  this.recaptchaResult = null
2081
- this.options = Object.assign(defaults, {}, {
2082
- // defaults go here
2083
- }, options)
2138
+ this.options = Object.assign({}, defaults, options)
2084
2139
  if (!elementId) {
2085
2140
  console.log('No element Id provided')
2086
2141
  return
@@ -2148,8 +2203,27 @@ class WebsyForm {
2148
2203
  const data = {}
2149
2204
  const temp = new FormData(formEl)
2150
2205
  temp.forEach((value, key) => {
2151
- data[key] = value
2206
+ if (this.fieldMap[key] && this.fieldMap[key].type === 'checkbox') {
2207
+ data[key] = true
2208
+ }
2209
+ if (this.fieldMap[key] && this.fieldMap[key].instance && this.fieldMap[key].instance.value) {
2210
+ data[key] = this.fieldMap[key].instance.value
2211
+ }
2212
+ else {
2213
+ data[key] = value
2214
+ }
2152
2215
  })
2216
+ let keys = Object.keys(data)
2217
+ for (const key in this.fieldMap) {
2218
+ if (keys.indexOf(key) === -1) {
2219
+ if (this.fieldMap[key] && this.fieldMap[key].type === 'checkbox') {
2220
+ data[key] = false
2221
+ }
2222
+ else if (this.fieldMap[key] && this.fieldMap[key].instance && this.fieldMap[key].instance.value) {
2223
+ data[key] = this.fieldMap[key].instance.value
2224
+ }
2225
+ }
2226
+ }
2153
2227
  return data
2154
2228
  }
2155
2229
  set data (d) {
@@ -2207,6 +2281,7 @@ class WebsyForm {
2207
2281
  handleClick (event) {
2208
2282
  if (event.target.classList.contains('submit')) {
2209
2283
  event.preventDefault()
2284
+ event.stopPropagation()
2210
2285
  this.submitForm()
2211
2286
  }
2212
2287
  else if (event.target.classList.contains('cancel')) {
@@ -2379,6 +2454,7 @@ class WebsyForm {
2379
2454
  `
2380
2455
  this.options.fields.forEach((f, i) => {
2381
2456
  this.fieldMap[f.field] = f
2457
+ f.owningElement = this.elementId
2382
2458
  if (f.component) {
2383
2459
  componentsToProcess.push(f)
2384
2460
  html += `
@@ -2465,6 +2541,10 @@ class WebsyForm {
2465
2541
  const el = document.getElementById(`${this.elementId}_input_${field}`)
2466
2542
  if (el) {
2467
2543
  el.value = value
2544
+ el.setAttribute('value', value)
2545
+ if (this.fieldMap[field].type === 'checkbox') {
2546
+ el.checked = value
2547
+ }
2468
2548
  }
2469
2549
  else {
2470
2550
  console.error(`Input for ${field} does not exist in form.`)
@@ -2622,6 +2702,10 @@ class MultiForm {
2622
2702
  }
2623
2703
  this.render()
2624
2704
  }
2705
+ addData (data) {
2706
+ this.formData = this.formData.concat(data)
2707
+ this.render()
2708
+ }
2625
2709
  addEntry () {
2626
2710
  const el = document.getElementById(`${this.elementId}_container`)
2627
2711
  let newId = WebsyDesigns.Utils.createIdentity()
@@ -2639,7 +2723,7 @@ class MultiForm {
2639
2723
  </button>
2640
2724
  `
2641
2725
  el.appendChild(newFormEl)
2642
- let formOptions = Object.assign({}, this.options)
2726
+ let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2643
2727
  this.forms.push(new WebsyDesigns.Form(`${this.elementId}_${newId}_form`, formOptions))
2644
2728
  }
2645
2729
  clear () {
@@ -2653,14 +2737,20 @@ class MultiForm {
2653
2737
  }
2654
2738
  get data () {
2655
2739
  const d = this.forms.map(f => (f.data))
2656
- // we don't return the last form
2657
- d.pop()
2740
+ console.log('forms data', d)
2741
+ if (this.options.allowAdd !== false) {
2742
+ // we don't return the last form
2743
+ d.pop()
2744
+ }
2658
2745
  return d
2659
2746
  }
2660
2747
  set data (d) {
2661
2748
  this.formData = d
2662
2749
  this.render()
2663
2750
  }
2751
+ get deleted () {
2752
+ return this.formData.filter(d => this.recordsToDelete.includes(`${d.id}`))
2753
+ }
2664
2754
  handleClick (event) {
2665
2755
  if (event.target.classList.contains('websy-multi-form-add')) {
2666
2756
  let id = event.target.getAttribute('data-formid')
@@ -2740,15 +2830,17 @@ class MultiForm {
2740
2830
  `
2741
2831
  }
2742
2832
  el.innerHTML = html
2743
- this.formData.forEach(d => {
2744
- let formOptions = Object.assign({}, this.options)
2833
+ this.forms = new Array(this.formData.length)
2834
+ this.formData.forEach((d, i) => {
2835
+ let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2745
2836
  let formObject = new WebsyDesigns.Form(`${this.elementId}_${d.formId}_form`, formOptions)
2746
2837
  formObject.data = d
2747
- this.forms.push(formObject)
2838
+ this.forms[i] = formObject
2748
2839
  })
2749
2840
  if (this.options.allowAdd === true) {
2750
- let formOptions = Object.assign({}, this.options)
2751
- this.forms.push(new WebsyDesigns.Form(`${this.elementId}_${id}_form`, formOptions))
2841
+ let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2842
+ let formObject = new WebsyDesigns.Form(`${this.elementId}_${id}_form`, formOptions)
2843
+ this.forms.push(formObject)
2752
2844
  }
2753
2845
  }
2754
2846
  }
@@ -3694,6 +3786,9 @@ class WebsyPubSub {
3694
3786
  }
3695
3787
  }
3696
3788
  subscribe (id, method, fn) {
3789
+ if (!this.subscriptions) {
3790
+ this.subscriptions = {}
3791
+ }
3697
3792
  if (arguments.length === 3) {
3698
3793
  if (!this.subscriptions[id]) {
3699
3794
  this.subscriptions[id] = {}
@@ -5097,7 +5192,52 @@ class WebsyTemplate {
5097
5192
  return html
5098
5193
  }
5099
5194
  handleClick (event) {
5100
- //
5195
+ if (event.target.classList.contains('clickable')) {
5196
+ this.handleEvent(event, 'clickable', 'click')
5197
+ }
5198
+ }
5199
+ handleEvent (event, eventType, action) {
5200
+ let l = event.target.getAttribute('data-event')
5201
+ if (l) {
5202
+ l = l.split('(')
5203
+ let params = []
5204
+ const id = event.target.getAttribute('data-id')
5205
+ // const locator = event.target.getAttribute('data-locator')
5206
+ // if (l[1]) {
5207
+ // l[1] = l[1].replace(')', '')
5208
+ // params = l[1].split(',')
5209
+ // }
5210
+ // l = l[0]
5211
+ let data = this.options.data
5212
+ // if (locator !== '') {
5213
+ // let locatorItems = locator.split(';')
5214
+ // locatorItems.forEach(loc => {
5215
+ // let locatorParts = loc.split(':')
5216
+ // if (data[locatorParts[0]]) {
5217
+ // data = data[locatorParts[0]]
5218
+ // let parts = locatorParts[1].split('.')
5219
+ // parts.forEach(p => {
5220
+ // data = data[p]
5221
+ // })
5222
+ // }
5223
+ // })
5224
+ // }
5225
+ // params = params.map(p => {
5226
+ // if (typeof p !== 'string' && typeof p !== 'number') {
5227
+ // if (data[+id]) {
5228
+ // p = data[+id][p]
5229
+ // }
5230
+ // }
5231
+ // else if (typeof p === 'string') {
5232
+ // p = p.replace(/"/g, '').replace(/'/g, '')
5233
+ // }
5234
+ // return p
5235
+ // })
5236
+ if (event.target.classList.contains(eventType) && this.options.listeners[action] && this.options.listeners[action][l]) {
5237
+ event.stopPropagation()
5238
+ this.options.listeners[action][l].call(this, event, data[+id], ...params)
5239
+ }
5240
+ }
5101
5241
  }
5102
5242
  render () {
5103
5243
  this.resize()