survey-analytics 2.5.18 → 2.5.19

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 (67) hide show
  1. package/LICENSE +1 -1
  2. package/fesm/shared.mjs +96 -68
  3. package/fesm/shared.mjs.map +1 -1
  4. package/fesm/shared2.mjs +69 -40
  5. package/fesm/shared2.mjs.map +1 -1
  6. package/fesm/survey.analytics.core.mjs +1 -1
  7. package/fesm/survey.analytics.mjs +1 -1
  8. package/fesm/survey.analytics.mongo.mjs +1 -1
  9. package/fesm/survey.analytics.tabulator.mjs +206 -5
  10. package/fesm/survey.analytics.tabulator.mjs.map +1 -1
  11. package/package.json +2 -2
  12. package/survey-analytics-tabulator.types/analytics-localization/arabic.d.ts +1 -0
  13. package/survey-analytics-tabulator.types/analytics-localization/dutch.d.ts +1 -0
  14. package/survey-analytics-tabulator.types/analytics-localization/farsi.d.ts +1 -0
  15. package/survey-analytics-tabulator.types/analytics-localization/finnish.d.ts +1 -0
  16. package/survey-analytics-tabulator.types/analytics-localization/french.d.ts +1 -0
  17. package/survey-analytics-tabulator.types/analytics-localization/german.d.ts +1 -0
  18. package/survey-analytics-tabulator.types/analytics-localization/italian.d.ts +1 -0
  19. package/survey-analytics-tabulator.types/analytics-localization/japanese.d.ts +1 -0
  20. package/survey-analytics-tabulator.types/analytics-localization/norwegian.d.ts +1 -0
  21. package/survey-analytics-tabulator.types/analytics-localization/polish.d.ts +1 -0
  22. package/survey-analytics-tabulator.types/analytics-localization/portuguese.d.ts +1 -0
  23. package/survey-analytics-tabulator.types/analytics-localization/russian.d.ts +1 -0
  24. package/survey-analytics-tabulator.types/analytics-localization/spanish.d.ts +1 -0
  25. package/survey-analytics-tabulator.types/analytics-localization/swedish.d.ts +1 -0
  26. package/survey-analytics-tabulator.types/tables/columnbuilder.d.ts +8 -2
  27. package/survey-analytics-tabulator.types/tables/columns.d.ts +11 -1
  28. package/survey-analytics-tabulator.types/tables/config.d.ts +2 -1
  29. package/survey-analytics-tabulator.types/tables/table.d.ts +8 -0
  30. package/survey-analytics-tabulator.types/tables/tabulator.d.ts +3 -0
  31. package/survey-analytics.types/analytics-localization/arabic.d.ts +1 -0
  32. package/survey-analytics.types/analytics-localization/dutch.d.ts +1 -0
  33. package/survey-analytics.types/analytics-localization/farsi.d.ts +1 -0
  34. package/survey-analytics.types/analytics-localization/finnish.d.ts +1 -0
  35. package/survey-analytics.types/analytics-localization/french.d.ts +1 -0
  36. package/survey-analytics.types/analytics-localization/german.d.ts +1 -0
  37. package/survey-analytics.types/analytics-localization/italian.d.ts +1 -0
  38. package/survey-analytics.types/analytics-localization/japanese.d.ts +1 -0
  39. package/survey-analytics.types/analytics-localization/norwegian.d.ts +1 -0
  40. package/survey-analytics.types/analytics-localization/polish.d.ts +1 -0
  41. package/survey-analytics.types/analytics-localization/portuguese.d.ts +1 -0
  42. package/survey-analytics.types/analytics-localization/russian.d.ts +1 -0
  43. package/survey-analytics.types/analytics-localization/spanish.d.ts +1 -0
  44. package/survey-analytics.types/analytics-localization/swedish.d.ts +1 -0
  45. package/survey-analytics.types/boolean.d.ts +1 -0
  46. package/survey-analytics.types/selectBase.d.ts +5 -1
  47. package/survey.analytics.core.css +1 -1
  48. package/survey.analytics.core.js +154 -95
  49. package/survey.analytics.core.js.map +1 -1
  50. package/survey.analytics.core.min.css +1 -1
  51. package/survey.analytics.core.min.js +1 -1
  52. package/survey.analytics.core.min.js.LICENSE.txt +1 -1
  53. package/survey.analytics.css +1 -1
  54. package/survey.analytics.js +154 -95
  55. package/survey.analytics.js.map +1 -1
  56. package/survey.analytics.min.css +1 -1
  57. package/survey.analytics.min.js +1 -1
  58. package/survey.analytics.min.js.LICENSE.txt +1 -1
  59. package/survey.analytics.mongo.js +1 -1
  60. package/survey.analytics.mongo.min.js.LICENSE.txt +1 -1
  61. package/survey.analytics.tabulator.css +39 -1
  62. package/survey.analytics.tabulator.css.map +1 -1
  63. package/survey.analytics.tabulator.js +337 -71
  64. package/survey.analytics.tabulator.js.map +1 -1
  65. package/survey.analytics.tabulator.min.css +2 -2
  66. package/survey.analytics.tabulator.min.js +1 -1
  67. package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * surveyjs - SurveyJS Dashboard library v2.5.18
