@iamproperty/components 3.6.0 → 3.7.1

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.
Files changed (77) hide show
  1. package/assets/css/components/accordion.css.map +1 -1
  2. package/assets/css/components/admin-panel.css +1 -1
  3. package/assets/css/components/admin-panel.css.map +1 -1
  4. package/assets/css/components/card.css +1 -1
  5. package/assets/css/components/card.css.map +1 -1
  6. package/assets/css/components/dialog.css +1 -1
  7. package/assets/css/components/dialog.css.map +1 -1
  8. package/assets/css/components/forms.css.map +1 -1
  9. package/assets/css/components/lists.css +1 -1
  10. package/assets/css/components/lists.css.map +1 -1
  11. package/assets/css/components/table.css +1 -1
  12. package/assets/css/components/table.css.map +1 -1
  13. package/assets/css/core.min.css +1 -1
  14. package/assets/css/core.min.css.map +1 -1
  15. package/assets/css/style.min.css +1 -1
  16. package/assets/css/style.min.css.map +1 -1
  17. package/assets/js/bundle.js +2 -0
  18. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  19. package/assets/js/components/card/card.component.js +2 -2
  20. package/assets/js/components/card/card.component.min.js +4 -4
  21. package/assets/js/components/card/card.component.min.js.map +1 -1
  22. package/assets/js/components/filterlist/filterlist.component.min.js +1 -1
  23. package/assets/js/components/header/header.component.min.js +1 -1
  24. package/assets/js/components/table/table.component.js +19 -9
  25. package/assets/js/components/table/table.component.min.js +13 -13
  26. package/assets/js/components/table/table.component.min.js.map +1 -1
  27. package/assets/js/components/tabs/tabs.component.min.js +2 -2
  28. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  29. package/assets/js/dynamic.js +3 -1
  30. package/assets/js/dynamic.min.js +2 -2
  31. package/assets/js/dynamic.min.js.map +1 -1
  32. package/assets/js/flat-components.js +2 -0
  33. package/assets/js/modules/applied-filters.js +1 -1
  34. package/assets/js/modules/dialogs.js +184 -0
  35. package/assets/js/modules/helpers.js +1 -89
  36. package/assets/js/modules/table.js +113 -37
  37. package/assets/js/modules/tabs.js +0 -2
  38. package/assets/js/scripts.bundle.js +26 -26
  39. package/assets/js/scripts.bundle.js.map +1 -1
  40. package/assets/js/scripts.bundle.min.js +2 -2
  41. package/assets/js/scripts.bundle.min.js.map +1 -1
  42. package/assets/js/tests/table.spec.js +34 -13
  43. package/assets/sass/_functions/variables.scss +3 -28
  44. package/assets/sass/components/admin-panel.scss +0 -10
  45. package/assets/sass/components/card.scss +32 -25
  46. package/assets/sass/components/dialog.scss +332 -28
  47. package/assets/sass/components/lists.scss +16 -33
  48. package/assets/sass/components/table.scss +125 -92
  49. package/assets/sass/foundations/buttons.scss +9 -13
  50. package/assets/sass/foundations/icons.scss +14 -69
  51. package/assets/sass/foundations/reboot.scss +19 -7
  52. package/assets/sass/foundations/root.scss +9 -0
  53. package/assets/sass/helpers/max-height.scss +15 -0
  54. package/assets/ts/bundle.ts +2 -0
  55. package/assets/ts/components/card/README.md +2 -1
  56. package/assets/ts/components/card/card.component.ts +2 -2
  57. package/assets/ts/components/table/table.component.ts +24 -10
  58. package/assets/ts/dynamic.ts +3 -1
  59. package/assets/ts/flat-components.ts +2 -0
  60. package/assets/ts/html.d.ts +7 -1
  61. package/assets/ts/modules/applied-filters.ts +1 -1
  62. package/assets/ts/modules/dialogs.ts +248 -0
  63. package/assets/ts/modules/helpers.ts +1 -123
  64. package/assets/ts/modules/table.ts +153 -47
  65. package/assets/ts/modules/tabs.ts +0 -4
  66. package/assets/ts/tests/table.spec.ts +21 -6
  67. package/dist/components.es.js +1114 -1101
  68. package/dist/components.umd.js +23 -19
  69. package/package.json +2 -3
  70. package/src/components/Card/Card.vue +2 -2
  71. package/src/components/Card/README.md +1 -1
  72. package/src/components/Nav/Nav.vue +1 -3
  73. package/src/index.js +0 -1
  74. package/assets/svg/icons.svg +0 -599
  75. package/src/foundations/Icon/Icon.spec.js +0 -24
  76. package/src/foundations/Icon/Icon.vue +0 -24
  77. package/src/foundations/Icon/README.md +0 -11
