diff --git a/client/src/components/Projects/ProjectTableRow.js b/client/src/components/Projects/ProjectTableRow.js index d85bd07a..8044c37d 100644 --- a/client/src/components/Projects/ProjectTableRow.js +++ b/client/src/components/Projects/ProjectTableRow.js @@ -46,30 +46,179 @@ const useStyles = createUseStyles({ } }); -const mapCsvRules = rules => { - // TODO: consider merging project meta data with rules values - const usedRules = rules.filter(rule => rule.used && rule.value); +const mapCsvRules = (project, rules) => { + // Specify which rules we want to include in the CSV, and in what order by code. + const includeRuleCodes = [ + "PROJECT_NAME", + "PROJECT_ADDRESS", + "APN", + "VERSION_NO", + "BUILDING_PERMIT", + "CASE_NO_LADOT", + "CASE_NO_PLANNING", + "PROJECT_DESCRIPTION", + "PROJECT_LEVEL", + "PARK_REQUIREMENT", + "PARK_SPACES", + "CALC_PARK_RATIO", + "TARGET_POINTS_PARK", + "PTS_EARNED", + "PTS_PKG_RESIDENTIAL_COMMERCIAL", + "PTS_PKG_SCHOOL", + "STRATEGY_AFFORDABLE", + "STRATEGY_BIKE_1", + "STRATEGY_BIKE_3", + "STRATEGY_BIKE_4", + "STRATEGY_BIKE_5", + "STRATEGY_CAR_SHARE_1", + "STRATEGY_CAR_SHARE_3", + "STRATEGY_CAR_SHARE_4", + "STRATEGY_CAR_SHARE_ELECTRIC", + "STRATEGY_CAR_SHARE_BONUS", + "STRATEGY_CHILD_CARE", + "STRATEGY_HOV_2", + "STRATEGY_HOV_3", + "STRATEGY_HOV_4", + "STRATEGY_HOV_5", + "STRATEGY_INFO_1", + "STRATEGY_INFO_2", + "STRATEGY_INFO_3", + "STRATEGY_INFO_5", + "STRATEGY_MIXED_USE", + "STRATEGY_MOBILITY_INVESTMENT_1", + "STRATEGY_MOBILITY_INVESTMENT_2", + "STRATEGY_PARKING_1", + "STRATEGY_PARKING_2", + "STRATEGY_PARKING_3", + "STRATEGY_PARKING_4", + "STRATEGY_PARKING_5", + "STRATEGY_SHARED_MOBILITY_1", + "STRATEGY_SHARED_MOBILITY_2", + "STRATEGY_TELECOMMUTE_1", + "STRATEGY_TELECOMMUTE_2", + "STRATEGY_TRANSIT_ACCESS_1", + "STRATEGY_TRANSIT_ACCESS_3", + "STRATEGY_TRANSIT_ACCESS_4", + "STRATEGY_TRANSIT_ACCESS_5", + "STRATEGY_TMO_1", + "STRATEGY_TMO_2", + "STRATEGY_APPLICANT", + "UNITS_CONDO", + "PARK_CONDO", + "UNITS_HABIT_LT3", + "UNITS_HABIT_3", + "UNITS_HABIT_GT3", + "AFFORDABLE_HOUSING", + "UNITS_GUEST", + "SF_RETAIL", + "SF_FURNITURE", + "SF_RESTAURANT", + "SF_HEALTH_CLUB", + "SF_RESTAURANT_TAKEOUT", + "SF_OFFICE", + "SF_INST_GOV", + "SF_INST_OTHER", + "SF_INDUSTRIAL", + "SF_WAREHOUSE", + "SF_INST_MEDICAL_SVC", + "SF_HOSPITAL", + "STUDENTS_ELEMENTARY", + "CLASSROOM_SCHOOL", + "STUDENTS_TRADE_SCHOOL", + "HS_STUDENTS", + "HS_AUDITORIUM_SEATS", + "HS_AUDITORIUM_SF", + "SEAT_AUDITORIUM", + "SF_AUDITORIUM_NO_SEATS" + ]; - // TODO: decide about using code or name for the header (or keep both) - const ruleCodes = usedRules.flatMap(rule => { - if (rule.dataType === "choice") { - return rule.choices.map(choice => rule.code + "_" + choice.id); - } else { - return rule.code; + // Get the needed data from the rule calculation + const orderedRules = includeRuleCodes + .map(rc => rules.find(r => r.code === rc)) + .map(r => ({ + code: r.code, + name: r.name, + dataType: r.dataType, + choices: r.choices, + value: r.value, + units: r.units + })); + + // Augment with meta-data from project table that is not included in rules. + const projectProperties = [ + { + code: "Id", + name: "Project Id", + dataType: "project", + choices: null, + value: project.id + }, + { + code: "Author FN", + name: "Author First Name", + dataType: "project", + choices: null, + value: project.firstName + }, + { + code: "Author LN", + name: "Author Last Name", + dataType: "project", + choices: null, + value: project.lastName + }, + { + code: "Date Created", + name: "Date Created", + dataType: "project", + choices: null, + value: project.dateCreated + }, + { + code: "Date Modified", + name: "Date Modified", + dataType: "project", + choices: null, + value: project.dateModified + }, + { + code: "Date Hidden", + name: "Date Hidden", + dataType: "project", + choices: null, + value: project.dateHidden + }, + { + code: "Date Deleted", + name: "Date Deleted", + dataType: "project", + choices: null, + value: project.dateTrashed + }, + { + code: "Date Snapshotted", + name: "Date Snapshotted", + dataType: "project", + choices: null, + value: project.dateSnapshotted } - }); - const ruleNames = usedRules.flatMap(rule => { + ]; + + let columnData = orderedRules.concat(projectProperties); + + const ruleNames = columnData.flatMap(rule => { if (rule.dataType === "choice") { return rule.choices.map(choice => rule.name + " - " + choice.name); } else { - return rule.name; + return `${rule.name}${rule.units ? " (" + rule.units + ")" : ""}`; } }); - const ruleValues = usedRules.flatMap(rule => { + + const ruleValues = columnData.flatMap(rule => { if (rule.dataType === "choice") { return rule.choices.map(choice => (choice.id == rule.value ? "Y" : "N")); } else { - return rule.value.toString(); + return rule.value ? rule.value.toString() : ""; } }); @@ -78,7 +227,6 @@ const mapCsvRules = rules => { ["Date Printed: " + Date().toString()], // TODO: prefer ISO string? [], ruleNames, - ruleCodes, ruleValues ]; return flat; @@ -106,7 +254,8 @@ const ProjectTableRow = ({ useEffect(() => { const fetchRules = async () => { const rules = await fetchEngineRules(project); - const csvData = mapCsvRules(rules || []); + const csvData = project && mapCsvRules(project, rules); + console.error(rules); setProjectData({ pdf: rules, csv: csvData }); }; diff --git a/client/src/components/Projects/ProjectsPage.js b/client/src/components/Projects/ProjectsPage.js index 6b6e6b78..f98b7628 100644 --- a/client/src/components/Projects/ProjectsPage.js +++ b/client/src/components/Projects/ProjectsPage.js @@ -495,7 +495,6 @@ const ProjectsPage = ({ account, contentContainerRef }) => { ); })} -