@churchapps/apphelper 0.2.1 → 0.2.2
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/components/ExportLink.d.ts +6 -0
- package/dist/components/ExportLink.d.ts.map +1 -1
- package/dist/components/ExportLink.js +3 -2
- package/dist/components/ExportLink.js.map +1 -1
- package/dist/components/reporting/ReportOutput.d.ts.map +1 -1
- package/dist/components/reporting/ReportOutput.js +60 -3
- package/dist/components/reporting/ReportOutput.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ExportLink.tsx +5 -2
- package/src/components/reporting/ReportOutput.tsx +63 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportLink.d.ts","sourceRoot":"","sources":["../../src/components/ExportLink.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,KAAK;IACb,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ExportLink.d.ts","sourceRoot":"","sources":["../../src/components/ExportLink.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,KAAK;IACb,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,EAAE,CAAA;CAC/C;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAuDtC,CAAA"}
|
|
@@ -60,10 +60,11 @@ const ExportLink = (props) => {
|
|
|
60
60
|
let items = [];
|
|
61
61
|
if (props.spaceBefore)
|
|
62
62
|
items.push(" ");
|
|
63
|
-
items.push(react_1.default.createElement(react_csv_1.CSVLink, { key: props.filename, data: people, headers: getHeaders(), filename: props.filename || "export.csv" },
|
|
63
|
+
items.push(react_1.default.createElement(react_csv_1.CSVLink, { key: props.filename, data: people, headers: props.customHeaders || getHeaders(), filename: props.filename || "export.csv" },
|
|
64
64
|
" ",
|
|
65
65
|
react_1.default.createElement(material_1.Button, null,
|
|
66
|
-
react_1.default.createElement(material_1.Icon,
|
|
66
|
+
react_1.default.createElement(material_1.Icon, { sx: { marginRight: props.text ? 1 : 0 } }, props.icon || "file_download"),
|
|
67
|
+
props.text || "")));
|
|
67
68
|
if (props.spaceAfter)
|
|
68
69
|
items.push(" ");
|
|
69
70
|
return (react_1.default.createElement(react_1.default.Fragment, null, items));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportLink.js","sourceRoot":"","sources":["../../src/components/ExportLink.tsx"],"names":[],"mappings":";;;;;;AAAA,4CAA6C;AAC7C,kDAA0B;AAC1B,yCAAoC;
|
|
1
|
+
{"version":3,"file":"ExportLink.js","sourceRoot":"","sources":["../../src/components/ExportLink.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportOutput.d.ts","sourceRoot":"","sources":["../../../src/components/reporting/ReportOutput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"ReportOutput.d.ts","sourceRoot":"","sources":["../../../src/components/reporting/ReportOutput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AACtC,OAAO,EAAgC,eAAe,EAAyB,MAAM,qBAAqB,CAAC;AAU3G,UAAU,KAAK;IAAG,MAAM,EAAE,eAAe,CAAA;CAAE;AAE3C,eAAO,MAAM,YAAY,UAAW,KAAK,sBA6HxC,CAAA"}
|
|
@@ -22,11 +22,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
25
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
35
|
exports.ReportOutput = void 0;
|
|
27
36
|
const react_1 = __importStar(require("react"));
|
|
37
|
+
const helpers_1 = require("@churchapps/helpers");
|
|
28
38
|
const __1 = require("../");
|
|
29
|
-
const
|
|
39
|
+
const helpers_2 = require("../../helpers");
|
|
30
40
|
const react_to_print_1 = require("react-to-print");
|
|
31
41
|
const TableReport_1 = require("./TableReport");
|
|
32
42
|
const ChartReport_1 = require("./ChartReport");
|
|
@@ -35,11 +45,37 @@ const material_1 = require("@mui/material");
|
|
|
35
45
|
const useMountedState_1 = require("../../hooks/useMountedState");
|
|
36
46
|
const ReportOutput = (props) => {
|
|
37
47
|
const [reportResult, setReportResult] = react_1.default.useState(null);
|
|
48
|
+
const [detailedPersonSummary, setDetailedPersonSummary] = react_1.default.useState(null);
|
|
49
|
+
const [customHeaders, setCustomHeaders] = react_1.default.useState([]);
|
|
50
|
+
const [anchorEl, setAnchorEl] = react_1.default.useState(null);
|
|
51
|
+
const open = Boolean(anchorEl);
|
|
38
52
|
const contentRef = (0, react_1.useRef)(null);
|
|
39
53
|
const isMounted = (0, useMountedState_1.useMountedState)();
|
|
40
54
|
const handlePrint = (0, react_to_print_1.useReactToPrint)({
|
|
41
55
|
content: () => contentRef.current
|
|
42
56
|
});
|
|
57
|
+
const populatePeople = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
let result = [];
|
|
59
|
+
let headers = [];
|
|
60
|
+
const peopleIds = helpers_1.ArrayHelper.getIds(data, "personId");
|
|
61
|
+
if (peopleIds.length > 0) {
|
|
62
|
+
const people = yield helpers_2.ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
|
|
63
|
+
data.forEach((d) => {
|
|
64
|
+
const person = helpers_1.ArrayHelper.getOne(people, "id", d.personId);
|
|
65
|
+
const funds = Object.assign({}, ...d.funds);
|
|
66
|
+
const obj = Object.assign({ firstName: person.name.first, lastName: person.name.last, address: person.contactInfo.address1 + (person.contactInfo.address2 ? `, ${person.contactInfo.address2}` : ""), city: person.contactInfo.city, state: person.contactInfo.state, zip: person.contactInfo.zip, totalDonation: d.totalAmount }, funds);
|
|
67
|
+
result.push(obj);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//set custom headers
|
|
71
|
+
const maxKeysObj = result === null || result === void 0 ? void 0 : result.reduce((a, b) => {
|
|
72
|
+
return Object.keys(a).length > Object.keys(b).length ? a : b;
|
|
73
|
+
}, []);
|
|
74
|
+
const objKeys = Object.keys(maxKeysObj);
|
|
75
|
+
objKeys.forEach(key => headers.push({ label: key, key: key }));
|
|
76
|
+
setCustomHeaders(headers);
|
|
77
|
+
setDetailedPersonSummary(result);
|
|
78
|
+
});
|
|
43
79
|
const runReport = () => {
|
|
44
80
|
if (props.report) {
|
|
45
81
|
const queryParams = [];
|
|
@@ -50,20 +86,41 @@ const ReportOutput = (props) => {
|
|
|
50
86
|
let url = "/reports/" + props.report.keyName + "/run";
|
|
51
87
|
if (queryParams)
|
|
52
88
|
url += "?" + queryParams.join("&");
|
|
53
|
-
|
|
89
|
+
helpers_2.ApiHelper.get(url, "ReportingApi").then((data) => {
|
|
54
90
|
if (isMounted()) {
|
|
55
91
|
setReportResult(data);
|
|
56
92
|
}
|
|
57
93
|
});
|
|
94
|
+
const donationUrl = "/donations/summary?type=person&" + queryParams.join("&");
|
|
95
|
+
helpers_2.ApiHelper.get(donationUrl, "GivingApi").then((data) => { populatePeople(data); });
|
|
58
96
|
}
|
|
59
97
|
};
|
|
98
|
+
const getExportMenu = (key) => {
|
|
99
|
+
var _a;
|
|
100
|
+
const handleClick = (event) => {
|
|
101
|
+
setAnchorEl(event.currentTarget);
|
|
102
|
+
};
|
|
103
|
+
const handleClose = () => {
|
|
104
|
+
setAnchorEl(null);
|
|
105
|
+
};
|
|
106
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
107
|
+
react_1.default.createElement(material_1.Button, { size: "small", title: "Download Options", onClick: handleClick, key: key },
|
|
108
|
+
react_1.default.createElement(material_1.Icon, null, "download")),
|
|
109
|
+
react_1.default.createElement(material_1.Menu, { anchorEl: anchorEl, open: open, onClose: handleClose },
|
|
110
|
+
((_a = reportResult === null || reportResult === void 0 ? void 0 : reportResult.table) === null || _a === void 0 ? void 0 : _a.length) > 0 && react_1.default.createElement(material_1.MenuItem, { sx: { padding: "5px" }, onClick: handleClose },
|
|
111
|
+
react_1.default.createElement(__1.ExportLink, { data: reportResult.table, filename: props.report.displayName.replace(" ", "_") + ".csv", text: "Fund Summary", icon: "volunteer_activism" })),
|
|
112
|
+
(detailedPersonSummary === null || detailedPersonSummary === void 0 ? void 0 : detailedPersonSummary.length) > 0 && react_1.default.createElement(material_1.MenuItem, { sx: { padding: "5px" }, onClick: handleClose },
|
|
113
|
+
react_1.default.createElement(__1.ExportLink, { data: detailedPersonSummary, filename: "Detailed_Donation_Summary.csv", text: "Detailed Summary", icon: "person", customHeaders: customHeaders, spaceAfter: true })))));
|
|
114
|
+
};
|
|
60
115
|
react_1.default.useEffect(runReport, [props.report, isMounted]);
|
|
61
116
|
const getEditContent = () => {
|
|
62
117
|
const result = [];
|
|
63
118
|
if (reportResult) {
|
|
64
119
|
result.push(react_1.default.createElement("button", { type: "button", className: "no-default-style", key: result.length - 2, onClick: handlePrint, title: "print" },
|
|
65
120
|
react_1.default.createElement(material_1.Icon, null, "print")));
|
|
66
|
-
|
|
121
|
+
}
|
|
122
|
+
if ((reportResult === null || reportResult === void 0 ? void 0 : reportResult.table.length) > 0 || (detailedPersonSummary === null || detailedPersonSummary === void 0 ? void 0 : detailedPersonSummary.length) > 0) {
|
|
123
|
+
result.push(getExportMenu(result.length - 1));
|
|
67
124
|
}
|
|
68
125
|
return result;
|
|
69
126
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportOutput.js","sourceRoot":"","sources":["../../../src/components/reporting/ReportOutput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReportOutput.js","sourceRoot":"","sources":["../../../src/components/reporting/ReportOutput.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAsC;AACtC,iDAA2G;AAC3G,2BAAqD;AACrD,2CAAyC;AACzC,mDAAiD;AACjD,+CAA4C;AAC5C,+CAA4C;AAC5C,6CAA0C;AAC1C,4CAA6D;AAC7D,iEAA8D;AAIvD,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;IAC3C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAwB,IAAI,CAAC,CAAC;IACpF,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAQ,IAAI,CAAC,CAAC;IACtF,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAqB,IAAI,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAA,iCAAe,GAAE,CAAC;IAEpC,MAAM,WAAW,GAAG,IAAA,gCAAe,EAAC;QAClC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO;KAClC,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,CAAO,IAAW,EAAE,EAAE;QAC3C,IAAI,MAAM,GAAU,EAAE,CAAC;QACvB,IAAI,OAAO,GAAmC,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,qBAAW,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACvD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,MAAM,MAAM,GAAG,MAAM,mBAAS,CAAC,GAAG,CAAC,kBAAkB,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,CAAC;YAC9F,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACjB,MAAM,MAAM,GAAoB,qBAAW,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM,GAAG,mBACP,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAC5B,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAC1B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC9G,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAC7B,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,EAC/B,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,EAC3B,aAAa,EAAE,CAAC,CAAC,WAAW,IACzB,KAAK,CACT,CAAC;gBACF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;SACJ;QAED,oBAAoB;QACpB,MAAM,UAAU,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAE/D,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1B,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAA,CAAA;IAED,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,IAAI,KAAK,CAAC,MAAM,EAAE;YAChB,MAAM,WAAW,GAAa,EAAE,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;gBAClC,IAAI,CAAC,CAAC,KAAK;oBAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;YACH,IAAI,GAAG,GAAG,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACtD,IAAI,WAAW;gBAAE,GAAG,IAAI,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEpD,mBAAS,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,IAA2B,EAAE,EAAE;gBACtE,IAAG,SAAS,EAAE,EAAE;oBACd,eAAe,CAAC,IAAI,CAAC,CAAC;iBACvB;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,iCAAiC,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9E,mBAAS,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACnF;IACH,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE;;QACpC,MAAM,WAAW,GAAG,CAAC,KAA0C,EAAE,EAAE;YACjE,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC,CAAA;QAED,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAA;QACD,OAAO,CAAC;YACN,8BAAC,iBAAM,IAAC,IAAI,EAAC,OAAO,EAAC,KAAK,EAAC,kBAAkB,EAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG;gBAAE,8BAAC,eAAI,mBAAgB,CAAS;YAC5G,8BAAC,eAAI,IAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW;gBACvD,CAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,0CAAE,MAAM,IAAG,CAAC,IAAI,8BAAC,mBAAQ,IAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW;oBAAE,8BAAC,cAAU,IAAC,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,IAAI,EAAC,cAAc,EAAC,IAAI,EAAC,oBAAoB,GAAG,CAAW;gBAC3P,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,MAAM,IAAG,CAAC,IAAI,8BAAC,mBAAQ,IAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW;oBAAE,8BAAC,cAAU,IAAC,IAAI,EAAE,qBAAqB,EAAE,QAAQ,EAAC,+BAA+B,EAAC,IAAI,EAAC,kBAAkB,EAAC,IAAI,EAAC,QAAQ,EAAC,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,GAAI,CAAW,CAC9Q,CACN,CAAC,CAAA;IACN,CAAC,CAAA;IAED,eAAK,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAEtD,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,IAAI,YAAY,EAAE;YAChB,MAAM,CAAC,IAAI,CAAC,0CAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,kBAAkB,EAAC,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAC,OAAO;gBAAC,8BAAC,eAAI,gBAAa,CAAS,CAAC,CAAC;SACzJ;QACD,IAAI,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAC,MAAM,IAAG,CAAC,IAAI,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,MAAM,IAAG,CAAC,EAAE;YACvE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;SAC9C;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAC/B,IAAI,CAAC,CAAC,UAAU,KAAK,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,8BAAC,yBAAW,IAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,GAAI,CAAC,CAAA;YACpH,IAAI,CAAC,CAAC,UAAU,KAAK,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,8BAAC,uBAAU,IAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,GAAI,CAAC,CAAA;iBAC7G,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU;gBAAE,MAAM,CAAC,IAAI,CAAC,8BAAC,yBAAW,IAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,GAAI,CAAC,CAAA;QAC9H,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,8BAAC,cAAU,IAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAC,YAAY,EAAC,UAAU,EAAC,WAAW,EAAC,UAAU,EAAC,YAAY,EAAC,WAAW,EAAE,cAAc,EAAE;gBAAE,6EAAwC,CAAa,CAAC,CAAC;aAExM,IAAI,CAAC,YAAY;YAAE,OAAO,8BAAC,WAAO,OAAG,CAAA;aACrC;YACH,OAAO,CAAC,8BAAC,cAAU,IAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAC,YAAY,EAAC,UAAU,EAAC,WAAW,EAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,IAC5I,UAAU,EAAE,CACF,CAAC,CAAC;SAChB;IACH,CAAC,CAAA;IAED,OAAO,CACL,8DACG,UAAU,EAAE,CACZ,CACJ,CAAC;AACJ,CAAC,CAAA;AA7HY,QAAA,YAAY,gBA6HxB"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,10 @@ interface Props {
|
|
|
6
6
|
data: any[],
|
|
7
7
|
spaceAfter?: boolean,
|
|
8
8
|
spaceBefore?: boolean,
|
|
9
|
-
filename?: string
|
|
9
|
+
filename?: string,
|
|
10
|
+
icon?: string,
|
|
11
|
+
text?: string,
|
|
12
|
+
customHeaders?: {label: string, key: string}[]
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export const ExportLink: React.FC<Props> = (props) => {
|
|
@@ -60,7 +63,7 @@ export const ExportLink: React.FC<Props> = (props) => {
|
|
|
60
63
|
else {
|
|
61
64
|
let items = [];
|
|
62
65
|
if (props.spaceBefore) items.push(" ");
|
|
63
|
-
items.push(<CSVLink key={props.filename} data={people} headers={getHeaders()} filename={props.filename || "export.csv"}> <Button><Icon>file_download</Icon
|
|
66
|
+
items.push(<CSVLink key={props.filename} data={people} headers={props.customHeaders || getHeaders()} filename={props.filename || "export.csv"}> <Button><Icon sx={{ marginRight: props.text ? 1 : 0 }}>{props.icon || "file_download"}</Icon>{props.text || ""}</Button></CSVLink>);
|
|
64
67
|
if (props.spaceAfter) items.push(" ");
|
|
65
68
|
return (<>{items}</>);
|
|
66
69
|
}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import React, { useRef } from "react";
|
|
2
|
-
import { ReportInterface, ReportResultInterface } from "@churchapps/helpers";
|
|
2
|
+
import { ArrayHelper, PersonInterface, ReportInterface, ReportResultInterface } from "@churchapps/helpers";
|
|
3
3
|
import { DisplayBox, ExportLink, Loading } from "../"
|
|
4
4
|
import { ApiHelper } from "../../helpers"
|
|
5
5
|
import { useReactToPrint } from "react-to-print";
|
|
6
6
|
import { TableReport } from "./TableReport";
|
|
7
7
|
import { ChartReport } from "./ChartReport";
|
|
8
8
|
import { TreeReport } from "./TreeReport";
|
|
9
|
-
import { Icon } from "@mui/material";
|
|
9
|
+
import { Button, Icon, Menu, MenuItem } from "@mui/material";
|
|
10
10
|
import { useMountedState } from "../../hooks/useMountedState";
|
|
11
11
|
|
|
12
12
|
interface Props { report: ReportInterface }
|
|
13
13
|
|
|
14
14
|
export const ReportOutput = (props: Props) => {
|
|
15
15
|
const [reportResult, setReportResult] = React.useState<ReportResultInterface>(null);
|
|
16
|
+
const [detailedPersonSummary, setDetailedPersonSummary] = React.useState<any[]>(null);
|
|
17
|
+
const [customHeaders, setCustomHeaders] = React.useState([]);
|
|
18
|
+
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
|
19
|
+
const open = Boolean(anchorEl);
|
|
16
20
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
17
21
|
const isMounted = useMountedState();
|
|
18
22
|
|
|
@@ -20,6 +24,40 @@ export const ReportOutput = (props: Props) => {
|
|
|
20
24
|
content: () => contentRef.current
|
|
21
25
|
})
|
|
22
26
|
|
|
27
|
+
const populatePeople = async (data: any[]) => {
|
|
28
|
+
let result: any[] = [];
|
|
29
|
+
let headers: {label: string, key: string}[] = [];
|
|
30
|
+
const peopleIds = ArrayHelper.getIds(data, "personId");
|
|
31
|
+
if (peopleIds.length > 0) {
|
|
32
|
+
const people = await ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
|
|
33
|
+
data.forEach((d) => {
|
|
34
|
+
const person: PersonInterface = ArrayHelper.getOne(people, "id", d.personId);
|
|
35
|
+
const funds = Object.assign({}, ...d.funds);
|
|
36
|
+
const obj = {
|
|
37
|
+
firstName: person.name.first,
|
|
38
|
+
lastName: person.name.last,
|
|
39
|
+
address: person.contactInfo.address1 + (person.contactInfo.address2 ? `, ${person.contactInfo.address2}` : ""),
|
|
40
|
+
city: person.contactInfo.city,
|
|
41
|
+
state: person.contactInfo.state,
|
|
42
|
+
zip: person.contactInfo.zip,
|
|
43
|
+
totalDonation: d.totalAmount,
|
|
44
|
+
...funds
|
|
45
|
+
};
|
|
46
|
+
result.push(obj);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//set custom headers
|
|
51
|
+
const maxKeysObj = result?.reduce((a, b) => {
|
|
52
|
+
return Object.keys(a).length > Object.keys(b).length ? a : b;
|
|
53
|
+
}, []);
|
|
54
|
+
const objKeys = Object.keys(maxKeysObj);
|
|
55
|
+
objKeys.forEach(key => headers.push({ label: key, key: key }));
|
|
56
|
+
|
|
57
|
+
setCustomHeaders(headers);
|
|
58
|
+
setDetailedPersonSummary(result);
|
|
59
|
+
}
|
|
60
|
+
|
|
23
61
|
const runReport = () => {
|
|
24
62
|
if (props.report) {
|
|
25
63
|
const queryParams: string[] = [];
|
|
@@ -34,9 +72,29 @@ export const ReportOutput = (props: Props) => {
|
|
|
34
72
|
setReportResult(data);
|
|
35
73
|
}
|
|
36
74
|
});
|
|
75
|
+
|
|
76
|
+
const donationUrl = "/donations/summary?type=person&" + queryParams.join("&");
|
|
77
|
+
ApiHelper.get(donationUrl, "GivingApi").then((data) => { populatePeople(data); });
|
|
37
78
|
}
|
|
38
79
|
}
|
|
39
80
|
|
|
81
|
+
const getExportMenu = (key: number) => {
|
|
82
|
+
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
83
|
+
setAnchorEl(event.currentTarget);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const handleClose = () => {
|
|
87
|
+
setAnchorEl(null);
|
|
88
|
+
}
|
|
89
|
+
return (<>
|
|
90
|
+
<Button size="small" title="Download Options" onClick={handleClick} key={key}><Icon>download</Icon></Button>
|
|
91
|
+
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
|
92
|
+
{reportResult?.table?.length > 0 && <MenuItem sx={{ padding: "5px" }} onClick={handleClose}><ExportLink data={reportResult.table} filename={props.report.displayName.replace(" ", "_") + ".csv"} text="Fund Summary" icon="volunteer_activism" /></MenuItem>}
|
|
93
|
+
{detailedPersonSummary?.length > 0 && <MenuItem sx={{ padding: "5px" }} onClick={handleClose}><ExportLink data={detailedPersonSummary} filename="Detailed_Donation_Summary.csv" text="Detailed Summary" icon="person" customHeaders={customHeaders} spaceAfter={true} /></MenuItem>}
|
|
94
|
+
</Menu>
|
|
95
|
+
</>)
|
|
96
|
+
}
|
|
97
|
+
|
|
40
98
|
React.useEffect(runReport, [props.report, isMounted]);
|
|
41
99
|
|
|
42
100
|
const getEditContent = () => {
|
|
@@ -44,7 +102,9 @@ export const ReportOutput = (props: Props) => {
|
|
|
44
102
|
|
|
45
103
|
if (reportResult) {
|
|
46
104
|
result.push(<button type="button" className="no-default-style" key={result.length - 2} onClick={handlePrint} title="print"><Icon>print</Icon></button>);
|
|
47
|
-
|
|
105
|
+
}
|
|
106
|
+
if (reportResult?.table.length > 0 || detailedPersonSummary?.length > 0) {
|
|
107
|
+
result.push(getExportMenu(result.length - 1))
|
|
48
108
|
}
|
|
49
109
|
return result;
|
|
50
110
|
}
|