@cellaware/utils 8.3.17 → 8.3.18

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.
@@ -8,6 +8,7 @@ export interface DatagridStateBase {
8
8
  export interface DatagridState extends DatagridStateBase {
9
9
  adjRowData: any[];
10
10
  chartRowData: any[];
11
+ html: string;
11
12
  }
12
13
  export declare function initDatagridState(): DatagridState;
13
14
  export type ColumnState = {
@@ -126,8 +127,4 @@ export declare function codifyCondition(condition: DatagridCondition): string;
126
127
  */
127
128
  export declare function stripNumericValueFormat(value: string | number | undefined): any;
128
129
  export declare function transformDatagrid(rows: any[], datagridState: DatagridStateBase, locale: string, condition?: DatagridCondition): DatagridState;
129
- export declare function datagridToString(datagridState: DatagridState, rowCnt?: number): {
130
- html: string;
131
- markdown: string;
132
- };
133
130
  export {};
@@ -3,7 +3,8 @@ import { CHATWMS_DEFAULT_LANGUAGE } from "./user.js";
3
3
  export function initDatagridState() {
4
4
  return {
5
5
  adjRowData: [],
6
- chartRowData: []
6
+ chartRowData: [],
7
+ html: ''
7
8
  };
8
9
  }
9
10
  export const DEFAULT_VALUE_FORMAT_VALUE = 'none';
@@ -756,6 +757,61 @@ function sortRows(data, sortModel) {
756
757
  return 0;
757
758
  });
758
759
  }
