@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.
- package/dist/chatwms/datagrid.d.ts +1 -4
- package/dist/chatwms/datagrid.js +87 -110
- package/package.json +1 -1
|
@@ -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 {};
|
package/dist/chatwms/datagrid.js
CHANGED
|
@@ -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
|
}
|