Skip to content

Commit

Permalink
Merge pull request #3642 from Tangerine-Community/release/v3.30.1
Browse files Browse the repository at this point in the history
Release/v3.30.1
  • Loading branch information
esurface authored Dec 12, 2023
2 parents 8437fdd + ad8d365 commit a81e12b
Show file tree
Hide file tree
Showing 103 changed files with 5,751 additions and 928 deletions.
107 changes: 98 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,66 @@
# What's new

# What's new
## v3.30.1

__New Features__
- Multiple Location Lists can be configured using the Tangerine server web interface
-- Create and manage location lists for use in Tangerine forms
-- The default location list is used for device and device user assignment.
- The app-config.json teachProperties has new properties, `"unitDates"` and `"studentRegistrationFields"`:
```
"unitDates": [{"name": "Unidad 1","start": "2023-02-15", "end": "2023-04-23"}, {"name": "Unidad 2","start": "2023-04-24", "end": "2023-06-30"}],
"studentRegistrationFields": ["student_name", "student_surname", "phone", "classId"]
```
The `unitDates` property is used to configure the dates for each unit in the Class module.
The `studentRegistrationFields` property is used to configure the fields from the Student Registration form to be saved in the class attendance, behavior, and score register and CSV's.
- The app-config.json teachProperties has a new property, `"showAttendanceCalendar"`, which enables the Attendance Calendar in the Class module when set to true.
- Intl/locale support in Class: The class module currently supports the es-gt locale. Add additional locales in class/module.ts:
```js
import { registerLocaleData } from '@angular/common';
import localeEsGt from '@angular/common/locales/es-GT';
registerLocaleData(localeEsGt);
```
- The "Request spreadsheets" CSV output form now has three new forms to view if `useAttendanceFeature` is set to true in app-config.json: Attendance, Behavior, and Score

__Server upgrade instructions__

