Skip to content

Commit

Permalink
Merge pull request #3678 from Tangerine-Community/release/v3.30.2
Browse files Browse the repository at this point in the history
Release/v3.30.2
  • Loading branch information
esurface authored Feb 14, 2024
2 parents a81e12b + 5b837a9 commit 3009478
Show file tree
Hide file tree
Showing 138 changed files with 10,542 additions and 3,326 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tanerine-env-vars.sh
.history
certs

content-sets/content-sets.json
translations/*.csv

tangerine-preview/app/
Expand Down
98 changes: 59 additions & 39 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
# What's new

## v3.30.2

__New Features__

- Customizable 'About' Page on client [#3677](https://github.com/Tangerine-Community/Tangerine/pull/3677)
-- Form developers can create or update a form with the id 'about'. There is an example form in the [Content Sets](https://github.com/Tangerine-Community/Tangerine/tree/release/v3.30.2/content-sets/default/client/about)
-- The form will appear in the 'About' page on the client

__General Updates__
- Password Visibility -- the login and register screen on the client shows an 'eye' icon used to hide or show passwords
- Re-organization of the client app menu
- Reintroduce `registrationRequiresServerUser` app config setting to make managing central user more flexible
- use `registrationRequiresServerUser` to require an import code when registering users on the client
- use `centrallyManagedUserProfile` to require an import code AND only allow changes to the user profile on the server
- use `hideProfile` to hide the manage user profile page from on the client

__Teach Module Updates__
- Behavior screen show a link instead of a checkbox to access the Behavior form
- Hint text added to attendance, behavior, and scoring tables
- Improved save messaging for attendance and scoring
- In Attendance Reports:
- add start and end dates to view a custom date range report
- Fix the names not displaying in the tables

__Fixes__
- Get Media Uploads working in Editor [#3583](https://github.com/Tangerine-Community/Tangerine/issues/3583)
- CSV Generation broken with 'doLocalWorkaround is undefined' error


__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.2
# Run the update to copy the new About page to all groups on your site.
docker exec -it tangerine /tangerine/server/src/upgrade/v3.30.2.js
# Remove Tangerine's previous version Docker Image.
docker rmi tangerine/tangerine:<previous_version>
```



## v3.30.1

__New Features__
Expand Down Expand Up @@ -218,45 +277,6 @@ 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

Expand Down
3 changes: 2 additions & 1 deletion client/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"src/assets"
],
"styles": [
"src/styles.scss"
"src/styles.scss",
"node_modules/font-awesome/css/font-awesome.css"
]
},
"configurations": {
Expand Down
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"date-carousel": "^5.2.1",
"date-fns": "^2.30.0",
"fast-json-patch": "^3.0.0-1",
"font-awesome": "^4.7.0",
"fs-extra": "^6.0.1",
"install": "^0.13.0",
"js-uuid": "0.0.6",
Expand Down
54 changes: 30 additions & 24 deletions client/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,62 @@

<paper-icon-button icon="more-vert" [matMenuTriggerFor]="appMenu" class="hamburger-menu"></paper-icon-button>
<mat-menu #appMenu="matMenu">
<button *ngIf="ready && appConfig && appConfig.kioskMode" (click)="kioskModeEnabled = true" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">screen_lock_landscape</mat-icon>
<span>{{'Kiosk Mode'|translate}}</span>
</button>
<button *ngIf="ready && !appConfig.hideProfile" routerLink="manage-user-profile" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">create</mat-icon>
<span>{{'Manage Profile'|translate}}</span>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/">
<mat-icon class="material-icons menu-tangy-location-list-icon">home</mat-icon>
<span>{{'Home'|translate}}</span>
</button>
<button *ngIf="!isLoggedIn" routerLink="" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">lock_open</mat-icon>
<span>{{'Login / Register'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="settings" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">settings</mat-icon>
<span>{{'Settings'|translate}}</span>
<button *ngIf="ready && appConfig && appConfig.kioskMode" (click)="kioskModeEnabled = true" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">screen_lock_landscape</mat-icon>
<span>{{'Kiosk Mode'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="/sync-records" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">autorenew</mat-icon>
<span>{{'Sync'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="/export-data" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">import_export</mat-icon>
<span>{{'Export Data'|translate}}</span>
</button>
<button mat-menu-item (click)="updateApp()" *ngIf="showUpdateAppLink">
<mat-icon class="material-icons menu-tangy-location-list-icon">cloud_download</mat-icon>
<span>{{'Update App'|translate}}</span>
</button>
<button mat-menu-item (click)="updateApp()" *ngIf="!showUpdateAppLink">
<mat-icon class="material-icons menu-tangy-location-list-icon">cloud_download</mat-icon>
<span>{{'Check for Update'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/maintenance">
<mat-icon class="material-icons menu-tangy-location-list-icon">build</mat-icon>
<span>{{'Maintenance'|translate}}</span>
<button *ngIf="ready && isLoggedIn && !appConfig.hideProfile" routerLink="manage-user-profile" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">create</mat-icon>
<span>{{'Manage Profile'|translate}}</span>
</button>
<button routerLink="settings" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">settings</mat-icon>
<span>{{'Settings'|translate}}</span>
</button>
<button routerLink="about" mat-menu-item>
<button *ngIf="ready && !appConfig.hideAbout" routerLink="about" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">info</mat-icon>
<span>{{'About'|translate}}</span>
</button>

<!-- Advanced Menu Items-->
<mat-divider *ngIf="isLoggedIn"></mat-divider>
<button *ngIf="isLoggedIn" mat-menu-item [matMenuTriggerFor]="advancedMenu">{{'Advanced'|translate}}
</button>
<mat-menu #advancedMenu="matMenu">
<button *ngIf="isLoggedIn" routerLink="/export-data" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">import_export</mat-icon>
<span>{{'Export Data'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/maintenance">
<mat-icon class="material-icons menu-tangy-location-list-icon">build</mat-icon>
<span>{{'Maintenance'|translate}}</span>
</button>
</mat-menu>
<mat-divider *ngIf="isLoggedIn"></mat-divider>
<button *ngIf="isLoggedIn" mat-menu-item (click)="logout()">
<mat-icon class="material-icons menu-tangy-location-list-icon">exit_to_app</mat-icon>
<span>{{'Logout'|translate}}</span>
</button>

</mat-menu>


</mat-toolbar>

<div class="tangerine-app-content mat-typography " [ngClass]="{'has-topbar': !kioskModeEnabled}">
<router-outlet *ngIf="ready"></router-outlet>
</div>
2 changes: 1 addition & 1 deletion client/src/app/class/_services/dashboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ export class DashboardService {
// const curriculumFormHtml = await this.getCurriculaForms(curriculum.name);
// const curriculumFormsList = await this.classUtils.createCurriculumFormsList(curriculumFormHtml);
const appConfig = await this.appConfigService.getAppConfig();
const studentRegistrationFields = appConfig.teachProperties?.studentRegistrationFields
const studentRegistrationFields = appConfig.teachProperties?.studentRegistrationFields || []
const list = []
for (const student of students) {
let studentResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ mat-chip-list.absent {
padding-left: 5px;
padding-right: 5px;
text-align: center;
}

.tableHintLabel {
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<mat-card>
<div class="selectedClassLabel">{{'Attendance'|translate}}<br/>{{getClassTitle(selectedClass)}} <ng-container *ngIf="!ignoreCurriculumsForTracking">: {{curriculum?.label}} </ng-container>: {{reportLocaltime}}</div>
<div class="tableHintLabel">
<mat-label>{{'Tap on the green checkmark to mark a student as absent'|translate}}</mat-label>
</div>
<div>
<table class="dashboard-table">
<tr>
Expand All @@ -23,88 +26,6 @@
</ng-template>
</mat-chip-list>
</td>
<!-- <td>-->
<!-- <mat-chip-list [selectable]="!element['absent']" multiple="false">-->
<!-- <ng-container *ngIf="element['mood'] == 'happy'; then happy; else happyDefault"></ng-container>-->
<!-- <ng-template #happy>-->
<!-- <mat-chip (click)="toggleMood('happy', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="primary" class="green">-->
<!-- <mat-icon>mood</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->
<!-- <ng-template #happyDefault>-->
<!-- <mat-chip (click)="toggleMood('happy', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="accent" class="accent">-->
<!-- <mat-icon>mood</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->

<!-- <ng-container-->
<!-- *ngIf="element['mood'] == 'neutral'; then neutral; else neutralDefault"></ng-container>-->
<!-- <ng-template #neutral>-->
<!-- <mat-chip (click)="toggleMood('neutral', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="accent" class="orange">-->
<!-- <mat-icon>sentiment_neutral</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->
<!-- <ng-template #neutralDefault>-->
<!-- <mat-chip (click)="toggleMood('neutral', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="accent">-->
<!-- <mat-icon>sentiment_neutral</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->

<!-- <ng-container *ngIf="element['mood'] == 'sad'; then sad; else sadDefault"></ng-container>-->
<!-- <ng-template #sad>-->
<!-- <mat-chip (click)="toggleMood('sad', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="accent" class="red">-->
<!-- <mat-icon>sentiment_dissatisfied</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->
<!-- <ng-template #sadDefault>-->
<!-- <mat-chip (click)="toggleMood('sad', element)" [disabled]="element['absent']"-->
<!-- [selectable]="!element['absent']" color="accent">-->
<!-- <mat-icon>sentiment_dissatisfied</mat-icon>-->
<!-- </mat-chip>-->
<!-- </ng-template>-->
<!-- </mat-chip-list>-->
<!-- </td>-->
<!-- <td class="checkbox-response" *ngIf="element.forms['form-internal-behaviour'] ; else elseBlock ">-->
<!-- <input type="checkbox"-->
<!-- (change)="$event ? selectCheckboxResult(element,'form-internal-behaviour',$event) : null"-->
<!-- [checked]="true"-->
<!-- [disabled]="element['absent']" -->
<!-- [hidden]="element['absent']"-->
<!-- />-->
<!-- </td>-->
<!-- <ng-template #elseBlock>-->
<!-- <td class="checkbox-response">-->
<!-- <input type="checkbox" -->
<!-- (click)="$event.stopPropagation()"-->
<!-- (change)="$event ? selectCheckbox(element,'form-internal-behaviour') : null"-->
<!-- [disabled]="element['absent']"-->
<!-- [hidden]="element['absent']"-->
<!-- />-->
<!-- </td>-->
<!-- </ng-template>-->
<!-- <td class="checkbox-response" *ngIf="element.forms['form-external-behaviour'] ; else elseBlock ">-->
<!-- <input type="checkbox"-->
<!-- (change)="$event ? selectCheckboxResult(element,'form-external-behaviour',$event) : null"-->
<!-- [checked]="true"-->
<!-- [disabled]="element['absent']"-->
<!-- [hidden]="element['absent']"-->
<!-- />-->
<!-- </td>-->
<!-- <ng-template #elseBlock>-->
<!-- <td class="checkbox-response">-->
<!-- <input type="checkbox" (click)="$event.stopPropagation()"-->
<!-- (change)="$event ? selectCheckbox(element,'form-external-behaviour') : null"-->
<!-- [disabled]="element['absent']"-->
<!-- [hidden]="element['absent']"-->
<!-- />-->
<!-- </td>-->
<!-- </ng-template>-->
</tr>
</table>
<span><p class="mat-h3"
*ngIf="attendanceList?.length === 0">{{'No Students currently registered.'|translate}}</p></span>
Expand Down
Loading

0 comments on commit 3009478

Please sign in to comment.