forked from beyondessential/tupaia
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WAI-44 LESMIS HLO1 list visuals (beyondessential#3171)
* NZ-44 Add drilldown dashboard items for number of students list items * NZ-44 Add a migration to setup the actual HLO dashboards * NZ-44 Update drilldowns to attach to HLO dashboards Move migration to be after HLO migration * NZ-44 Move drilldowns to HLO dashboards too * NZ-44 Remove primary education level from drill downs migration * WAI-44 Add HLO1 list visuals for ECE, LSE, USE * WAI-44 Change aggregation to include per period * WAI-44 Update report configs * WAI-44 Change <= to < for 5 year indicator Co-authored-by: Klaus-S <69126149+Klaus-S@users.noreply.github.com>
- Loading branch information
Showing
5 changed files
with
1,342 additions
and
0 deletions.
There are no files selected for viewing
137 changes: 137 additions & 0 deletions
137
packages/database/src/migrations/20210905222526-ESSDPAddHLODashboardHeaders-modifies-data.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
'use strict'; | ||
|
||
import { | ||
insertObject, | ||
generateId, | ||
deleteObject, | ||
updateValues, | ||
findSingleRecord, | ||
} from '../utilities'; | ||
|
||
var dbm; | ||
var type; | ||
var seed; | ||
|
||
/** | ||
* We receive the dbmigrate dependency from dbmigrate initially. | ||
* This enables us to not have to rely on NODE_PATH. | ||
*/ | ||
exports.setup = function (options, seedLink) { | ||
dbm = options.dbmigrate; | ||
type = dbm.dataType; | ||
seed = seedLink; | ||
}; | ||
|
||
const SUBSECTORS = [ | ||
'EarlyChildhoodSubSector', | ||
'PrimarySubSector', | ||
'LowerSecondarySubSector', | ||
'UpperSecondarySubSector', | ||
]; | ||
|
||
const NEW_DASHBOARDS = [ | ||
...SUBSECTORS.map(sector => ({ | ||
code: `LESMIS_ESSDP_${sector}_HLO1`, | ||
name: 'HLO 1: Graduates', | ||
})), | ||
...SUBSECTORS.map(sector => ({ | ||
code: `LESMIS_ESSDP_${sector}_HLO2`, | ||
name: 'HLO 2: Competent Teachers', | ||
})), | ||
...SUBSECTORS.map(sector => ({ | ||
code: `LESMIS_ESSDP_${sector}_HLO3`, | ||
name: 'HLO 3: Resources', | ||
})), | ||
// From the docs only USE has HLO5 | ||
{ | ||
code: 'LESMIS_ESSDP_UpperSecondarySubSector_HLO5', | ||
name: 'HLO 5: School Leavers', | ||
}, | ||
]; | ||
|
||
const DASHBOARD_ITEMS = [ | ||
'LESMIS_enrolment_ece_5_target', | ||
'LESMIS_enrolment_ece_3_4_target', | ||
'LESMIS_enrolment_ece_0_2_target', | ||
'LESMIS_ESSDP_ECE_HLO1', // We'll be moving it after it's renamed | ||
]; | ||
|
||
const moveItemToNewDashboard = async (db, itemCode, oldDashboardCode, newDashboardCode) => { | ||
const itemId = (await findSingleRecord(db, 'dashboard_item', { code: itemCode })).id; | ||
const oldDashboardId = (await findSingleRecord(db, 'dashboard', { code: oldDashboardCode })).id; | ||
const newDashboardId = (await findSingleRecord(db, 'dashboard', { code: newDashboardCode })).id; | ||
|
||
await updateValues( | ||
db, | ||
'dashboard_relation', | ||
{ dashboard_id: newDashboardId }, // new values | ||
{ dashboard_id: oldDashboardId, child_id: itemId }, // old values | ||
); | ||
}; | ||
|
||
exports.up = async function (db) { | ||
// Add new dashboards | ||
for (const { code, name } of NEW_DASHBOARDS) { | ||
await insertObject(db, 'dashboard', { | ||
id: generateId(), | ||
code, | ||
name, | ||
root_entity_code: 'LA', | ||
}); | ||
} | ||
// Rename list to be more accurate | ||
await updateValues( | ||
db, | ||
'report', | ||
{ code: 'LESMIS_ESSDP_ECE_HLO1' }, // new value | ||
{ code: 'LESMIS_ESSDP_ECE_SubSector_List' }, // old value | ||
); | ||
await updateValues( | ||
db, | ||
'dashboard_item', | ||
{ code: 'LESMIS_ESSDP_ECE_HLO1', report_code: 'LESMIS_ESSDP_ECE_HLO1' }, // new values | ||
{ code: 'LESMIS_ESSDP_ECE_SubSector_List' }, // old value | ||
); | ||
// Move list and drilldowns to new dashboard | ||
for (const code of DASHBOARD_ITEMS) { | ||
await moveItemToNewDashboard( | ||
db, | ||
code, | ||
'LESMIS_ESSDP_EarlyChildhoodSubSector_Schools', | ||
'LESMIS_ESSDP_EarlyChildhoodSubSector_HLO1', | ||
); | ||
} | ||
}; | ||
|
||
exports.down = async function (db) { | ||
// Move list and drilldowns back to old dashboard | ||
for (const code of DASHBOARD_ITEMS) { | ||
await moveItemToNewDashboard( | ||
db, | ||
code, | ||
'LESMIS_ESSDP_EarlyChildhoodSubSector_HLO1', | ||
'LESMIS_ESSDP_EarlyChildhoodSubSector_Schools', | ||
); | ||
} | ||
// Rename list | ||
await updateValues( | ||
db, | ||
'report', | ||
{ code: 'LESMIS_ESSDP_ECE_SubSector_List' }, // new value | ||
{ code: 'LESMIS_ESSDP_ECE_HLO1' }, // old value | ||
); | ||
await updateValues( | ||
db, | ||
'dashboard_item', | ||
{ code: 'LESMIS_ESSDP_ECE_SubSector_List', report_code: 'LESMIS_ESSDP_ECE_SubSector_List' }, // new value | ||
{ code: 'LESMIS_ESSDP_ECE_HLO1' }, // old values | ||
); | ||
// Remove new dashboards | ||
for (const { code } of NEW_DASHBOARDS) { | ||
await deleteObject(db, 'dashboard', { code }); | ||
} | ||
}; | ||
|
||
exports._meta = { | ||
version: 1, | ||
}; |
189 changes: 189 additions & 0 deletions
189
.../src/migrations/20210905333536-ESSDPListVisualNumberOfStudentsDrillDowns-modifies-data.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
'use strict'; | ||
|
||
import { insertObject, generateId, findSingleRecord, findSingleRecordBySql } from '../utilities'; | ||
|
||
var dbm; | ||
var type; | ||
var seed; | ||
|
||
/** | ||
* We receive the dbmigrate dependency from dbmigrate initially. | ||
* This enables us to not have to rely on NODE_PATH. | ||
*/ | ||
exports.setup = function (options, seedLink) { | ||
dbm = options.dbmigrate; | ||
type = dbm.dataType; | ||
seed = seedLink; | ||
}; | ||
|
||
const generateReportConfig = educationLevel => ({ | ||
fetch: { | ||
dataElements: [ | ||
`nostu_${educationLevel}_f_public`, | ||
`nostu_${educationLevel}_f_private`, | ||
`nostu_${educationLevel}_m_public`, | ||
`nostu_${educationLevel}_m_private`, | ||
], | ||
aggregations: [ | ||
'FINAL_EACH_YEAR', | ||
{ | ||
type: 'SUM_PER_PERIOD_PER_ORG_GROUP', | ||
config: { | ||
dataSourceEntityType: 'sub_district', | ||
aggregationEntityType: 'requested', | ||
}, | ||
}, | ||
], | ||
}, | ||
transform: [ | ||
{ | ||
transform: 'select', | ||
"translate($row.dataElement.split('_')[3], { m: 'Male', f: 'Female' })": '$row.value', | ||
"'name'": | ||
"translate($row.dataElement.split('_')[4], { public: 'Public', private: 'Private' })", | ||
"'timestamp'": 'periodToTimestamp($row.period)', | ||
'...': '*', | ||
}, | ||
{ | ||
transform: 'aggregate', | ||
timestamp: 'group', | ||
name: 'group', | ||
'...': 'last', | ||
}, | ||
{ | ||
transform: 'select', | ||
"'name'": "$row.name.concat(' ', $row.period)", | ||
"'GPI'": '$row.Female/$row.Male', | ||
"'Male_metadata'": '{ total: $row.Male + $row.Female }', | ||
"'Female_metadata'": '{ total: $row.Male + $row.Female }', | ||
'...': ['Male', 'Female'], | ||
}, | ||
{ | ||
transform: 'sort', | ||
by: '$row.name', | ||
}, | ||
], | ||
}); | ||
|
||
const FRONT_END_CONFIG = { | ||
name: 'Number of Students (Gender, GPI, Public/Private)', | ||
type: 'chart', | ||
chartType: 'composed', | ||
xName: 'Year', | ||
periodGranularity: 'year', | ||
chartConfig: { | ||
GPI: { | ||
chartType: 'line', | ||
color: '#ffeb3b', | ||
yAxisOrientation: 'right', | ||
yName: 'GPI', | ||
}, | ||
Male: { | ||
chartType: 'bar', | ||
labelType: 'fraction', | ||
color: '#f44336', | ||
stackId: '1', | ||
yName: 'Number of Students', | ||
valueType: 'number', | ||
}, | ||
Female: { | ||
chartType: 'bar', | ||
labelType: 'fraction', | ||
color: '#2196f3', | ||
stackId: '1', | ||
valueType: 'number', | ||
}, | ||
}, | ||
}; | ||
|
||
const DASHBOARD_ITEMS = [ | ||
{ | ||
code: 'LESMIS_ESSDP_ece_NumberOfStudents', | ||
reportConfig: generateReportConfig('ece'), | ||
dashboardCode: 'LESMIS_ESSDP_EarlyChildhoodSubSector_HLO1', | ||
}, | ||
{ | ||
code: 'LESMIS_ESSDP_lse_NumberOfStudents', | ||
reportConfig: generateReportConfig('lse'), | ||
dashboardCode: 'LESMIS_ESSDP_LowerSecondarySubSector_HLO1', | ||
}, | ||
{ | ||
code: 'LESMIS_ESSDP_use_NumberOfStudents', | ||
reportConfig: generateReportConfig('use'), | ||
dashboardCode: 'LESMIS_ESSDP_UpperSecondarySubSector_HLO1', | ||
}, | ||
]; | ||
|
||
// Same util functions as always | ||
const addNewDashboardItemAndReport = async ( | ||
db, | ||
{ code, frontEndConfig, reportConfig, permissionGroup, dashboardCode, entityTypes, projectCodes }, | ||
) => { | ||
// insert report | ||
const reportId = generateId(); | ||
const permissionGroupId = ( | ||
await findSingleRecord(db, 'permission_group', { name: permissionGroup }) | ||
).id; | ||
await insertObject(db, 'report', { | ||
id: reportId, | ||
code, | ||
config: reportConfig, | ||
permission_group_id: permissionGroupId, | ||
}); | ||
|
||
// insert dashboard item | ||
const dashboardItemId = generateId(); | ||
await insertObject(db, 'dashboard_item', { | ||
id: dashboardItemId, | ||
code, | ||
config: frontEndConfig, | ||
report_code: code, | ||
}); | ||
|
||
// insert relation record connecting dashboard item to dashboard | ||
const dashboardId = (await findSingleRecord(db, 'dashboard', { code: dashboardCode })).id; | ||
const maxSortOrder = ( | ||
await findSingleRecordBySql( | ||
db, | ||
`SELECT max(sort_order) as max_sort_order FROM dashboard_relation WHERE dashboard_id = '${dashboardId}';`, | ||
) | ||
).max_sort_order; | ||
await insertObject(db, 'dashboard_relation', { | ||
id: generateId(), | ||
dashboard_id: dashboardId, | ||
child_id: dashboardItemId, | ||
entity_types: `{${entityTypes.join(', ')}}`, | ||
project_codes: `{${projectCodes.join(', ')}}`, | ||
permission_groups: `{${permissionGroup}}`, | ||
sort_order: maxSortOrder + 1, | ||
}); | ||
}; | ||
|
||
const removeDashboardItemAndReport = async (db, code) => { | ||
await db.runSql(`DELETE FROM dashboard_item WHERE code = '${code}';`); // delete cascades to dashboard_relation | ||
await db.runSql(`DELETE FROM report WHERE code = '${code}';`); | ||
}; | ||
|
||
exports.up = async function (db) { | ||
for (const { code, reportConfig, dashboardCode } of DASHBOARD_ITEMS) { | ||
await addNewDashboardItemAndReport(db, { | ||
code, | ||
reportConfig, | ||
frontEndConfig: FRONT_END_CONFIG, | ||
permissionGroup: 'LESMIS Public', | ||
dashboardCode, | ||
entityTypes: ['sub_district', 'district', 'country'], | ||
projectCodes: ['laos_schools'], | ||
}); | ||
} | ||
}; | ||
|
||
exports.down = async function (db) { | ||
for (const { code } of DASHBOARD_ITEMS) { | ||
await removeDashboardItemAndReport(db, code); | ||
} | ||
}; | ||
|
||
exports._meta = { | ||
version: 1, | ||
}; |
Oops, something went wrong.