Reminder: Consider using the [Tangerine Upgrade Checklist](https://docs.tangerinecentral.org/system-administrator/upgrade-checklist.html) for making sure you test the upgrade safely.

```
cd tangerine
# Check the size of the data folder.
du -sh data
# Check disk for free space.
df -h
# If there is not more than 12 GB plus the size of the data folder, create more space before proceeding.
# Good candidates to remove are: data back-up folders and older versions of the Tangerine image
# rm -rf ../data-backup-<date>
# docker rmi tangerine/tangerine:<version>
# Create a backup of the data folder.
cp -r data ../data-backup-$(date "+%F-%T")
# Check logs for the past hour on the server to ensure it's not being actively used. Look for log messages like "Created sync session" for Devices that are syncing and "login success" for users logging in on the server.
docker logs --since=60m tangerine
# Fetch the updates.
git fetch origin
git checkout -b v3.30.1 v3.30.1
./start.sh v3.30.1
# Remove Tangerine's previous version Docker Image.
docker rmi tangerine/tangerine:<previous_version>
```

## v3.30.0

__New Features__
- The 'teach' content-set now supports an optional 'Attendance' feature, enabled by adding `"useAttendanceFeature": true` and "homeUrl": "attendance-dashboard"
to app-config.json. It also has a new Class/Attendance menu which enables collection of those values per student, and an 'Attendance' report.

- The 'teach' content-set now supports an optional 'Attendance' feature, enabled by adding `"useAttendanceFeature": true` and `"homeUrl": "attendance-dashboard"`
to app-config.json. It also has a new Class/Attendance menu which enables collection of those values per student, and an 'Attendance' report.
- The Attendance records generate _id's based on the grade, curriculum, user, and date and time of the record, so that they can be sorted chronologically.
See dashboard.service generateSearchableId for details.
- Class now supports `eventFormRedirect` to redirect to different url after submit: `on-submit="window.eventFormRedirect = `/attendance-check`"`
- New app-config.json configuration for teach properties:
```js
"teachProperties": {
"units": ["unit 1", "unit 2", "unit 3", "unit 4"],
"units": ["Unidad 1", "Unidad 2"],
"attendancePrimaryThreshold": 80,
"attendanceSecondaryThreshold": 70,
"scoringPrimaryThreshold": 70,
Expand All @@ -22,8 +69,8 @@ __New Features__
"behaviorSecondaryThreshold": 80,
"useAttendanceFeature": true
}
```
The PrimaryThreshold and SecondaryThreshold values are used to determine the color of the cell in the reports.
- Updated docker-tangerine-base-image to v3.8.0, which adds the cordova-plugin-x-socialsharing plugin and enables sharing to WhatsApp.
__Fixes__
Expand Down Expand Up @@ -52,12 +99,14 @@ git checkout -b v3.30.0 v3.30.0
# Remove Tangerine's previous version Docker Image.
docker rmi tangerine/tangerine:v3.29.1
```
## v3.29.1
__Fixes__
- Fix undefined reference in markQualifyingEventsAsComplete
__Server upgrade instructions__
- Fix undefined referencein markQualifyingEventsAsComplete
__Server upgrade instructions__
Reminder: Consider using the [Tangerine Upgrade Checklist](https://docs.tangerinecentral.org/system-administrator/upgrade-checklist.html) for making sure you test the upgrade safely.
Expand Down Expand Up @@ -119,9 +168,9 @@ git checkout -b v3.29.0 v3.29.0
docker rmi tangerine/tangerine:<previous_version>
```
## v3.28.X
## v3.28
This released turned into v4.X
- This became v4
## v3.27.8
Expand Down Expand Up @@ -169,6 +218,46 @@ git checkout -b v3.27.8 v3.27.8
docker rmi tangerine/tangerine:v3.27.7
```
## v3.29.0
__New Features__
- Case, Event and Form Archive and Unarchive
We have released an update to Tangerine which allows for the archiving and un-archiving of both events, and forms within events. This is an extension of the already existing functionality by which an entire case can be archived. The purpose of this is to empower data management teams using Tangerine to "clean up" messy cases where extraneous data has been added to a case in error, or by a conflict situation. The purpose of this document is to summarize both the configuration to enable this, and to demonstrate the use of these functions. This functionality will only apply to the web-based version of Tangerine, and will not be available on tablets.
__Package Updates__
- Updated tangy-form to v4.40.0
__Server upgrade instructions__
Reminder: Consider using the [Tangerine Upgrade Checklist](https://docs.tangerinecentral.org/system-administrator/upgrade-checklist.html) for making sure you test the upgrade safely.
```
cd tangerine
# Check the size of the data folder.
du -sh data
# Check disk for free space.
df -h
# If there is not more than 12 GB plus the size of the data folder, create more space before proceeding.
# Good candidates to remove are: data back-up folders and older versions of the Tangerine image
# rm -rf ../data-backup-<date>
# docker rmi tangerine/tangerine:<version>
# Create a backup of the data folder.
cp -r data ../data-backup-$(date "+%F-%T")
# Check logs for the past hour on the server to ensure it's not being actively used. Look for log messages like "Created sync session" for Devices that are syncing and "login success" for users logging in on the server.
docker logs --since=60m tangerine
# Fetch the updates.
git fetch origin
git checkout -b v3.29.0 v3.29.0
./start.sh v3.29.0
# Remove Tangerine's previous version Docker Image.
docker rmi tangerine/tangerine:<previous_version>
```
## v3.28.X
- Became v4.0
## v3.27.7
__Fixes__
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ cp config.defaults.sh config.sh

Now open <http://localhost/> in your web browser. To debug the node.js server, install [NiM](https://chrome.google.com/webstore/detail/nodejs-v8-inspector-manag/gnhhdgbaldcilmgcpfddgdbkhjohddkj), open it through your devtools and connect to port 9229.

__Optional__: If you want to test deploying APKs and PWAs, you'll need to make your sandbox publicly accessible at a URL. Tangerine Developers have had good luck using [ngrok](https://ngrok.com/) to create an https tunnel to your local server. Be sure to modify T_HOST_NAME and T_PROTOCOL in config.sh using the URL that NGROK gives you. It can be worth it to pay for a static domain name as you would otherwise have to keep destroying your data folder, updating config.sh with the new URL, and starting over every time you get one of the random NGROK addresses.
__Optional__: If you want to test deploying APKs and PWAs, you'll need to make your sandbox accessible using an https URL. A reverse proxy will forward https requests to your dev instance running on port 80. Tangerine Developers have had good luck using [tunnelto](https://tunnelto.dev/) and [ngrok](https://ngrok.com/) to create an https tunnel to your local server. Please note that using those methods expose your dev environment to the Internet. An alternative is to create your own reverse proxy - see the [Reverse Proxy for Developers](./docs/developer/reverse-proxy-for-developers.md) doc for more information.

Example config.sh when using ngrok:
You must modify T_HOST_NAME and T_PROTOCOL in config.sh using the URL of your dev server. When using a service such as NGROK, it can be worth it to pay for a static domain name as you would otherwise have to keep destroying your data folder, updating config.sh with the new URL, and starting over every time you get one of the random NGROK addresses.

Example config.sh settings when using a reverse proxy:
```bash
T_HOST_NAME='123random.ngrok.io'
T_PROTOCOL="https"
Expand Down
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"rxjs-compat": "^6.5.5",
"sanitize-filename-ts": "^1.0.2",
"spark-md5": "^3.0.2",
"tangy-form": "4.41.1",
"tangy-form": "4.42.0",
"translation-web-component": "1.1.1",
"tslib": "^1.10.0",
"underscore": "^1.9.1",
Expand Down
33 changes: 22 additions & 11 deletions client/src/app/case-management/_services/case-management.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ export class CaseManagementService {
const allLocations:any = Object.assign({}, res);
// Calculate our locations by generating the path in the locationList object.
const locationList = allLocations.locations;
const myLocations = [];
const locations = [];
const results = await this.getVisitsByYearMonthLocationId();
const visits = removeDuplicates(results, 'key'); // Remove duplicates due to multiple form responses in a given location in a day
visits.forEach(visit => {
const visitKey = visit.key.split('-');
if (visitKey[2].toString() === month.toString() && visitKey[3].toString() === year.toString()) {
let item = findById(locationList, visitKey[0]);
const parts = this._splitQueryKeyParts(visit.key)
if (parts.month === month.toString() && parts.year === year.toString()) {
let item = findById(locationList, parts.location);
if (!item) {
locations.push({
location: visitKey[0],
visits: countUnique(visits, visitKey[0]),
id: visitKey[0]
location: parts.location,
visits: countUnique(visits, parts.location),
id: parts.location
})
} else {
locations.push({
Expand All @@ -54,20 +53,31 @@ export class CaseManagementService {
}

async getFilterDatesForAllFormResponses() {

const results = await this.getVisitsByYearMonthLocationId();
const timeLapseFilter = [];
const visits = removeDuplicates(results, 'key'); // Remove duplicates due to multiple form responses in a given location in a day
visits.forEach(visit => {
const visitKey = visit.key.split('-');
const parts = this._splitQueryKeyParts(visit.key)
timeLapseFilter.push({
value: `${visitKey[2].toString()}-${visitKey[3].toString()}`,
label: `${this.monthNames[visitKey[2].toString()]}, ${visitKey[3].toString()}`,
value: `${parts.month}-${parts.year}`,
label: `${this.monthNames[parts.month]}, ${parts.year}`,
});
});
return removeDuplicates(timeLapseFilter, 'value');
}

_splitQueryKeyParts(key) {
// This is a very hacky way to get the dates from the result key
// A better fix would be to assign the values to the result value
let keyParts = key.split('-')
const yearKey = keyParts.pop()
const monthKey = keyParts.pop()
const dayKey = keyParts.pop()
const locationKey = keyParts.join('-')

return { year: yearKey, month: monthKey, day: dayKey, location: locationKey }
}

async getFilterDatesForAllFormResponsesByLocationId(locationId: string) {
const userDb = await this.userService.getUserDatabase()
const result = await userDb.query('tangy-form/responsesByLocationId', { key: locationId, include_docs: true });
Expand Down Expand Up @@ -126,6 +136,7 @@ export class CaseManagementService {
return {
formTitle,
startDatetime: observation.doc.startUnixtime,
uploadDatetime: observation.doc.uploadDatetime,
complete: observation.doc.complete,
formIndex: index,
_id: observation.doc._id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
<th *ngFor="let col of columns">
{{col.name}}
</th>
<th>{{'Start Date and Time'|translate}}</th>
<th>{{'Complete?'|translate}}</th>
<th>{{'Date and Time'|translate}}</th>
<th>{{'Upload Date and Time'|translate}}</th>
</tr>
</thead>
<tbody>
Expand All @@ -26,11 +27,14 @@
<td *ngFor="let col of observation.columns">
{{col.value|json}}
</td>
<td>
{{observation.startDatetime| date:'MMM d, y, h:mm a'}}
</td>
<td>
{{observation.complete}}
</td>
<td>
{{observation.startDatetime| date:'MMM d, y, h:mm a'}}
{{observation.uploadDatetime| date:'MMM d, y, h:mm a'}}
</td>
</tr>
</tbody>
Expand Down
Loading

0 comments on commit a81e12b

Please sign in to comment.