Compare commits

...

76 Commits

Author SHA1 Message Date
Christian Landgren a8281d4370
trigger build 2024-04-30 23:13:02 +02:00
Christian Landgren 098bc544f2
correct context 2024-04-30 22:51:48 +02:00
Christian Landgren c16d60c2e2
Feat: pull image from github registry 2024-04-30 22:44:11 +02:00
Christian Landgren a7fa22cd54
Update website-build-and-push-registry.yml 2024-04-30 22:42:02 +02:00
Christian Landgren a7b9d81714
Trigger build 2024-04-30 13:18:06 +02:00
Christian Landgren b8ed895e52
Use semver patches for build to trigger new versions in docker registry 2024-04-30 13:16:47 +02:00
Christian Landgren caafb59f8d
Trigger build 2024-04-30 13:13:03 +02:00
Christian Landgren 81e448c035
Update and rename docker-publish.yml to website-build-and-push-registry.yml 2024-04-30 13:12:08 +02:00
Christian Landgren 62de54ef80
Ignore buildstep for website 2024-04-30 13:11:13 +02:00
Christian Landgren d5e4bfd149
Trigger build 2024-04-30 12:48:32 +02:00
Christian Landgren 28e1481e3f
Build and push website to ghcr.io 2024-04-30 12:44:44 +02:00
semantic-release-bot f2a87117ba chore(release): 2.17.0 [skip ci]
# [2.17.0](https://github.com/kolplattformen/skolplattformen/compare/v2.16.1...v2.17.0) (2024-04-29)

### Features