2
+ * surveyjs - SurveyJS Dashboard library v2.5.19
3
3
  * Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
4
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * surveyjs - SurveyJS Dashboard library v2.5.18
2
+ * surveyjs - SurveyJS Dashboard library v2.5.19
3
3
  * Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
4
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * surveyjs - SurveyJS Dashboard library v2.5.18
2
+ * surveyjs - SurveyJS Dashboard library v2.5.19
3
3
  * Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
4
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * surveyjs - SurveyJS Dashboard library v2.5.18
2
+ * surveyjs - SurveyJS Dashboard library v2.5.19
3
3
  * Copyright (c) 2015-2026 Devsoft Baltic OÜ - http://surveyjs.io/
4
4
  * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
5
  */
@@ -274,7 +274,8 @@ var ColumnDataType;
274
274
  ColumnDataType[ColumnDataType["Text"] = 0] = "Text";
275
275
  ColumnDataType[ColumnDataType["FileLink"] = 1] = "FileLink";
276
276
  ColumnDataType[ColumnDataType["Image"] = 2] = "Image";
277
- ColumnDataType[ColumnDataType["Html"] = 3] = "Html";
277
+ ColumnDataType[ColumnDataType["NestedTable"] = 3] = "NestedTable";
278
+ ColumnDataType[ColumnDataType["Html"] = 4] = "Html";
278
279
  })(ColumnDataType || (ColumnDataType = {}));
279
280
 
280
281
  TableExtensions.registerExtension({
@@ -758,6 +759,42 @@ class CompositeQuestionColumn extends BaseColumn {
758
759
  });
759
760
  }
760
761
  }
762
+ class MatrixDynamicColumn extends BaseColumn {
763
+ getDataType() {
764
+ return this.table.options.useNestedTables ? ColumnDataType.NestedTable : ColumnDataType.Text;
765
+ }
766
+ getDisplayValue(data, table, options) {
767
+ if (table.options.useNestedTables) {
768
+ return this.getDisplayValueCore(data);
769
+ }
770
+ return super.getDisplayValue(data, table, options);
771
+ }
772
+ getCellData(table, data) {
773
+ const displayValue = this.getDisplayValue(data, table, table.options);
774
+ const formattedValue = table.options.useNestedTables && Array.isArray(displayValue)
775
+ ? displayValue
776
+ : (typeof displayValue === "string" ? displayValue : JSON.stringify(displayValue) || "");
777
+ return { question: this.question, displayValue: formattedValue };
778
+ }
779
+ }
780
+ class PanelDynamicColumn extends BaseColumn {
781
+ getDataType() {
782
+ return this.table.options.useNestedTables ? ColumnDataType.NestedTable : ColumnDataType.Text;
783
+ }
784
+ getDisplayValue(data, table, options) {
785
+ if (table.options.useNestedTables) {
786
+ return this.getDisplayValueCore(data);
787
+ }
788
+ return super.getDisplayValue(data, table, options);
789
+ }
790
+ getCellData(table, data) {
791
+ const displayValue = this.getDisplayValue(data, table, table.options);
792
+ const formattedValue = table.options.useNestedTables && Array.isArray(displayValue)
793
+ ? displayValue
794
+ : (typeof displayValue === "string" ? displayValue : JSON.stringify(displayValue) || "");
795
+ return { question: this.question, displayValue: formattedValue };
796
+ }
797
+ }
761
798
 