@@ -7,7 +7,7 @@ export const addDataAttributes = (table) => {
7
7
  const colRows = Array.from(table.querySelectorAll('tbody tr'));
8
8
  colRows.forEach((row, index) => {
9
9
  const cells = Array.from(row.querySelectorAll('th, td'));
10
- const statuses = ['Low', 'Medium', 'High', 'N/A', 'Pending', 'Verified', 'Incomplete', 'Completed', 'Requires approval'];
10
+ const statuses = ['0', 'low', 'medium', 'high', 'unknown', 'n/a', 'pending', 'verified', 'incomplete', 'completed', 'requires approval'];
11
11
  cells.forEach((cell, cellIndex) => {
12
12
  const heading = colHeadings[cellIndex];
13
13
  if (typeof heading != "undefined") {
@@ -19,10 +19,10 @@ export const addDataAttributes = (table) => {
19
19
  cell.setAttribute('class', heading.getAttribute('data-td-class'));
20
20
  if (heading.hasAttribute('data-format')) {
21
21
  cell.setAttribute('data-format', heading.getAttribute('data-format'));
22
- cell.innerHTML = formatCell('date', cell.textContent.trim()); //Make sure date format is consistent
22
+ cell.innerHTML = formatCell(heading.getAttribute('data-format'), cell.textContent.trim()); //Make sure date format is consistent
23
23
  }
24
- if (statuses.includes(cell.textContent.trim())) {
25
- cell.setAttribute('data-content', cell.textContent.trim());
24
+ if (statuses.includes(cell.textContent.trim().toLowerCase())) {
25
+ cell.setAttribute('data-content', cell.textContent.trim().toLowerCase());
26
26
  }
27
27
  }
28
28
  });
@@ -46,6 +46,8 @@ export const getLargestLastColWidth = (table) => {
46
46
  export const createMobileButton = (table) => {
47
47
  if (table.closest('.table--fullwidth'))
48
48
  return false;
49
+ if (table.querySelectorAll('thead tr th').length < 4)
50
+ return false;
49
51
  Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
50
52
  let firstCol = row.querySelector(':scope > :is(td,th):first-child');
51
53
  let colContent = firstCol.textContent;
@@ -98,9 +100,16 @@ export const createSearchDataList = (table, form) => {
98
100
  export const addFilterEventListeners = (table, form, pagination, wrapper, savedTableBody) => {
99
101
  var timer;
100
102
  // Check what conditions are set on the table to see what the form actions are
101
- let formSubmit = function () {
102
- if (form.hasAttribute('data-ajax'))
103
+ let formSubmit = function (paginate = false) {
104
+ if (form.hasAttribute('data-ajax')) {
105
+ // Default back to page 1
106
+ if (!paginate) {
107
+ let paginationInput = form.querySelector('[data-pagination]');
108
+ paginationInput.value = 1;
109
+ wrapper.setAttribute('data-page', 1);
110
+ }
103
111
  loadAjaxTable(table, form, pagination, wrapper);
112
+ }
104
113
  else if (form.hasAttribute('data-submit'))
105
114
  form.submit();
106
115
  else {
@@ -137,6 +146,9 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
137
146
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')) {
138
147
  formSubmit();
139
148
  }
149
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-mimic]')) {
150
+ formSubmit();
151
+ }
140
152
  });
141
153
  form.addEventListener('click', (event) => {
142
154
  clearTimeout(timer);
@@ -166,6 +178,50 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
166
178
  form.addEventListener('force', (event) => {
167
179
  formSubmit();
168
180
  });
181
+ form.addEventListener('paginate', (event) => {
182
+ formSubmit(true);
183
+ });
184
+ // Mmimic fields
185
+ let forms = [];
186
+ let fields = [];
187
+ // Collect the forms that we need to add an event listener for.
188
+ Array.from(form.querySelectorAll('[data-mimic]')).forEach((input, index) => {
189
+ let mimicField = input.getAttribute('data-mimic');
190
+ Array.from(document.querySelectorAll(`[name="${mimicField}"]`)).forEach((mimicInput, index) => {
191
+ let parentForm = mimicInput.closest('form');
192
+ if (!forms.includes(parentForm))
193
+ forms.push(parentForm);
194
+ if (!fields.includes(mimicInput))
195
+ fields.push(mimicInput);
196
+ });
197
+ });
198
+ // For each form add change listener
199
+ forms.forEach((parentForm, index) => {
200
+ const updateMimicInput = function () {
201
+ let mimickedAlready = [];
202
+ let formData = new FormData(parentForm);
203
+ let i = 1;
204
+ for (const [key, value] of formData) {
205
+ if (document.querySelector(`[data-mimic="${key}"]`) && !mimickedAlready.includes(key)) {
206
+ mimickedAlready.push(key);
207
+ document.querySelector(`[data-mimic="${key}"]`).value = value;
208
+ }
209
+ else if (document.querySelector(`[data-mimic="${key}"]`))
210
+ document.querySelector(`[data-mimic="${key}"]`).value += "," + value;
211
+ i++;
212
+ }
213
+ for (const value of mimickedAlready) {
214
+ const event = new Event("force");
215
+ form.dispatchEvent(event);
216
+ }
217
+ };
218
+ parentForm.addEventListener('force', (event) => {
219
+ updateMimicInput();
220
+ });
221
+ parentForm.addEventListener('change', (event) => {
222
+ updateMimicInput();
223
+ });
224
+ });
169
225
  };
170
226
  export const sortTable = (table, form, savedTableBody) => {
171
227
  if (form.getAttribute('data-ajax')) {
@@ -246,10 +302,11 @@ export const filterTable = (table, form, wrapper) => {
246
302
  filters[filterInput.getAttribute('data-filter')].push(value);
247
303
  }
248
304
  }
249
- else if (filterInput.value) {
250
- if (!filters[filterInput.getAttribute('data-filter')])
251
- filters[filterInput.getAttribute('data-filter')] = new Array();
252
- filters[filterInput.getAttribute('data-filter')].push(filterInput.value);
305
+ else if (filterInput && filterInput.value) {
306
+ let dataFilter = filterInput.getAttribute('data-filter');
307
+ if (!filters[dataFilter])
308
+ filters[dataFilter] = new Array();
309
+ filters[dataFilter].push(filterInput.value);
253
310
  }
254
311
  });
255
312
  // Add search columns too
@@ -269,11 +326,8 @@ export const filterTable = (table, form, wrapper) => {
269
326
  element.innerHTML += `(${filters.length})`;
270
327
  });
271
328
  }
272
- // Stop function if no filters identified
273
- if (!Object.keys(searches).length && !Object.keys(filters).length)
274
- return false;
275
- table.classList.add('table--filtered');
276
329
  // Filter the table
330
+ table.classList.add('table--filtered');
277
331
  for (const [key, filterValue] of Object.entries(filters)) {
278
332
  Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row, index) => {
279
333
  let isMatched = false;
@@ -354,7 +408,8 @@ export const filterTable = (table, form, wrapper) => {
354
408
  matched++;
355
409
  row.classList.add('filtered--matched');
356
410
  // pagination bit
357
- if (Math.ceil(matched / showRows) == parseInt(page))
411
+ let matchesPage = Math.ceil(matched / showRows);
412
+ if (matchesPage == parseInt(page))
358
413
  row.classList.add('filtered--show');
359
414
  });
360
415
  if (wrapper) {
@@ -364,13 +419,16 @@ export const filterTable = (table, form, wrapper) => {
364
419
  wrapper.setAttribute('data-show', showRows);
365
420
  }
366
421
  };
367
- export const populateDataQueries = (table, form) => {
422
+ export const populateDataQueries = (table, form, wrapper) => {
368
423
  const dataQueries = Array.from(form.querySelectorAll('[data-query]'));
369
424
  dataQueries.forEach((queryElement, index) => {
370
425
  let query = queryElement.getAttribute('data-query');
371
426
  let numberOfMatchedRows;
372
427
  if (query == 'total') {
373
- numberOfMatchedRows = table.classList.contains('table--filtered') ? table.querySelectorAll('tbody tr').length : table.querySelectorAll('tbody tr').length;
428
+ if (wrapper.hasAttribute('data-total'))
429
+ numberOfMatchedRows = wrapper.getAttribute('data-total');
430
+ else
431
+ numberOfMatchedRows = table.classList.contains('table--filtered') ? table.querySelectorAll('tbody tr').length : table.querySelectorAll('tbody tr').length;
374
432
  }
375
433
  else if (!query.includes(' == ') && query.includes(' & ')) {
376
434
  let queries = query.split(' & ');
@@ -416,10 +474,12 @@ export const addPaginationEventListeners = function (table, form, pagination, wr
416
474
  let newPage = event.target.closest('[data-page]').getAttribute('data-page');
417
475
  paginationInput.value = newPage;
418
476
  wrapper.setAttribute('data-page', newPage);
419
- form.dispatchEvent(new Event("submit"));
420
- const url = new URL(location);
421
- url.searchParams.set("page", newPage);
422
- history.pushState({ 'type': 'pagination', 'form': form.getAttribute('id'), 'page': newPage }, "", url);
477
+ form.dispatchEvent(new Event("paginate"));
478
+ if (table.hasAttribute('data-show-history')) {
479
+ const url = new URL(location);
480
+ url.searchParams.set("page", newPage);
481
+ history.pushState({ 'type': 'pagination', 'form': form.getAttribute('id'), 'page': newPage }, "", url);
482
+ }
423
483
  }
424
484
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-show]')) {
425
485
  event.preventDefault();
@@ -475,9 +535,9 @@ export const exportAsCSV = function (table) {
475
535
  };
476
536
  // After table is loaded
477
537
  export const makeTableFunctional = function (table, form, pagination, wrapper) {
478
- createMobileButton(table);
479
538
  addDataAttributes(table);
480
- populateDataQueries(table, form);
539
+ createMobileButton(table);
540
+ populateDataQueries(table, form, wrapper);
481
541
  // Work out the largest width of the CTA's in the last column
482
542
  if (wrapper && wrapper.classList.contains('table--cta')) {
483
543
  const largestWidth = getLargestLastColWidth(table);
@@ -486,10 +546,12 @@ export const makeTableFunctional = function (table, form, pagination, wrapper) {
486
546
  };
487
547
  export const loadAjaxTable = function (table, form, pagination, wrapper) {
488
548
  const resolvePath = (object, path, defaultValue) => path.split(/[\.\[\]\'\"]/).filter(p => p).reduce((o, p) => o ? o[p] : defaultValue, object);
489
- let queryString = new URLSearchParams(new FormData(form)).toString();
549
+ let formData = new FormData(form);
550
+ let queryString = new URLSearchParams(formData).toString();
490
551
  let columns = table.querySelectorAll('thead tr th');
491
552
  let tbody = table.querySelector('tbody');
492
- fetch(form.getAttribute('data-ajax'), {
553
+ wrapper.classList.add('table--loading');
554
+ fetch(form.getAttribute('data-ajax') + '?' + queryString, {
493
555
  method: 'get',
494
556
  credentials: 'same-origin',
495
557
  headers: new Headers({
@@ -498,9 +560,15 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
498
560
  'X-Requested-With': 'XMLHttpRequest'
499
561
  })
500
562
  }).then((response) => response.json()).then((response) => {
501
- if (response.data) {
563
+ let schema = form.hasAttribute('data-schema') ? form.getAttribute('data-schema') : 'data';
564
+ let totalNumberSchema = form.hasAttribute('data-schema-total') ? form.getAttribute('data-schema-total') : 'meta.total';
565
+ let currentPageSchema = form.hasAttribute('data-schema-page') ? form.getAttribute('data-schema-page') : 'meta.current_page';
566
+ let totalNumber = resolvePath(response, totalNumberSchema, 1);
567
+ let currentPage = resolvePath(response, currentPageSchema, 1);
568
+ let data = resolvePath(response, schema);
569
+ if (data) {
502
570
  tbody.innerHTML = '';
503
- response.data.forEach((row, index) => {
571
+ data.forEach((row, index) => {
504
572
  var table_row = document.createElement('tr');
505
573
  columns.forEach((col, index) => {
506
574
  let cellOutput = '';
@@ -512,8 +580,11 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
512
580
  // Use a regex to replace {var} with actual values from the json data
513
581
  cellOutput = cellTemplate.replace(new RegExp(/{(.*?)}/, "gm"), function (matched) { return resolvePath(row, matched.replace('{', '').replace('}', '')); });
514
582
  }
515
- if (col.hasAttribute('data-format')) {
516
- cellOutput = formatCell(col.getAttribute('data-format'), cellOutput);
583
+ if (col.hasAttribute('data-transform')) {
584
+ const transforms = JSON.parse(col.getAttribute('data-transform'));
585
+ cellOutput = transforms[cellOutput];
586
+ if (!cellOutput && col.hasAttribute('data-default'))
587
+ cellOutput = col.getAttribute('data-default');
517
588
  }
518
589
  table_cell.innerHTML = cellOutput;
519
590
  table_row.appendChild(table_cell);
@@ -522,28 +593,33 @@ export const loadAjaxTable = function (table, form, pagination, wrapper) {
522
593
  });
523
594
  createSearchDataList(table, form);
524
595
  // Add data to the pagination
525
- makeTableFunctional(table, form, pagination, wrapper);
526
- wrapper.setAttribute('data-total', (response.meta.total ? response.meta.total : 1));
527
- wrapper.setAttribute('data-page', (response.meta.current_page ? response.meta.current_page : 1));
596
+ wrapper.setAttribute('data-total', parseInt(totalNumber));
597
+ wrapper.setAttribute('data-page', parseInt(currentPage));
528
598
  wrapper.setAttribute('data-pages', Math.ceil(wrapper.getAttribute('data-total') / wrapper.getAttribute('data-show')));
599
+ makeTableFunctional(table, form, pagination, wrapper);
529
600
  createPaginationButttons(wrapper, pagination);
530
601
  if (response.data.length == 0) {
531
602
  tbody.innerHTML = '<tr><td colspan="100%"><span class="h4 m-0">No results found</span></td></tr>';
532
603
  }
604
+ wrapper.classList.remove('table--loading');
533
605
  }
534
606
  else {
535
607
  tbody.innerHTML = '<tr><td colspan="100%"><span class="h6 m-0">Error loading table</span></td></tr>';
536
608
  }
537
609
  });
610
+ if (form.hasAttribute('data-ajax-post')) {
611
+ const http = new XMLHttpRequest();
612
+ http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
613
+ http.send();
614
+ }
538
615
  };
539
616
  export const formatCell = (format, cellOutput) => {
540
617
  switch (format) {
618
+ case 'datetime':
619
+ return new Date(cellOutput).toLocaleDateString('en-gb', { weekday: 'short', year: "2-digit", month: "long", day: "numeric", }) + " " + new Date(cellOutput).toLocaleTimeString("en-gb", { hour: "2-digit", minute: "2-digit" });
541
620
  case 'date':
542
- cellOutput = new Date(cellOutput).toLocaleDateString('en-gb', { year: "2-digit", month: "long", day: "numeric" });
543
- break;
621
+ return new Date(cellOutput).toLocaleDateString('en-gb', { year: "2-digit", month: "long", day: "numeric" });
544
622
  case 'capitalise':
545
- cellOutput = ucfirst(cellOutput);
546
- break;
623
+ return cellOutput = ucfirst(cellOutput);
547
624
  }
548
- return cellOutput;
549
625
  };
@@ -35,11 +35,9 @@ export const setTabsEventHandlers = function (tabsElement) {
35
35
  let buttons = tabsElement.querySelectorAll(':scope .tabs__links > .link');
36
36
  if (tabsElement.shadowRoot)
37
37
  buttons = tabsElement.shadowRoot.querySelectorAll('.tabs__links > .link');
38
- console.log(buttons);
39
38
  // Set the on click for the tab buttons, these will open the details box it matches too
40
39
  buttons.forEach((button) => {
41
40
  button.addEventListener("click", (e) => {
42
- console.log('hi');
43
41
  e.preventDefault();
44
42
  buttons.forEach((buttonLoopItem) => {
45
43
  let buttonPressed = buttonLoopItem == button ? true : false;