* 🎸 Added privacy policy for Öppna Elevappen on the site ([6eb6d3a](6eb6d3a6e3))
2024-04-29 22:26:21 +02:00
Kajetan Kazimierczak 6eb6d3a6e3 feat: 🎸 Added privacy policy for Öppna Elevappen on the site 2024-04-29 22:24:08 +02:00
Kajetan Kazimierczak c0e6ce9e06
chore: 🤖 Bumped version to 3.0.10 (#672) 2024-04-09 22:01:46 +02:00
Weblate (bot) c9907a68b6
Translations update from Hosted Weblate (#669)
* Translated using Weblate (Spanish)

Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/es/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/nl/

---------

Co-authored-by: Sergio Avalos <sergio.avalos@gmail.com>
Co-authored-by: Karin Nygårds <karinnygards@gmail.com>
Co-authored-by: Raul Jimenez <rauljim@gmail.com>
Co-authored-by: Mikachu <micah.sh@proton.me>
2024-04-09 21:17:12 +02:00
Kajetan Kazimierczak 320ab1f1f5
Merge pull request #671 from kolplattformen/chore/v3.0.9
chore: 🤖 Bumped version to 3.0.9
2024-04-09 21:13:06 +02:00
Kajetan Kazimierczak 7962234e26 chore: 🤖 Bumped version to 3.0.9 2024-04-09 21:11:58 +02:00
Kajetan Kazimierczak b66f56b312
Update Podfile.lock 2024-04-09 20:51:08 +02:00
Kajetan Kazimierczak 442aad7fda
Update README.md
one more year...
2024-04-09 20:17:05 +02:00
semantic-release-bot 1f2c7ee762 chore(release): 2.16.1 [skip ci]
## [2.16.1](https://github.com/kolplattformen/skolplattformen/compare/v2.16.0...v2.16.1) (2024-04-09)

### Bug Fixes

* 🐛 Site moved to new url ([c93e27b](c93e27bec0))
2024-04-09 20:15:57 +02:00
Kajetan Kazimierczak d51cfe36fe
chore: 🤖 Updated TimeTable URLs (#670)
* chore: 🤖 Updated TimeTable URLs

* test: 💍 fixed failing tests
2024-04-09 20:13:11 +02:00
Kajetan Kazimierczak c93e27bec0 fix: 🐛 Site moved to new url 2024-02-13 15:32:29 +01:00
Kajetan Kazimierczak 84ddda3f46
Update routes.ts 2024-02-13 08:52:03 +01:00
semantic-release-bot ab90b944ae chore(release): 2.16.0 [skip ci]
# [2.16.0](https://github.com/kolplattformen/skolplattformen/compare/v2.15.10...v2.16.0) (2023-11-02)

### Features

* navigate from "Your Children" to specific tabs ([#660](https://github.com/kolplattformen/skolplattformen/issues/660)) ([34c376a](34c376a727))
2023-11-02 07:30:50 +01:00
Sebastian Palmqvist 34c376a727
feat: navigate from "Your Children" to specific tabs (#660)
* chore (substring to only show firstname, size of name made bigger)

* Co-authored-by: Lee Sheppard<coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

* chore(size edit)

Co-authored-by: Lee Sheppard<coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

* feat (navigate to specific tabs from childlist)

Co-authored-by: Lee Sheppard<coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

* fix (title now gets inititated with correct value, not default "News")

Co-authored-by: Lee Sheppard<coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

* Revert "feat (navigate to specific tabs from childlist)"

This reverts commit 8af068946d.

* fix(correct title showing in header)

* fix(removed TouchableOpacity. Using Pressable)

Co-authored-by: Lee Sheppard<coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

---------

Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>
2023-11-02 07:27:34 +01:00
Sergio Avalos ce535518a9
chore(docs): update ios_mac.md (#665)
Minor typo
2023-11-02 07:25:04 +01:00
Kajetan Kazimierczak 09ae4f0eaa
Bumped version to 3.0.8 2023-10-13 19:09:38 +02:00
Kajetan Kazimierczak b5a2943fbb
Update Podfile.lock 2023-10-13 16:44:01 +02:00
Kajetan Kazimierczak 4d3f940171
Update package.json 2023-10-13 08:38:25 +02:00
Kajetan Kazimierczak 6d9325c20c bumped version to 3.0.7 2023-10-12 19:06:17 +02:00
Kajetan Kazimierczak 27e9fb8cf7 uppdated webview 2023-10-12 19:00:25 +02:00
Kajetan Kazimierczak c26b118ad0
added .node-version 2023-10-11 11:13:21 +02:00
Kajetan Kazimierczak 4e51bb8de7
Update build.gradle 2023-10-11 10:15:25 +02:00
Kajetan Kazimierczak 5d61cd150a
Update build.gradle 2023-10-11 09:35:47 +02:00
Kajetan Kazimierczak 7e5013e7ca
Update .nvmrc 2023-10-09 21:44:41 +02:00
semantic-release-bot 394d0d973d chore(release): 2.15.10 [skip ci]
## [2.15.10](https://github.com/kolplattformen/skolplattformen/compare/v2.15.9...v2.15.10) (2023-10-07)

### Bug Fixes

* 🐛 Updated Timetable URLs ([#659](https://github.com/kolplattformen/skolplattformen/issues/659)) ([e6ba622](e6ba622fa9))
2023-10-07 23:37:04 +02:00
Kajetan Kazimierczak e6ba622fa9
fix: 🐛 Updated Timetable URLs (#659) 2023-10-07 23:33:45 +02:00
semantic-release-bot bee6d59283 chore(release): 2.15.9 [skip ci]
## [2.15.9](https://github.com/kolplattformen/skolplattformen/compare/v2.15.8...v2.15.9) (2023-09-21)

### Bug Fixes

* copyright year ([#657](https://github.com/kolplattformen/skolplattformen/issues/657)) ([20ae87f](20ae87fee1))
2023-09-21 07:11:41 +02:00
Mohammed Chammam 20ae87fee1
fix: copyright year (#657) 2023-09-21 07:08:31 +02:00
Christian Landgren 565c27e6fb
Host web in kubernetes instead of Vercel (#647)
* chore: upgrade to node 16.13

* feat: add kubernetes manifests to run the web in kubernetes instead of Vercel

* fix: rearrange build scripts for speed

* feat: add readiness prope to never replace a working site with a failed one

* fix: add headers for hsts etc

* fix: add unsafe-inline

* fix: duplicate entities inline-style

* fix: add ipv6 support in web

* fix: Ingress should be ClusterIP, not LoadBalancer

* Add resources

* feat: switch to main domain

* fix: hsts preload requires www to also be encrypted
2023-09-18 23:25:34 +02:00
semantic-release-bot 6589d85ab0 chore(release): 2.15.8 [skip ci]
## [2.15.8](https://github.com/kolplattformen/skolplattformen/compare/v2.15.7...v2.15.8) (2023-09-17)

### Bug Fixes

*  removed price components. Altered QA. ([#653](https://github.com/kolplattformen/skolplattformen/issues/653)) ([fef71c7](fef71c7923))
2023-09-17 19:42:11 +02:00
Sebastian Palmqvist fef71c7923
fix: removed price components. Altered QA. (#653)
* fix: (index.tsx, FunFacts.tsx, NavLinks.tsx, QA.tsx) removed price components. Altered QA.

* Keeping FunFacts.tsx unchanged. Changing value of price to 0.

Co-authored-by: Lee Sheppard <coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>

* Updated price to 0. Altered PricingTemp text.

* fix: (PricingTemp.tsx) added features to "baseFeatures"

---------

Co-authored-by: Lee Sheppard <coolusername244@users.noreply.github.com>
Co-authored-by: Lvan Ni <lvan-ni@users.noreply.github.com>
2023-09-17 19:38:08 +02:00
semantic-release-bot ae5fd0624c chore(release): 2.15.7 [skip ci]
## [2.15.7](https://github.com/kolplattformen/skolplattformen/compare/v2.15.6...v2.15.7) (2023-03-28)

### Bug Fixes

* 🐛 Change broken links caused by name change of repo ([#649](https://github.com/kolplattformen/skolplattformen/issues/649)) ([61d47b4](61d47b4440))
2023-03-28 22:38:58 +02:00
Oskar Strömberg 61d47b4440
fix: 🐛 Change broken links caused by name change of repo (#649) 2023-03-28 22:35:19 +02:00
semantic-release-bot ee35ba7108 chore(release): 2.15.6 [skip ci]
## [2.15.6](https://github.com/kolplattformen/skolplattformen/compare/v2.15.5...v2.15.6) (2023-03-21)

### Bug Fixes

* 🐛 BankID urls changed ([#646](https://github.com/kolplattformen/skolplattformen/issues/646)) ([25a2d7f](25a2d7f3f5))
2023-03-21 21:35:15 +01:00
Kajetan Kazimierczak 25a2d7f3f5
fix: 🐛 BankID urls changed (#646)
* fix: 🐛 BankID urls changed

* lint

* fix: 🐛 Tests
2023-03-21 21:31:57 +01:00
Kajetan Kazimierczak 0db53ca046
Merge pull request #645 from kolplattformen/chore/android-targetversion
chore: 🤖 fix android build and deploy
2023-01-18 22:37:52 +01:00
Kajetan Kazimierczak f7493767b0 chore: 🤖 fix android build and deploy 2023-01-18 22:36:36 +01:00
Kajetan Kazimierczak 7b3dfb91e7
Merge pull request #644 from kolplattformen/chore/kotlin-version
chore: 🤖 kotlinVersion in build.gradle
2023-01-18 21:52:25 +01:00
Kajetan Kazimierczak 52c491213c chore: 🤖 kotlinVersion in build.gradle 2023-01-18 21:50:12 +01:00
Viktor Sarström 3a9c337bdd Merge branch 'main' of github.com:kolplattformen/skolplattformen 2023-01-18 13:31:55 +01:00
Viktor Sarström 68249e849a removed fixe 2023-01-18 13:31:34 +01:00
semantic-release-bot e77054fa60 chore(release): 2.15.5 [skip ci]
## [2.15.5](https://github.com/kolplattformen/skolplattformen/compare/v2.15.4...v2.15.5) (2023-01-18)

### Bug Fixes

* Bitrise build ([10e993a](10e993ab9d))
2023-01-18 10:03:03 +01:00
Viktor Sarström 10e993ab9d fix: Bitrise build 2023-01-18 09:59:47 +01:00
semantic-release-bot 8a1123d640 chore(release): 2.15.4 [skip ci]
## [2.15.4](https://github.com/kolplattformen/skolplattformen/compare/v2.15.3...v2.15.4) (2023-01-14)

### Bug Fixes

* 🐛 Better fix for the isoWeek bug in Timetable ([ea6b385](ea6b385b4f))
2023-01-14 18:40:59 +01:00
Kajetan Kazimierczak 6d49e4767c
Merge pull request #643 from kolplattformen/fix/wrong-date2
fix: 🐛 Better fix for the isoWeek bug in Timetable
2023-01-14 18:36:33 +01:00
Kajetan Kazimierczak ea6b385b4f fix: 🐛 Better fix for the isoWeek bug in Timetable 2023-01-14 18:31:02 +01:00
semantic-release-bot 3acd27cc1f chore(release): 2.15.3 [skip ci]
## [2.15.3](https://github.com/kolplattformen/skolplattformen/compare/v2.15.2...v2.15.3) (2023-01-14)

### Bug Fixes

* 🐛 Week starts on monday regardless of selected locale ([#642](https://github.com/kolplattformen/skolplattformen/issues/642)) ([7e8ee95](7e8ee956f4))
2023-01-14 17:44:13 +01:00
Kajetan Kazimierczak 7e8ee956f4
fix: 🐛 Week starts on monday regardless of selected locale (#642)
* fix: 🐛 Week starts on monday regardless of selected locale

* style: 💄 lint
2023-01-14 17:39:50 +01:00
Kajetan Kazimierczak 7d8662ff09
Merge pull request #641 from kolplattformen/weblate-translations
Translations update from Hosted Weblate
2023-01-14 17:31:00 +01:00
Theo Haglund 1c0ea08056
Translated using Weblate (Japanese)
Currently translated at 61.4% (70 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/ja/
2022-12-24 23:48:04 +01:00
Lorentz Lasson b1504fa181
Fix typo (#640)
Looks to have been added by mistake 
fd495f9d45 (diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L12-R12)
2022-12-13 22:13:14 +01:00
Kajetan Kazimierczak e44c0cc392
Merge pull request #637 from kolplattformen/weblate-translations
Translations update from Hosted Weblate
2022-12-02 00:31:04 +01:00
Theo O aa9bb8c41a
Translated using Weblate (Japanese)
Currently translated at 55.2% (63 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/ja/
2022-10-19 15:02:59 +02:00
Lage Linnarsson b09d888f4a
Translated using Weblate (Japanese)
Currently translated at 55.2% (63 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/ja/
2022-10-19 15:02:59 +02:00
Kajetan Kazimierczak a314b7ab78
Merge pull request #635 from kolplattformen/chore/v3.0.5
chore: 🤖 Bump version to 3.0.5
2022-09-05 12:30:56 +02:00
Kajetan Kazimierczak 23e6fe0919 chore: 🤖 Bump version to 3.0.5 2022-09-05 12:25:52 +02:00
Kajetan Kazimierczak 17b5d8ab40
Merge pull request #634 from kolplattformen/weblate-translations
Translations update from Hosted Weblate
2022-09-05 10:36:45 +02:00
WhiredPlanck 1684126446
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/zh_Hans/
2022-07-06 09:20:07 +02:00
Kajetan Kazimierczak e00bd6ad45
Merge pull request #629 from kolplattformen/weblate-translations 2022-04-30 21:28:53 +02:00
Kajetan Kazimierczak c7c170aa83
Translated using Weblate (Swedish)
Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/sv/
2022-04-30 21:21:46 +02:00
Kajetan Kazimierczak 8de7192003
Translated using Weblate (Swedish)
Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/sv/
2022-04-30 21:21:46 +02:00
Luna Jernberg 689f6c685d
Translated using Weblate (Swedish)
Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/sv/
2022-04-30 21:21:46 +02:00
Weblate (bot) 63fbd3042a
Translations update from Hosted Weblate (#628) 2022-04-30 21:21:42 +02:00
Andreas Eriksson 20ee509c28 style: 💄 Add eslint rules to api-skolplattformen and autofix
Add react-native-community eslint rules to project and run autofix on
all files.
2022-04-24 20:27:10 +02:00
Weblate (bot) 0508329998
Translations update from Hosted Weblate (#627)
* Translated using Weblate (English)

Currently translated at 100.0% (114 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/en/

* Translated using Weblate (Polish)

Currently translated at 99.1% (113 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/pl/

* Translated using Weblate (Ukrainian)

Currently translated at 98.2% (112 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/uk/

* Translated using Weblate (Thai)

Currently translated at 66.6% (76 of 114 strings)

Translation: Skolplattformen/App translations
Translate-URL: https://hosted.weblate.org/projects/skolplattformen/app-translation/th/

Co-authored-by: Kajetan Kazimierczak <kajetanek@gmail.com>
Co-authored-by: Adam Nybäck <adamnybeck@gmail.com>
2022-04-24 19:52:08 +02:00
81 changed files with 2414 additions and 1753 deletions

View File

@ -4,6 +4,8 @@ on:
push:
branches:
- main
paths-ignore:
- 'apps/website/**'
jobs:
build:

View File

@ -0,0 +1,81 @@
name: Docker
# Build to docker registry. This will trigger an update event from the Kubernetes cluster
on:
push:
branches: [ "main" ]
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
paths:
- 'apps/website/**'
pull_request:
branches: [ "main" ]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
if [[ $GITHUB_REF == refs/tags/production* ]]; then
npm version major
elif [[ $GITHUB_REF == refs/tags/staging* ]]; then
npm version minor
else
npm version patch
fi
- name: 📝 Get Current Version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: apps/website
push: ${{ github.event_name != 'pull_request' }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.package-version.outputs.current-version}},
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max

1
.node-version Normal file
View File

@ -0,0 +1 @@
16.19.1

2
.nvmrc
View File

@ -1 +1 @@
v14.15.4
v16.19.1

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,7 @@ Give us a ⭐ if you appreciate what we do!
[![Translation status](https://hosted.weblate.org/widgets/skolplattformen/-/svg-badge.svg)](https://hosted.weblate.org/engage/skolplattformen/)
[![Build Status](https://app.bitrise.io/app/8e56bd02bc602da5/status.svg?token=h8gI2dB_jXLurj9EO_fXWw)](https://app.bitrise.io/app/8e56bd02bc602da5)
We are parents who got fed up with Skolplattformen, the City of Stockholm's school administration platform. \ We reverse-engineered the platform's API to create a simpler, faster, more consistent, and secure experience for parents and guardians.
P
If you're simply looking for information about the app, our website can be found at [https://skolplattformen.org/](https://skolplattformen.org/). \
We are parents who got fed up with Skolplattformen, the City of Stockholm's school administration platform. \ We reverse-engineered the platform's API to create a simpler, faster, more consistent, and secure experience for parents and guardians. If you're simply looking for information about the app, our website can be found at [https://skolplattformen.org/](https://skolplattformen.org/). \
Check out [the changelog](CHANGELOG.md) to see what new features are added, and a list of fixed bugs.
This main repository for the project contains the source code for both the [app](apps/skolplattformen-app) and its [website](https://skolplattformen.org/). \
@ -163,7 +161,7 @@ Once done, create a _pull request_ where you explain why we should incorporate y
If you're new to GitHub, there's a number of excellent guides available, such as [this one on forking projects and making pull requests](https://guides.github.com/activities/forking/).
There are many ways to contribute to the project. \
If you don't know how to program and want help, you can [file an issue](https://github.com/kolplattformen/skolplattformen-app/issues/new) to let us know when something isn't working properly. \
If you don't know how to program and want help, you can [file an issue](https://github.com/kolplattformen/skolplattformen/issues/new) to let us know when something isn't working properly. \
We're super duper happy for both issues and pull requests, and we try to answer all of them as soon as humanly possible.
Another way to contribute is by helping translate Öppna skolplattformen [on Hosted Weblate](https://hosted.weblate.org/engage/skolplattformen-app/) into a new language, or to improve existing translations.
@ -196,7 +194,7 @@ If you're offended by this initiative, rest assured there is no reason to be —
## License
Öppna skolplattformen is copyright 20202021 Not Free Beer AB.
Öppna skolplattformen is copyright 20202024 Not Free Beer AB.
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License"); you may use Öppna skolplattformen in compliance with the License. A copy of the License is included with this repository.

View File

@ -139,7 +139,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 20000
versionName "3.0.4"
versionName "3.0.10"
}
splits {
abi {

View File

@ -11,6 +11,7 @@
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"

View File

@ -4,9 +4,10 @@ buildscript {
ext {
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
compileSdkVersion = 33
targetSdkVersion = 33
ndkVersion = "21.4.7075529"
kotlinVersion = "1.6.0"
}
repositories {
google()

View File

@ -139,7 +139,10 @@ const TabNavigator = ({
)
const getHeaderTitle = (route: any) => {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'News'
const routeName =
getFocusedRouteNameFromRoute(route) ??
route.params.initialRouteName ??
'News'
return getRouteTitleFromName(routeName)
}

View File

@ -18,7 +18,7 @@ import {
} from '@ui-kitten/components'
import moment, { Moment } from 'moment'
import React, { useEffect } from 'react'
import { TouchableOpacity, useColorScheme, View } from 'react-native'
import { Pressable, useColorScheme, View } from 'react-native'
import { useTranslation } from '../hooks/useTranslation'
import { Colors, Layout, Sizing } from '../styles'
import { getMeaningfulStartingDate } from '../utils/calendarHelpers'
@ -157,11 +157,15 @@ export const ChildListItem = ({
)
return (
<TouchableOpacity
onPress={() => navigation.navigate('Child', { child, color })}
>
<View style={styles.card}>
<View style={styles.cardHeader}>
<View style={styles.card}>
<View style={styles.cardHeader}>
<Pressable
style={({ pressed }) => [
styles.cardHeaderLeft || {},
{ opacity: pressed ? 0.5 : 1 },
]}
onPress={() => navigation.navigate('Child', { child, color })}
>
<View style={styles.cardHeaderLeft}>
<StudentAvatar name={studentName(child.name)} color={color} />
<View style={styles.cardHeaderText}>
@ -178,16 +182,37 @@ export const ChildListItem = ({
name="star"
/>
</View>
</View>
</Pressable>
</View>
<Pressable
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
onPress={() =>
navigation.navigate('Child', {
child,
color,
initialRouteName: 'Calendar',
})
}
>
<DaySummary child={child} date={meaningfulStartingDate} />
{scheduleAndCalendarThisWeek.slice(0, 3).map((calendarItem, i) => (
<Text category="p1" key={i}>
{`${calendarItem.title} (${displayDate(calendarItem.startDate)})`}
</Text>
))}
</Pressable>
<Pressable
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
onPress={() =>
navigation.navigate('Child', {
child,
color,
initialRouteName: 'News',
})
}
>
<Text category="c2" style={styles.label}>
{t('navigation.news')}
</Text>
@ -202,43 +227,52 @@ export const ChildListItem = ({
{newsItem.header ?? ''}
</Text>
))}
</Pressable>
{scheduleAndCalendarThisWeek.length ||
notificationsThisWeek.length ||
newsThisWeek.length ? null : (
<Text category="p1" style={styles.noNewNewsItemsText}>
{t('news.noNewNewsItemsThisWeek')}
{scheduleAndCalendarThisWeek.length ||
notificationsThisWeek.length ||
newsThisWeek.length ? null : (
<Text category="p1" style={styles.noNewNewsItemsText}>
{t('news.noNewNewsItemsThisWeek')}
</Text>
)}
{shouldShowLunchMenu ? (
<Pressable
style={({ pressed }) => ['' || {}, { opacity: pressed ? 0.5 : 1 }]}
onPress={() =>
navigation.navigate('Child', {
child,
color,
initialRouteName: 'Menu',
})
}
>
<Text category="c2" style={styles.label}>
{meaningfulStartingDate.format(
'[' + t('schedule.lunch') + '] dddd'
)}
</Text>
)}
{shouldShowLunchMenu ? (
<>
<Text category="c2" style={styles.label}>
{meaningfulStartingDate.format(
'[' + t('schedule.lunch') + '] dddd'
)}
</Text>
<Text>
{menu[meaningfulStartingDate.isoWeekday() - 1]?.description}
</Text>
</>
) : null}
<Text>
{menu[meaningfulStartingDate.isoWeekday() - 1]?.description}
</Text>
</Pressable>
) : null}
<View style={styles.itemFooter}>
<Button
accessible
accessibilityRole="button"
accessibilityLabel={`${child.name}, ${t('abscense.title')}`}
appearance="ghost"
accessoryLeft={AlertIcon}
status="primary"
style={styles.absenceButton}
onPress={() => navigation.navigate('Absence', { child })}
>
{t('abscense.title')}
</Button>
</View>
<View style={styles.itemFooter}>
<Button
accessible
accessibilityRole="button"
accessibilityLabel={`${child.name}, ${t('abscense.title')}`}
appearance="ghost"
accessoryLeft={AlertIcon}
status="primary"
style={styles.absenceButton}
onPress={() => navigation.navigate('Absence', { child })}
>
{t('abscense.title')}
</Button>
</View>
</TouchableOpacity>
</View>
)
}

View File

@ -19,7 +19,11 @@ export const NavigationTitle = ({ title, subtitle }: NavigationTitleProps) => {
{title}
</Text>
)}
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
{subtitle && (
<Text style={styles.subtitle}>
{subtitle.substring(0, subtitle.indexOf(' '))}
</Text>
)}
</View>
)
}
@ -32,5 +36,5 @@ const styles = StyleSheet.create({
...fontSize.sm,
fontWeight: '500',
},
subtitle: { ...fontSize.xxs },
subtitle: { ...fontSize.base },
})

View File

@ -159,7 +159,10 @@ export const Week = ({ child }: WeekProps) => {
<>
<Text style={styles.tabTitle}>{weekDay}</Text>
<Text style={styles.tabTitleDate}>
{displayDate.startOf('week').add(index, 'day').format('D')}
{displayDate
.startOf('isoWeek')
.add(index, 'day')
.format('D')}
</Text>
</>
)}

View File

@ -299,7 +299,7 @@ PODS:
- react-native-simple-toast (1.1.3):
- React-Core
- Toast (~> 4.0.0)
- react-native-webview (11.15.0):
- react-native-webview (12.4.0):
- React-Core
- React-perflogger (0.66.4)
- React-RCTActionSheet (0.66.4):
@ -617,7 +617,7 @@ SPEC CHECKSUMS:
react-native-restart: 733a51ad137f15b0f8dc34c4082e55af7da00979
react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057
react-native-simple-toast: bf002828cf816775a6809f7a9ec3907509bce11f
react-native-webview: e89bf2dba26a04cda967814df3ed1be99f291233
react-native-webview: 65f1143983cfeaedf02fd25b2621d3f4a37075de
React-perflogger: 93075d8931c32cd1fce8a98c15d2d5ccc4d891bd
React-RCTActionSheet: 7d3041e6761b4f3044a37079ddcb156575fb6d89
React-RCTAnimation: 743e88b55ac62511ae5c2e22803d4f503f2a3a13
@ -646,4 +646,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: f4a92b32cc4938e15ad7ccfefe9898548670abed
COCOAPODS: 1.11.2
COCOAPODS: 1.14.2

View File

@ -530,9 +530,9 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
@ -610,9 +610,9 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
@ -794,7 +794,7 @@
ENABLE_BITCODE = NO;
INFOPLIST_FILE = app/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.0.4;
MARKETING_VERSION = 3.0.10;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@ -823,7 +823,7 @@
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = app/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 3.0.4;
MARKETING_VERSION = 3.0.10;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",

View File

@ -19,8 +19,8 @@
"auth": {
"bankid": {
"OpenManually": "BankID manuell öffnen",
"OpenOnAnotherDevice": "BankID auf einem anderen Gerät benutzen",
"OpenOnThisDevice": "BankID auf diesem Gerät benutzen",
"OpenOnAnotherDevice": "BankID auf einem anderen Gerät öffnen",
"OpenOnThisDevice": "BankID auf diesem Gerät öffnen",
"Waiting": "Wartet auf BankID…"
},
"chooseLoginMethod": "Anmeldemethode auswählen",
@ -51,7 +51,13 @@
"a11y_clear_social_security_input_field": "Personenkennziffer-Feld löschen",
"a11y_image_two_boys": "Bild von zwei Personen, die ihre Mobiltelefon überprüfen",
"a11y_change_language": "Wähle deine Sprache",
"chooseSchoolPlatform": "Plattform wählen"
"chooseSchoolPlatform": "Plattform wählen",
"freja": {
"Waiting": "Wartet auf Freja eID+…",
"OpenManually": "Freja eID+ manuell öffnen",
"OpenOnThisDevice": "Freja eID+ auf diesem Gerät öffnen"
},
"loginSuccessful": "Eingeloggt, wird geladen…"
},
"calender": {
"approveAccessToCalender": "Du musst Zugriff auf deinen Kalender erlauben",

View File

@ -25,7 +25,7 @@
},
"freja": {
"OpenManually": "Open Freja eID+ manually",
"OpenOnThisDevice": "Freja eID+",
"OpenOnThisDevice": "Open Freja eID+ on this device",
"Waiting": "Waiting for Freja eID+…"
},
"chooseLoginMethod": "Choose login method",

View File

@ -4,13 +4,18 @@
"noNewNewsItemsThisWeek": "No hay noticias nuevas esta semana.",
"backToChild": "Volver al niño",
"title": "Noticias de Skolplattformen",
"published": "Publicada"
"published": "Publicada",
"updated": "Actualizado",
"search": {
"placeholder": "Buscar en las noticias…"
}
},
"navigation": {
"notifications": "Notificaciones",
"news": "Noticias",
"calender": "Calendario",
"menu": "Menú"
"menu": "Menú",
"classmates": "Compañeros de clase"
},
"language": {
"changeLanguage": "Cambiar idioma",
@ -25,20 +30,28 @@
"loading": "Cargando…",
"confirm": "Confirmar",
"title": "Öppna skolplattformen",
"cancel": "Anular"
"cancel": "Anular",
"tomorrow": "Mañana",
"logoutAndClearPersonalData": "Cierre la sesión y borre sus datos personales",
"logoutAndClearAllDataInclSettings": "Cierre la sesión y borre todos sus datos incluyendo sus configuraciones"
},
"children": {
"viewStatus": "Ver estado en skolplattformen.org",
"tryAgain": "Intentar otra vez",
"title": "Tus hijos",
"noKids_title": "Sin niños"
"noKids_title": "Sin niños",
"loadingErrorHeading": "¡Ahijoles!",
"loadingErrorInformationText": "La página no pudo ser cargada. Intente de nuevo o mire su estado actual en skolplattformen.org.",
"noKids_description": "No hay infantes registrados en la ciudad de Estocolmo con su número de identificación personal"
},
"calender": {
"showCalenderActions": "Mostrar acciones de calendario",
"saveToCalenderSuccess": "✔️ Guardado en el calendario",
"saveToCalenderError": "Algo salió mal",
"saveToCalender": "Guardar en calendario",
"approveAccessToCalender": "Tienes que aprobar el acceso a tu calendario"
"approveAccessToCalender": "Tienes que aprobar el acceso a tu calendario",
"emptyText": "No hay algo que mostrar",
"emptyHeadline": "El calendario está un poco vacío"
},
"auth": {
"words": {
@ -60,8 +73,8 @@
"fast": "rápida",
"fun": "divertido"
},
"subtitle": "La alternativa {{word}}",
"placeholder_SocialSecurityNumber": "Tu personnummer",
"subtitle": "La alternativa de {{word}}",
"placeholder_SocialSecurityNumber": "Tu número de identidad personal",
"loginFailed": "No se pudo iniciar sesión. Vuelva a intentarlo.",
"chooseLoginMethod": "Elija el método de inicio de sesión",
"bankid": {
@ -72,17 +85,27 @@
},
"loginAsTestUser": "Inicie sesión como usuario de pruebas",
"a11y_change_language": "Elija su idioma",
"a11y_image_two_boys": "Fotografia de dos personas mirando su telefono movil"
"a11y_image_two_boys": "Fotografia de dos personas mirando su telefono movil",
"chooseSchoolPlatform": "Elija la plataforma",
"a11y_clear_social_security_input_field": "Borrar el campo del número de identificación personal",
"loginSuccessful": "Se ha iniciado la sesión correctamente, cargando…",
"freja": {
"OpenManually": "Abrir Freja eID+ manualmente",
"OpenOnThisDevice": "Abrir Freja eID+ en este dispositivo",
"Waiting": "Esperando a Freja eID+…"
},
"a11y_select_login_method": "Seleccione el metodo para iniciar sesión"
},
"abscense": {
"title": "Informar ausencia",
"startTime": "hora de inicio",
"selectAbscenseStartTime": "Elige la hora de inicio",
"personalNumberMissing": "Falta el personnummer",
"invalidPersonalNumber": "El personnumer no es válido",
"personalNumberMissing": "Falta el número personal",
"invalidPersonalNumber": "Número personal inválido",
"entireDay": "Día completo",
"endTime": "hora de finalización",
"selectAbscenseEndTime": "Elige la hora de finalización"
"selectAbscenseEndTime": "Elige hora de finalización",
"childsPersonalNumber": "Numero de identificación del infante (personnummer)"
},
"abbrevations": {
"upperSecondarySchool": "Escuela Secundaria Obligatoria",
@ -92,5 +115,42 @@
},
"notifications": {
"notificationTitle": "Notificación: {{message}} ({{dateCreated}})"
},
"contact": {
"home": "Dirección",
"email": "Correo electrónico",
"call": "Llamar",
"a11y_show_contact_info_button_label": "Mostrar información de contacto",
"a11y_show_contact_info_button_hint": "Muestra información de contacto",
"sms": "Mensaje de texto"
},
"settings": {
"language": "Idioma",
"useSystemTheme": "Use el aspecto claro/oscuro dispositivo",
"licenses": "Licencias",
"themeAuto": "Automático",
"appearance": "Diseño",
"theme": "Aspecto",
"settings": "Configuraciones"
},
"themes": {
"dark": "Oscuro",
"light": "Claro"
},
"menu": {
"emptyText": "No hay nada para esta semana",
"emptyHeadline": "El menu del almuerzo se ve algo vacio"
},
"classmates": {
"class": "Clase",
"child": "Infante",
"contactsForGuardiansFor": "Información de contacto de los tutores de"
},
"schedule": {
"gymBag": "Mochila de gimnasio",
"end": "Termina",
"start": "Inicia",
"lunch": "Almuerzo",
"week": "Semana"
}
}

View File

@ -29,7 +29,11 @@
},
"children": {
"tryAgain": "やり直してください",
"title": "あなたの子供"
"title": "あなたの子供",
"noKids_title": "子供のない",
"loadingErrorHeading": "おっと!",
"loadingErrorInformationText": "このページを読み込むことができません。もう一度してみるか、skolplattformen.orgで現在のステータスを調べてください。",
"noKids_description": "ストックホルム市にその個人識別番号で登録された子供はいません"
},
"auth": {
"a11y_image_two_boys": "自分の携帯電話を見ている二人",
@ -54,16 +58,25 @@
"awaited": "待ち受ける"
},
"subtitle": "{{word}}の選択肢",
"chooseLoginMethod": "ログイン方法を選択してください",
"chooseLoginMethod": "ログイン方法を選んでください",
"loginAsTestUser": "テスト・ユーザーでログインしてください",
"bankid": {
"OpenManually": "BankIDを手動で開く",
"OpenManually": "手動でBankIDを開ける",
"OpenOnAnotherDevice": "別のデバイスでBankIDを使用する",
"Waiting": "BankIDを待っています…",
"OpenOnThisDevice": "このデバイスでBankIDを使用する"
},
"loginFailed": "ログインできませんでした。再試行してください。",
"placeholder_SocialSecurityNumber": "あなたの個人番号"
"placeholder_SocialSecurityNumber": "あなたの個人番号",
"freja": {
"OpenOnThisDevice": "このデバイスで Freja eID+を使用する",
"OpenManually": "手動でFreja eID+を開ける",
"Waiting": "Freja eID+を待っています…"
},
"a11y_clear_social_security_input_field": "個人識別番号のフィールドを空にする",
"chooseSchoolPlatform": "ログイン方法を選んでください",
"loginSuccessful": "ログインは完成した、よみこんでいる。。。",
"a11y_select_login_method": "ログインする方法を選ぶ"
},
"language": {
"changeLanguage": "他の言語を選択"
@ -73,6 +86,13 @@
},
"calender": {
"approveAccessToCalender": "カレンダーのアクセスを許可する必要があります",
"saveToCalenderError": "エラーが発生しました"
"saveToCalenderError": "エラーが発生しました",
"saveToCalender": "カレンダーに保存する",
"saveToCalenderSuccess": "✔️ カレンダーへに保存しました",
"emptyHeadline": "カレンダーがなんか空っぽになりそう",
"emptyText": "表示するものが見つかりませんでした"
},
"classmates": {
"child": "子供"
}
}

View File

@ -4,29 +4,29 @@
"loginFailed": "Nomen dare non possibilis erat. Denuo conare.",
"chooseLoginMethod": "Methodum nomen dare legere",
"bankid": {
"Waiting": "Pro BankID exspectans…",
"Waiting": "BankID exspectans…",
"OpenOnThisDevice": "In hac machina BankID aperire",
"OpenOnAnotherDevice": "In machina differenti BankID aperire",
"OpenManually": "Manu BankID aperire"
"OpenManually": "Manualiter BankID aperire"
},
"words": {
"awaited": "exspectatus",
"awaited": "exspectata",
"agile": "agilis",
"better": "melior",
"cheap": "vilis",
"cooler": "amatior",
"working": "operans",
"simple": "simplus",
"simple": "simplex",
"rebellious": "rebellis",
"open": "apertus",
"imperfect": "imperfectus",
"open": "aperta",
"imperfect": "imperfecta",
"fun": "oblectans",
"free": "liber",
"fast": "celer",
"fantastic": "mirificus",
"enlightened": "illuminatus",
"first": "primus",
"homemade": "domi factus"
"free": "libera",
"fast": "celeris",
"fantastic": "mirifica",
"enlightened": "illuminata",
"first": "prima",
"homemade": "domi facta"
},
"subtitle": "Optio {{word}}",
"loginAsTestUser": "In parte investigatoris nomen dare",
@ -34,7 +34,13 @@
"a11y_change_language": "Linguam legere",
"a11y_image_two_boys": "Pictura duobus hominibus telephona sua specientibus",
"a11y_clear_social_security_input_field": "Cellam numeri personalis vacuare",
"chooseSchoolPlatform": "Rostra legere"
"chooseSchoolPlatform": "Rostra legere",
"loginSuccessful": "Nomen tuum datum est, carricans…",
"freja": {
"OpenManually": "Manualiter Freja eID+ aperire",
"Waiting": "Freja eID+ exspectans…",
"OpenOnThisDevice": "In hac machina Freja eID+ aperire"
}
},
"abscense": {
"title": "Absentiam referre",
@ -138,7 +144,7 @@
"licenses": "Licentiae",
"appearance": "Species",
"language": "Lingua",
"themeAuto": "Automatus",
"themeAuto": "Automato",
"useSystemTheme": "Themate lucido/obscuro systemae uti",
"settings": "Configurationes",
"theme": "Thema"

View File

@ -10,7 +10,8 @@
"socialSecurityNumber": "Burgerservicenummer",
"cancel": "Annuleren",
"logoutAndClearAllDataInclSettings": "Log uit en wis alle gegevens inclusief instellingen",
"logoutAndClearPersonalData": "Uitloggen en persoonlijke gegevens wissen"
"logoutAndClearPersonalData": "Uitloggen en persoonlijke gegevens wissen",
"tomorrow": "Morgen"
},
"auth": {
"placeholder_SocialSecurityNumber": "Jouw burgerservicenummer",
@ -46,7 +47,14 @@
"a11y_select_login_method": "Selecteer de inlogmethode",
"a11y_clear_social_security_input_field": "Wis het veld voor het burgerservicenummer",
"a11y_image_two_boys": "Foto van twee mensen die naar hun mobiele telefoons kijken",
"a11y_change_language": "Selecteer je taal"
"a11y_change_language": "Selecteer je taal",
"chooseSchoolPlatform": "Platform kiezen",
"freja": {
"OpenManually": "Freja eID+ handmatig openen",
"Waiting": "Wachten op Freja eID+…",
"OpenOnThisDevice": "Freja eID+ openen op dit apparaat"
},
"loginSuccessful": "Inloggen gelukt, laden…"
},
"abbrevations": {
"preSchool": "Peuterschool",
@ -98,7 +106,9 @@
"approveAccessToCalender": "Je moet de toegang tot je agenda goedkeuren",
"saveToCalenderError": "Er is iets fout gegaan",
"saveToCalenderSuccess": "✔️ Opgeslagen in kalender",
"saveToCalender": "Opslaan in kalender"
"saveToCalender": "Opslaan in kalender",
"emptyHeadline": "De kalender ziet er nogal leeg uit",
"emptyText": "Kon niets vinden om te laten zien"
},
"notifications": {
"notificationTitle": "Melding: {{message}} ({{dateCreated}})"
@ -114,10 +124,11 @@
"end": "Eind",
"gymBag": "Sporttas",
"lunch": "Middageten",
"start": "Start"
"start": "Start",
"week": "Week"
},
"contact": {
"a11y_show_contact_info_button_hint": "Toon contactgegevens",
"a11y_show_contact_info_button_hint": "Toont contactgegevens",
"email": "E-mail",
"home": "Adres",
"call": "Telefoongesprek",

View File

@ -56,7 +56,8 @@
"a11y_clear_social_security_input_field": "Wyczyść pole z personnumerem",
"a11y_image_two_boys": "Ilustracja: dwie osoby patrzą w telefony komórkowe",
"a11y_change_language": "Wybierz język",
"chooseSchoolPlatform": "Wybierz platformę"
"chooseSchoolPlatform": "Wybierz platformę",
"loginSuccessful": "Logowanie powiodło się. Trwa ładowanie…"
},
"calender": {
"approveAccessToCalender": "Musisz zatwierdzić dostęp do kalendarza",

View File

@ -35,7 +35,10 @@
"subtitle": "ทางเลือกที่{{word}}",
"placeholder_SocialSecurityNumber": "เลขบัตรประจำตัวประชาชนของคุณ",
"a11y_change_language": "เลือกภาษา",
"a11y_select_login_method": "เลือกวิธีการเข้าสู่ระบบ"
"a11y_select_login_method": "เลือกวิธีการเข้าสู่ระบบ",
"freja": {
"Waiting": "กำลังรอ Freja eID+…"
}
},
"language": {
"changeLanguageButton": "บันทึก",

View File

@ -51,7 +51,12 @@
"a11y_change_language": "Оберіть вашу мову",
"a11y_image_two_boys": "Зображення двох людей, які перевіряють свої телефони",
"a11y_clear_social_security_input_field": "Очистити поле вводу ідентифікаційного номера",
"a11y_select_login_method": "Оберіть як увійти"
"a11y_select_login_method": "Оберіть як увійти",
"freja": {
"Waiting": "Очікую на Freja eID+…",
"OpenManually": "Відкрити Freja eID+ власноруч",
"OpenOnThisDevice": "Відкрити Freja eID+ на цьому пристрої"
}
},
"calender": {
"approveAccessToCalender": "Вам потрібно дозволити доступ до вашого календаря",

View File

@ -51,14 +51,22 @@
"a11y_change_language": "选择您的语言",
"a11y_image_two_boys": "两个人看手机的图片",
"a11y_select_login_method": "选择登录方式",
"chooseSchoolPlatform": "选择平台"
"chooseSchoolPlatform": "选择平台",
"freja": {
"OpenManually": "手动打开 Freja eID+",
"OpenOnThisDevice": "在此设备上打开 Freja eID+",
"Waiting": "正在等待 Freja eID+ 响应…"
},
"loginSuccessful": "登录成功,正在加载…"
},
"calender": {
"saveToCalender": "保存到日历中",
"saveToCalenderError": "出了点问题",
"saveToCalenderSuccess": "✔️ 已保存到日历中",
"showCalenderActions": "显示日历操作",
"approveAccessToCalender": "您必须允许访问日历"
"approveAccessToCalender": "您必须允许访问日历",
"emptyHeadline": "日历看起来有点空",
"emptyText": "找不到任何可以显示的东西"
},
"children": {
"loadingErrorHeading": "啊噢!",
@ -80,7 +88,8 @@
"send": "发送",
"socialSecurityNumber": "个人身份号码",
"title": "开放学校平台",
"settings": "设置"
"settings": "设置",
"tomorrow": "明天"
},
"language": {
"changeLanguage": "更改语言",
@ -128,7 +137,8 @@
"start": "开始",
"end": "结束",
"lunch": "午餐",
"gymBag": "健身袋"
"gymBag": "健身袋",
"week": "星期"
},
"classmates": {
"class": "课堂",

View File

@ -0,0 +1,2 @@
k8s
k8s

44
apps/website/Dockerfile Normal file
View File

@ -0,0 +1,44 @@
# Install dependencies only when needed
FROM node:16-alpine AS builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat autoconf automake build-base curl git libtool make nodejs npm pkgconf nasm yasm optipng
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn build
# Production image, copy all the files and run next
FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.* ./
COPY --from=builder /app/*.js ./
COPY --from=builder /app/*.ts ./
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
USER nextjs
EXPOSE 3000
ENV PORT 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]

View File

@ -56,6 +56,11 @@ const Footer = () => {
Integritetspolicy
</Link.Internal>
</li>
<li>
<Link.Internal href="/integritetspolicy-elevapp">
Integritetspolicy ElevApp
</Link.Internal>
</li>
<li>
<Link.Internal href="/qa">Frågor och svar</Link.Internal>
</li>

View File

@ -3,7 +3,7 @@ import DownloadButtons from './DownloadButtons'
import Icon from './Icon'
import SectionTitle from './SectionTitle'
export const price = 11
export const price = 0
const baseFeatures = [
{

View File

@ -17,6 +17,14 @@ const baseFeatures = [
included: true,
title: 'Se notifieringar',
},
{
included: true,
title: 'Se klasslista',
},
{
included: true,
title: 'Se schema',
},
{
included: false,
title: 'Gratis support',
@ -32,17 +40,12 @@ const Pricing = () => {
<section className="px-5 py-8 md:px-0 md:py-32" id="vad-kostar-det">
<div className="max-w-2xl mx-auto">
<SectionTitle
title="Varför inte gratis?"
text={`
Vi som bygger appen vill gärna fortsätta vidareutveckla den och även ha möjlighet att ge ersättning
till de som hjälper till. Vi gjorde ett försök att ge ut appen gratis och hoppades att fler kunde stötta oss via
Patreon istället. Det visade sig inte vara hållbart men om vi får fler sponsorer kommer vi göra appen gratis igen!
`}
title="Appen är Gratis,"
text={`samtidigt, för att kunna fortsätta utveckla och bibehålla appens kvalitet så länge som möjligt, skulle vi uppskatta mycket om du bidrar på Patreon!`}
/>
</div>
<div className="flex">
<div className="flex flex-col items-center inline-block px-5 py-8 mx-auto text-center shadow-lg rounded-md dark:bg-gray-800">
<h3 className="text-3xl text-gray-800 dark:text-gray-400">Just nu</h3>
<div className="mt-5 text-6xl text-pink-500">
{formatPrice(price)}
</div>

View File

@ -87,7 +87,7 @@ const Privacy = () => {
<p>
Denna integritetspolicy gäller fr.o.m. 2021-09-13. Ändringar i denna
policy finns dokumenterade vår{' '}
<Link.External href="https://github.com/kolplattformen/skolplattformen-app/">
<Link.External href="https://github.com/kolplattformen/skolplattformen/">
GitHub
</Link.External>
.

View File

@ -0,0 +1,105 @@
import Link from './Link'
const PrivacyElevApp = () => {
return (
<div>
<div className="max-w-6xl mx-auto px-5 md:px-0 my-5 md:my-24 prose dark:prose-dark">
<h1>Öppna Elevappen</h1>
<h2>Integritetspolicy</h2>
<p>
"Öppna Elevappen", hädanefter "appen", byggs av "Not free beer
AB" som en kommersiell app. Appen hämtar all information från
respektive skolplattform, hädanefter Skolplattformen, efter
inloggning via respektive plattforms inloggningsmetod. Appens funktion är därmed direkt knuten till
att Skolplattformen fungerar. Vi kan endast ta ansvar för att vår kod
fungerar inte deras.
</p>
<p>
Denna sida är till för att informera våra besökare och användare om
våra policies gällande insamling och hantering av personlig
information från användare av tjänsten.
</p>
<h3>TLDR (~kort sammanfattning ren svenska)</h3>
<p>
All information i appen kommer från Skolplattformen. Informationen
lämnar aldrig din telefon. Vi är snudd integritetsfanatiker och
skulle aldrig drömma om att samla in information om dig eller dina
barn. Det enda som lagras är sånt som lagras i din telefon för att det
ska snabbare att använda appen. Om vi börjar samla loggar för att
lättare kunna lösa eventuella buggar kommer vi se till att de inte
innehåller någon som helst information om dig - bara om koden.
</p>
<h3>Insamling och användning av personlig information</h3>
<p>
All information som hämtas visas endast för inloggad användare.
Informationen cacheas den mobila enheten. Ingen information skickas
från den mobila enheten eller lagras, analyseras eller processas någon
annanstans.
</p>
<p>
Inga tredjepartssystem har tillgång till någon del av informationen.
</p>
<h3>Loggning av data</h3>
<p>
För närvarande sker ingen loggning av data. Detta kan komma att
ändras. Om sker kommer loggad data att vara strikt begränsad till
systeminformation såsom namn mobil enhet och operativsystemversion
samt information om eventuella fel som uppstått i användningen. Ingen
personlig information härrörande från Skolplattformen kommer att
samlas in.
</p>
<h3>Cookies</h3>
<p>
Cookies är filer med små mängder data som används för att identifiera
användaren. Dessa används av Skolplattformen och skickas endast dit.
Cookies sparas lokalt i enheten och rensas när en inloggad session
avslutas.
</p>
<h3>Säkerhet</h3>
<p>
Vi har gjort vårt yttersta för att säkerställa säkerheten för din
information. Detta innebär i praktiken att vi aldrig skickar vidare
någon personlig data från din mobila enhet. All personlig information
levereras från Skolplattformen och därmed är du i slutänden hänvisad
till att lita säkerheten i det systemet. I fall vi, i arbetet
med att bygga denna app, har upptäckt potentiella svagheter i
Skolplattformen har vi vidtagit steg för att rapportera detta ett
ansvarsfullt sätt. Detta kommer vi göra även fortsättningsvis. Kom
ihåg att elektronisk lagring och överföring över Internet aldrig kan
garanteras vara 100% säker.
</p>
<h3>Integritet för barn</h3>
<p>
Appen läser information från system som hanterar barn under 13 år.
Oavsett barnets ålder skickar vi ingen information vidare från din
enhet. Den information du får tillgång via appen är samma som du når
via Skolplattformen.
</p>
<h3>Förändringar av integritetspolicyn</h3>
<p>
Denna integritetspolicy kan komma att uppdateras. Eftersom vi inte
samlar in någon information om våra användare kan vi tyvärr inte
kontakta dig om sker. Vi kommer dock informera om det i appen. Om
du vill vara den säkra sidan kan du återbesöka den här sidan och
.
</p>
<p>
Denna integritetspolicy gäller fr.o.m. 2024-04-29. Ändringar i denna
policy finns dokumenterade vår{' '}
<Link.External href="https://github.com/kolplattformen/skolplattformen/">
GitHub
</Link.External>
.
</p>
<h3>Kontakta oss</h3>
<p>
Tveka inte att kontakta oss om du har några frågor eller förslag till
förbättringar av denna integritetspolicy. Skicka ett mail till{' '}
<a href="mailto:dev@skolplattformen.org">dev@skolplattformen.org</a>.
</p>
</div>
</div>
)
}
export default PrivacyElevApp

View File

@ -251,13 +251,11 @@ const QA = () => {
de?
</h3>
<p>
Appen kostar {price} kronor. Intäkten registreras i aktiebolaget Not Free
Beer som ägs av tre av utvecklarna och går till att täcka kostnader
för inköp. Det täcker inte långa vägar den tid vi lagt ner. Med en
låg engångskostnad ökar vi chansen att vi orkar syssla med underhåll
och uppdateringar. Vi vill ju ha en stabil lösning som håller. Just nu
jobbar vi egen fritid med något som förbättrar det kommunen lagt en
miljard av allmänna medel .
Vi har en Patreon där summan är synlig. Intäkten registreras i
aktiebolaget Not Free Beer som ägs av tre av utvecklarna och går till
att täcka kostnader för inköp. Det täcker inte långa vägar den tid
vi lagt ner. Just nu jobbar vi egen fritid med något som förbättrar
det kommunen lagt en miljard av allmänna medel .
</p>
<h3>
Är det moraliskt att tjäna pengar något som kommunen borde erbjuda
@ -311,13 +309,13 @@ const QA = () => {
Det är en anspelning hur GNU-projektet beskriver fri programvara:
To understand the concept, you should think of free as in free
speech, not as in free beer. vi har valt att tillgängliggöra all
kod som öppen källkod (Apache 2.0) men ändå ta betalt för appen,
tyckte vi att namnet var passande.
kod som öppen källkod (Apache 2.0), tyckte vi att namnet var passande.
</p>
<h3>Kontakta oss</h3>
<p>
Tveka inte att kontakta oss. Skicka ett mail till{' '}
<a href="mailto:info@skolplattformen.org">info@skolplattformen.org</a>.
<a href="mailto:info@skolplattformen.org">info@skolplattformen.org</a>
.
</p>
</div>
</div>

View File

@ -16,13 +16,13 @@ const Status = () => {
<ul>
<li>Skicka en tweet 🥉</li>
<li>
<a href="https://github.com/kolplattformen/skolplattformen-app/issues">
<a href="https://github.com/kolplattformen/skolplattformen/issues">
Lägg en buggrapport här
</a>{' '}
🥈
</li>
<li>
<a href="https://github.com/kolplattformen/skolplattformen-app/pulls">
<a href="https://github.com/kolplattformen/skolplattformen/pulls">
Skicka en PR
</a>{' '}
🥇

View File

@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- web.yaml

93
apps/website/k8s/web.yaml Normal file
View File

@ -0,0 +1,93 @@
apiVersion: v1
kind: Namespace
metadata:
name: skolplattformen-web
---
apiVersion: v1
kind: Service
metadata:
name: skolplattformen-web
namespace: skolplattformen-web
spec:
ports:
- port: 3000
type: ClusterIP
selector:
app: skolplattformen-web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: skolplattformen-web
namespace: skolplattformen-web
spec:
selector:
matchLabels:
app: skolplattformen-web
template:
metadata:
labels:
app: skolplattformen-web
spec:
containers:
- name: skolplattformen-web
resources:
requests:
cpu: 100m
memory: 100Mi
image: ghcr.io/kolplattformen/skolplattformen
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: skolplattformen-web
namespace: skolplattformen-web
annotations:
cert-manager.io/cluster-issuer: 'letsencrypt-prod'
nginx.ingress.kubernetes.io/from-to-www-redirect: 'true'
nginx.ingress.kubernetes.io/http2-push-preload: 'true'
nginx.ingress.kubernetes.io/proxy-body-size: '500m'
nginx.ingress.kubernetes.io/proxy-pass-headers: 'Location'
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Xss-Protection: 0";
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload";
more_set_headers "Cross-Origin-Resource-Policy: same-site";
more_set_headers "Referrer-Policy strict-origin";
external-dns.alpha.kubernetes.io/hostname: new.skolplattformen.org.
spec:
ingressClassName: nginx
tls:
- hosts:
- skolplattformen.org
- www.skolplattformen.org
secretName: web-secret-tls
rules:
- host: skolplattformen.org
http:
paths:
- pathType: Prefix
path: '/'
backend:
service:
name: skolplattformen-web
port:
number: 3000

View File

@ -1,6 +1,6 @@
{
"name": "skolplattformen-site",
"version": "1.0.0",
"version": "1.0.4",
"main": "index.js",
"license": "MIT",
"dependencies": {

View File

@ -0,0 +1,8 @@
import { NextPage } from 'next'
import PrivacyElevApp from '../components/PrivacyElevApp'
const IntegrityElevAppPage: NextPage = () => {
return <PrivacyElevApp />
}
export default IntegrityElevAppPage

View File

@ -0,0 +1,13 @@
apiVersion: skaffold/v4beta1
kind: Config
metadata:
name: skolplattformen-web
build:
artifacts:
- image: skolplattformen/web
context: .
manifests:
rawYaml:
- k8s/web.yaml
deploy:
kubectl: {}

View File

@ -49,7 +49,7 @@ For more information, please visit [CocoaPods Getting Started guide](https://gui
### Running on a device
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://reactnative.dev/docs/running-on-device.
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://reactnative.dev/docs/running-on-device).
## Running the app

View File

@ -1,5 +1,5 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"extends": ["@react-native-community","plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "public", ".cache", "node_modules"],
"overrides": [
{

View File

@ -1,29 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`handles route calender 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/Calender/GetSchoolCalender?childId=123&rowLimit=50"`;
exports[`handles route calender 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/Calender/GetSchoolCalender?childId=123&rowLimit=50"`;
exports[`handles route children 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/GetChildren"`;
exports[`handles route children 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/GetChildren"`;
exports[`handles route classmates 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/contacts/GetStudentsByClass?studentId=123"`;
exports[`handles route classmates 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/contacts/GetStudentsByClass?studentId=123"`;
exports[`handles route image 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/NewsBanner?url=https://example.com/img.png"`;
exports[`handles route image 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/NewsBanner?url=https://example.com/img.png"`;
exports[`handles route login with personal number 1`] = `"https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&initialize=bankid&personalNumber=201701012393&_=1618404258782"`;
exports[`handles route login with personal number 1`] = `"https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d&initialize=bankid&personalNumber=201701012393&_=1618404258782"`;
exports[`handles route login without personal number 1`] = `"https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&initialize=bankid&_=1618404258782"`;
exports[`handles route login without personal number 1`] = `"https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d&initialize=bankid&_=1618404258782"`;
exports[`handles route menuChoice 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelChoice?childId=123"`;
exports[`handles route menuChoice 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelChoice?childId=123"`;
exports[`handles route menuList 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelList?childId=123"`;
exports[`handles route menuList 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelList?childId=123"`;
exports[`handles route menuRss 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelRSS?childId=123"`;
exports[`handles route menuRss 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/Matsedel/GetMatsedelRSS?childId=123"`;
exports[`handles route news 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/News/GetNewsArchive?bannerImageLimit=5000&childId=123"`;
exports[`handles route news 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/News/GetNewsArchive?bannerImageLimit=5000&childId=123"`;
exports[`handles route newsDetails 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/News/GetNewsArticle?newsItemId=321&childId=123"`;
exports[`handles route newsDetails 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/News/GetNewsArticle?newsItemId=321&childId=123"`;
exports[`handles route notifications 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/notifications/getnotifications?childId=123"`;
exports[`handles route notifications 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/notifications/getnotifications?childId=123"`;
exports[`handles route schedule 1`] = `"https://etjanst.stockholm.se/vardnadshavare/inloggad2/Calender/GetSchema?childId=123&startDate=2021-01-01&endDate=2021-01-01"`;
exports[`handles route schedule 1`] = `"https://etjanster.stockholm.se/vardnadshavare/inloggad2/Calender/GetSchema?childId=123&startDate=2021-01-01&endDate=2021-01-01"`;
exports[`handles route user 1`] = `"https://etjanst.stockholm.se/vardnadshavare/base/getuserdata"`;
exports[`handles route user 1`] = `"https://etjanster.stockholm.se/vardnadshavare/base/getuserdata"`;

View File

@ -1,6 +1,6 @@
import QueueFetcher from '../queue/queueFetcher'
let sut : QueueFetcher
let sut: QueueFetcher
beforeEach(() => {
jest.useFakeTimers('legacy')
sut = new QueueFetcher(async () => '')

View File

@ -44,8 +44,9 @@ describe('api', () => {
token: '9462cf77-bde9-4029-bb41-e599f3094613',
order: '5fe57e4c-9ad2-4b52-b794-48adef2f6663',
}
const pending = { state: 'PENDING' }
response.json.mockResolvedValue(data)
response.text.mockResolvedValue('PENDING')
response.json.mockResolvedValue(pending)
const personalNumber = 'my personal number'
api.login(personalNumber).then((status) => {
@ -60,14 +61,16 @@ describe('api', () => {
token: '9462cf77-bde9-4029-bb41-e599f3094613',
order: '5fe57e4c-9ad2-4b52-b794-48adef2f6663',
}
const pending = { state: 'PENDING' }
const ok = { state: 'OK' }
response.json.mockResolvedValue(data)
response.text.mockResolvedValueOnce('PENDING')
response.text.mockResolvedValueOnce('OK')
response.json.mockResolvedValueOnce(pending)
response.json.mockResolvedValueOnce(ok)
const personalNumber = 'my personal number'
api.login(personalNumber).then((status) => {
status.on('OK', () => {
expect(fetch).toHaveBeenCalledTimes(4)
expect(fetch).toHaveBeenCalledTimes(3)
done()
})
})
@ -89,8 +92,9 @@ describe('api', () => {
token: '9462cf77-bde9-4029-bb41-e599f3094613',
order: '5fe57e4c-9ad2-4b52-b794-48adef2f6663',
}
const error = { state: 'ERROR' }
response.json.mockResolvedValue(data)
response.text.mockResolvedValueOnce('ERROR')
response.json.mockResolvedValue(error)
const personalNumber = 'my personal number'
api.login(personalNumber).then((status) => {
@ -112,7 +116,7 @@ describe('api', () => {
const personalNumber = 'my personal number'
try {
await api.login(personalNumber)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
expect(error.message).toEqual(expect.stringContaining('Server Error'))
}

View File

@ -44,12 +44,12 @@ const s24Init = {
headers: {
accept: 'application/json, text/javascript, */*; q=0.01',
referer:
'https://fns.stockholm.se/ng/timetable/timetable-viewer/fns.stockholm.se/',
'https://websthlm.skola24.se/ng/timetable/timetable-viewer/fns.stockholm.se/',
'accept-language': 'en-US,en;q=0.9,sv;q=0.8',
'cache-control': 'no-cache',
'content-type': 'application/json',
pragma: 'no-cache',
host: 'fns.stockholm.se',
host: 'websthlm.skola24.se',
'x-scope': '8a22163c-8662-4535-9050-bc5e1923df48',
},
}
@ -99,16 +99,17 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
}
}
public async getSessionHeaders(url: string): Promise<{ [index: string]: string }> {
public async getSessionHeaders(
url: string
): Promise<{ [index: string]: string }> {
const init = this.getRequestInit()
const cookie = await this.cookieManager.getCookieString(url)
return {
...init.headers,
cookie,
...init.headers,
cookie,
}
}
public async getSession(
url: string,
options?: RequestInit
@ -157,7 +158,10 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
status.on('OK', async () => {
await this.retrieveSessionCookie()
const [user, ] = await Promise.all([this.getUser(), this.retrieveXsrfToken()])
const [user] = await Promise.all([
this.getUser(),
this.retrieveXsrfToken(),
])
this.personalNumber = user.personalNumber
this.isLoggedIn = true
@ -171,14 +175,11 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
}
public async loginFreja(): Promise<FrejaLoginStatusChecker> {
await this.clearSession()
const loginUrl = routes.frejaLogin
const loginResponse = await this.fetch('auth-ticket', loginUrl)
// if (!ticketResponse.ok) {
// throw new Error(
// `Server Error [${ticketResponse.status}] [${ticketResponse.statusText}] [${ticketUrl}]`
@ -190,15 +191,21 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
console.log('getting freja login url: ' + cleanAppSwitchUrl)
const checkStatusSession = await this.getSession(loginUrl, {
const checkStatusSession = await this.getSession(loginUrl, {
redirect: 'manual',
})
const status = checkFrejaStatus(this.fetch, cleanAppSwitchUrl, checkStatusSession)
const status = checkFrejaStatus(
this.fetch,
cleanAppSwitchUrl,
checkStatusSession
)
status.on('APPROVED', async () => {
await this.retrieveFrejaSessionCookie()
const [user, ] = await Promise.all([this.getUser(), this.retrieveXsrfToken()])
const [user] = await Promise.all([
this.getUser(),
this.retrieveXsrfToken(),
])
this.personalNumber = user.personalNumber
this.isLoggedIn = true
@ -213,7 +220,6 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
return parts[0]
}
public async setSessionCookie(sessionCookie: string): Promise<void> {
// Manually set cookie in this call and let the cookieManager
// handle it from here
@ -238,27 +244,22 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
}
private async retrieveSessionCookie(): Promise<void> {
const url = routes.loginCookie
await this.fetch('login-cookie', url)
}
private async retrieveFrejaSessionCookie(): Promise<void> {
try{
try {
const url = routes.frejaReturnUrl
await this.fetch('freja-login-return-url', url)
} catch(error){
} catch (error) {
console.log(JSON.stringify(error))
}
try{
try {
const url2 = routes.frejaLoginCookie
const session = await this.getSession(url2, {
redirect: 'manual',
})
await this.fetch('freja-login-cookie', url2)
} catch(error2){
await this.fetch('freja-login-cookie', url2)
} catch (error2) {
console.log(JSON.stringify(error2))
}
}
@ -306,9 +307,9 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
const url = routes.children
const session = this.getRequestInit({
headers: {
Accept: 'application/json;odata=verbose',
Host: 'etjanst.stockholm.se',
Referer: 'https://etjanst.stockholm.se/vardnadshavare/inloggad2/hem',
Accept: 'application/json, text/plain, */*',
Host: 'etjanster.stockholm.se',
Referer: 'https://etjanster.stockholm.se/vardnadshavare/inloggad2/hem',
},
})
const response = await this.fetch('children', url, session)
@ -322,10 +323,14 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
const data = await response.json()
const parsed = parse.children(data)
const useSpecialQueueModeForFSChildren = parsed.some((c) => (c.status || '').includes('FS'))
const useSpecialQueueModeForFSChildren = parsed.some((c) =>
(c.status || '').includes('FS')
)
if(useSpecialQueueModeForFSChildren) {
this.fetch = queueFetcherWrapper(this.fetch, (childId) => this.selectChildById(childId))
if (useSpecialQueueModeForFSChildren) {
this.fetch = queueFetcherWrapper(this.fetch, (childId) =>
this.selectChildById(childId)
)
}
return parsed
@ -359,23 +364,26 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
const schoolForms = (child.status || '').split(';')
let teachers: Teacher[] = []
for(let i = 0; i< schoolForms.length; i+=1){
for (let i = 0; i < schoolForms.length; i += 1) {
const url = routes.teachers(child.sdsId, schoolForms[i])
// eslint-disable-next-line no-await-in-loop
const response = await this.fetch(`teachers_${schoolForms[i]}`, url, session)
// eslint-disable-next-line no-await-in-loop
const response = await this.fetch(
`teachers_${schoolForms[i]}`,
url,
session
)
const data = await response.json()
teachers = [
...teachers,
...parse.teachers(data)
]
teachers = [...teachers, ...parse.teachers(data)]
}
return teachers
}
public async getSchoolContacts(child: EtjanstChild): Promise<SchoolContact[]> {
if(this.isFake) return fakeResponse(fake.schoolContacts(child))
public async getSchoolContacts(
child: EtjanstChild
): Promise<SchoolContact[]> {
if (this.isFake) return fakeResponse(fake.schoolContacts(child))
const url = routes.schoolContacts(child.sdsId, child.schoolId || '')
const session = this.getRequestInit()
@ -411,7 +419,6 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
return parse.news(data)
}
// eslint-disable-next-line class-methods-use-this
private CheckResponseForCorrectChildStatus(
response: Response,
child: EtjanstChild
@ -432,7 +439,12 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
item: NewsItem
): Promise<NewsItem | undefined> {
if (this.isFake) {
return fakeResponse(fake.news(child).find((ni) => ni.id === item.id) || {id: "", published: ""})
return fakeResponse(
fake.news(child).find((ni) => ni.id === item.id) || {
id: '',
published: '',
}
)
}
const url = routes.newsDetails(child.id, item.id)
const session = this.getRequestInit()
@ -558,7 +570,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
await this.ssoAuthorize('TimetableViewer')
const body = {
getPersonalTimetablesRequest: {
hostName: 'fns.stockholm.se',
hostName: 'stockholm.skola24.se',
},
}
const session = this.getRequestInit({
@ -574,7 +586,6 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
getPersonalTimetablesResponse: { childrenTimetables },
},
} = await response.json()
return childrenTimetables as Skola24Child[]
}
@ -607,7 +618,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
customerKey: '',
endDate: null,
height: 1063,
host: 'fns.stockholm.se',
host: 'stockholm.skola24.se',
periodText: '',
privateFreeTextMode: null,
privateSelectionMode: true,
@ -621,6 +632,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
week,
width: 1227,
year,
schoolYear: 'b976f986-4308-4583-b39e-2d3933094eb2',
}
const session = this.getRequestInit({
...s24Init,
@ -637,7 +649,7 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
return parse.timetable(json, year, week, lang)
}
public async selectChild(child : EtjanstChild): Promise<EtjanstChild> {
public async selectChild(child: EtjanstChild): Promise<EtjanstChild> {
const response = await this.selectChildById(child.id)
const data = await response.json()
@ -660,7 +672,11 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
}),
})
const response = await this.fetch('selectChild', routes.selectChild, requestInit)
const response = await this.fetch(
'selectChild',
routes.selectChild,
requestInit
)
return response
}

View File

@ -1,4 +1,4 @@
import { EtjanstChild, Skola24Child } from "@skolplattformen/api"
import { EtjanstChild, Skola24Child } from '@skolplattformen/api'
export const children = (): EtjanstChild[] => [
{
@ -24,6 +24,6 @@ export const skola24Children = (): Skola24Child[] => [
schoolGuid: 'def456',
schoolID: 'Superskolan',
timetableID: 'jkl012',
unitGuid: 'mno345'
unitGuid: 'mno345',
},
]

View File

@ -1,448 +1,452 @@
import { Child, Classmate } from '@skolplattformen/api';
import { Child, Classmate } from '@skolplattformen/api'
import { children } from './children'
export const classmates = (child: Child): Classmate[] => classmatesData.get(child.id) ?? []
export const classmates = (child: Child): Classmate[] =>
classmatesData.get(child.id) ?? []
const [child1, child2] = children()
const classmatesData = new Map<string, Classmate[]>([
[
child1.id, [
{
sisId: 'd004a-98d965a-45174-d2894ca2-f74ebcb',
firstname: 'Darion',
lastname: 'Gustafsson',
guardians: [
{
email: 'Mike_Svensson@example.net',
firstname: 'Tad',
lastname: 'Eriksson',
mobile: '07074791613',
address: 'Martinvägen 50',
},
],
className: '2B',
},
{
sisId: '54075-284de06-5664c-750b7b13-520fb61',
firstname: 'Brock',
lastname: 'Andersson',
guardians: [
{
email: 'Brad56@example.org',
firstname: 'Camren',
lastname: 'Eriksson',
mobile: '07075129297',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'c1fc7-285f95d-c0f37-ea48a297-281e985',
firstname: 'Eloy',
lastname: 'Karlsson',
guardians: [
{
email: 'Samara.Larsson@example.net',
firstname: 'Ike',
lastname: 'Gustafsson',
mobile: '07077667407',
address: undefined,
},
],
className: '2B',
},
{
sisId: '212e9-8a2609c-b29c1-97a32bd8-5f84645',
firstname: 'Kristina',
lastname: 'Eriksson',
guardians: [
{
email: 'Doug57@example.com',
firstname: 'Rollin',
lastname: 'Olsson',
mobile: '07071720107',
address: 'Höckertsvägen 2',
},
],
className: '2B',
},
{
sisId: '01d21-ebc6f8b-526f8-7cfba0ab-26b9956',
firstname: 'Cydney',
lastname: 'Larsson',
guardians: [
{
email: 'Davon6@example.org',
firstname: 'Oleta',
lastname: 'Svensson',
mobile: '07079762186',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'a45bb-8a481af-0ad12-7bd1fa4c-1eed4b1',
firstname: 'Berneice',
lastname: 'Persson',
guardians: [
{
email: 'Milford_Johansson72@example.com',
firstname: 'Arely',
lastname: 'Johansson',
mobile: '07071926019',
address: 'Roslinvägen 36',
},
],
className: '2B',
},
{
sisId: '32f31-039fbed-9060b-2d857c46-e47177d',
firstname: 'Emory',
lastname: 'Svensson',
guardians: [
{
email: 'Alfredo_Nilsson96@example.org',
firstname: 'Dolores',
lastname: 'Andersson',
mobile: '070752561937',
address: 'Börjesonsvägen 6',
},
],
className: '2B',
},
{
sisId: 'c9d0a-28c371d-e7be2-9781386b-6841eb0',
firstname: 'Maryjane',
lastname: 'Eriksson',
guardians: [
{
email: 'Eula_Olsson@example.net',
firstname: 'Wendy',
lastname: 'Andersson',
mobile: '07078513037',
address: undefined,
},
{
email: 'Lesley_Persson45@example.org',
firstname: 'Erich',
lastname: 'Persson',
mobile: '070788191316',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'e0f51-3fbd0be-5a8c3-ded7bbed-1d655d5',
firstname: 'Rosendo',
lastname: 'Eriksson',
guardians: [
{
email: 'Mitchell.Gustafsson84@example.org',
firstname: 'Mariam',
lastname: 'Johansson',
mobile: '07074537423',
address: 'Molinvägen 29',
},
{
email: 'Rachelle_Olsson@example.net',
firstname: 'Shaniya',
lastname: 'Persson',
mobile: '070765878480',
address: 'Molinvägen 29',
},
],
className: '2B',
},
{
sisId: '298c2-46a24d4-548b9-3d1f90ee-4fae0ab',
firstname: 'Sammy',
lastname: 'Persson',
guardians: [
{
email: 'Gloria_Svensson@example.com',
firstname: 'Simeon',
lastname: 'Olsson',
mobile: '070753525610',
address: 'Börjesonsvägen 43',
},
],
className: '2B',
},
{
sisId: 'e7628-09352ea-b5d19-1af845b7-63b3e08',
firstname: 'Abraham',
lastname: 'Svensson',
guardians: [
{
email: 'Erica_Johansson40@example.net',
firstname: 'Carlotta',
lastname: 'Nilsson',
mobile: '070737951712',
address: 'Aroseniusvägen 27',
},
{
email: 'Malcolm_Gustafsson55@example.org',
firstname: 'Ramon',
lastname: 'Persson',
mobile: '07070395626',
address: 'Aroseniusvägen 27',
},
],
className: '2B',
},
{
sisId: 'ae315-4696438-b3db6-8f0a5b39-74e34bd',
firstname: 'Devante',
lastname: 'Olsson',
guardians: [
{
email: 'Alf.Johansson39@example.com',
firstname: 'Schuyler',
lastname: 'Gustafsson',
mobile: '07070724289',
address: undefined,
},
],
className: '2B',
},
{
sisId: '0d812-350f1d5-323aa-d5d93cdd-406e337',
firstname: 'Tyrell',
lastname: 'Eriksson',
guardians: [
{
email: 'Brennon.Svensson@example.com',
firstname: 'Belle',
lastname: 'Nilsson',
mobile: '07070137347',
address: undefined,
},
],
className: '2B',
},
]],
[
child2.id, [
{
sisId: '9ee9e-312233c-0df98-05fa5a65-a3787ec',
firstname: 'Raphael',
lastname: 'Olsson',
guardians: [
{
email: 'Johan99@example.com',
firstname: 'Alessandra',
lastname: 'Svensson',
mobile: '070767120463',
address: 'Franklandsvägen 34',
},
],
className: '8C',
},
{
sisId: 'd3a4b-16b53de-63c22-56d1ad24-4a64a2d',
firstname: 'Fanny',
lastname: 'Karlsson',
guardians: [
{
email: 'Bernadette.Eriksson@example.org',
firstname: 'Bernadette',
lastname: 'Karlsson',
mobile: '070759877956',
address: undefined,
},
{
email: 'Candice29@example.net',
firstname: 'Kelley',
lastname: 'Gustafsson',
mobile: '070748592035',
address: undefined,
},
],
className: '8C',
},
{
sisId: '42bde-8fabd1c-7a00e-28aea88a-8481bac',
firstname: 'Jamie',
lastname: 'Persson',
guardians: [
{
email: 'Louisa82@example.net',
firstname: 'Mose',
lastname: 'Larsson',
mobile: '07076548362',
address: undefined,
},
],
className: '8C',
},
{
sisId: 'dad49-74308c8-83612-5eb7f3a5-e1c4047',
firstname: 'Iris',
lastname: 'Eriksson',
guardians: [
{
email: 'Vaughn90@example.net',
firstname: 'Ezra',
lastname: 'Andersson',
mobile: '07078700165',
address: 'Björnsonsgatan 251 D Lgh 1503',
},
{
email: 'Stephany_Svensson22@example.net',
firstname: 'Mia',
lastname: 'Larsson',
mobile: '070761752378',
address: 'Björnsonsgatan 251 D Lgh 1503',
},
],
className: '8C',
},
{
sisId: 'b3425-ada6d70-d3acc-a49a12a6-8b3afdc',
firstname: 'Evans',
lastname: 'Nilsson',
guardians: [
{
email: 'Terry_Svensson@example.com',
firstname: 'Christop',
lastname: 'Olsson',
mobile: '070767660094',
address: undefined,
},
{
email: 'Johanna_Svensson30@example.org',
firstname: 'Madisen',
lastname: 'Johansson',
mobile: '07072269029',
address: undefined,
},
],
className: '8C',
},
{
sisId: '67471-6c03979-9ef6e-bb2827c4-96d00d5',
firstname: 'Evy',
lastname: 'Larsson',
guardians: [
{
email: 'Serenity.Gustafsson@example.net',
firstname: 'Toni',
lastname: 'Larsson',
mobile: '07075211567',
address: 'Roslinvägen 48',
},
],
className: '8C',
},
{
sisId: 'f4040-516c4ed-34555-fd525183-6a2f666',
firstname: 'Maximillia',
lastname: 'Karlsson',
guardians: [
{
email: 'Faustino.Andersson@example.com',
firstname: 'Eriberto',
lastname: 'Nilsson',
mobile: '07076024039',
address: 'Beckombergavägen 213 Lgh 1304',
},
],
className: '8C',
},
{
sisId: 'a9494-75d8ca7-a5fd4-977eca3c-40edbc1',
firstname: 'Pia',
lastname: 'Karlsson',
guardians: [
{
email: 'Arthur.Karlsson4@example.org',
firstname: 'Eldred',
lastname: 'Svensson',
mobile: '07077609534',
address: 'Börjesonsvägen 6',
},
],
className: '8C',
},
{
sisId: '42a6d-3eaf407-fed01-4a9538de-b822503',
firstname: 'Logan',
lastname: 'Larsson',
guardians: [
{
email: 'Blake4@example.org',
firstname: 'Jan',
lastname: 'Karlsson',
mobile: '070728715653',
address: 'Bällstavägen 162',
},
],
className: '8C',
},
{
sisId: '9077d-c323c8d-d0d29-5690abfb-d348317',
firstname: 'Torun',
lastname: 'Eriksson',
guardians: [
{
email: 'Blanca98@example.net',
firstname: 'Dallin',
lastname: 'Eriksson',
mobile: '070766214425',
address: 'Molinvägen 1',
},
],
className: '8C',
},
{
sisId: '31c68-5b86667-0701d-6b7e2471-89e6df9',
firstname: 'Izabella',
lastname: 'Johansson',
guardians: [
{
email: 'Elouise_Johansson25@example.org',
firstname: 'Jerrold',
lastname: 'Nilsson',
mobile: '07073789274',
address: 'Stobaeusvägen 11',
},
],
className: '8C',
},
{
sisId: '1bb69-5f1c3a6-f0ea8-e1dbb608-2756a52',
firstname: 'Ella',
lastname: 'Persson',
guardians: [
{
email: 'Shayna.Olsson54@example.net',
firstname: 'Onie',
lastname: 'Nilsson',
mobile: '07076957797',
address: undefined,
},
],
className: '8C',
},
{
sisId: '348a7-2d0eccc-02981-a02ccb03-cb2a8f2',
firstname: 'Jaylen',
lastname: 'Larsson',
guardians: [
{
email: 'Aileen_Andersson@example.net',
firstname: 'Tess',
lastname: 'Karlsson',
mobile: '070715315590',
address: 'Peringskiöldsvägen 64',
},
],
className: '8C',
}
child1.id,
[
{
sisId: 'd004a-98d965a-45174-d2894ca2-f74ebcb',
firstname: 'Darion',
lastname: 'Gustafsson',
guardians: [
{
email: 'Mike_Svensson@example.net',
firstname: 'Tad',
lastname: 'Eriksson',
mobile: '07074791613',
address: 'Martinvägen 50',
},
],
className: '2B',
},
{
sisId: '54075-284de06-5664c-750b7b13-520fb61',
firstname: 'Brock',
lastname: 'Andersson',
guardians: [
{
email: 'Brad56@example.org',
firstname: 'Camren',
lastname: 'Eriksson',
mobile: '07075129297',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'c1fc7-285f95d-c0f37-ea48a297-281e985',
firstname: 'Eloy',
lastname: 'Karlsson',
guardians: [
{
email: 'Samara.Larsson@example.net',
firstname: 'Ike',
lastname: 'Gustafsson',
mobile: '07077667407',
address: undefined,
},
],
className: '2B',
},
{
sisId: '212e9-8a2609c-b29c1-97a32bd8-5f84645',
firstname: 'Kristina',
lastname: 'Eriksson',
guardians: [
{
email: 'Doug57@example.com',
firstname: 'Rollin',
lastname: 'Olsson',
mobile: '07071720107',
address: 'Höckertsvägen 2',
},
],
className: '2B',
},
{
sisId: '01d21-ebc6f8b-526f8-7cfba0ab-26b9956',
firstname: 'Cydney',
lastname: 'Larsson',
guardians: [
{
email: 'Davon6@example.org',
firstname: 'Oleta',
lastname: 'Svensson',
mobile: '07079762186',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'a45bb-8a481af-0ad12-7bd1fa4c-1eed4b1',
firstname: 'Berneice',
lastname: 'Persson',
guardians: [
{
email: 'Milford_Johansson72@example.com',
firstname: 'Arely',
lastname: 'Johansson',
mobile: '07071926019',
address: 'Roslinvägen 36',
},
],
className: '2B',
},
{
sisId: '32f31-039fbed-9060b-2d857c46-e47177d',
firstname: 'Emory',
lastname: 'Svensson',
guardians: [
{
email: 'Alfredo_Nilsson96@example.org',
firstname: 'Dolores',
lastname: 'Andersson',
mobile: '070752561937',
address: 'Börjesonsvägen 6',
},
],
className: '2B',
},
{
sisId: 'c9d0a-28c371d-e7be2-9781386b-6841eb0',
firstname: 'Maryjane',
lastname: 'Eriksson',
guardians: [
{
email: 'Eula_Olsson@example.net',
firstname: 'Wendy',
lastname: 'Andersson',
mobile: '07078513037',
address: undefined,
},
{
email: 'Lesley_Persson45@example.org',
firstname: 'Erich',
lastname: 'Persson',
mobile: '070788191316',
address: undefined,
},
],
className: '2B',
},
{
sisId: 'e0f51-3fbd0be-5a8c3-ded7bbed-1d655d5',
firstname: 'Rosendo',
lastname: 'Eriksson',
guardians: [
{
email: 'Mitchell.Gustafsson84@example.org',
firstname: 'Mariam',
lastname: 'Johansson',
mobile: '07074537423',
address: 'Molinvägen 29',
},
{
email: 'Rachelle_Olsson@example.net',
firstname: 'Shaniya',
lastname: 'Persson',
mobile: '070765878480',
address: 'Molinvägen 29',
},
],
className: '2B',
},
{
sisId: '298c2-46a24d4-548b9-3d1f90ee-4fae0ab',
firstname: 'Sammy',
lastname: 'Persson',
guardians: [
{
email: 'Gloria_Svensson@example.com',
firstname: 'Simeon',
lastname: 'Olsson',
mobile: '070753525610',
address: 'Börjesonsvägen 43',
},
],
className: '2B',
},
{
sisId: 'e7628-09352ea-b5d19-1af845b7-63b3e08',
firstname: 'Abraham',
lastname: 'Svensson',
guardians: [
{
email: 'Erica_Johansson40@example.net',
firstname: 'Carlotta',
lastname: 'Nilsson',
mobile: '070737951712',
address: 'Aroseniusvägen 27',
},
{
email: 'Malcolm_Gustafsson55@example.org',
firstname: 'Ramon',
lastname: 'Persson',
mobile: '07070395626',
address: 'Aroseniusvägen 27',
},
],
className: '2B',
},
{
sisId: 'ae315-4696438-b3db6-8f0a5b39-74e34bd',
firstname: 'Devante',
lastname: 'Olsson',
guardians: [
{
email: 'Alf.Johansson39@example.com',
firstname: 'Schuyler',
lastname: 'Gustafsson',
mobile: '07070724289',
address: undefined,
},
],
className: '2B',
},
{
sisId: '0d812-350f1d5-323aa-d5d93cdd-406e337',
firstname: 'Tyrell',
lastname: 'Eriksson',
guardians: [
{
email: 'Brennon.Svensson@example.com',
firstname: 'Belle',
lastname: 'Nilsson',
mobile: '07070137347',
address: undefined,
},
],
className: '2B',
},
],
],
[
child2.id,
[
{
sisId: '9ee9e-312233c-0df98-05fa5a65-a3787ec',
firstname: 'Raphael',
lastname: 'Olsson',
guardians: [
{
email: 'Johan99@example.com',
firstname: 'Alessandra',
lastname: 'Svensson',
mobile: '070767120463',
address: 'Franklandsvägen 34',
},
],
className: '8C',
},
{
sisId: 'd3a4b-16b53de-63c22-56d1ad24-4a64a2d',
firstname: 'Fanny',
lastname: 'Karlsson',
guardians: [
{
email: 'Bernadette.Eriksson@example.org',
firstname: 'Bernadette',
lastname: 'Karlsson',
mobile: '070759877956',
address: undefined,
},
{
email: 'Candice29@example.net',
firstname: 'Kelley',
lastname: 'Gustafsson',
mobile: '070748592035',
address: undefined,
},
],
className: '8C',
},
{
sisId: '42bde-8fabd1c-7a00e-28aea88a-8481bac',
firstname: 'Jamie',
lastname: 'Persson',
guardians: [
{
email: 'Louisa82@example.net',
firstname: 'Mose',
lastname: 'Larsson',
mobile: '07076548362',
address: undefined,
},
],
className: '8C',
},
{
sisId: 'dad49-74308c8-83612-5eb7f3a5-e1c4047',
firstname: 'Iris',
lastname: 'Eriksson',
guardians: [
{
email: 'Vaughn90@example.net',
firstname: 'Ezra',
lastname: 'Andersson',
mobile: '07078700165',
address: 'Björnsonsgatan 251 D Lgh 1503',
},
{
email: 'Stephany_Svensson22@example.net',
firstname: 'Mia',
lastname: 'Larsson',
mobile: '070761752378',
address: 'Björnsonsgatan 251 D Lgh 1503',
},
],
className: '8C',
},
{
sisId: 'b3425-ada6d70-d3acc-a49a12a6-8b3afdc',
firstname: 'Evans',
lastname: 'Nilsson',
guardians: [
{
email: 'Terry_Svensson@example.com',
firstname: 'Christop',
lastname: 'Olsson',
mobile: '070767660094',
address: undefined,
},
{
email: 'Johanna_Svensson30@example.org',
firstname: 'Madisen',
lastname: 'Johansson',
mobile: '07072269029',
address: undefined,
},
],
className: '8C',
},
{
sisId: '67471-6c03979-9ef6e-bb2827c4-96d00d5',
firstname: 'Evy',
lastname: 'Larsson',
guardians: [
{
email: 'Serenity.Gustafsson@example.net',
firstname: 'Toni',
lastname: 'Larsson',
mobile: '07075211567',
address: 'Roslinvägen 48',
},
],
className: '8C',
},
{
sisId: 'f4040-516c4ed-34555-fd525183-6a2f666',
firstname: 'Maximillia',
lastname: 'Karlsson',
guardians: [
{
email: 'Faustino.Andersson@example.com',
firstname: 'Eriberto',
lastname: 'Nilsson',
mobile: '07076024039',
address: 'Beckombergavägen 213 Lgh 1304',
},
],
className: '8C',
},
{
sisId: 'a9494-75d8ca7-a5fd4-977eca3c-40edbc1',
firstname: 'Pia',
lastname: 'Karlsson',
guardians: [
{
email: 'Arthur.Karlsson4@example.org',
firstname: 'Eldred',
lastname: 'Svensson',
mobile: '07077609534',
address: 'Börjesonsvägen 6',
},
],
className: '8C',
},
{
sisId: '42a6d-3eaf407-fed01-4a9538de-b822503',
firstname: 'Logan',
lastname: 'Larsson',
guardians: [
{
email: 'Blake4@example.org',
firstname: 'Jan',
lastname: 'Karlsson',
mobile: '070728715653',
address: 'Bällstavägen 162',
},
],
className: '8C',
},
{
sisId: '9077d-c323c8d-d0d29-5690abfb-d348317',
firstname: 'Torun',
lastname: 'Eriksson',
guardians: [
{
email: 'Blanca98@example.net',
firstname: 'Dallin',
lastname: 'Eriksson',
mobile: '070766214425',
address: 'Molinvägen 1',
},
],
className: '8C',
},
{
sisId: '31c68-5b86667-0701d-6b7e2471-89e6df9',
firstname: 'Izabella',
lastname: 'Johansson',
guardians: [
{
email: 'Elouise_Johansson25@example.org',
firstname: 'Jerrold',
lastname: 'Nilsson',
mobile: '07073789274',
address: 'Stobaeusvägen 11',
},
],
className: '8C',
},
{
sisId: '1bb69-5f1c3a6-f0ea8-e1dbb608-2756a52',
firstname: 'Ella',
lastname: 'Persson',
guardians: [
{
email: 'Shayna.Olsson54@example.net',
firstname: 'Onie',
lastname: 'Nilsson',
mobile: '07076957797',
address: undefined,
},
],
className: '8C',
},
{
sisId: '348a7-2d0eccc-02981-a02ccb03-cb2a8f2',
firstname: 'Jaylen',
lastname: 'Larsson',
guardians: [
{
email: 'Aileen_Andersson@example.net',
firstname: 'Tess',
lastname: 'Karlsson',
mobile: '070715315590',
address: 'Peringskiöldsvägen 64',
},
],
className: '8C',
},
],
],
]
])

View File

@ -1,13 +1,13 @@
import { fourDaysAgo, oneDayAgo, oneWeekAgo } from './dates';
/* eslint-disable max-len */
import { fourDaysAgo, oneDayAgo, oneWeekAgo } from './dates'
import {
CalendarItem,
Child,
Notification,
ScheduleItem,
User,
} from '@skolplattformen/api';
import { oneDayForward, oneWeekForward, twoDaysForward } from './dates';
} from '@skolplattformen/api'
import { oneDayForward, oneWeekForward, twoDaysForward } from './dates'
const data: any = {
'39b59e-bf4b9f-f68ac25321-977218-bf0': {
@ -203,18 +203,17 @@ const data: any = {
allDayEvent: false,
startDate: oneDayForward.startOf('day').toISO(),
endDate: oneDayForward.endOf('day').toISO(),
oneDayEvent: true
} as ScheduleItem
oneDayEvent: true,
} as ScheduleItem,
],
notifications: [
{
id: 'bfe19b-766db3-b38d99d321-bbed3d-506',
sender: 'Planering och Bedömning',
dateCreated: oneDayAgo.minus({months: 6}).toISO(),
dateCreated: oneDayAgo.minus({ months: 6 }).toISO(),
dateModified: fourDaysAgo.toISO(),
message: 'Ett nytt inlägg i en lärlogg har skapats.',
url:
'https://www.breakit.se/artikel/21423/har-ar-it-bolaget-bakom-haveriet-pa-skolplattformen',
url: 'https://www.breakit.se/artikel/21423/har-ar-it-bolaget-bakom-haveriet-pa-skolplattformen',
category: 'Lärlogg',
type: 'avisering',
},
@ -224,8 +223,7 @@ const data: any = {
dateCreated: '2020-12-10T14:31:29.966Z',
message:
'Nu kan du ta del av ditt barns dokumentation av utvecklingssamtal',
url:
'https://www.breakit.se/artikel/21404/kodaren-slog-larm-nu-akutstoppas-skolplattformen-i-stockholm',
url: 'https://www.breakit.se/artikel/21404/kodaren-slog-larm-nu-akutstoppas-skolplattformen-i-stockholm',
category: null,
type: 'webnotify',
},
@ -234,8 +232,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-06-10T12:18:00.000Z',
message: 'Nu finns det en bedömning att titta på.',
url:
'https://www.svt.se/nyheter/lokalt/stockholm/skolplattformen-i-stockholm-beratta-om-era-erfarenheter',
url: 'https://www.svt.se/nyheter/lokalt/stockholm/skolplattformen-i-stockholm-beratta-om-era-erfarenheter',
category: 'Bedömning',
type: 'avisering',
},
@ -244,8 +241,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-03-24T14:28:00.000Z',
message: 'Nu finns det en bedömning att titta på.',
url:
'https://www.breakit.se/artikel/18120/skolplattformen-kostade-700-miljoner-strid-med-entreprenor-om-varumarket',
url: 'https://www.breakit.se/artikel/18120/skolplattformen-kostade-700-miljoner-strid-med-entreprenor-om-varumarket',
category: 'Bedömning',
type: 'avisering',
},
@ -254,8 +250,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-03-24T13:48:00.000Z',
message: 'Nu finns det en bedömning att titta på.',
url:
'https://www.mitti.se/nyheter/forskolans-tur-att-fa-kritiserade-skolplattformen-app/lmsau!5338007/',
url: 'https://www.mitti.se/nyheter/forskolans-tur-att-fa-kritiserade-skolplattformen-app/lmsau!5338007/',
category: 'Bedömning',
type: 'avisering',
},
@ -434,8 +429,8 @@ const data: any = {
allDayEvent: false,
startDate: twoDaysForward.startOf('day').toISO(),
endDate: twoDaysForward.endOf('day').toISO(),
oneDayEvent: false
} as ScheduleItem
oneDayEvent: false,
} as ScheduleItem,
],
notifications: [
{
@ -444,8 +439,7 @@ const data: any = {
dateCreated: fourDaysAgo.toISO(),
dateModified: fourDaysAgo.toISO(),
message: 'Ett nytt inlägg i en lärlogg har skapats.',
url:
'https://www.mitti.se/nyheter/rekorddyr-skolplattform-kostar-258-miljoner-till/lmsao!5381301/',
url: 'https://www.mitti.se/nyheter/rekorddyr-skolplattform-kostar-258-miljoner-till/lmsao!5381301/',
category: 'Lärlogg',
messageType: 'avisering',
},
@ -454,8 +448,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-12-01T12:43:00.000Z',
message: 'Ett nytt inlägg i en lärlogg har skapats.',
url:
'https://computersweden.idg.se/2.2683/1.722561/lacka-skolplattformen-datainspektionen',
url: 'https://computersweden.idg.se/2.2683/1.722561/lacka-skolplattformen-datainspektionen',
category: 'Lärlogg',
messageType: 'avisering',
},
@ -473,8 +466,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-11-16T13:24:00.000Z',
message: 'Ett nytt inlägg i en lärlogg har skapats.',
url:
'https://www.breakit.se/artikel/27075/skolplattformen-kostade-1-miljard-att-bygga-nu-tvingas-stockholm-bota',
url: 'https://www.breakit.se/artikel/27075/skolplattformen-kostade-1-miljard-att-bygga-nu-tvingas-stockholm-bota',
category: 'Lärlogg',
messageType: 'avisering',
},
@ -483,8 +475,7 @@ const data: any = {
sender: 'Planering och Bedömning',
dateCreated: '2020-11-12T13:27:00.000Z',
message: 'Ett nytt inlägg i en lärlogg har skapats.',
url:
'https://www.nyteknik.se/sakerhet/ygeman-om-datalackan-i-skolplattformen-det-ar-upprorande-6968853',
url: 'https://www.nyteknik.se/sakerhet/ygeman-om-datalackan-i-skolplattformen-det-ar-upprorande-6968853',
category: 'Lärlogg',
messageType: 'avisering',
},
@ -496,7 +487,7 @@ export const user = (): User => ({
personalNumber: '195001182046', // Test personal number from Skatteverket
firstName: 'Namn',
lastName: 'Namnsson',
isAuthenticated: true
isAuthenticated: true,
})
export const calendar = (child: Child): CalendarItem[] =>

View File

@ -1,14 +1,14 @@
import { DateTime } from "luxon"
import { DateTime } from 'luxon'
export const getDate = () => DateTime.now()
export const oneDayAgo = getDate().minus({days: 1})
export const twoDaysAgo = getDate().minus({days: 2})
export const fourDaysAgo = getDate().minus({days: 4})
export const oneWeekAgo = getDate().minus({weeks: 1})
export const oneDayAgo = getDate().minus({ days: 1 })
export const twoDaysAgo = getDate().minus({ days: 2 })
export const fourDaysAgo = getDate().minus({ days: 4 })
export const oneWeekAgo = getDate().minus({ weeks: 1 })
export const oneDayForward = getDate().plus({days: 1})
export const twoDaysForward = getDate().plus({days: 2})
export const fourDaysForward = getDate().plus({days: 4})
export const oneWeekForward = getDate().plus({weeks: 1})
export const oneDayForward = getDate().plus({ days: 1 })
export const twoDaysForward = getDate().plus({ days: 2 })
export const fourDaysForward = getDate().plus({ days: 4 })
export const oneWeekForward = getDate().plus({ weeks: 1 })
export const week = getDate().weekNumber.toString()

View File

@ -10,9 +10,9 @@ const week = getDate().weekNumber.toString()
const [child1, child2] = children()
const menuData = new Map<string, MenuItem[]>([
[
child1.id,
[
[
child1.id,
[
{
title: 'Måndag - Vecka ' + week,
description: 'Kebabgryta ris<br/>Ratatouille med kikärter',
@ -37,28 +37,33 @@ const menuData = new Map<string, MenuItem[]>([
},
],
],
[child2.id,
[
child2.id,
[
{
title: "Måndag - Vecka " + week,
description: "Thailändsk kycklinggryta med kokosmjölk, rödcurry och jasminris<br/>Thailänsk grönsaksgryta med kokosmjölk, rödcurry och jasminris"
title: 'Måndag - Vecka ' + week,
description:
'Thailändsk kycklinggryta med kokosmjölk, rödcurry och jasminris<br/>Thailänsk grönsaksgryta med kokosmjölk, rödcurry och jasminris',
},
{
title: "Tisdag - Vecka " + week,
description: "Örtomlett med potatis , medelhavsost och olivtapenad"
title: 'Tisdag - Vecka ' + week,
description: 'Örtomlett med potatis , medelhavsost och olivtapenad',
},
{
title: "Onsdag - Vecka " + week,
description: "Spagetti med rökt kalkon , grädde, dijon och persilja<br/>Spagetti med rostade bönor , grädde , dijon och persilja"
title: 'Onsdag - Vecka ' + week,
description:
'Spagetti med rökt kalkon , grädde, dijon och persilja<br/>Spagetti med rostade bönor , grädde , dijon och persilja',
},
{
title: "Torsdag - Vecka " + week,
description: "Panerad flundra med dansk remoulad och koktåotatis<br/>morot och linsbiff med danska remoulad och koktpotatis"
title: 'Torsdag - Vecka ' + week,
description:
'Panerad flundra med dansk remoulad och koktåotatis<br/>morot och linsbiff med danska remoulad och koktpotatis',
},
{
title: "Fredag - Vecka " + week,
description: "Texaschili på högrev med picklad rödlök och bulgur<br/>Texaschili på svartabönor picklad rödlök och bulgur"
}
title: 'Fredag - Vecka ' + week,
description:
'Texaschili på högrev med picklad rödlök och bulgur<br/>Texaschili på svartabönor picklad rödlök och bulgur',
},
],
]
],
])

View File

@ -7,137 +7,132 @@ export const news = (child: Child): NewsItem[] => newsData.get(child.id) ?? []
const [child1, child2] = children()
const newsData = new Map<string, NewsItem[]>([
[child1.id, [
{
id: 'asdfasdfasdfw',
author: 'Vaktmästare Persson',
header: 'Brandsläckare!',
intro: 'Idag hade vi en incident med en brandsläckare.',
body:
'## Information om brandsläckarincidenten\n\nHej, idag vid lunchtid utlöste en elev av misstag en pulverbrandsläckare i kapprummet. En del pulver yrde runt i rummet och under saneringen fick eleverna i angränsande klassrum vara i aulan istället för klassrummet.\n\nFlera elever var på plats i hallen när detta inträffade men utrymdes kort därefter. Pulvret är INTE hälsovådligt men kan ge upphov till halsirritation vid inandning.\n\nJag har pratat med berörda elever om det inträffade och uppmanat dem att ta hem kläder och tillhörigheter som fanns i kapprummet eftersom de troligen blivit dammiga. Vi rekommenderar att ni tvättar eller vädrar dessa.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://cdn.breakit.se/assets/article/6607f9b923edb6f85aa4417bab43c0f8.jpg?d=980x500',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.twoDaysAgo.toISO(),
modified: dates.twoDaysAgo.plus({ hours: 1 }).toISO(),
},
{
id: 'asdfabbuasdfs',
author: 'Ada L.',
header: 'Bygg din egen app',
intro: 'Denna vecka bygger vi appar!',
body:
'## Appar med öppen data \n\nDenna vecka har vi förmånen att få besök av några föräldrar som visar hur vi enkelt kan skapa appar som visar information ifrån öppna datakällor.\n\nEn fantastisk möjlighet att lära oss hur digitalisering skapar nya möjligheter i såväl skolan som arbetslivet.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfasdfasdfs',
author: 'Magister Svensson',
header: 'Läxor vecka 6.',
intro: 'Alla elever måste göra sina läxor!',
body:
'## Läxor vecka 6 \n\nFöljande läxor är obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.minus({ hours: 3 }).toISO(),
},
]
],
[
child1.id,
[
{
id: 'asdfasdfasdfw',
author: 'Vaktmästare Persson',
header: 'Brandsläckare!',
intro: 'Idag hade vi en incident med en brandsläckare.',
body: '## Information om brandsläckarincidenten\n\nHej, idag vid lunchtid utlöste en elev av misstag en pulverbrandsläckare i kapprummet. En del pulver yrde runt i rummet och under saneringen fick eleverna i angränsande klassrum vara i aulan istället för klassrummet.\n\nFlera elever var på plats i hallen när detta inträffade men utrymdes kort därefter. Pulvret är INTE hälsovådligt men kan ge upphov till halsirritation vid inandning.\n\nJag har pratat med berörda elever om det inträffade och uppmanat dem att ta hem kläder och tillhörigheter som fanns i kapprummet eftersom de troligen blivit dammiga. Vi rekommenderar att ni tvättar eller vädrar dessa.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://cdn.breakit.se/assets/article/6607f9b923edb6f85aa4417bab43c0f8.jpg?d=980x500',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.twoDaysAgo.toISO(),
modified: dates.twoDaysAgo.plus({ hours: 1 }).toISO(),
},
{
id: 'asdfabbuasdfs',
author: 'Ada L.',
header: 'Bygg din egen app',
intro: 'Denna vecka bygger vi appar!',
body: '## Appar med öppen data \n\nDenna vecka har vi förmånen att få besök av några föräldrar som visar hur vi enkelt kan skapa appar som visar information ifrån öppna datakällor.\n\nEn fantastisk möjlighet att lära oss hur digitalisering skapar nya möjligheter i såväl skolan som arbetslivet.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfasdfasdfs',
author: 'Magister Svensson',
header: 'Läxor vecka 6.',
intro: 'Alla elever måste göra sina läxor!',
body: '## Läxor vecka 6 \n\nFöljande läxor är obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.minus({ hours: 3 }).toISO(),
},
],
],
[child2.id, [
{
id: 'asdfasdfasdfa',
author: 'Rektor Gustavsson',
header: 'Välkommen till skolan!',
intro:
'Hej alla barn och föräldrar och välkomna till Storskolan! Här kommer en del information som kan vara bra att känna till inför första dagen.',
body:
'## Information till föräldrar \n\nSkolan börjar kl 08.00 och slutar 18.00. Kommer man sent eller blir sjuk så ska det anmälas via Skolplattformen. Se till så att dina barn har ätit frukost. Frukt är nyttigt! \n\n## Information till barn\n\nLek är tillåtet på rasterna men enbart på skolgården. Medtag ej egna leksaker. Tvätta händerna.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://timbro.se/app/uploads/2020/10/broman-skolplattformen-1280x752.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfabbuasdfs',
author: 'Ada L.',
header: 'App, App, App',
intro: 'Denna vecka bygger vi appar!',
body:
'## Appar med öppen data \n\nDenna vecka har vi förmånen att få besök av några föräldrar som visar hur vi enkelt kan skapa appar som visar information ifrån öppna datakällor.\n\nEn fantastisk möjlighet att lära oss hur digitalisering skapar nya möjligheter i såväl skolan som arbetslivet.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.fourDaysAgo.toISO(),
modified: dates.fourDaysAgo.plus({minutes: 45}).toISO(),
},
{
id: 'asdfasdfasdfs',
author: 'Magister Svensson',
header: 'Läxor i veckan',
intro: 'Alla elever måste göra sina läxor!',
body:
'## Läxor vecka 6 \n\nFöljande läxor är obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfasdfasdfd',
author: 'Information från Förskoleklass',
header: 'Vinteraktiviteter',
intro:
'Vi kommer efter att förskoleklassen är slut arrangera olika vinteraktiviteter genom fridtidsverksamheten.',
body:
'## Vänligen ta med hjälm, skridskor eller stjärtlapp.\n\n ![Bild](https://images.unsplash.com/photo-1495377701095-00261b767581?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80)\n\n Alla barn måste ha hjälm på sig samt varma kläder. Vi kommer åka i backen bakom skolbyggnaden samt använda isen som spolats vid Mullsjöskolan. Personal kommer finnas på plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjälm eller lämpligt åkdon.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/yB_aiAWkm40',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({weeks: 2}).toISO(),
modified: dates.oneWeekAgo.minus({weeks: 1}).toISO(),
},
{
id: 'asdfasdfasdfdsa',
author: 'Köket',
header: 'Ekologisk vecka i matsalen',
intro: 'Ekologiska veckan i matsalen vecka 11',
body:
'## Vi kommer ha tema jorden i matsalen och servera ekologisk mat från hela världen med tema jorden. Detta för att belysa att man kan använda alla delar av råvaorna. Det kommer erbjudas rätter från alla världsdelar som är producerat för jordens bästa. Smaklig spis hälsar Gunnel i köket med personal.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/7K17MvT8qBg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({weeks: 3}).toISO(),
modified: dates.oneWeekAgo.minus({days: 2}).toISO(),
},
{
id: 'asdfasdfasdfbvdsa',
author: 'Vaktmästaren',
header: 'Klotter i korridoren (igen)',
intro:
'Ännu en gång har vi råka ut för skadegörelse i korridorerna vid åk 5',
body:
'## Tyvärr har flera elever klottat på skåp och väggar vid åk5 skåpen. Detta är helt oacceptablet beteende och kostar skolan stora belopp att åtgärda. Vi ber alla föräldrar prata med sina barn om klotter samt att det var väldigt grovt spårkbruk. Personalen på skolan kommer att hålla extra uppsikt och vi har även pratat med en del av de inblandade eleverna i denna skadegörelse.\n\nPersonalen har även börjat forska på vad vissa av de skrivna orden betyder och Eva-Britt är förfasad över språkbruket samt vad de innebär. Bernt kommer att påbörja saneringen och återställningen av skadegörelsen samt vakta korridorerna nogrannare för att säkerställa att detta ej kommer ske igen.\n\n Klotter\n\nUPPDATERING: Det som är skrivet om Sara är inte sant! ',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/SkbEZ16VywM',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({weeks: 4}).toISO(),
modified: dates.oneWeekAgo.minus({weeks: 2}).toISO(),
},
]
]
[
child2.id,
[
{
id: 'asdfasdfasdfa',
author: 'Rektor Gustavsson',
header: 'Välkommen till skolan!',
intro:
'Hej alla barn och föräldrar och välkomna till Storskolan! Här kommer en del information som kan vara bra att känna till inför första dagen.',
body: '## Information till föräldrar \n\nSkolan börjar kl 08.00 och slutar 18.00. Kommer man sent eller blir sjuk så ska det anmälas via Skolplattformen. Se till så att dina barn har ätit frukost. Frukt är nyttigt! \n\n## Information till barn\n\nLek är tillåtet på rasterna men enbart på skolgården. Medtag ej egna leksaker. Tvätta händerna.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://timbro.se/app/uploads/2020/10/broman-skolplattformen-1280x752.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfabbuasdfs',
author: 'Ada L.',
header: 'App, App, App',
intro: 'Denna vecka bygger vi appar!',
body: '## Appar med öppen data \n\nDenna vecka har vi förmånen att få besök av några föräldrar som visar hur vi enkelt kan skapa appar som visar information ifrån öppna datakällor.\n\nEn fantastisk möjlighet att lära oss hur digitalisering skapar nya möjligheter i såväl skolan som arbetslivet.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://live.staticflickr.com/4063/4369776892_5cd42d27ba.jpg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.fourDaysAgo.toISO(),
modified: dates.fourDaysAgo.plus({ minutes: 45 }).toISO(),
},
{
id: 'asdfasdfasdfs',
author: 'Magister Svensson',
header: 'Läxor i veckan',
intro: 'Alla elever måste göra sina läxor!',
body: '## Läxor vecka 6 \n\nFöljande läxor är obligatoriska:\n\n- Antikens historia\n- Svenska stormaktstiden\n- Statistik A\n- Flerdimensionell analys, del 1',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl:
'https://www.mitti.se/_internal/cimg!0/ejf8efxee735ymm8tm40q3hhkl36sdt.jpeg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.toISO(),
modified: dates.oneWeekAgo.toISO(),
},
{
id: 'asdfasdfasdfd',
author: 'Information från Förskoleklass',
header: 'Vinteraktiviteter',
intro:
'Vi kommer efter att förskoleklassen är slut arrangera olika vinteraktiviteter genom fridtidsverksamheten.',
body: '## Vänligen ta med hjälm, skridskor eller stjärtlapp.\n\n ![Bild](https://images.unsplash.com/photo-1495377701095-00261b767581?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80)\n\n Alla barn måste ha hjälm på sig samt varma kläder. Vi kommer åka i backen bakom skolbyggnaden samt använda isen som spolats vid Mullsjöskolan. Personal kommer finnas på plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjälm eller lämpligt åkdon.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/yB_aiAWkm40',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({ weeks: 2 }).toISO(),
modified: dates.oneWeekAgo.minus({ weeks: 1 }).toISO(),
},
{
id: 'asdfasdfasdfdsa',
author: 'Köket',
header: 'Ekologisk vecka i matsalen',
intro: 'Ekologiska veckan i matsalen vecka 11',
body: '## Vi kommer ha tema jorden i matsalen och servera ekologisk mat från hela världen med tema jorden. Detta för att belysa att man kan använda alla delar av råvaorna. Det kommer erbjudas rätter från alla världsdelar som är producerat för jordens bästa. Smaklig spis hälsar Gunnel i köket med personal.',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/7K17MvT8qBg',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({ weeks: 3 }).toISO(),
modified: dates.oneWeekAgo.minus({ days: 2 }).toISO(),
},
{
id: 'asdfasdfasdfbvdsa',
author: 'Vaktmästaren',
header: 'Klotter i korridoren (igen)',
intro:
'Ännu en gång har vi råka ut för skadegörelse i korridorerna vid åk 5',
body: '## Tyvärr har flera elever klottat på skåp och väggar vid åk5 skåpen. Detta är helt oacceptablet beteende och kostar skolan stora belopp att åtgärda. Vi ber alla föräldrar prata med sina barn om klotter samt att det var väldigt grovt spårkbruk. Personalen på skolan kommer att hålla extra uppsikt och vi har även pratat med en del av de inblandade eleverna i denna skadegörelse.\n\nPersonalen har även börjat forska på vad vissa av de skrivna orden betyder och Eva-Britt är förfasad över språkbruket samt vad de innebär. Bernt kommer att påbörja saneringen och återställningen av skadegörelsen samt vakta korridorerna nogrannare för att säkerställa att detta ej kommer ske igen.\n\n Klotter\n\nUPPDATERING: Det som är skrivet om Sara är inte sant! ',
imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg',
fullImageUrl: 'https://unsplash.com/photos/SkbEZ16VywM',
imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.',
published: dates.oneWeekAgo.minus({ weeks: 4 }).toISO(),
modified: dates.oneWeekAgo.minus({ weeks: 2 }).toISO(),
},
],
],
])

View File

@ -1,47 +1,52 @@
import { SchoolContact, Child } from '@skolplattformen/api';
import { SchoolContact, Child } from '@skolplattformen/api'
import { children } from './children'
export const schoolContacts = (child: Child): SchoolContact[] => schoolContactData.get(child.id) ?? []
export const schoolContacts = (child: Child): SchoolContact[] =>
schoolContactData.get(child.id) ?? []
const [child1,child2] = children()
const [child1, child2] = children()
const schoolContactData = new Map<string, SchoolContact[]>([
[
child1.id, [
child1.id,
[
{
title: "Expedition",
title: 'Expedition',
name: undefined,
phone: "508 000 00",
email: "",
schoolName: "Vallaskolan",
phone: '508 000 00',
email: '',
schoolName: 'Vallaskolan',
className: '',
},
{
title: "Rektor",
name: "Alvar Sträng",
phone: "08-50800001",
email: "alvar.strang@edu.stockholm.se",
title: 'Rektor',
name: 'Alvar Sträng',
phone: '08-50800001',
email: 'alvar.strang@edu.stockholm.se',
schoolName: '',
className: '',
}
]],
},
],
],
[
child2.id, [
{
title: "Expedition",
name: undefined,
phone: "508 000 00",
email: "",
schoolName: "Vallaskolan",
className: '',
},
{
title: "Rektor",
name: "Alvar Sträng",
phone: "08-50800001",
email: "alvar.strang@edu.stockholm.se",
schoolName: '',
className: '',
}
]]
child2.id,
[
{
title: 'Expedition',
name: undefined,
phone: '508 000 00',
email: '',
schoolName: 'Vallaskolan',
className: '',
},
{
title: 'Rektor',
name: 'Alvar Sträng',
phone: '08-50800001',
email: 'alvar.strang@edu.stockholm.se',
schoolName: '',
className: '',
},
],
],
])

View File

@ -1,81 +1,86 @@
import { Teacher, Child } from '@skolplattformen/api';
import { Teacher, Child } from '@skolplattformen/api'
import { children } from './children'
export const teachers = (child: Child): Teacher[] => teacherData.get(child.id) ?? []
export const teachers = (child: Child): Teacher[] =>
teacherData.get(child.id) ?? []
const [child1,child2] = children()
const [child1, child2] = children()
const teacherData = new Map<string, Teacher[]>([
[
child1.id, [
child1.id,
[
{
id: 15662220,
firstname: "Cecilia",
firstname: 'Cecilia',
sisId: '',
lastname: "Test",
email: "cecilia.test@edu.stockholm.se",
lastname: 'Test',
email: 'cecilia.test@edu.stockholm.se',
phoneWork: undefined,
active: true,
status: " S",
status: ' S',
timeTableAbbreviation: 'CTE',
},
{
id: 15662221,
firstname: "Anna",
lastname: "Test",
firstname: 'Anna',
lastname: 'Test',
sisId: '',
email: "anna.test@edu.stockholm.se",
email: 'anna.test@edu.stockholm.se',
phoneWork: '08000000',
active: true,
status: " GR",
status: ' GR',
timeTableAbbreviation: 'ATE',
},
{
id: 15662221,
firstname: "Greta",
lastname: "Test",
firstname: 'Greta',
lastname: 'Test',
sisId: '',
email: undefined,
phoneWork: '08000001',
active: true,
status: " F",
status: ' F',
timeTableAbbreviation: 'GTE',
},
]],
[
child2.id, [
{
id: 15662220,
firstname: "Cecilia",
sisId: '',
lastname: "Test",
email: "cecilia.test@edu.stockholm.se",
phoneWork: undefined,
active: true,
status: " S",
timeTableAbbreviation: 'CTE',
},
{
id: 15662221,
firstname: "Anna",
lastname: "Test",
sisId: '',
email: "anna.test@edu.stockholm.se",
phoneWork: '08000000',
active: true,
status: " GR",
timeTableAbbreviation: 'ATE',
},
{
id: 15662221,
firstname: "Greta",
lastname: "Test",
sisId: '',
email: undefined,
phoneWork: '08000001',
active: true,
status: " F",
timeTableAbbreviation: 'GTE',
},
]],
],
],
[
child2.id,
[
{
id: 15662220,
firstname: 'Cecilia',
sisId: '',
lastname: 'Test',
email: 'cecilia.test@edu.stockholm.se',
phoneWork: undefined,
active: true,
status: ' S',
timeTableAbbreviation: 'CTE',
},
{
id: 15662221,
firstname: 'Anna',
lastname: 'Test',
sisId: '',
email: 'anna.test@edu.stockholm.se',
phoneWork: '08000000',
active: true,
status: ' GR',
timeTableAbbreviation: 'ATE',
},
{
id: 15662221,
firstname: 'Greta',
lastname: 'Test',
sisId: '',
email: undefined,
phoneWork: '08000001',
active: true,
status: ' F',
timeTableAbbreviation: 'GTE',
},
],
],
])

View File

@ -1,5 +1,4 @@
import { Skola24Child, TimetableEntry } from "@skolplattformen/api"
import { Skola24Child, TimetableEntry } from '@skolplattformen/api'
export const timetable = (child: Skola24Child): TimetableEntry[] => {
if (!child.personGuid || !child.unitGuid) return []
@ -460,6 +459,6 @@ export const timetable = (child: Skola24Child): TimetableEntry[] => {
timeStart: '10:40:00',
dateStart: '2021-04-16T10:40:00.000+02:00',
dateEnd: '2021-04-16T11:35:00.000+02:00',
}
},
]
}

View File

@ -1,50 +1,57 @@
import { EventEmitter } from 'events';
import { frejaLoginStatus } from './routes';
import { Fetcher, FrejaLoginStatusChecker, RequestInit } from '@skolplattformen/api';
export class FrejaChecker extends EventEmitter implements FrejaLoginStatusChecker {
public token: string;
import { EventEmitter } from 'events'
import { frejaLoginStatus } from './routes'
import {
Fetcher,
FrejaLoginStatusChecker,
RequestInit,
} from '@skolplattformen/api'
export class FrejaChecker
extends EventEmitter
implements FrejaLoginStatusChecker
{
public token: string
private fetcher: Fetcher
private url: string
private fetcher: Fetcher
private url: string
private cancelled = false;
private cancelled = false
constructor(fetcher: Fetcher, token: string) {
super();
this.fetcher = fetcher
constructor(fetcher: Fetcher, token: string) {
super()
this.fetcher = fetcher
this.token = token
this.url = frejaLoginStatus;
this.check();
}
this.token = token
this.url = frejaLoginStatus
this.check()
}
async check(): Promise<void> {
const response = await this.fetcher('freja-login-status', this.url);
let status = await response.text();
async check(): Promise<void> {
const response = await this.fetcher('freja-login-status', this.url)
let status = await response.text()
// For Freja we recieve CANCELED (with one L) - BankId returns CANCELLED (with two L)
// To make the API consistent - we choose the same as BankId - two L
if (status === 'CANCELED') status = 'CANCELLED'
// For Freja we recieve CANCELED (with one L) - BankId returns CANCELLED (with two L)
// To make the API consistent - we choose the same as BankId - two L
if (status === 'CANCELED') status = 'CANCELLED'
console.debug(status)
this.emit(status);
if (!this.cancelled &&
status !== 'APPROVED' &&
status !== 'ERROR' &&
status !== 'CANCELLED'
){
setTimeout(() => this.check(), 1000);
}
}
async cancel(): Promise<void> {
this.cancelled = true;
console.debug(status)
this.emit(status)
if (
!this.cancelled &&
status !== 'APPROVED' &&
status !== 'ERROR' &&
status !== 'CANCELLED'
) {
setTimeout(() => this.check(), 1000)
}
}
async cancel(): Promise<void> {
this.cancelled = true
}
}
export const checkStatus = (
fetch: Fetcher,
token: string,
session: RequestInit
): FrejaLoginStatusChecker => new FrejaChecker(fetch, token)
export const checkStatus = (
fetch: Fetcher,
token: string,
session: RequestInit
): FrejaLoginStatusChecker => new FrejaChecker(fetch, token)

View File

@ -1,49 +1,53 @@
import { EventEmitter } from 'events';
import { loginStatus } from './routes';
import { AuthTicket, Fetcher, LoginStatusChecker } from '@skolplattformen/api';
import { EventEmitter } from 'events'
import { loginStatus } from './routes'
import { AuthTicket, Fetcher, LoginStatusChecker } from '@skolplattformen/api'
export class Checker extends EventEmitter implements LoginStatusChecker {
public token: string;
public token: string
private fetcher: Fetcher;
private fetcher: Fetcher
private url: string;
private url: string
private cancelled = false;
private cancelled = false
constructor(fetcher: Fetcher, ticket: AuthTicket) {
super();
this.fetcher = fetcher;
this.url = loginStatus(ticket.order);
this.token = ticket.token;
this.check();
super()
this.fetcher = fetcher
this.url = loginStatus(ticket.order)
this.token = ticket.token
this.check()
}
async check(): Promise<void> {
const response = await this.fetcher('login-status', this.url);
const status = await response.text();
this.emit(status);
if (!this.cancelled &&
status !== 'OK' &&
status !== 'ERROR!' &&
status !== 'CANCELLED') {
setTimeout(() => this.check(), 1000);
const response = await this.fetcher('login-status', this.url)
const status = await response.json()
this.emit(status.state)
if (
!this.cancelled &&
status.state !== 'OK' &&
status.state !== 'ERROR' &&
status.state !== 'CANCELLED'
) {
setTimeout(() => this.check(), 1000)
}
}
async cancel(): Promise<void> {
this.cancelled = true;
this.cancelled = true
}
}
export const checkStatus = (
fetch: Fetcher,
ticket: AuthTicket
): LoginStatusChecker => new Checker(fetch, ticket)
export class DummyStatusChecker extends EventEmitter implements LoginStatusChecker {
token = ""
export class DummyStatusChecker
extends EventEmitter
implements LoginStatusChecker
{
token = ''
async cancel(): Promise<void> {
// do nothing
}

View File

@ -19,7 +19,8 @@ describe('news', () => {
NewsListId: '3EC323A1-EA16-4D24-84C8-DAA49E76F9F4',
NewsItemId:
'elevstockholm.sharepoint.com,27892ACC-BA2E-4DEC-97B8-25F7098C3BF6,A239466A-9A52-42FF-8A3F-D94C342F2700_99',
Header: 'Problemet med att se betyg i bild, slöjd och teknik löst!',
Header:
'Problemet med att se betyg i bild, slöjd och teknik löst!',
PublicationDate: '/Date(1608304542000)/',
PubDateSE: '18 december 2020 16:15',
ModifiedDate: '/Date(1608304680000)/',
@ -30,8 +31,7 @@ describe('news', () => {
BannerImageUrl: 'A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg',
BannerImageGuid: 'A703552D-DBF3-45B0-8E67-6E062105A0C5',
BannerImageListId: 'FFBE49E9-BDE1-4C75-BA0E-D98D4E2FCF21',
Body:
'<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
BodyNoHtml: null,
AuthorDisplayName: 'Eva-Lotta Rönnberg',
altText: 'Nyhetsbild. Bildtext ej tillgänglig.',
@ -72,7 +72,7 @@ describe('news', () => {
)
expect(item.imageUrl).toEqual('A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg')
expect(item.fullImageUrl).toEqual(
'https://etjanst.stockholm.se/Vardnadshavare/inloggad2/NewsBanner?url=A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg'
'https://etjanster.stockholm.se/Vardnadshavare/inloggad2/NewsBanner?url=A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg'
)
expect(item.imageAltText).toEqual('Nyhetsbild. Bildtext ej tillgänglig.')
expect(item.intro).toEqual(
@ -108,7 +108,8 @@ describe('news', () => {
NewsListId: '3EC323A1-EA16-4D24-84C8-DAA49E76F9F4',
NewsItemId:
'elevstockholm.sharepoint.com,27892ACC-BA2E-4DEC-97B8-25F7098C3BF6,A239466A-9A52-42FF-8A3F-D94C342F2700_99',
Header: 'Problemet med att se betyg i bild, slöjd och teknik löst!',
Header:
'Problemet med att se betyg i bild, slöjd och teknik löst!',
PublicationDate: '/Date(1608304542000)/',
PubDateSE: '18 december 2020 16:15',
ModifiedDate: '/Date(1608304680000)/',
@ -119,8 +120,7 @@ describe('news', () => {
BannerImageUrl: 'A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg',
BannerImageGuid: 'A703552D-DBF3-45B0-8E67-6E062105A0C5',
BannerImageListId: 'FFBE49E9-BDE1-4C75-BA0E-D98D4E2FCF21',
Body:
'<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
BodyNoHtml: null,
AuthorDisplayName: 'Eva-Lotta Rönnberg',
altText: 'Nyhetsbild. Bildtext ej tillgänglig.',
@ -132,7 +132,8 @@ describe('news', () => {
NewsListId: '3EC323A1-EA16-4D24-84C8-DAA49E76F9F4',
NewsItemId:
'elevstockholm.sharepoint.com,27892ACC-BA2E-4DEC-97B8-25F7098C3BF6,A239466A-9A52-42FF-8A3F-D94C342F2700_99',
Header: 'Problemet med att se betyg i bild, slöjd och teknik löst!',
Header:
'Problemet med att se betyg i bild, slöjd och teknik löst!',
PublicationDate: '/Date(1608304542000)/',
PubDateSE: '18 november 2021 16:15',
ModifiedDate: '/Date(1608304680000)/',
@ -143,8 +144,7 @@ describe('news', () => {
BannerImageUrl: 'A703552D-DBF3-45B0-8E67-6E062105A0C5.jpeg',
BannerImageGuid: 'A703552D-DBF3-45B0-8E67-6E062105A0C5',
BannerImageListId: 'FFBE49E9-BDE1-4C75-BA0E-D98D4E2FCF21',
Body:
'<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;4,&quot;id&quot;&#58;&quot;1212fc8d-dd6b-408a-8d5d-9f1cc787efbb&quot;,&quot;position&quot;&#58;&#123;&quot;controlIndex&quot;&#58;2,&quot;sectionIndex&quot;&#58;1,&quot;sectionFactor&quot;&#58;12,&quot;zoneIndex&quot;&#58;1,&quot;layoutIndex&quot;&#58;1&#125;,&quot;addedFromPersistedData&quot;&#58;true,&quot;emphasis&quot;&#58;&#123;&#125;&#125;"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska.&#160;</p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="&#123;&quot;controlType&quot;&#58;0,&quot;pageSettingsSlice&quot;&#58;&#123;&quot;isDefaultDescription&quot;&#58;true,&quot;isDefaultThumbnail&quot;&#58;true&#125;&#125;"></div></div>',
BodyNoHtml: null,
AuthorDisplayName: 'Eva-Lotta Rönnberg',
altText: 'Nyhetsbild. Bildtext ej tillgänglig.',
@ -206,8 +206,7 @@ describe('newsItem', () => {
BannerImageUrl: '123123.jpeg',
BannerImageGuid: '7a8142d9d9d54cf090e8457e4c629227',
BannerImageListId: 'a88c22e8-7094-4a71-b4fd-8792c62a7b4a',
Body:
'<div data-sp-rte=""><p><span><span><span>Kära vårdnadshavare!</span></span></span></p><p><span><span><span>I helgen är det avlusningsdagar! Ta <strong>tillfället </strong>i akt att luskamma ditt barn </span></span></span></p><p><span><span><span>Du finner all info du behöver på <a href="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-cke-saved-href="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-interception="on" title="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/">1177 hemsida </a></span></span></span><span><span><span></span></span></span></p><p><span><span><span>Trevlig helg!</span></span></span></p><p><span><span><span></span></span></span></p></div>',
Body: '<div data-sp-rte=""><p><span><span><span>Kära vårdnadshavare!</span></span></span></p><p><span><span><span>I helgen är det avlusningsdagar! Ta <strong>tillfället </strong>i akt att luskamma ditt barn </span></span></span></p><p><span><span><span>Du finner all info du behöver på <a href="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-cke-saved-href="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-interception="on" title="https&#58;//www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/">1177 hemsida </a></span></span></span><span><span><span></span></span></span></p><p><span><span><span>Trevlig helg!</span></span></span></p><p><span><span><span></span></span></span></p></div>',
BodyNoHtml: null,
AuthorDisplayName: 'Tieto Evry',
altText: null,
@ -264,7 +263,6 @@ describe('newsItem', () => {
})
})
describe('newsItem', () => {
beforeEach(() => {
response = {
@ -288,8 +286,7 @@ describe('newsItem', () => {
BannerImageUrl: '123123.jpeg',
BannerImageGuid: '7a8142d9d9d54cf090e8457e4c629227',
BannerImageListId: 'a88c22e8-7094-4a71-b4fd-8792c62a7b4a',
Body:
'<i>italic</i> <b>bold</b> <em>emphasis </em><br/><strong>strong</strong><strong>nbsp&#160;</strong>',
Body: '<i>italic</i> <b>bold</b> <em>emphasis </em><br/><strong>strong</strong><strong>nbsp&#160;</strong>',
BodyNoHtml: null,
AuthorDisplayName: 'Tieto Evry',
altText: null,
@ -330,4 +327,4 @@ describe('newsItem', () => {
expect(item.body).toContain('**strong**')
expect(item.body).toContain('**nbsp**')
})
})
})

View File

@ -56,7 +56,7 @@ it(' notifications correctly', () => {
sender: 'Elevdokumentation',
url: 'https://elevdokumentation.stockholm.se/loa3/gradesStudent.do',
dateCreated: '2020-12-18T14:59:46.340Z',
dateModified: "2020-12-18T15:59:46.340Z",
dateModified: '2020-12-18T15:59:46.340Z',
category: null,
type: 'webnotify',
},

View File

@ -5,46 +5,46 @@ let response: EtjanstResponse
beforeEach(() => {
response = {
"Success": true,
"Error": null,
"Data": [
{
"Title": "Expedition",
"Name": null,
"Phone": "508 000 00",
"Email": "",
"SchoolName": "Påhittade skolan",
"ClassName": null
},
{
"Title": "Rektor",
"Name": "Andersson, Anna Bella Cecilia",
"Phone": "08-508 000 00",
"Email": "anna.anderssonn@edu.stockholm.se",
"SchoolName": null,
"ClassName": null
}
]
}
Success: true,
Error: null,
Data: [
{
Title: 'Expedition',
Name: null,
Phone: '508 000 00',
Email: '',
SchoolName: 'Påhittade skolan',
ClassName: null,
},
{
Title: 'Rektor',
Name: 'Andersson, Anna Bella Cecilia',
Phone: '08-508 000 00',
Email: 'anna.anderssonn@edu.stockholm.se',
SchoolName: null,
ClassName: null,
},
],
}
})
it('parses teachers correctly', () => {
expect(schoolContacts(response)).toEqual([
{
title: 'Expedition',
name: null,
phone: '508 000 00',
email: '',
schoolName: 'Påhittade skolan',
className: null
},
{
title: 'Rektor',
name: 'Andersson, Anna Bella Cecilia',
phone: '08-508 000 00',
email: 'anna.anderssonn@edu.stockholm.se',
schoolName: null,
className: null
}
title: 'Expedition',
name: null,
phone: '508 000 00',
email: '',
schoolName: 'Påhittade skolan',
className: null,
},
{
title: 'Rektor',
name: 'Andersson, Anna Bella Cecilia',
phone: '08-508 000 00',
email: 'anna.anderssonn@edu.stockholm.se',
schoolName: null,
className: null,
},
])
})

View File

@ -5,64 +5,64 @@ let response: EtjanstResponse
beforeEach(() => {
response = {
"Success": true,
"Error": null,
"Data": [
Success: true,
Error: null,
Data: [
{
"ID": 156735,
"BATCH": "GR",
"SIS_ID": "F154239A-EA4A-4C6C-A112-0B9581132E3D",
"USERNAME": "anna.andersson",
"SCHOOL_SIS_ID": "DE2E1293-0F40-4B91-9D91-1E99355DC257",
"EMAILADDRESS": null,
"STATUS": " GR",
"ERRORCODE": 0,
"FIRSTNAME": "Anna",
"LASTNAME": "Andersson",
"ACTIVE": true,
"TELWORK": "08 508 0000000"
ID: 156735,
BATCH: 'GR',
SIS_ID: 'F154239A-EA4A-4C6C-A112-0B9581132E3D',
USERNAME: 'anna.andersson',
SCHOOL_SIS_ID: 'DE2E1293-0F40-4B91-9D91-1E99355DC257',
EMAILADDRESS: null,
STATUS: ' GR',
ERRORCODE: 0,
FIRSTNAME: 'Anna',
LASTNAME: 'Andersson',
ACTIVE: true,
TELWORK: '08 508 0000000',
},
{
"ID": 156690,
"BATCH": "GR",
"SIS_ID": "9EC59FCA-80AD-4774-AABD-427040207E33",
"USERNAME": "gunnar.grymm",
"SCHOOL_SIS_ID": "DE2E1293-0F40-4B91-9D91-1E99355DC257",
"EMAILADDRESS": "gunnar.grymm@edu.stockholm.se",
"STATUS": " F",
"ERRORCODE": 0,
"FIRSTNAME": "Gunnar",
"LASTNAME": "Grymm",
"ACTIVE": true,
"TELWORK": null
}
]
}
ID: 156690,
BATCH: 'GR',
SIS_ID: '9EC59FCA-80AD-4774-AABD-427040207E33',
USERNAME: 'gunnar.grymm',
SCHOOL_SIS_ID: 'DE2E1293-0F40-4B91-9D91-1E99355DC257',
EMAILADDRESS: 'gunnar.grymm@edu.stockholm.se',
STATUS: ' F',
ERRORCODE: 0,
FIRSTNAME: 'Gunnar',
LASTNAME: 'Grymm',
ACTIVE: true,
TELWORK: null,
},
],
}
})
it('parses teachers correctly', () => {
expect(teachers(response)).toEqual([
{
id: 156735,
sisId: 'F154239A-EA4A-4C6C-A112-0B9581132E3D',
firstname: 'Anna',
lastname: 'Andersson',
email: null,
phoneWork: '08 508 0000000',
active: true,
status: ' GR',
timeTableAbbreviation: 'AAN'
},
{
id: 156690,
sisId: '9EC59FCA-80AD-4774-AABD-427040207E33',
firstname: 'Gunnar',
lastname: 'Grymm',
email: 'gunnar.grymm@edu.stockholm.se',
phoneWork: null,
active: true,
status: ' F',
timeTableAbbreviation: 'GGR'
},
id: 156735,
sisId: 'F154239A-EA4A-4C6C-A112-0B9581132E3D',
firstname: 'Anna',
lastname: 'Andersson',
email: null,
phoneWork: '08 508 0000000',
active: true,
status: ' GR',
timeTableAbbreviation: 'AAN',
},
{
id: 156690,
sisId: '9EC59FCA-80AD-4774-AABD-427040207E33',
firstname: 'Gunnar',
lastname: 'Grymm',
email: 'gunnar.grymm@edu.stockholm.se',
phoneWork: null,
active: true,
status: ' F',
timeTableAbbreviation: 'GGR',
},
])
})

View File

@ -18,7 +18,7 @@ describe('Timetable', () => {
italic: false,
id: 9,
parentId: 6,
type: 'ClockAxisBox'
type: 'ClockAxisBox',
},
{
x: 11,
@ -30,7 +30,7 @@ describe('Timetable', () => {
italic: false,
id: 12,
parentId: 6,
type: 'ClockAxisBox'
type: 'ClockAxisBox',
},
],
boxList: [
@ -44,7 +44,7 @@ describe('Timetable', () => {
id: 0,
parentId: null,
type: 'Footer',
lessonGuids: null
lessonGuids: null,
},
{
x: 56,
@ -56,7 +56,7 @@ describe('Timetable', () => {
id: 1,
parentId: null,
type: 'HeadingDay',
lessonGuids: null
lessonGuids: null,
},
],
lineList: [
@ -68,7 +68,7 @@ describe('Timetable', () => {
color: '#000000',
id: 7,
parentId: 6,
type: 'ClockAxisGradiation'
type: 'ClockAxisGradiation',
},
{
p1x: 0,
@ -78,35 +78,27 @@ describe('Timetable', () => {
color: '#000000',
id: 8,
parentId: 6,
type: 'ClockAxisGradiation'
type: 'ClockAxisGradiation',
},
],
lessonInfo: [
{
guidId: 'N2FjMDc1NjYtZmM2Yy0wZDQyLTY3M2YtZWI5NGNiZDA3ZGU4',
texts: [
'Lunch',
'',
'Ö5'
],
texts: ['Lunch', '', 'Ö5'],
timeStart: '11:40:00',
timeEnd: '12:05:00',
dayOfWeekNumber: 1,
blockName: ''
blockName: '',
},
{
guidId: 'ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw',
texts: [
'BL',
'KUr',
'221'
],
texts: ['BL', 'KUr', '221'],
timeStart: '09:40:00',
timeEnd: '11:35:00',
dayOfWeekNumber: 1,
blockName: 'block'
blockName: 'block',
},
]
],
},
exception: null,
validation: [],
@ -116,7 +108,9 @@ describe('Timetable', () => {
it('parses basic timeTableEntry data correctly', () => {
const entry = timetableEntry(response.data.lessonInfo[1], 2021, 15, 'sv')
expect(entry.id).toEqual('ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw')
expect(entry.id).toEqual(
'ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw'
)
expect(entry.code).toEqual('BL')
expect(entry.name).toEqual('Bild')
expect(entry.teacher).toEqual('KUr')
@ -142,8 +136,12 @@ describe('Timetable', () => {
const table = timetable(response, 2021, 15, 'sv')
expect(table).toHaveLength(2)
expect(table[0].id).toEqual('N2FjMDc1NjYtZmM2Yy0wZDQyLTY3M2YtZWI5NGNiZDA3ZGU4')
expect(table[1].id).toEqual('ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw')
expect(table[0].id).toEqual(
'N2FjMDc1NjYtZmM2Yy0wZDQyLTY3M2YtZWI5NGNiZDA3ZGU4'
)
expect(table[1].id).toEqual(
'ZTQ1NWE0N2EtNzAwOS0wZTAzLTQ1ZDYtNTA1NWI4Y2JhNDYw'
)
})
})
})

View File

@ -1,7 +1,6 @@
import { MenuItem, MenuList, toMarkdown } from '@skolplattformen/api'
import { etjanst } from './etjanst'
export const menuItem = ({ title, description }: any): MenuItem => ({
title,
description: toMarkdown(description),
@ -24,7 +23,7 @@ export const menuList = (data: any): MenuItem[] => {
const menuItemsFS = [
{
title: `Måndag - Vecka ${currentWeek.week}`,
description: toMarkdown(currentWeek.mon) ,
description: toMarkdown(currentWeek.mon),
},
{
title: `Tisdag - Vecka ${currentWeek.week}`,

View File

@ -1,9 +1,8 @@
import { NewsItem, parseDate, toMarkdown } from '@skolplattformen/api';
import { NewsItem, parseDate, toMarkdown } from '@skolplattformen/api'
import { etjanst } from './etjanst'
const IMAGE_HOST =
'https://etjanst.stockholm.se/Vardnadshavare/inloggad2/NewsBanner?url='
'https://etjanster.stockholm.se/Vardnadshavare/inloggad2/NewsBanner?url='
export const newsItem = ({
newsId,
@ -28,10 +27,10 @@ export const newsItem = ({
body: toNonEmptyMarkdownString(body),
})
// Fixes https://github.com/kolplattformen/skolplattformen-app/issues/525
// Fixes https://github.com/kolplattformen/skolplattformen/issues/525
const toNonEmptyMarkdownString = (str: string): string => {
const res = toMarkdown(str);
if(res?.length == 0 ) return ' '
const res = toMarkdown(str)
if (res?.length == 0) return ' '
return res
}

View File

@ -25,7 +25,10 @@ export const notification = ({
type,
})
const notificationsSort = (item1: Notification, item2: Notification): number => {
const notificationsSort = (
item1: Notification,
item2: Notification
): number => {
const m1 = item1.dateModified || item1.dateCreated
const m2 = item2.dateModified || item2.dateCreated
return m1 < m2 ? 1 : -1

View File

@ -20,19 +20,18 @@ export const scheduleItem = ({
})
export const schedule = (data: any): ScheduleItem[] => {
try{
try {
const scheduleData = etjanst(data)
const mapped = scheduleData.map(scheduleItem)
return mapped
}
catch(e){
} catch (e) {
if (e instanceof Error) {
// If this happens the child has no schedule
// If this happens the child has no schedule
// It is the same on the official web
// Instead of retrying and spamming errors - lets return en empty array
if(e.message === 'A task was canceled.'){
if (e.message === 'A task was canceled.') {
return new Array<ScheduleItem>()
}
}
}
throw e
}

View File

@ -2,21 +2,20 @@ import { etjanst } from './etjanst'
import { SchoolContact } from '@skolplattformen/api'
export const schoolContact = ({
title,
name,
phone,
email,
schoolName,
className,
title,
name,
phone,
email,
schoolName,
className,
}: any): SchoolContact => ({
title,
name,
phone,
email,
schoolName,
className,
title,
name,
phone,
email,
schoolName,
className,
})
export const schoolContacts = (data: any): SchoolContact[] =>
etjanst(data).map(schoolContact)

View File

@ -1,8 +1,8 @@
import { etjanst } from './etjanst'
import { Teacher } from '@skolplattformen/api'
const abbreviate = (firstname?: string, lastname?: string): string =>
`${firstname?.substr(0,1)}${lastname?.substr(0,2)}`.toUpperCase()
const abbreviate = (firstname?: string, lastname?: string): string =>
`${firstname?.substr(0, 1)}${lastname?.substr(0, 2)}`.toUpperCase()
export const teacher = ({
id,
@ -22,8 +22,7 @@ export const teacher = ({
phoneWork: telwork,
active,
status,
timeTableAbbreviation: abbreviate(firstname, lastname)
timeTableAbbreviation: abbreviate(firstname, lastname),
})
export const teachers = (data: any): Teacher[] =>
etjanst(data).map(teacher)
export const teachers = (data: any): Teacher[] => etjanst(data).map(teacher)

View File

@ -85,8 +85,8 @@ export const timetable = (
throw new Error(response.error)
}
if(!response.data.lessonInfo){
throw new Error("Empty lessonInfo received")
if (!response.data.lessonInfo) {
throw new Error('Empty lessonInfo received')
}
return response.data.lessonInfo.map((entry) =>

View File

@ -1,4 +1,4 @@
import { User } from "@skolplattformen/api";
import { User } from '@skolplattformen/api'
export const user = ({
socialSecurityNumber,

View File

@ -29,13 +29,19 @@ export default class AutoQueue extends Queue {
}
public async dequeue() {
if (this.runningTasks >= this.maxConcurrentTasks) { return false }
if (this.runningTasks >= this.maxConcurrentTasks) {
return false
}
if (this.isPaused) { return false }
if (this.isPaused) {
return false
}
const item = super.dequeue()
if (!item) { return false }
if (!item) {
return false
}
try {
this.runningTasks += 1
@ -60,13 +66,15 @@ export default class AutoQueue extends Queue {
public async start() {
this.isPaused = false
// eslint-disable-next-line no-await-in-loop
while (await this.dequeue()) {
// do nothing
}
}
public get runningTaskCount() { return this.runningTasks }
public get runningTaskCount() {
return this.runningTasks
}
public getQueueStatus() {
return this.queueStatus

View File

@ -1,11 +1,19 @@
export class Queue {
private items: any[]
constructor() { this.items = [] }
constructor() {
this.items = []
}
enqueue(item : any) { this.items.push(item) }
enqueue(item: any) {
this.items.push(item)
}
dequeue() { return this.items.shift() }
dequeue() {
return this.items.shift()
}
get size() { return this.items.length }
get size() {
return this.items.length
}
}

View File

@ -2,12 +2,12 @@ import AutoQueue from './autoQueue'
import RoundRobinArray from './roundRobinArray'
export interface QueueEntry {
id : string
queue : AutoQueue
id: string
queue: AutoQueue
}
function delay(time : any) {
return new Promise(resolve => setTimeout(resolve, time))
function delay(time: any) {
return new Promise((resolve) => setTimeout(resolve, time))
}
/**
@ -17,15 +17,15 @@ function delay(time : any) {
* Why? The external api uses state where the child must be selected
* before any calls to News etc can be done.
*
*/
*/
export default class QueueFetcher {
private queues: RoundRobinArray<QueueEntry>
private currentRunningQueue : QueueEntry | undefined
private currentRunningQueue: QueueEntry | undefined
private changeChildFunc : (childId : string) => Promise<any>
private changeChildFunc: (childId: string) => Promise<any>
private lastChildId = ''
private lastChildId = ''
private scheduleTimeout: any
@ -40,7 +40,7 @@ export default class QueueFetcher {
* @param changeChildFunc function that is called to change the current
* selected child on the server
*/
constructor(changeChildFunc : (childId : string) => Promise<any>) {
constructor(changeChildFunc: (childId: string) => Promise<any>) {
this.changeChildFunc = changeChildFunc
this.queues = new RoundRobinArray(new Array<QueueEntry>())
}
@ -54,7 +54,7 @@ export default class QueueFetcher {
* @returns a Promise that resolves when the Promise created by the func is resolved
* (i.e. is dequeued and executed)
*/
public async fetch<T>(func : () => Promise<T>, id : string) : Promise<T> {
public async fetch<T>(func: () => Promise<T>, id: string): Promise<T> {
if (!this.queues.array.some((e) => e.id === id)) {
const newQueue = new AutoQueue(10)
this.queues.add({ id, queue: newQueue })
@ -73,7 +73,9 @@ export default class QueueFetcher {
return promise
}
public get Queues() { return this.queues.array }
public get Queues() {
return this.queues.array
}
/**
* Method to schedule next queue
@ -81,10 +83,9 @@ export default class QueueFetcher {
*/
async schedule() {
// Debug print info for all queues
this.queues.array.forEach(({ id: childId, queue }) => this.debug(
'Schedule: ',
childId, '=>', queue.getQueueInfo(),
))
this.queues.array.forEach(({ id: childId, queue }) =>
this.debug('Schedule: ', childId, '=>', queue.getQueueInfo())
)
if (this.queues.size === 0) {
this.debug('No queues created yet')
@ -130,11 +131,10 @@ export default class QueueFetcher {
})
}
private async runNext(queueToRun : QueueEntry) {
private async runNext(queueToRun: QueueEntry) {
const { id: childId, queue } = queueToRun
this.debug('About to run', childId, queue.getQueueInfo())
if (this.lastChildId === childId) {
this.debug('Child already selected, skipping select call')
} else {
@ -154,20 +154,21 @@ export default class QueueFetcher {
this.scheduleTimeout = setTimeout(async () => this.schedule(), 3000)
}
private findNextQueueToRun() : QueueEntry | undefined {
private findNextQueueToRun(): QueueEntry | undefined {
// Iterate all queues and look for next queue with work to do
for (let i = 0; i < this.queues.size; i += 1) {
const { id: childId, queue } = this.queues.next()
// If queue has items to execute, return it
if (queue.size > 0 || queue.runningTaskCount > 0) return { id: childId, queue }
if (queue.size > 0 || queue.runningTaskCount > 0)
return { id: childId, queue }
}
// Nothing more to do
return undefined
}
private debug(message : any, ...args : any[]) {
private debug(message: any, ...args: any[]) {
if (this.verboseDebug) {
console.debug(message, ...args)
}

View File

@ -3,7 +3,7 @@ export default class RoundRobinArray<T> {
array: T[]
constructor(array : Array<T>, index?: number | undefined) {
constructor(array: Array<T>, index?: number | undefined) {
this.index = index || 0
if (array === undefined || array === null) {
@ -20,11 +20,15 @@ export default class RoundRobinArray<T> {
return this.array[this.index]
}
add(item : T) {
add(item: T) {
this.array.push(item)
}
get first() { return this.array[0] }
get first() {
return this.array[0]
}
get size() { return this.array.length }
get size() {
return this.array.length
}
}

View File

@ -1,14 +1,19 @@
import QueueFetcher from './queue/queueFetcher'
import {Fetcher, RequestInit, Response } from '@skolplattformen/api'
import { Fetcher, RequestInit, Response } from '@skolplattformen/api'
export default function queueFetcherWrapper(fetch: Fetcher,
changeChildFunc: ((childId: string) => Promise<Response>)) : Fetcher {
export default function queueFetcherWrapper(
fetch: Fetcher,
changeChildFunc: (childId: string) => Promise<Response>
): Fetcher {
const queue = new QueueFetcher(changeChildFunc)
queue.verboseDebug = false
return async (name: string, url: string, init: RequestInit = { headers: {} }, childId? : string)
: Promise<Response> => {
return async (
name: string,
url: string,
init: RequestInit = { headers: {} },
childId?: string
): Promise<Response> => {
if (childId === undefined) {
return fetch(name, url, init)
}

View File

@ -1,25 +1,28 @@
// BankId
export const login = (personalNumber?: string) => {
const baseUrl = 'https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt'
const optionalPersonalNumber = personalNumber === undefined ? '' : `&personalNumber=${personalNumber}`
const baseUrl =
'https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d'
const optionalPersonalNumber =
personalNumber === undefined ? '' : `&personalNumber=${personalNumber}`
return `${baseUrl}&initialize=bankid${optionalPersonalNumber}&_=${Date.now()}`
}
export const loginStatus = (order: string) =>
`https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&verifyorder=${order}&_=${Date.now()}`
export const loginCookie =
'https://login003.stockholm.se/NECSadcmbid/authenticate/SiteMinderAuthADC?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvR2V0Q2hpbGRyZW4%3d'
export const loginStatus = (order: string) =>
`https://login003.stockholm.se/NECSadcmbid/authenticate/NECSadcmbid?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d&verifyorder=${order}&_=${Date.now()}`
export const loginCookie =
'https://login003.stockholm.se/NECSadcmbid/authenticate/SiteMinderAuthADC?TYPE=33554433&REALMOID=06-42f40edd-0c5b-4dbc-b714-1be1e907f2de&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d'
// Freja
export const frejaLogin = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?action=init&return_url=https%3A%2F%2Flogin003.stockholm.se%2FNECSadcfreja%2Fauthenticate%2FNECSadcfreja'
export const frejaLoginStatus = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvaGVt&action=checkstatus'
export const frejaReturnUrl = 'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvT3ZlcnNpa3Q%3d'
export const frejaLoginCookie = 'https://login003.stockholm.se/NECSadcfreja/authenticate/SiteMinderAuthADCFREJA?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvT3ZlcnNpa3Q%3d'
export const frejaLogin =
'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?action=init&return_url=https%3A%2F%2Flogin003.stockholm.se%2FNECSadcfreja%2Fauthenticate%2FNECSadcfreja'
export const frejaLoginStatus =
'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d&action=checkstatus'
export const frejaReturnUrl =
'https://login003.stockholm.se/NECSadcfreja/authenticate/NECSadcfreja?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d'
export const frejaLoginCookie =
'https://login003.stockholm.se/NECSadcfreja/authenticate/SiteMinderAuthADCFREJA?TYPE=33554433&REALMOID=06-89cf916c-9764-45fa-8690-eaf3fe9282bc&GUID=1&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2ffreja%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0ZXIuc3RvY2tob2xtLnNlL3ZhcmRuYWRzaGF2YXJlL2lubG9nZ2FkMi9oZW0%3d'
const urlLoggedIn = `https://etjanst.stockholm.se/vardnadshavare/inloggad2`
const urlLoggedIn = `https://etjanster.stockholm.se/vardnadshavare/inloggad2`
export const children = `${urlLoggedIn}/GetChildren`
@ -36,7 +39,7 @@ export const schoolContacts = (childId: string, schoolId: string) =>
`${urlLoggedIn}/contacts/GetSchoolContacts?schoolId=${schoolId}&studentId=${childId}&schoolForm=Klasslista`
export const user =
'https://etjanst.stockholm.se/vardnadshavare/base/getuserdata'
'https://etjanster.stockholm.se/vardnadshavare/base/getuserdata'
export const news = (childId: string) =>
`${urlLoggedIn}/News/GetNewsArchive?bannerImageLimit=5000&childId=${childId}`
@ -47,7 +50,7 @@ export const newsDetails = (childId: string, newsId: string) =>
export const image = (url: string) => `${urlLoggedIn}/NewsBanner?url=${url}`
export const notifications = (childId: string) =>
`${urlLoggedIn}/notifications/getnotifications?childId=${childId}`
`${urlLoggedIn}/notifications/getnotifications?childId=${childId}`
export const menuRss = (childId: string) =>
`${urlLoggedIn}/Matsedel/GetMatsedelRSS?childId=${childId}`
@ -61,37 +64,43 @@ export const menuChoice = (childId: string) =>
export const schedule = (childId: string, fromDate: string, endDate: string) =>
`${urlLoggedIn}/Calender/GetSchema?childId=${childId}&startDate=${fromDate}&endDate=${endDate}`
export const cdn = 'https://etjanst.stockholm.se/vardnadshavare/base/cdn'
export const cdn = 'https://etjanster.stockholm.se/vardnadshavare/base/cdn'
export const auth = 'https://etjanst.stockholm.se/vardnadshavare/base/auth'
export const auth = 'https://etjanster.stockholm.se/vardnadshavare/base/auth'
export const startBundle =
'https://etjanst.stockholm.se/vardnadshavare/bundles/start'
'https://etjanster.stockholm.se/vardnadshavare/bundles/start'
export const hemPage =
'https://etjanst.stockholm.se/vardnadshavare/inloggad2/hem'
'https://etjanster.stockholm.se/vardnadshavare/inloggad2/hem'
export const navigationControllerScript =
'https://etjanst.stockholm.se/vardnadshavare/bundles/navigationController'
'https://etjanster.stockholm.se/vardnadshavare/bundles/navigationController'
export const baseEtjanst = 'https://etjanst.stockholm.se'
export const baseEtjanst = 'https://etjanster.stockholm.se'
export const childcontrollerScript = `https://etjanst.stockholm.se/vardnadshavare/bundles/childcontroller?v=${Date.now()}`
export const childcontrollerScript = `https://etjanster.stockholm.se/vardnadshavare/bundles/childcontroller?v=${Date.now()}`
export const createItemConfig =
'https://raw.githubusercontent.com/kolplattformen/embedded-api/main/config.json'
// Skola24
export const ssoRequestUrl = (targetSystem: string) =>
`https://fnsservicesso1.stockholm.se/sso-ng/saml-2.0/authenticate?customer=https://login001.stockholm.se&targetsystem=${targetSystem}`
`https://stockholm-sso.skola24.se/nssso/saml-2.0/authenticate?customer=https://login001.stockholm.se&targetsystem=${targetSystem}`
export const ssoResponseUrl = 'https://login001.stockholm.se/affwebservices/public/saml2sso'
export const samlResponseUrl = 'https://fnsservicesso1.stockholm.se/sso-ng/saml-2.0/response'
export const ssoResponseUrl =
'https://login001.stockholm.se/affwebservices/public/saml2sso'
export const samlResponseUrl =
'https://stockholm-sso.skola24.se/nssso/saml-2.0/response'
export const timetables = 'https://fns.stockholm.se/ng/api/services/skola24/get/personal/timetables'
export const renderKey = 'https://fns.stockholm.se/ng/api/get/timetable/render/key'
export const timetable = 'https://fns.stockholm.se/ng/api/render/timetable'
export const timetables =
'https://websthlm.skola24.se/api/services/skola24/get/personal/timetables'
export const renderKey =
'https://websthlm.skola24.se/api/get/timetable/render/key'
export const timetable = 'https://websthlm.skola24.se/api/render/timetable'
export const topologyConfigUrl = 'https://fantomenkrypto.vercel.app/api/getConfig'
export const topologyConfigUrl =
'https://fantomenkrypto.vercel.app/api/getConfig'
export const selectChild = 'https://etjanst.stockholm.se/vardnadshavare/inloggad2/SelectChild'
export const selectChild =
'https://etjanster.stockholm.se/vardnadshavare/inloggad2/SelectChild'

View File

@ -1 +1 @@
import '@testing-library/jest-native/extend-expect';
import '@testing-library/jest-native/extend-expect'

View File

@ -70,7 +70,6 @@ export const apiMiddleware: IMiddleware =
}
}
} catch (err) {
// eslint-disable-next-line no-console
console.error(err)
}
return next(action)
@ -105,7 +104,6 @@ export const cacheMiddleware: IMiddleware =
}
}
} catch (err) {
// eslint-disable-next-line no-console
console.error(err)
}
return next(action)

View File

@ -54,7 +54,6 @@ export const ApiProvider: TApiProvider = ({
api.off('login', handler)
api.off('logout', handler)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [api])
return (

View File

@ -33,7 +33,6 @@ const appReducer = combineReducers({
})
const rootReducer: typeof appReducer = (state, action) => {
if (action.type === 'CLEAR') {
// eslint-disable-next-line no-param-reassign
state = undefined
}
return appReducer(state, action)

View File

@ -1,6 +1,6 @@
{
"name": "skolplattformen",
"version": "2.15.2",
"version": "2.17.0",
"license": "MIT",
"scripts": {
"start": "nx start",
@ -70,7 +70,7 @@
"react-native-simple-toast": "1.1.3",
"react-native-svg": "12.1.1",
"react-native-typography": "1.4.1",
"react-native-webview": "^11.15.0",
"react-native-webview": "^11.26.1",
"react-redux": "^7.2.3",
"redux": "^4.0.5",
"regenerator-runtime": "^0.13.9",

View File

@ -11132,10 +11132,10 @@ react-native-typography@1.4.1:
resolved "https://registry.yarnpkg.com/react-native-typography/-/react-native-typography-1.4.1.tgz#2d05cb5935a2f7fdb6b43bbde93d60f1324578e3"
integrity sha512-dc9Zfs4jUdq4ygx4/KwO6jKTERBu6cRrfPJGntw/pA+D6BMjlWfMNuhZ/69vf4Zpsnt9s4AGe+Z/V1QFYaCXAA==
react-native-webview@^11.15.0:
version "11.15.0"
resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.15.0.tgz#b5aea9da579ca17fb9fd324e5202b1b5b8ce9fa8"
integrity sha512-0Wv+8qu8XuACx1xZwzc2Yfl+rOvxUouLcPxUKdkhaMVNpwoM5/ePpczCQZ3LpiRnSoEtjaUkfyQHbJQ+x4dDJQ==
react-native-webview@^12.1.0:
version "12.4.0"
resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-12.4.0.tgz#421db8e5601b4851c5796c5d4736b6b8439d1469"
integrity sha512-wYzTfNADidmqv6bY+x6NUfX8+uBR9mmF1CO1NOvY4oD2vv+D4rA0XwcwAe2D7RevXUy3fmuTT93kFQcgo8fEhg==
dependencies:
escape-string-regexp "2.0.0"
invariant "2.2.4"