760
+ function processHtmlStyles(value, columnFormat, rowStyles, columnStyles) {
761
+ let columnStyle = {
762
+ columnName: '',
763
+ styles: []
764
+ };
765
+ // Reminder: Value Formatting is performed **before** Conditional Formatting.
766
+ // https://chatwms.io/user-manual/concepts/column-formatting#conditional-formatting
767
+ for (const condFmt of columnFormat.conditionalFormats.slice().reverse()) {
768
+ // `conditionalFormats` has already been sorted by `sequence`.
769
+ // NOTE: need to reverse the array for sequence to be correctly applied.
770
+ // NOTE: using `slice` to make shallow copy of array since `reverse` does so in place.
771
+ if (evaluateConditionalFormat(condFmt, columnFormat.type, formatNumberEnabled(columnFormat.valueFormat) ? stripNumericValueFormat(value) : value)) {
772
+ if (condFmt.row) {
773
+ rowStyles.push(condFmt.style);
774
+ }
775
+ else {
776
+ columnStyle.styles.push(condFmt.style);
777
+ }
778
+ }
779
+ }
780
+ columnStyles.push(columnStyle);
781
+ return [rowStyles, columnStyles];
782
+ }
783
+ function buildHtmlHeader(columnNames) {
784
+ let buf = '<table>\n\t<thead>\n\t\t<tr>';
785
+ for (const columnName of columnNames) {
786
+ buf += `\n\t\t\t<th>${columnName}</th>`;
787
+ }
788
+ buf += '\n\t\t</tr>\n\t</thead>';
789
+ buf += '\n\t<tbody>';
790
+ return buf;
791
+ }
792
+ function buildHtmlRow(rowValues, rowStyles, columnStyles) {
793
+ let buf = '';
794
+ // Apply row styles.
795
+ if (rowStyles.length > 0) {
796
+ buf += `\n\t\t<tr class="${rowStyles.join(' ')}">`;
797
+ }
798
+ else {
799
+ buf += '\n\t\t<tr>';
800
+ }
801
+ // Write cell values with styles.
802
+ let colIdx = 0;
803
+ for (const rowValue of rowValues) {
804
+ if (columnStyles[colIdx].styles.length > 0) {
805
+ buf += `\n\t\t\t<td class="${columnStyles[colIdx].styles.join(' ')}">${rowValue}</td>`;
806
+ }
807
+ else {
808
+ buf += `\n\t\t\t<td>${rowValue}</td>`;
809
+ }
810
+ colIdx++;
811
+ }
812
+ buf += '\n\t\t</tr>';
813
+ return buf;
814
+ }
759
815
  export function transformDatagrid(rows, datagridState, locale, condition) {
760
816
  const columnState = datagridState.columnState ?? [];
761
817
  const filterModel = datagridState.filterModel ?? {};
@@ -764,6 +820,8 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
764
820
  const { rowGroupCols, pivotCols, valueCols, sortModel } = parseColumnState(columnState);
765
821
  rows = filterRows(rows, filterModel);
766
822
  const chartRowData = [];
823
+ let htmlBuf = '';
824
+ const htmlColumnNames = [];
767
825
  // IMPORTANT: we evaluate the datagrid condition AFTER we are done with all transformations.
768
826
  // NOTE: we do not need any pivot columns for pivot mode to be valid.
769
827
  // https://chatwms.io/user-manual/chatwms/faq#q-do-i-have-to-have-a-group-column-to-just-display-a-count-in-the-datagrid
@@ -773,14 +831,23 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
773
831
  rows = sortModel.length > 0 ? sortRows(rows, sortModel) : rows;
774
832
  let mappedDisplayColumnNames = new Map();
775
833
  // Should not need to do hidden/visible column analysis -- pivoting creates new results with only the necessary columns.
834
+ let rowIdx = 0;
776
835
  rows.forEach(row => {
777
836
  let chartRow = {};
837
+ let htmlRowValues = [];
838
+ let htmlRowStyles = [];
839
+ let htmlColumnStyles = [];
778
840
  columnFormats.forEach(columnFormat => {
779
841
  if (columnFormat.name in row) {
780
842
  const value = row[columnFormat.name];
781
843
  const formattedValue = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
782
844
  row[columnFormat.displayName] = formattedValue;
783
845
  chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
846
+ htmlRowValues.push(formattedValue);
847
+ [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
848
+ if (rowIdx === 0) {
849
+ htmlColumnNames.push(columnFormat.displayName);
850
+ }
784
851
  // Remove name in favor of display name.
785
852
  if (columnFormat.displayName !== columnFormat.name) {
786
853
  delete row[columnFormat.name];
@@ -797,6 +864,11 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
797
864
  const formattedValue = evaluateValueFormat(columnFormat, row[mappedColumnName], locale);
798
865
  row[adjDisplayName] = formattedValue;
799
866
  chartRow[adjDisplayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
867
+ htmlRowValues.push(formattedValue);
868
+ [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
869
+ if (rowIdx === 0) {
870
+ htmlColumnNames.push(columnFormat.displayName);
871
+ }
800
872
  // Remove name in favor of display name.
801
873
  if (adjDisplayName !== mappedColumnName) {
802
874
  delete row[mappedColumnName];
@@ -815,6 +887,8 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
815
887
  }
816
888
  });
817
889
  chartRowData.push(chartRow);
890
+ htmlBuf += buildHtmlRow(htmlRowValues, htmlRowStyles, htmlColumnStyles);
891
+ rowIdx++;
818
892
  });
819
893
  if (!!condition) {
820
894
  rows = evaluatePivotDatagridCondition(rows, condition, mappedDisplayColumnNames);
@@ -827,8 +901,12 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
827
901
  rows = sortModel.length > 0 ? sortRows(rows, sortModel) : rows;
828
902
  const hiddenColumnNames = columnState.filter(column => !!column.hide && !column.rowGroup).map(column => column.colId) ?? [];
829
903
  const visibleColumnFormats = columnFormats.filter(column => !hiddenColumnNames.includes(column.name)) ?? [];
904
+ let rowIdx = 0;
830
905
  rows.forEach(row => {
831
906
  let chartRow = {};
907
+ let htmlRowValues = [];
908
+ let htmlRowStyles = [];
909
+ let htmlColumnStyles = [];
832
910
  hiddenColumnNames.forEach(columnName => {
833
911
  delete row[columnName];
834
912
  });
@@ -837,124 +915,23 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
837
915
  const formattedValue = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
838
916
  row[columnFormat.displayName] = formattedValue;
839
917
  chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
918
+ htmlRowValues.push(formattedValue);
919
+ [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
920
+ if (rowIdx === 0) {
921
+ htmlColumnNames.push(columnFormat.displayName);
922
+ }
840
923
  // Remove name in favor of display name.
841
924
  if (columnFormat.displayName !== columnFormat.name) {
842
925
  delete row[columnFormat.name];
843
926
  }
844
927
  });
845
928
  chartRowData.push(chartRow);
929
+ htmlBuf += buildHtmlRow(htmlRowValues, htmlRowStyles, htmlColumnStyles);
930
+ rowIdx++;
846
931
  });
847
932
  if (!!condition) {
848
933
  rows = evaluateDatagridCondition(rows, condition);
849
934
  }
850
935
  }
851
- return { ...datagridState, adjRowData: rows, chartRowData };
852
- }
853
- export function datagridToString(datagridState, rowCnt) {
854
- let htmlBuf = '';
855
- let markdownBuf = '';
856
- if (datagridState.adjRowData.length === 0) {
857
- return {
858
- html: htmlBuf,
859
- markdown: markdownBuf
860
- };
861
- }
862
- const columnFormats = datagridState.columnFormats ?? [];
863
- if (columnFormats.length === 0) {
864
- return {
865
- html: htmlBuf,
866
- markdown: markdownBuf
867
- };
868
- }
869
- const totalRowCnt = datagridState.adjRowData.length;
870
- rowCnt = rowCnt ?? totalRowCnt;
871
- if (rowCnt < totalRowCnt) {
872
- const message = `Displaying the first ${rowCnt} rows.`;
873
- htmlBuf += `<p style="font-style: italic;">${message}</p>`;
874
- markdownBuf += `\n*${message}*\n\n`;
875
- }
876
- // Header:
877
- htmlBuf += '<table>\n\t<thead>\n\t\t<tr>';
878
- let columns = [];
879
- for (const key in datagridState.adjRowData[0]) {
880
- columns.push(key);
881
- htmlBuf += `\n\t\t\t<th>${key}</th>`;
882
- markdownBuf += `| ${key} `;
883
- }
884
- markdownBuf += '|\n';
885
- for (const _ of columns) {
886
- markdownBuf += `| ----- `;
887
- }
888
- markdownBuf += '|\n';
889
- htmlBuf += '\n\t\t</tr>\n\t</thead>';
890
- // Rows:
891
- htmlBuf += '\n\t<tbody>';
892
- let rowIdx = 0;
893
- for (const row of datagridState.adjRowData) {
894
- if (rowIdx >= rowCnt) {
895
- break;
896
- }
897
- let colIdx = 0;
898
- const rowStyles = [];
899
- const colStyles = [];
900
- let cellValues = [];
901
- // Extract cell values and row/column styles first, then write to html & markdown.
902
- for (const key in row) {
903
- let val = row[key];
904
- if (val instanceof Date) {
905
- const dteStr = val.toISOString();
906
- val = dteStr.substring(0, dteStr.lastIndexOf('.'));
907
- }
908
- cellValues.push(val);
909
- let colStyle = {
910
- columnName: '',
911
- styles: []
912
- };
913
- // Reminder: Value Formatting is performed **before** Conditional Formatting.
914
- // https://chatwms.io/user-manual/concepts/column-formatting#conditional-formatting
915
- const colFmt = columnFormats[colIdx];
916
- for (const condFmt of colFmt.conditionalFormats.slice().reverse()) {
917
- // `conditionalFormats` has already been sorted by `sequence`.
918
- // NOTE: need to reverse the array for sequence to be correctly applied.
919
- // NOTE: using `slice` to make shallow copy of array since `reverse` does so in place.
920
- if (evaluateConditionalFormat(condFmt, colFmt.type, formatNumberEnabled(colFmt.valueFormat) ? stripNumericValueFormat(val) : val)) {
921
- if (condFmt.row) {
922
- rowStyles.push(condFmt.style);
923
- }
924
- else {
925
- colStyle.styles.push(condFmt.style);
926
- }
927
- }
928
- }
929
- colStyles.push(colStyle);
930
- colIdx++;
931
- }
932
- // Apply row styles.
933
- if (rowStyles.length > 0) {
934
- htmlBuf += `\n\t\t<tr class="${rowStyles.join(' ')}">`;
935
- }
936
- else {
937
- htmlBuf += '\n\t\t<tr>';
938
- }
939
- // Write cell values with styles.
940
- colIdx = 0;
941
- for (const rowValue of cellValues) {
942
- if (colStyles[colIdx].styles.length > 0) {
943
- htmlBuf += `\n\t\t\t<td class="${colStyles[colIdx].styles.join(' ')}">${rowValue}</td>`;
944
- }
945
- else {
946
- htmlBuf += `\n\t\t\t<td>${rowValue}</td>`;
947
- }
948
- markdownBuf += `| ${rowValue} `;
949
- colIdx++;
950
- }
951
- htmlBuf += '\n\t\t</tr>';
952
- markdownBuf += '|\n';
953
- rowIdx++;
954
- }
955
- htmlBuf += '\n\t</tbody>\n</table>';
956
- return {
957
- html: htmlBuf,
958
- markdown: markdownBuf
959
- };
936
+ return { ...datagridState, adjRowData: rows, chartRowData, html: `${buildHtmlHeader(htmlColumnNames)}${htmlBuf}` };
960
937
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cellaware/utils",
3
- "version": "8.3.17",
3
+ "version": "8.3.18",
4
4
  "description": "Cellaware Utilities for Node.js",
5
5
  "author": "Cellaware Technologies",
6
6
  "type": "module",