762
799
  class DefaultColumnsBuilder {
763
800
  createColumn(question, table) {
@@ -900,6 +937,18 @@ class CompositeColumnsBuilder extends DefaultColumnsBuilder {
900
937
  }
901
938
  CompositeColumnsBuilder.ShowAsSeparateColumns = true;
902
939
  ColumnsBuilderFactory.Instance.registerBuilderColumn("composite", new CompositeColumnsBuilder());
940
+ class MatrixDynamicColumnsBuilder extends DefaultColumnsBuilder {
941
+ createColumn(question, table) {
942
+ return new MatrixDynamicColumn(question, table);
943
+ }
944
+ }
945
+ ColumnsBuilderFactory.Instance.registerBuilderColumn("matrixdynamic", new MatrixDynamicColumnsBuilder());
946
+ class PanelDynamicColumnsBuilder extends DefaultColumnsBuilder {
947
+ createColumn(question, table) {
948
+ return new PanelDynamicColumn(question, table);
949
+ }
950
+ }
951
+ ColumnsBuilderFactory.Instance.registerBuilderColumn("paneldynamic", new PanelDynamicColumnsBuilder());
903
952
 
904
953
  // export type GetDataFn = (params: { filter?: any, limit?: number, offset?: number, callback?: (response: { data: Array<Object>, total: number, error?: any }) => void }) => Promise<{ data: Array<Object>, total: number, error?: any }> | void;
905
954
  class TableEvent extends EventBase {
@@ -939,6 +988,9 @@ class Table {
939
988
  if (!this._options) {
940
989
  this._options = {};
941
990
  }
991
+ if (typeof this._options.useNestedTables === "undefined") {
992
+ this._options.useNestedTables = true;
993
+ }
942
994
  this.initialize();
943
995
  this.extensions = new TableExtensions(this);
944
996
  const f = hasLicense;
@@ -1452,6 +1504,9 @@ class Tabulator extends Table {
1452
1504
  if (column.dataType === ColumnDataType.Html) {
1453
1505
  return decodeHtmlEntities(cellData);
1454
1506
  }
1507
+ if (column.dataType === ColumnDataType.NestedTable && Array.isArray(cellData)) {
1508
+ return this.formatNestedDataForExport(cellData, column);
1509
+ }
1455
1510
  }
1456
1511
  }
1457
1512
  if (this.currentDownloadType === "csv" || this.currentDownloadType === "xlsx") {
@@ -1465,7 +1520,7 @@ class Tabulator extends Table {
1465
1520
  if (((options && options.jspdf) || (!!window && window["jspdf"] !== undefined)) && defaultOptions.downloadButtons.indexOf("pdf") === -1) {
1466
1521
  defaultOptions.downloadButtons.unshift("pdf");
1467
1522
  }
1468
- this._options = Object.assign({}, defaultOptions, options);
1523
+ this._options = Object.assign({}, defaultOptions, this._options);
1469
1524
  }
1470
1525
  supportSoftRefresh() {
1471
1526
  return true;
@@ -1580,6 +1635,141 @@ class Tabulator extends Table {
1580
1635
  });
1581
1636
  return container;
1582
1637
  }
1638
+ createNestedTable(nestedTableColumns, cellData) {
1639
+ const container = document.createElement("div");
1640
+ container.className = "sa-nested-table-container";
1641
+ const table = document.createElement("table");
1642
+ table.className = "sa-nested-table";
1643
+ const thead = document.createElement("thead");
1644
+ const headerRow = document.createElement("tr");
1645
+ nestedTableColumns.forEach((col) => {
1646
+ const th = document.createElement("th");
1647
+ th.textContent = col.title;
1648
+ headerRow.appendChild(th);
1649
+ });
1650
+ thead.appendChild(headerRow);
1651
+ table.appendChild(thead);
1652
+ const tbody = document.createElement("tbody");
1653
+ cellData.forEach((row) => {
1654
+ const tr = document.createElement("tr");
1655
+ nestedTableColumns.forEach((col) => {
1656
+ const td = document.createElement("td");
1657
+ const value = row[col.field];
1658
+ td.textContent = value !== undefined && value !== null ? String(value) : "";
1659
+ tr.appendChild(td);
1660
+ });
1661
+ tbody.appendChild(tr);
1662
+ });
1663
+ table.appendChild(tbody);
1664
+ container.appendChild(table);
1665
+ return container;
1666
+ }
1667
+ createNestedTableFormatter(column) {
1668
+ return (cell, formatterParams, onRendered) => {
1669
+ const cellData = cell.getValue();
1670
+ if (!Array.isArray(cellData) || cellData.length === 0) {
1671
+ return "<span>No data</span>";
1672
+ }
1673
+ const question = this._survey.getQuestionByName(column.name);
1674
+ if (!question) {
1675
+ return "<span>Error: Question not found</span>";
1676
+ }
1677
+ let nestedTableColumns = [];
1678
+ if (question.getType() === "matrixdynamic") {
1679
+ const matrixQuestion = question;
1680
+ nestedTableColumns = matrixQuestion.columns.map((col) => ({
1681
+ title: col.title || col.name,
1682
+ field: col.name,
1683
+ }));
1684
+ }
1685
+ else if (question.getType() === "paneldynamic") {
1686
+ const panelQuestion = question;
1687
+ const templateQuestions = panelQuestion.template.questions;
1688
+ nestedTableColumns = templateQuestions.map((q) => ({
1689
+ title: q.title || q.name,
1690
+ field: q.name,
1691
+ }));
1692
+ }
1693
+ if (this.options.useNestedTables === true) {
1694
+ return this.createNestedTable(nestedTableColumns, cellData);
1695
+ }
1696
+ const tableEl = document.createElement("div");
1697
+ tableEl.classList.add("sa-nested-table");
1698
+ // Defer nested Tabulator initialization to onRendered so that it
1699
+ // runs once per cell and can be properly cleaned up.
1700
+ onRendered(() => {
1701
+ const el = tableEl;
1702
+ // Avoid creating multiple nested tables for the same cell element.
1703
+ if (el._nestedTabulator) {
1704
+ return;
1705
+ }
1706
+ const nestedTable = new Tabulator.tabulatorTablesConstructor(tableEl, {
1707
+ // layout: "fitDataFill",
1708
+ data: cellData,
1709
+ columns: nestedTableColumns,
1710
+ pagination: false,
1711
+ });
1712
+ // Cache instance on the element for reuse / potential future teardown.
1713
+ el._nestedTabulator = nestedTable;
1714
+ nestedTable.on("tableBuilt", () => {
1715
+ // cell.getRow().normalizeHeight();
1716
+ this.layout(false);
1717
+ });
1718
+ // Ensure nested table is destroyed when the parent row is deleted.
1719
+ try {
1720
+ const row = cell.getRow && cell.getRow();
1721
+ const parentTable = row && row.getTable && row.getTable();
1722
+ if (parentTable && parentTable.on) {
1723
+ parentTable.on("rowDeleted", (deletedRow) => {
1724
+ if (deletedRow === row && el._nestedTabulator) {
1725
+ // Destroy nested Tabulator and clear cache.
1726
+ el._nestedTabulator.destroy();
1727
+ el._nestedTabulator = null;
1728
+ }
1729
+ });
1730
+ }
1731
+ }
1732
+ catch (e) {
1733
+ // Fail-safe: if lifecycle hooks are unavailable, we still avoid
1734
+ // multiple instances per cell via the cached _nestedTabulator.
1735
+ }
1736
+ });
1737
+ return tableEl;
1738
+ };
1739
+ }
1740
+ formatNestedDataForExport(nestedData, column) {
1741
+ if (!Array.isArray(nestedData) || nestedData.length === 0) {
1742
+ return "";
1743
+ }
1744
+ const question = this._survey.getQuestionByName(column.name);
1745
+ if (!question) {
1746
+ return "";
1747
+ }
1748
+ let nestedColumns = [];
1749
+ if (question.getType() === "matrixdynamic") {
1750
+ const matrixQuestion = question;
1751
+ nestedColumns = matrixQuestion.columns.map((col) => ({
1752
+ title: col.title || col.name,
1753
+ field: col.name,
1754
+ }));
1755
+ }
1756
+ else if (question.getType() === "paneldynamic") {
1757
+ const panelQuestion = question;
1758
+ const templateQuestions = panelQuestion.template.questions;
1759
+ nestedColumns = templateQuestions.map((q) => ({
1760
+ title: q.title || q.name,
1761
+ field: q.name,
1762
+ }));
1763
+ }
1764
+ const header = nestedColumns.map(col => col.title).join(" | ");
1765
+ const rows = nestedData.map(rowData => {
1766
+ return nestedColumns.map(col => {
1767
+ const value = rowData[col.field];
1768
+ return value !== undefined && value !== null ? String(value) : "";
1769
+ }).join(" | ");
1770
+ });
1771
+ return `[${header}]\n${rows.join("\n")}`;
1772
+ }
1583
1773
  getTitleFormatter(cell, formatterParams, onRendered, columnName) {
1584
1774
  var container = DocumentHelper.createElement("div");
1585
1775
  var title = DocumentHelper.createElement("span", "", {
@@ -1609,7 +1799,7 @@ class Tabulator extends Table {
1609
1799
  if (column.dataType == ColumnDataType.Image) {
1610
1800
  formatter = "image";
1611
1801
  }
1612
- return {
1802
+ const columnDef = {
1613
1803
  field: column.name,
1614
1804
  title: column.displayName || column.name,
1615
1805
  width: column.width,
@@ -1626,6 +1816,17 @@ class Tabulator extends Table {
1626
1816
  return this.getTitleFormatter(cell, formatterParams, onRendered, column.name);
1627
1817
  },
1628
1818
  };
1819
+ if (column.dataType == ColumnDataType.NestedTable) {
1820
+ columnDef.formatter = this.createNestedTableFormatter(column);
1821
+ columnDef.tooltip = (_, cell) => {
1822
+ const cellData = cell.getValue();
1823
+ if (Array.isArray(cellData) && cellData.length > 0) {
1824
+ return this.formatNestedDataForExport(cellData, column);
1825
+ }
1826
+ return "";
1827
+ };
1828
+ }
1829
+ return columnDef;
1629
1830
  });
1630
1831
  // const rowExtensions = TableExtensions.getExtensions("row").filter(e => e.visibleIndex >= 0);
1631
1832
  // const detailsExtension = TableExtensions.getExtensions("details").filter(e => e.visibleIndex >= 0);
@@ -1768,5 +1969,5 @@ class TabulatorRow extends TableRow {
1768
1969
 
1769
1970
  Tabulator.initTabulatorConstructor(TabulatorFull);
1770
1971
 
1771
- export { BaseColumn, CheckboxColumn, CheckboxColumnsBuilder, ColumnsBuilderFactory, CommentColumn, CompositeColumnsBuilder, CompositeQuestionColumn, CustomColumnsBuilder, CustomQuestionColumn, DefaultColumn, DefaultColumnsBuilder, DocumentHelper, FileColumn, FileColumnsBuilder, FlattenedCheckboxColumn, ImageColumn, ImageColumnsBuilder, MatrixColumn, MatrixColumnsBuilder, MatrixDropdownColumn, MatrixDropdownColumnBuilder, OtherColumn, SelectBaseColumn, SelectBaseColumnsBuilder, SingleChoiceColumn, SingleChoiceColumnsBuilder, Table, TableEvent, TableExtensions, TableRow, Tabulator, TabulatorRow, defaultDownloadOptions, defaultOptions, localization };
1972
+ export { BaseColumn, CheckboxColumn, CheckboxColumnsBuilder, ColumnsBuilderFactory, CommentColumn, CompositeColumnsBuilder, CompositeQuestionColumn, CustomColumnsBuilder, CustomQuestionColumn, DefaultColumn, DefaultColumnsBuilder, DocumentHelper, FileColumn, FileColumnsBuilder, FlattenedCheckboxColumn, ImageColumn, ImageColumnsBuilder, MatrixColumn, MatrixColumnsBuilder, MatrixDropdownColumn, MatrixDropdownColumnBuilder, MatrixDynamicColumn, MatrixDynamicColumnsBuilder, OtherColumn, PanelDynamicColumn, PanelDynamicColumnsBuilder, SelectBaseColumn, SelectBaseColumnsBuilder, SingleChoiceColumn, SingleChoiceColumnsBuilder, Table, TableEvent, TableExtensions, TableRow, Tabulator, TabulatorRow, defaultDownloadOptions, defaultOptions, localization };
1772
1973
  //# sourceMappingURL=survey.analytics.tabulator.mjs.map