Skip to content

Commit ed396a4

Browse files
authored
Workload snapshots (#1898)
* add workload snapshots * test downloads * match existing report view * handle variable unit courses * fix SCH tally * move unnamed instructors to bottom * show previous year census * add instructor type to TBD * fix variable names * add ability to download multiple departments * remove unused status message * include previous years for comparison * clean up * fix saved selections * newline * newline * allow modal dismiss after submit * Dependency bump * Revert "Dependency bump" This reverts commit 9919569. * remove frontend generated download
1 parent f3bdd4c commit ed396a4

15 files changed

+1281
-53
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
th {
2-
font-weight: 700;
2+
font-weight: 700;
33
}
44

5-
th, td {
6-
text-align: center;
5+
th,
6+
td {
7+
padding-bottom: 1em;
8+
text-align: center;
79
}

app/summary/directives/downloadSummary/downloadSummary.html

+19-4
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,36 @@
1414
<td>LS Workload Summary</td>
1515
<td>
1616
<spinner ng-show="isLoading" size="20"></spinner>
17-
<span ng-show="!isLoading"> {{ fileStatus }} </span>
17+
<span ng-show="!isLoading"> {{ downloadStatus.workloadSummaries.fileStatus }} </span>
1818
</td>
1919
<td>
2020
<ipa-button
2121
text="'Generate'"
2222
size="'small'"
2323
on-click="generate()"
24-
is-disabled="disableGenerate"
24+
is-disabled="downloadStatus.workloadSummaries.disableGenerate"
2525
tooltip-message="'This can take up to an hour. You will receive an email when file is ready for download.'"
2626
></ipa-button>
2727
<ipa-button
2828
text="'Download'"
2929
size="'small'"
30-
on-click="download()"
31-
is-disabled="disableDownload"
30+
on-click="download('workloadSummaries')"
31+
is-disabled="downloadStatus.workloadSummaries.disableDownload"
32+
></ipa-button>
33+
</td>
34+
</tr>
35+
<tr>
36+
<td>LS Workload Snapshots</td>
37+
<td>
38+
<spinner ng-show="isLoading" size="20"></spinner>
39+
<span ng-show="!isLoading"> {{ downloadStatus.workloadSnapshots.fileStatus }} </span>
40+
</td>
41+
<td>
42+
<ipa-button
43+
text="'Download'"
44+
size="'small'"
45+
on-click="download('workloadSnapshots')"
46+
is-disabled="downloadStatus.workloadSnapshots.disableDownload"
3247
></ipa-button>
3348
</td>
3449
</tr>

app/summary/directives/downloadSummary/downloadSummary.js

+46-24
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,69 @@ let downloadSummary = function (ApiService) {
1818
scope.disableGenerate = true;
1919
scope.disableDownload = true;
2020

21+
scope.downloadStatus = {
22+
workloadSummaries: {
23+
isEmpty: true,
24+
isLessThanOneHourOld: true,
25+
disableDownload: true,
26+
disableGenerate: false,
27+
fileStatus: ""
28+
},
29+
workloadSnapshots: {
30+
isEmpty: true,
31+
isLessThanOneHourOld: true
32+
}
33+
};
34+
2135
ApiService.get(`/api/workloadSummaryReport/years/${year}/download/status`).then(metadata => {
22-
if (metadata) {
23-
const isEmptyFile = metadata.contentLength === 0;
24-
const isLessThanOneHourAgo = scope.IsDateLessThanOneHourAgo(metadata.lastModified);
36+
Object.keys(metadata).forEach(file => {
37+
const isEmpty = metadata[file].contentLength === 0;
38+
const isLessThanOneHourOld = scope.IsDateLessThanOneHourAgo(metadata[file].lastModified);
39+
40+
scope.downloadStatus[file].isEmpty = isEmpty;
41+
scope.downloadStatus[file].isLessThanOneHourOld = isLessThanOneHourOld;
2542

26-
if (isEmptyFile && isLessThanOneHourAgo) {
27-
scope.disableDownload = true;
28-
scope.disableGenerate = true;
29-
scope.fileStatus = "In progress, check back later.";
30-
} else if (isEmptyFile && !isLessThanOneHourAgo) {
31-
scope.disableDownload = true;
32-
scope.disableGenerate = false;
33-
scope.fileStatus = "File creation failed, please try again.";
43+
if (isEmpty && isLessThanOneHourOld) {
44+
scope.downloadStatus[file].disableDownload = true;
45+
scope.downloadStatus[file].disableGenerate = true;
46+
scope.downloadStatus[file].fileStatus = "In progress, check back later.";
47+
} else if (isEmpty && !isLessThanOneHourOld) {
48+
scope.downloadStatus[file].disableDownload = true;
49+
scope.downloadStatus[file].disableGenerate = false;
50+
scope.downloadStatus[file].fileStatus = "File creation failed, please try again.";
3451
} else {
35-
scope.disableDownload = false;
36-
scope.disableGenerate = false;
37-
scope.fileStatus = "Created: " + new Date(metadata.lastModified).toLocaleString();
52+
scope.downloadStatus[file].disableDownload = false;
53+
scope.downloadStatus[file].disableGenerate = false;
54+
scope.downloadStatus[file].fileStatus = "Created: " + new Date(metadata[file].lastModified).toLocaleString();
3855
}
39-
} else {
40-
scope.disableDownload = true;
41-
scope.disableGenerate = false;
42-
}
56+
});
57+
4358
scope.isLoading = false;
4459
});
4560

4661
scope.generate = () => {
47-
scope.disableGenerate = true;
48-
scope.fileStatus = "In progress, check back later.";
62+
scope.downloadStatus.workloadSummaries.disableGenerate = true;
63+
scope.downloadStatus.workloadSummaries.fileStatus = "In progress, check back later.";
4964

50-
ApiService.get(`/api/workloadSummaryReport/${workgroupId}/years/${year}/generateMultiple`);
65+
ApiService.post(`/api/workloadSummaryReport/${workgroupId}/years/${year}/generateMultiple`, null);
5166
};
5267

53-
scope.download = () => {
54-
ApiService.postWithResponseType(`/api/workloadSummaryReport/${scope.workgroup.id}/years/${year}/downloadMultiple`, "", "", 'arraybuffer').then(
68+
scope.download = (file) => {
69+
let reportName;
70+
if (file === "workloadSummaries") {
71+
reportName = `Summary Report`;
72+
} else if (file === "workloadSnapshots") {
73+
reportName = `Snapshots`;
74+
}
75+
76+
ApiService.postWithResponseType(`/api/workloadSummaryReport/years/${year}/downloadMultiple/${file}`, "", "", 'arraybuffer').then(
5577
response => {
5678
var url = window.URL.createObjectURL(
5779
new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
5880
);
5981
var a = window.document.createElement('a'); // eslint-disable-line
6082
a.href = url;
61-
a.download = `${year} Workload Summary Report.xlsx`;
83+
a.download = `${year} Workload ${reportName}.xlsx`;
6284
window.document.body.appendChild(a); // eslint-disable-line
6385
a.click();
6486
a.remove(); //afterwards we remove the element again
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
.table-dark tbody {
2+
display: block;
3+
max-height: 50vh;
4+
overflow: auto;
5+
}
6+
.table-dark thead,
7+
.table-dark tbody tr {
8+
display: table;
9+
width: 100%;
10+
table-layout: fixed;
11+
}
12+
13+
.neon-dark-confirm-btn,
14+
.neon-dark-confirm-btn:focus,
15+
.neon-dark-confirm-btn:active,
16+
.neon-dark-confirm-btn {
17+
background-color: rgb(48, 54, 65);
18+
border-color: rgb(48, 54, 65);
19+
color: white;
20+
}
21+
22+
.neon-dark-confirm-btn:hover {
23+
background-color: rgb(18, 24, 35); /* Darker Version for hover */
24+
color: white;
25+
}
26+
27+
.neon-dark-confirm-btn.disabled,
28+
.neon-dark-confirm-btn.disabled:hover,
29+
.neon-dark-confirm-btn.disabled:focus,
30+
.neon-dark-confirm-btn.disabled:active {
31+
background-color: rgb(48, 54, 65);
32+
color: white;
33+
}
34+
35+
/* override to match Budget module */
36+
.btn-default {
37+
color: #303641;
38+
background-color: white;
39+
border: 1px solid #d6d6d6;
40+
}
41+
42+
.table-toolbar .dropdown-menu {
43+
min-width: 200px;
44+
}
45+
46+
#workload-download-modal-table {
47+
margin-bottom: 0;
48+
}
49+
50+
.workload-download-modal-footer {
51+
display: flex;
52+
align-items: center;
53+
justify-content: space-between;
54+
border-top: 1px solid #ddd;
55+
}
56+
57+
.workload-download-modal-footer__status {
58+
display: flex;
59+
justify-content: center;
60+
align-items: center;
61+
}
62+
.workload-download-modal-footer__status span {
63+
padding-bottom: 4px;
64+
}
65+
66+
.workload-download-modal-footer__buttons {
67+
display: flex;
68+
align-items: center;
69+
}
70+
71+
.workload-download-modal-footer button {
72+
display: inline-block;
73+
margin: 8px;
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<div class="workload-download-modal">
2+
<div>
3+
<table class="table table-dark" id="workload-download-modal-table" style="font-size: 12px;">
4+
<thead style="border-bottom: 1px solid #ddd; margin-bottom: -1px;">
5+
<tr>
6+
<th style="width: 25px;">
7+
<ipa-checkbox is-checked="downloadAllDepartments"
8+
click-action="toggleAllDepartmentDownloads()"></ipa-checkbox>
9+
</th>
10+
<th scope="col" style="padding-left: 10px;"><strong>Department</strong></th>
11+
<th scope="col"><strong>Snapshot 1</strong></th>
12+
<th scope="col"><strong>Snapshot 2</strong></th>
13+
</tr>
14+
</thead>
15+
<tbody>
16+
<tr ng-repeat="department in departmentSnapshots">
17+
<td style="width: 25px; vertical-align: middle;"><ipa-checkbox is-checked="department.download"
18+
click-action="toggleDepartmentDownload(department)"></ipa-checkbox></td>
19+
<td style="padding-left: 10px; vertical-align: middle;">
20+
<i ng-show="department.showWarning" class="glyphicon glyphicon-warning-sign" style="color: #cc2424;"></i>
21+
{{ department.name }}<br>
22+
<small style="color:rgba(0, 0, 0, 0.6);">Last Active: {{
23+
dateToCalendar(department.lastActivity) }}</small>
24+
</td>
25+
<td>
26+
<select style="width: 100%; padding:4px 8px;" ng-model="department.selectedPrevious">
27+
<option ng-repeat="snapshot in department.snapshots" value={{snapshot.id}}>
28+
{{ snapshot.name }}
29+
</option>
30+
</select>
31+
</td>
32+
<td>
33+
<select style="width: 100%; padding:4px 8px;" ng-model="department.selectedNext">
34+
<option ng-repeat="snapshot in department.snapshots" value={{snapshot.id}}>
35+
{{ snapshot.name }}
36+
</option>
37+
</select>
38+
</td>
39+
</tr>
40+
</tbody>
41+
</table>
42+
</div>
43+
<div class="workload-download-modal-footer">
44+
<div style="display: flex; margin-left: 8px;">
45+
<ipa-checkbox is-checked="isSortedByRecentActivity" click-action="sortDepartmentsByRecentActivity()">
46+
</ipa-checkbox>
47+
<span style="margin-left: 8px;">Sort By Recent Activity</span>
48+
</div>
49+
<div class="workload-download-modal-footer__buttons">
50+
<button ng-show="!isDisabled" ng-click="close()" type="button" class="btn btn-default modal-button">
51+
Cancel
52+
</button>
53+
<button class="btn btn-secondary" confirm-button="resetDownloadSelections()"
54+
placement=message="Are you sure you want to reset selections Live Data?">
55+
Reset selections
56+
</button>
57+
<button class="btn btn-info" confirm-button="selectLatestSnapshots()" placement="top"
58+
message="Are you sure you want to select the last snapshot created by each department?">
59+
Select Latest Snapshots
60+
</button>
61+
<button ng-click="submit()" type="button" class="btn neon-dark-confirm-btn" ng-disabled="isDisabled">
62+
Download
63+
</button>
64+
</div>
65+
</div>
66+
<div class="workload-download-modal-footer__status">
67+
<span ng-show="showScenarioWarning" style="color: #cc2424;">
68+
<i class="glyphicon glyphicon-warning-sign" style="padding-right: 4px"></i> Department is missing snapshots -
69+
download will fail if department is selected.
70+
</span>
71+
<span ng-show="isDisabled">
72+
<i class="glyphicon glyphicon-info-sign" style="padding-right: 4px; color: #21a9e1;"></i> Generating Excel
73+
Download - You will receive an email once it is completed.
74+
</span>
75+
</div>
76+
</div>

0 commit comments

Comments
 (0)