@cellaware/utils 8.6.3 → 8.6.4

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.
@@ -6,11 +6,15 @@ export interface DatagridStateBase {
6
6
  columnFormats?: ColumnFormat[];
7
7
  }
8
8
  export interface DatagridState extends DatagridStateBase {
9
- adjRowData: any[];
10
- chartRowData: any[];
11
- html: string;
9
+ adjRows: any[];
12
10
  }
13
11
  export declare function initDatagridState(): DatagridState;
12
+ export interface VisualDatagridState extends DatagridState {
13
+ chartRows: any[];
14
+ html: string;
15
+ teamsRows: any[];
16
+ }
17
+ export declare function initVisualDatagridState(): VisualDatagridState;
14
18
  export type ColumnState = {
15
19
  colId: string;
16
20
  hide?: boolean | null;
@@ -107,6 +111,7 @@ export interface ConditionalFormat {
107
111
  row: boolean;
108
112
  }
109
113
  export declare function evaluateConditionalFormat(condFmt: ConditionalFormat, dataType: string, value: any): boolean;
114
+ export declare function evaluateValueStyles(datagridState: DatagridStateBase, columnName: string, value: any): string[];
110
115
  export interface DatagridCondition {
111
116
  columnName: string;
112
117
  /** `text` | `number` | `date` | `boolean` */
@@ -126,8 +131,26 @@ export declare function codifyCondition(condition: DatagridCondition): string;
126
131
  * https://github.com/cellaware/chatwms-az-swa-ng/blob/development/src/app/utils/data.ts#L126
127
132
  */
128
133
  export declare function stripNumericValueFormat(value: string | number | undefined): any;
134
+ interface HtmlColumnStyle {
135
+ columnName: string;
136
+ styles: string[];
137
+ }
138
+ interface TeamsColumnStyleAttributes {
139
+ color?: string;
140
+ style?: string;
141
+ weight?: string;
142
+ isSubtle?: boolean;
143
+ italic?: boolean;
144
+ }
145
+ interface TeamsColumnStyle {
146
+ columnName: string;
147
+ styles: TeamsColumnStyleAttributes[];
148
+ }
149
+ export declare function mapTeamsStyles(columnNames: string[], htmlRowStyles: string[], htmlColumnStyles: HtmlColumnStyle[], teamsRowStyles: string[], teamsColumnStyles: TeamsColumnStyle[]): [string[], TeamsColumnStyle[]];
129
150
  /**
130
- * **Important:** `html` output will be limited to **1,000 rows** and **8 columns**.
151
+ * **Important:** `html` and `teamsRows` output will be limited to **1,000 rows** and **8 columns**.
152
+ *
153
+ * All outputs respect and will be filtered by optional `condition` argument.
131
154
  */
132
- export declare function transformDatagrid(rows: any[], datagridState: DatagridStateBase, locale: string, condition?: DatagridCondition): DatagridState;
155
+ export declare function transformDatagrid(rows: any[], datagridState: DatagridStateBase, locale: string, condition?: DatagridCondition): VisualDatagridState;
133
156
  export {};
@@ -2,9 +2,15 @@ import { isDateString } from "../util.js";
2
2
  import { CHATWMS_DEFAULT_LANGUAGE } from "./user.js";
3
3
  export function initDatagridState() {
4
4
  return {
5
- adjRowData: [],
6
- chartRowData: [],
7
- html: ''
5
+ adjRows: []
6
+ };
7
+ }
8
+ export function initVisualDatagridState() {
9
+ return {
10
+ ...initDatagridState(),
11
+ chartRows: [],
12
+ html: '',
13
+ teamsRows: []
8
14
  };
9
15
  }
10
16
  export const DEFAULT_VALUE_FORMAT_VALUE = 'none';
@@ -258,6 +264,23 @@ export function evaluateConditionalFormat(condFmt, dataType, value) {
258
264
  return false;
259
265
  }
260
266
  }
267
+ export function evaluateValueStyles(datagridState, columnName, value) {
268
+ const styles = [];
269
+ // Reminder: Value Formatting is performed **before** Conditional Formatting.
270
+ // https://chatwms.io/user-manual/concepts/column-formatting#conditional-formatting
271
+ const colFmt = datagridState.columnFormats?.find(colFmt => colFmt.displayName === columnName);
272
+ if (!!colFmt) {
273
+ for (const condFmt of colFmt.conditionalFormats.slice().reverse()) {
274
+ // `conditionalFormats` has already been sorted by `sequence`.
275
+ // NOTE: need to reverse the array for sequence to be correctly applied.
276
+ // NOTE: using `slice` to make shallow copy of array since `reverse` does so in place.
277
+ if (evaluateConditionalFormat(condFmt, colFmt.type, formatNumberEnabled(colFmt.valueFormat) ? stripNumericValueFormat(value) : value)) {
278
+ styles.push(condFmt.style);
279
+ }
280
+ }
281
+ }
282
+ return styles;
283
+ }
261
284
  export function initDatagridCondition() {
262
285
  return {
263
286
  columnName: '',
@@ -780,6 +803,127 @@ function processHtmlStyles(value, columnFormat, rowStyles, columnStyles) {
780
803
  columnStyles.push(columnStyle);
781
804
  return [rowStyles, columnStyles];
782
805
  }
806
+ export function mapTeamsStyles(columnNames, htmlRowStyles, htmlColumnStyles, teamsRowStyles, teamsColumnStyles) {
807
+ // IMPORTANT: both column/row style sorting have **already** been reversed (line 1170).
808
+ // We can simply iterate over all the matched styles and accumulate them.
809
+ const getColumnStyle = (style) => {
810
+ switch (style) {
811
+ case 'conditional-format-style-green-background':
812
+ return {
813
+ color: 'Good',
814
+ style: 'good'
815
+ };
816
+ case 'conditional-format-style-yellow-background':
817
+ return {
818
+ color: 'Warning',
819
+ style: 'warning'
820
+ };
821
+ case 'conditional-format-style-red-background':
822
+ return {
823
+ color: 'Attention',
824
+ style: 'attention'
825
+ };
826
+ case 'conditional-format-style-blue-background':
827
+ return {
828
+ color: 'Accent',
829
+ style: 'accent'
830
+ };
831
+ case 'conditional-format-style-bold':
832
+ return {
833
+ weight: 'Bolder'
834
+ };
835
+ case 'conditional-format-style-green-bold':
836
+ return {
837
+ color: 'Good',
838
+ weight: 'Bolder'
839
+ };
840
+ case 'conditional-format-style-yellow-bold':
841
+ return {
842
+ color: 'Warning',
843
+ weight: 'Bolder'
844
+ };
845
+ case 'conditional-format-style-red-bold':
846
+ return {
847
+ color: 'Attention',
848
+ weight: 'Bolder'
849
+ };
850
+ case 'conditional-format-style-blue-bold':
851
+ return {
852
+ color: 'Accent',
853
+ weight: 'Bolder'
854
+ };
855
+ case 'conditional-format-style-not-important':
856
+ return {
857
+ isSubtle: true,
858
+ italic: true
859
+ };
860
+ default:
861
+ return {};
862
+ }
863
+ };
864
+ for (const htmlColumnStyle of htmlColumnStyles) {
865
+ teamsColumnStyles.push({
866
+ columnName: htmlColumnStyle.columnName,
867
+ styles: htmlColumnStyle.styles.map(style => getColumnStyle(style))
868
+ });
869
+ }
870
+ const applyRowStyleToColumns = (style) => {
871
+ for (const columnName of columnNames) {
872
+ const columnStyle = getColumnStyle(style);
873
+ const teamsColumnStyle = teamsColumnStyles.find(c => c.columnName === columnName);
874
+ if (!!teamsColumnStyle) {
875
+ teamsColumnStyle.styles.push(columnStyle);
876
+ }
877
+ else {
878
+ teamsColumnStyles.push({
879
+ columnName,
880
+ styles: [columnStyle]
881
+ });
882
+ }
883
+ }
884
+ };
885
+ for (const htmlRowStyle of htmlRowStyles) {
886
+ switch (htmlRowStyle) {
887
+ case 'conditional-format-style-green-background':
888
+ teamsRowStyles.push('good');
889
+ applyRowStyleToColumns('conditional-format-style-green-background');
890
+ break;
891
+ case 'conditional-format-style-yellow-background':
892
+ teamsRowStyles.push('warning');
893
+ applyRowStyleToColumns('conditional-format-style-yellow-background');
894
+ break;
895
+ case 'conditional-format-style-red-background':
896
+ teamsRowStyles.push('attention');
897
+ applyRowStyleToColumns('conditional-format-style-red-background');
898
+ break;
899
+ case 'conditional-format-style-blue-background':
900
+ teamsRowStyles.push('accent');
901
+ applyRowStyleToColumns('conditional-format-style-blue-background');
902
+ break;
903
+ case 'conditional-format-style-bold':
904
+ applyRowStyleToColumns('conditional-format-style-bold');
905
+ break;
906
+ case 'conditional-format-style-green-bold':
907
+ applyRowStyleToColumns('conditional-format-style-green-bold');
908
+ break;
909
+ case 'conditional-format-style-yellow-bold':
910
+ applyRowStyleToColumns('conditional-format-style-yellow-bold');
911
+ break;
912
+ case 'conditional-format-style-red-bold':
913
+ applyRowStyleToColumns('conditional-format-style-red-bold');
914
+ break;
915
+ case 'conditional-format-style-blue-bold':
916
+ applyRowStyleToColumns('conditional-format-style-blue-bold');
917
+ break;
918
+ case 'conditional-format-style-not-important':
919
+ applyRowStyleToColumns('conditional-format-style-not-important');
920
+ break;
921
+ default:
922
+ break;
923
+ }
924
+ }
925
+ return [teamsRowStyles, teamsColumnStyles];
926
+ }
783
927
  function buildHtmlTableHeader(columnNames) {
784
928
  let buf = '<table>\n\t<thead>\n\t\t<tr>';
785
929
  for (const columnName of columnNames) {
@@ -818,8 +962,83 @@ function buildHtmlRow(rowValues, rowStyles, columnStyles, columnCount) {
818
962
  buf += '\n\t\t</tr>';
819
963
  return buf;
820
964
  }
965
+ function createTeamsTableColumnText(columnName) {
966
+ return {
967
+ type: "TextBlock",
968
+ text: columnName,
969
+ size: "Small",
970
+ weight: "Bolder",
971
+ wrap: false,
972
+ maxLines: 1,
973
+ spacing: "None"
974
+ };
975
+ }
976
+ function createTeamsTableColumns(columnNames) {
977
+ return {
978
+ type: "TableRow",
979
+ cells: columnNames.map((columnName) => ({
980
+ type: "TableCell",
981
+ items: [createTeamsTableColumnText(columnName)]
982
+ }))
983
+ };
984
+ }
985
+ function createTeamsTableCellText(value, columnStyle) {
986
+ let color = undefined;
987
+ let weight = undefined;
988
+ let isSubtle = undefined;
989
+ let italic = undefined;
990
+ for (const styles of columnStyle?.styles ?? []) {
991
+ if (!!styles.color) {
992
+ color = styles.color;
993
+ }
994
+ if (!!styles.weight) {
995
+ weight = styles.weight;
996
+ }
997
+ if (!!styles.isSubtle) {
998
+ isSubtle = styles.isSubtle;
999
+ }
1000
+ }
1001
+ return {
1002
+ type: "TextBlock",
1003
+ text: italic ? `*${value}*` : value,
1004
+ size: "Small",
1005
+ color,
1006
+ weight: weight ?? "Default",
1007
+ wrap: false,
1008
+ maxLines: 1,
1009
+ spacing: "None",
1010
+ isSubtle
1011
+ };
1012
+ }
1013
+ function createTeamsTableRow(columnNames, values, oddRow, rowStyles, columnStyles) {
1014
+ let rowStyle = undefined;
1015
+ for (const style of rowStyles) {
1016
+ rowStyle = style;
1017
+ }
1018
+ return {
1019
+ type: "TableRow",
1020
+ ...(rowStyle ? { style: rowStyle } : (oddRow ? { style: "emphasis" } : {})),
1021
+ cells: values.map((value, idx) => {
1022
+ const columnName = columnNames[idx];
1023
+ const columnStyle = columnStyles.find(columnStyle => columnStyle.columnName === columnName);
1024
+ let style = undefined;
1025
+ for (const styles of columnStyle?.styles ?? []) {
1026
+ if (!!styles.style) {
1027
+ style = styles.style;
1028
+ }
1029
+ }
1030
+ return {
1031
+ type: "TableCell",
1032
+ style,
1033
+ items: [createTeamsTableCellText(value, columnStyle)]
1034
+ };
1035
+ })
1036
+ };
1037
+ }
821
1038
  /**
822
- * **Important:** `html` output will be limited to **1,000 rows** and **8 columns**.
1039
+ * **Important:** `html` and `teamsRows` output will be limited to **1,000 rows** and **8 columns**.
1040
+ *
1041
+ * All outputs respect and will be filtered by optional `condition` argument.
823
1042
  */
824
1043
  export function transformDatagrid(rows, datagridState, locale, condition) {
825
1044
  const HTML_ROWS = 1000;
@@ -830,9 +1049,10 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
830
1049
  const columnFormats = datagridState.columnFormats ?? [];
831
1050
  const { rowGroupCols, pivotCols, valueCols, sortModel } = parseColumnState(columnState);
832
1051
  rows = filterRows(rows, filterModel);
833
- const chartRowData = [];
1052
+ const chartRows = [];
834
1053
  let htmlBuf = '';
835
1054
  const htmlColumnNames = [];
1055
+ const teamsRows = [];
836
1056
  // IMPORTANT: we evaluate the datagrid condition AFTER we are done with all transformations.
837
1057
  // NOTE: we do not need any pivot columns for pivot mode to be valid.
838
1058
  // https://chatwms.io/user-manual/chatwms/faq#q-do-i-have-to-have-a-group-column-to-just-display-a-count-in-the-datagrid
@@ -842,27 +1062,60 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
842
1062
  rows = sortModel.length > 0 ? sortRows(rows, sortModel) : rows;
843
1063
  let mappedDisplayColumnNames = new Map();
844
1064
  // Should not need to do hidden/visible column analysis -- pivoting creates new results with only the necessary columns.
1065
+ rows.forEach(row => {
1066
+ columnFormats.forEach(columnFormat => {
1067
+ if (columnFormat.name in row) {
1068
+ row[columnFormat.displayName] = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
1069
+ if (columnFormat.displayName !== columnFormat.name) { // Remove name in favor of display name.
1070
+ delete row[columnFormat.name];
1071
+ }
1072
+ }
1073
+ else {
1074
+ const mappedColumnNamesSet = pivotOutput.mappedColumnNames.get(columnFormat.name);
1075
+ if (!!mappedColumnNamesSet) {
1076
+ const mappedColumnNamesArr = Array.from(mappedColumnNamesSet);
1077
+ for (const mappedColumnName of mappedColumnNamesArr) {
1078
+ if (mappedColumnName in row) {
1079
+ const adjDisplayName = mappedColumnName.replace(columnFormat.name, columnFormat.displayName);
1080
+ row[adjDisplayName] = evaluateValueFormat(columnFormat, row[mappedColumnName], locale);
1081
+ if (adjDisplayName !== mappedColumnName) { // Remove name in favor of display name.
1082
+ delete row[mappedColumnName];
1083
+ }
1084
+ let displayColumnNames = mappedDisplayColumnNames.get(columnFormat.displayName);
1085
+ if (!!displayColumnNames) {
1086
+ displayColumnNames.add(adjDisplayName);
1087
+ }
1088
+ else {
1089
+ displayColumnNames = new Set([adjDisplayName]);
1090
+ mappedDisplayColumnNames.set(columnFormat.displayName, displayColumnNames);
1091
+ }
1092
+ }
1093
+ }
1094
+ }
1095
+ }
1096
+ });
1097
+ });
1098
+ if (!!condition) {
1099
+ rows = evaluatePivotDatagridCondition(rows, condition, mappedDisplayColumnNames);
1100
+ }
845
1101
  let rowIdx = 0;
846
1102
  rows.forEach(row => {
847
1103
  let chartRow = {};
848
1104
  let htmlRowValues = [];
849
1105
  let htmlRowStyles = [];
850
1106
  let htmlColumnStyles = [];
1107
+ let teamsRowStyles = [];
1108
+ let teamsColumnStyles = [];
851
1109
  columnFormats.forEach(columnFormat => {
852
1110
  if (columnFormat.name in row) {
853
- const value = row[columnFormat.name];
854
1111
  const formattedValue = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
855
- row[columnFormat.displayName] = formattedValue;
856
- chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
1112
+ chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? stripNumericValueFormat(formattedValue) : formattedValue;
857
1113
  htmlRowValues.push(formattedValue);
858
1114
  [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
1115
+ [teamsRowStyles, teamsColumnStyles] = mapTeamsStyles(htmlColumnNames, htmlRowStyles, htmlColumnStyles, teamsRowStyles, teamsColumnStyles);
859
1116
  if (rowIdx === 0) {
860
1117
  htmlColumnNames.push(columnFormat.displayName);
861
1118
  }
862
- // Remove name in favor of display name.
863
- if (columnFormat.displayName !== columnFormat.name) {
864
- delete row[columnFormat.name];
865
- }
866
1119
  }
867
1120
  else {
868
1121
  const mappedColumnNamesSet = pivotOutput.mappedColumnNames.get(columnFormat.name);
@@ -871,41 +1124,25 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
871
1124
  for (const mappedColumnName of mappedColumnNamesArr) {
872
1125
  if (mappedColumnName in row) {
873
1126
  const adjDisplayName = mappedColumnName.replace(columnFormat.name, columnFormat.displayName);
874
- const value = row[mappedColumnName];
875
1127
  const formattedValue = evaluateValueFormat(columnFormat, row[mappedColumnName], locale);
876
- row[adjDisplayName] = formattedValue;
877
- chartRow[adjDisplayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
1128
+ chartRow[adjDisplayName] = formatNumberEnabled(columnFormat.valueFormat) ? stripNumericValueFormat(formattedValue) : formattedValue;
878
1129
  htmlRowValues.push(formattedValue);
879
1130
  [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
880
1131
  if (rowIdx === 0) {
881
1132
  htmlColumnNames.push(columnFormat.displayName);
882
1133
  }
883
- // Remove name in favor of display name.
884
- if (adjDisplayName !== mappedColumnName) {
885
- delete row[mappedColumnName];
886
- }
887
- let displayColumnNames = mappedDisplayColumnNames.get(columnFormat.displayName);
888
- if (!!displayColumnNames) {
889
- displayColumnNames.add(adjDisplayName);
890
- }
891
- else {
892
- displayColumnNames = new Set([adjDisplayName]);
893
- mappedDisplayColumnNames.set(columnFormat.displayName, displayColumnNames);
894
- }
895
1134
  }
896
1135
  }
897
1136
  }
898
1137
  }
899
1138
  });
900
- chartRowData.push(chartRow);
1139
+ chartRows.push(chartRow);
901
1140
  if (rowIdx < HTML_ROWS) {
902
1141
  htmlBuf += buildHtmlRow(htmlRowValues, htmlRowStyles, htmlColumnStyles, HTML_COLS);
1142
+ teamsRows.push(createTeamsTableRow(htmlColumnNames, htmlRowValues, rowIdx % 2 === 1, teamsRowStyles, teamsColumnStyles));
903
1143
  }
904
1144
  rowIdx++;
905
1145
  });
906
- if (!!condition) {
907
- rows = evaluatePivotDatagridCondition(rows, condition, mappedDisplayColumnNames);
908
- }
909
1146
  }
910
1147
  else {
911
1148
  if (rowGroupCols.length > 0) {
@@ -914,44 +1151,53 @@ export function transformDatagrid(rows, datagridState, locale, condition) {
914
1151
  rows = sortModel.length > 0 ? sortRows(rows, sortModel) : rows;
915
1152
  const hiddenColumnNames = columnState.filter(column => !!column.hide && !column.rowGroup).map(column => column.colId) ?? [];
916
1153
  const visibleColumnFormats = columnFormats.filter(column => !hiddenColumnNames.includes(column.name)) ?? [];
1154
+ rows.forEach(row => {
1155
+ hiddenColumnNames.forEach(columnName => {
1156
+ delete row[columnName];
1157
+ });
1158
+ visibleColumnFormats.forEach(columnFormat => {
1159
+ row[columnFormat.displayName] = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
1160
+ if (columnFormat.displayName !== columnFormat.name) { // Remove name in favor of display name.
1161
+ delete row[columnFormat.name];
1162
+ }
1163
+ });
1164
+ });
1165
+ if (!!condition) {
1166
+ rows = evaluateDatagridCondition(rows, condition);
1167
+ }
917
1168
  let rowIdx = 0;
918
1169
  rows.forEach(row => {
919
1170
  let chartRow = {};
920
1171
  let htmlRowValues = [];
921
1172
  let htmlRowStyles = [];
922
1173
  let htmlColumnStyles = [];
923
- hiddenColumnNames.forEach(columnName => {
924
- delete row[columnName];
925
- });
1174
+ let teamsRowStyles = [];
1175
+ let teamsColumnStyles = [];
926
1176
  visibleColumnFormats.forEach(columnFormat => {
927
- const value = row[columnFormat.name];
928
1177
  const formattedValue = evaluateValueFormat(columnFormat, row[columnFormat.name], locale);
929
- row[columnFormat.displayName] = formattedValue;
930
- chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? value : formattedValue;
1178
+ chartRow[columnFormat.displayName] = formatNumberEnabled(columnFormat.valueFormat) ? stripNumericValueFormat(formattedValue) : formattedValue;
931
1179
  htmlRowValues.push(formattedValue);
932
1180
  [htmlRowStyles, htmlColumnStyles] = processHtmlStyles(formattedValue, columnFormat, htmlRowStyles, htmlColumnStyles);
933
1181
  if (rowIdx === 0) {
934
1182
  htmlColumnNames.push(columnFormat.displayName);
935
1183
  }
936
- // Remove name in favor of display name.
937
- if (columnFormat.displayName !== columnFormat.name) {
938
- delete row[columnFormat.name];
939
- }
940
1184
  });
941
- chartRowData.push(chartRow);
1185
+ chartRows.push(chartRow);
942
1186
  if (rowIdx < HTML_ROWS) {
943
1187
  htmlBuf += buildHtmlRow(htmlRowValues, htmlRowStyles, htmlColumnStyles, HTML_COLS);
1188
+ teamsRows.push(createTeamsTableRow(htmlColumnNames, htmlRowValues, rowIdx % 2 === 1, teamsRowStyles, teamsColumnStyles));
944
1189
  }
945
1190
  rowIdx++;
946
1191
  });
947
- if (!!condition) {
948
- rows = evaluateDatagridCondition(rows, condition);
949
- }
950
1192
  }
951
1193
  return {
952
1194
  ...datagridState,
953
- adjRowData: rows,
954
- chartRowData,
955
- html: `${buildHtmlTableHeader(htmlColumnNames.slice(0, HTML_COLS))}${htmlBuf}${buildHtmlTableFooter()}`
1195
+ adjRows: rows,
1196
+ chartRows,
1197
+ html: `${buildHtmlTableHeader(htmlColumnNames.slice(0, HTML_COLS))}${htmlBuf}${buildHtmlTableFooter()}`,
1198
+ teamsRows: [
1199
+ createTeamsTableColumns(htmlColumnNames),
1200
+ ...teamsRows
1201
+ ]
956
1202
  };
957
1203
  }
@@ -0,0 +1,81 @@
1
+ export declare function createTeamsTableCard(title: string, columnNames: string[], table: any[], summary: string): {
2
+ type: string;
3
+ version: string;
4
+ msteams: {
5
+ width: string;
6
+ };
7
+ body: ({
8
+ type: string;
9
+ text: string;
10
+ size: string;
11
+ weight: string;
12
+ } | {
13
+ type: string;
14
+ text: string;
15
+ size: string;
16
+ isSubtle: boolean;
17
+ wrap: boolean;
18
+ } | {
19
+ type: string;
20
+ roundedCorners: boolean;
21
+ firstRowAsHeaders: boolean;
22
+ columns: {
23
+ width: number;
24
+ }[];
25
+ rows: any[];
26
+ })[];
27
+ };
28
+ export declare function createTeamsValueCard(title: string, columnName: string, value: any, styles: string[], summary: string): {
29
+ type: string;
30
+ version: string;
31
+ msteams: {
32
+ width: string;
33
+ };
34
+ body: ({
35
+ type: string;
36
+ text: string;
37
+ size: string;
38
+ weight: string;
39
+ } | {
40
+ type: string;
41
+ text: string;
42
+ size: string;
43
+ isSubtle: boolean;
44
+ wrap: boolean;
45
+ } | {
46
+ type: string;
47
+ roundedCorners: boolean;
48
+ items: {
49
+ type: string;
50
+ text: any;
51
+ wrap: boolean;
52
+ size: string;
53
+ color: string | undefined;
54
+ weight: string | undefined;
55
+ }[];
56
+ style: string | undefined;
57
+ })[];
58
+ };
59
+ export declare function createTeamsChartCard(title: string, png: string, summary: string): {
60
+ type: string;
61
+ version: string;
62
+ msteams: {
63
+ width: string;
64
+ };
65
+ body: ({
66
+ type: string;
67
+ text: string;
68
+ size: string;
69
+ weight: string;
70
+ } | {
71
+ type: string;
72
+ text: string;
73
+ size: string;
74
+ isSubtle: boolean;
75
+ wrap: boolean;
76
+ } | {
77
+ type: string;
78
+ url: string;
79
+ })[];
80
+ };
81
+ export declare function sendTeamsWebhook(url: string, card: any): Promise<Response>;
@@ -0,0 +1,107 @@
1
+ import { mapTeamsStyles } from "./datagrid.js";
2
+ function createTeamsTitleItem(title) {
3
+ return {
4
+ type: "TextBlock",
5
+ text: title,
6
+ size: "Medium",
7
+ weight: "Bolder"
8
+ };
9
+ }
10
+ function createTeamsSummaryItem(summary) {
11
+ return {
12
+ type: "TextBlock",
13
+ text: `*${summary}*`,
14
+ size: "Small",
15
+ isSubtle: true,
16
+ wrap: true
17
+ };
18
+ }
19
+ export function createTeamsTableCard(title, columnNames, table, summary) {
20
+ return {
21
+ type: "AdaptiveCard",
22
+ version: "1.5",
23
+ msteams: { width: "Full" },
24
+ body: [
25
+ createTeamsTitleItem(title),
26
+ {
27
+ type: "Table",
28
+ roundedCorners: true,
29
+ firstRowAsHeaders: true,
30
+ columns: columnNames.map(() => ({ width: 3 })),
31
+ rows: table
32
+ },
33
+ createTeamsSummaryItem(summary)
34
+ ]
35
+ };
36
+ }
37
+ export function createTeamsValueCard(title, columnName, value, styles, summary) {
38
+ let teamsStyles = [];
39
+ let _ = [];
40
+ [teamsStyles, _] = mapTeamsStyles([columnName], styles, [], _, teamsStyles);
41
+ let color = undefined;
42
+ let style = undefined;
43
+ let weight = undefined;
44
+ let isSubtle = undefined;
45
+ for (const styles of teamsStyles) {
46
+ if (!!styles.color) {
47
+ color = styles.color;
48
+ }
49
+ if (!!styles.style) {
50
+ style = styles.style;
51
+ }
52
+ if (!!styles.weight) {
53
+ weight = styles.weight;
54
+ }
55
+ if (!!styles.isSubtle) {
56
+ isSubtle = styles.isSubtle;
57
+ }
58
+ }
59
+ return {
60
+ type: "AdaptiveCard",
61
+ version: "1.5",
62
+ msteams: { width: "Full" },
63
+ body: [
64
+ createTeamsTitleItem(title),
65
+ {
66
+ type: "Container",
67
+ roundedCorners: true,
68
+ items: [
69
+ {
70
+ type: "TextBlock",
71
+ text: value,
72
+ wrap: true,
73
+ size: "ExtraLarge",
74
+ color,
75
+ weight
76
+ }
77
+ ],
78
+ style
79
+ },
80
+ createTeamsSummaryItem(summary)
81
+ ]
82
+ };
83
+ }
84
+ export function createTeamsChartCard(title, png, summary) {
85
+ return {
86
+ type: "AdaptiveCard",
87
+ version: "1.5",
88
+ msteams: { width: "Full" },
89
+ body: [
90
+ createTeamsTitleItem(title),
91
+ {
92
+ type: "Image",
93
+ url: png
94
+ },
95
+ createTeamsSummaryItem(summary)
96
+ ]
97
+ };
98
+ }
99
+ export async function sendTeamsWebhook(url, card) {
100
+ return fetch(url, {
101
+ method: "POST",
102
+ headers: {
103
+ "content-type": "application/json"
104
+ },
105
+ body: JSON.stringify(card),
106
+ });
107
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cellaware/utils",
3
- "version": "8.6.3",
3
+ "version": "8.6.4",
4
4
  "description": "Cellaware Utilities for Node.js",
5
5
  "author": "Cellaware Technologies",
6
6
  "type": "module",