Compare commits
117 Commits
Author | SHA1 | Date |
---|---|---|
Christian Landgren | a8281d4370 | |
Christian Landgren | 098bc544f2 | |
Christian Landgren | c16d60c2e2 | |
Christian Landgren | a7fa22cd54 | |
Christian Landgren | a7b9d81714 | |
Christian Landgren | b8ed895e52 | |
Christian Landgren | caafb59f8d | |
Christian Landgren | 81e448c035 | |
Christian Landgren | 62de54ef80 | |
Christian Landgren | d5e4bfd149 | |
Christian Landgren | 28e1481e3f | |
semantic-release-bot | f2a87117ba | |
Kajetan Kazimierczak | 6eb6d3a6e3 | |
Kajetan Kazimierczak | c0e6ce9e06 | |
Weblate (bot) | c9907a68b6 | |
Kajetan Kazimierczak | 320ab1f1f5 | |
Kajetan Kazimierczak | 7962234e26 | |
Kajetan Kazimierczak | b66f56b312 | |
Kajetan Kazimierczak | 442aad7fda | |
semantic-release-bot | 1f2c7ee762 | |
Kajetan Kazimierczak | d51cfe36fe | |
Kajetan Kazimierczak | c93e27bec0 | |
Kajetan Kazimierczak | 84ddda3f46 | |
semantic-release-bot | ab90b944ae | |
Sebastian Palmqvist | 34c376a727 | |
Sergio Avalos | ce535518a9 | |
Kajetan Kazimierczak | 09ae4f0eaa | |
Kajetan Kazimierczak | b5a2943fbb | |
Kajetan Kazimierczak | 4d3f940171 | |
Kajetan Kazimierczak | 6d9325c20c | |
Kajetan Kazimierczak | 27e9fb8cf7 | |
Kajetan Kazimierczak | c26b118ad0 | |
Kajetan Kazimierczak | 4e51bb8de7 | |
Kajetan Kazimierczak | 5d61cd150a | |
Kajetan Kazimierczak | 7e5013e7ca | |
semantic-release-bot | 394d0d973d | |
Kajetan Kazimierczak | e6ba622fa9 | |
semantic-release-bot | bee6d59283 | |
Mohammed Chammam | 20ae87fee1 | |
Christian Landgren | 565c27e6fb | |
semantic-release-bot | 6589d85ab0 | |
Sebastian Palmqvist | fef71c7923 | |
semantic-release-bot | ae5fd0624c | |
Oskar Strömberg | 61d47b4440 | |
semantic-release-bot | ee35ba7108 | |
Kajetan Kazimierczak | 25a2d7f3f5 | |
Kajetan Kazimierczak | 0db53ca046 | |
Kajetan Kazimierczak | f7493767b0 | |
Kajetan Kazimierczak | 7b3dfb91e7 | |
Kajetan Kazimierczak | 52c491213c | |
Viktor Sarström | 3a9c337bdd | |
Viktor Sarström | 68249e849a | |
semantic-release-bot | e77054fa60 | |
Viktor Sarström | 10e993ab9d | |
semantic-release-bot | 8a1123d640 | |
Kajetan Kazimierczak | 6d49e4767c | |
Kajetan Kazimierczak | ea6b385b4f | |
semantic-release-bot | 3acd27cc1f | |
Kajetan Kazimierczak | 7e8ee956f4 | |
Kajetan Kazimierczak | 7d8662ff09 | |
Theo Haglund | 1c0ea08056 | |
Lorentz Lasson | b1504fa181 | |
Kajetan Kazimierczak | e44c0cc392 | |
Theo O | aa9bb8c41a | |
Lage Linnarsson | b09d888f4a | |
Kajetan Kazimierczak | a314b7ab78 | |
Kajetan Kazimierczak | 23e6fe0919 | |
Kajetan Kazimierczak | 17b5d8ab40 | |
WhiredPlanck | 1684126446 | |
Kajetan Kazimierczak | e00bd6ad45 | |
Kajetan Kazimierczak | c7c170aa83 | |
Kajetan Kazimierczak | 8de7192003 | |
Luna Jernberg | 689f6c685d | |
Weblate (bot) | 63fbd3042a | |
Andreas Eriksson | 20ee509c28 | |
Weblate (bot) | 0508329998 | |
semantic-release-bot | 778823cc92 | |
Andreas Eriksson | 051df2da39 | |
semantic-release-bot | 46485dd3eb | |
Andreas Eriksson | 5577c7fe42 | |
semantic-release-bot | 1731d16c28 | |
Andreas Eriksson | 8724fa46b7 | |
Kajetan Kazimierczak | 022e422089 | |
Andreas Eriksson | dcb6d23976 | |
Andreas Eriksson | 498bdc500c | |
Andreas Eriksson | a63373caaf | |
Kajetan Kazimierczak | bc2625dc59 | |
Kajetan Kazimierczak | d8c6441c63 | |
Kajetan Kazimierczak | 8b2b680c17 | |
Kajetan Kazimierczak | 6806847d7d | |
Kajetan Kazimierczak | 8e3a9c1390 | |
Serhii Halchenko | bb9006b6ce | |
Andreas Eriksson | d1e659be42 | |
Kajetan Kazimierczak | 30b5bbb51e | |
Kajetan Kazimierczak | a6114608ed | |
Kajetan Kazimierczak | be22fd8cd3 | |
Kajetan Kazimierczak | 38cc7626ad | |
Kajetan Kazimierczak | 0c64f5ae35 | |
Kajetan Kazimierczak | 170b4da39a | |
Kajetan Kazimierczak | c5bec5f9ee | |
Kajetan Kazimierczak | 2b898854dd | |
Hosted Weblate | 0ae304633d | |
semantic-release-bot | f8de3cf741 | |
Kajetan Kazimierczak | bd02b378c0 | |
Kajetan Kazimierczak | c5302b0dff | |
Nuanla-ong Monfong | 72cc6efe33 | |
Adam Nybäck | 850831c16b | |
Nuanla-ong Monfong | dd4fa4e565 | |
Kajetan Kazimierczak | d9c62a6d91 | |
Adam Nybäck | a719fb5170 | |
Adam Nybäck | d566628189 | |
Adam Nybäck | a142468910 | |
Anna Babaryka | 4f26b541a4 | |
Marcus Dansarie | 88daf52014 | |
Lage Linnarsson | 0be6811dec | |
Lage Linnarsson | 9517a25353 | |
Lage Linnarsson | 162b0a2f0b |
|
@ -4,6 +4,8 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'apps/website/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
16.19.1
|
1180
CHANGELOG.md
1180
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
|
@ -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 2020–2021 Not Free Beer AB.
|
||||
Öppna skolplattformen is copyright 2020–2024 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.
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 20000
|
||||
versionName "3.0.3"
|
||||
versionName "3.0.10"
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-console */
|
||||
import { useApi } from '@skolplattformen/hooks'
|
||||
import {
|
||||
Button,
|
||||
|
@ -16,6 +17,7 @@ import Personnummer from 'personnummer'
|
|||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import {
|
||||
Image,
|
||||
ImageProps,
|
||||
Linking,
|
||||
Platform,
|
||||
TouchableWithoutFeedback,
|
||||
|
@ -43,18 +45,13 @@ const BankId = () => (
|
|||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
|
||||
interface Logins {
|
||||
BANKID_SAME_DEVICE: number
|
||||
BANKID_ANOTHER_DEVICE: number
|
||||
TEST_USER: number
|
||||
}
|
||||
|
||||
const LoginMethods: Logins = {
|
||||
BANKID_SAME_DEVICE: 0,
|
||||
BANKID_ANOTHER_DEVICE: 2,
|
||||
TEST_USER: 3,
|
||||
}
|
||||
const FrejaEid = () => (
|
||||
<Image
|
||||
style={themedStyles.icon}
|
||||
source={require('../assets/freja_eid_logo.png')}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
|
||||
export const Login = () => {
|
||||
const { api } = useApi()
|
||||
|
@ -66,6 +63,7 @@ export const Login = () => {
|
|||
const [showSchoolPlatformPicker, setShowSchoolPlatformPicker] =
|
||||
useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [loginStatusText, setLoginStatusText] = useState('')
|
||||
const [personalIdNumber, setPersonalIdNumber] = useSettingsStorage(
|
||||
'cachedPersonalIdentityNumber'
|
||||
)
|
||||
|
@ -74,6 +72,7 @@ export const Login = () => {
|
|||
const loginBankIdSameDeviceWithoutId = useFeature(
|
||||
'LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID'
|
||||
)
|
||||
const loginWithFrejaEnabled = useFeature('LOGIN_FREJA_EID')
|
||||
const { currentSchoolPlatform, changeSchoolPlatform } = useContext(
|
||||
SchoolPlatformContext
|
||||
)
|
||||
|
@ -85,22 +84,34 @@ export const Login = () => {
|
|||
const loginMethods = [
|
||||
{ id: 'thisdevice', title: t('auth.bankid.OpenOnThisDevice') },
|
||||
{ id: 'otherdevice', title: t('auth.bankid.OpenOnAnotherDevice') },
|
||||
{ id: 'freja', title: t('auth.freja.OpenOnThisDevice') },
|
||||
{ id: 'testuser', title: t('auth.loginAsTestUser') },
|
||||
] as const
|
||||
|
||||
const loginHandler = async () => {
|
||||
const user = await api.getUser()
|
||||
await AppStorage.clearPersonalData(user)
|
||||
showModal(false)
|
||||
if (loginMethodId === 'freja' && !loginWithFrejaEnabled) {
|
||||
setLoginMethodId('thisdevice')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const loginHandler = async () => {
|
||||
console.debug('Runnning loginHandler')
|
||||
const user = await api.getUser()
|
||||
await AppStorage.clearPersonalData(user)
|
||||
showModal(false)
|
||||
}
|
||||
|
||||
api.on('login', loginHandler)
|
||||
return () => {
|
||||
api.off('login', loginHandler)
|
||||
}
|
||||
}, [api])
|
||||
|
||||
const LoginProviderImage = () => {
|
||||
//if(loginMethodId == 'testuser') return undefined
|
||||
if (loginMethodId === 'freja') return FrejaEid()
|
||||
return BankId()
|
||||
}
|
||||
|
||||
const getSchoolPlatformName = () => {
|
||||
return schoolPlatforms.find((item) => item.id === currentSchoolPlatform)
|
||||
?.displayName
|
||||
|
@ -120,12 +131,47 @@ export const Login = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const openFreja = (token: string) => {
|
||||
try {
|
||||
const originAppScheme = encodeURIComponent(schema)
|
||||
const frejaUrl =
|
||||
Platform.OS === 'ios'
|
||||
? `${token}&originAppScheme=${originAppScheme}`
|
||||
: `${token}`
|
||||
Linking.openURL(frejaUrl)
|
||||
} catch (err) {
|
||||
setError(t('auth.freja.OpenManually'))
|
||||
}
|
||||
}
|
||||
|
||||
const isUsingPersonalIdNumber =
|
||||
loginMethodId === 'otherdevice' ||
|
||||
(loginMethodId === 'thisdevice' && !loginBankIdSameDeviceWithoutId)
|
||||
|
||||
const startLogin = async (text: string) => {
|
||||
if (loginMethodId === 'thisdevice' || loginMethodId === 'otherdevice') {
|
||||
if (loginMethodId === 'freja') {
|
||||
setLoginStatusText(t('auth.freja.Waiting'))
|
||||
showModal(true)
|
||||
const status = await api.loginFreja()
|
||||
setCancelLoginRequest(() => () => status.cancel())
|
||||
openFreja(status.token)
|
||||
status.on('STARTED', () => console.log('Freja eID app not yet opened'))
|
||||
status.on('DELIVERED_TO_MOBILE', () =>
|
||||
console.log('Freja eID app is open')
|
||||
)
|
||||
status.on('CANCELLED', () => {
|
||||
console.log('User pressed cancel in Freja eID')
|
||||
showModal(false)
|
||||
})
|
||||
status.on('APPROVED', () => {
|
||||
console.log('Freja eID ok')
|
||||
setLoginStatusText(t('auth.loginSuccessful'))
|
||||
})
|
||||
} else if (
|
||||
loginMethodId === 'thisdevice' ||
|
||||
loginMethodId === 'otherdevice'
|
||||
) {
|
||||
setLoginStatusText(t('auth.bankid.Waiting'))
|
||||
showModal(true)
|
||||
|
||||
let ssn
|
||||
|
@ -150,7 +196,10 @@ export const Login = () => {
|
|||
setError(t('auth.loginFailed'))
|
||||
showModal(false)
|
||||
})
|
||||
status.on('OK', () => console.log('BankID ok'))
|
||||
status.on('OK', () => {
|
||||
console.log('BankID ok')
|
||||
setLoginStatusText(t('auth.loginSuccessful'))
|
||||
})
|
||||
} else {
|
||||
await api.login('201212121212')
|
||||
}
|
||||
|
@ -200,7 +249,7 @@ export const Login = () => {
|
|||
appearance="ghost"
|
||||
disabled={isUsingPersonalIdNumber && !valid}
|
||||
status="primary"
|
||||
accessoryLeft={BankId}
|
||||
accessoryLeft={LoginProviderImage}
|
||||
size="medium"
|
||||
>
|
||||
{currentLoginMethod.title}
|
||||
|
@ -245,7 +294,11 @@ export const Login = () => {
|
|||
{t('auth.chooseLoginMethod')}
|
||||
</Text>
|
||||
<List
|
||||
data={loginMethods}
|
||||
data={
|
||||
loginWithFrejaEnabled
|
||||
? loginMethods
|
||||
: loginMethods.filter((f) => f.id !== 'freja')
|
||||
}
|
||||
ItemSeparatorComponent={Divider}
|
||||
renderItem={({ item, index }) => (
|
||||
<ListItem
|
||||
|
@ -279,8 +332,7 @@ export const Login = () => {
|
|||
backdropStyle={styles.backdrop}
|
||||
>
|
||||
<Card disabled>
|
||||
<Text style={styles.bankIdLoading}>{t('auth.bankid.Waiting')}</Text>
|
||||
|
||||
<Text style={styles.bankIdLoading}>{loginStatusText}</Text>
|
||||
<Button
|
||||
status="primary"
|
||||
accessible={true}
|
||||
|
|
|
@ -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 },
|
||||
})
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -7,7 +7,11 @@ export type ChildPersonalNumbers = Record<string, string>
|
|||
export const settingsState = proxy({
|
||||
hydrated: false,
|
||||
settings: {
|
||||
loginMethodId: 'thisdevice' as 'thisdevice' | 'otherdevice' | 'testuser',
|
||||
loginMethodId: 'thisdevice' as
|
||||
| 'thisdevice'
|
||||
| 'otherdevice'
|
||||
| 'testuser'
|
||||
| 'freja',
|
||||
usingSystemTheme: true,
|
||||
theme: 'light',
|
||||
cachedPersonalIdentityNumber: '',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.3;
|
||||
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.3;
|
||||
MARKETING_VERSION = 3.0.10;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
"OpenOnThisDevice": "Open BankID on this device",
|
||||
"Waiting": "Waiting for BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Open Freja eID+ manually",
|
||||
"OpenOnThisDevice": "Open Freja eID+ on this device",
|
||||
"Waiting": "Waiting for Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Choose login method",
|
||||
"chooseSchoolPlatform": "Choose platform",
|
||||
"loginAsTestUser": "Log in as a test user",
|
||||
"loginFailed": "Could not log in. Please try again.",
|
||||
"loginSuccessful": "Login successful, loading…",
|
||||
"placeholder_SocialSecurityNumber": "Your personal identity number",
|
||||
"subtitle": "The {{word}} alternative",
|
||||
"words": {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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": "子供"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
"OpenOnThisDevice": "Otwórz BankID na tym urządzeniu",
|
||||
"Waiting": "Oczekiwanie na BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Otwórz Freja eID+ manualnie",
|
||||
"OpenOnThisDevice": "Otwórz Freja eID+ na tym urządzeniu",
|
||||
"Waiting": "Oczekiwanie na Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Wybierz sposób logowania",
|
||||
"loginAsTestUser": "Zaloguj się jako użytkownik testowy",
|
||||
"loginFailed": "Logowanie nie powiodło się. Spróbuj ponownie.",
|
||||
|
@ -51,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",
|
||||
|
|
|
@ -23,10 +23,16 @@
|
|||
"OpenOnThisDevice": "Logga in med BankID",
|
||||
"Waiting": "Väntar på BankID…"
|
||||
},
|
||||
"freja": {
|
||||
"OpenManually": "Öppna Freja eID+ manuellt",
|
||||
"OpenOnThisDevice": "Logga in med Freja eID+",
|
||||
"Waiting": "Väntar på Freja eID+…"
|
||||
},
|
||||
"chooseLoginMethod": "Välj inloggningsmetod",
|
||||
"chooseSchoolPlatform": "Välj plattform",
|
||||
"loginAsTestUser": "Logga in som testanvändare",
|
||||
"loginFailed": "Inloggningen misslyckades, försök igen!",
|
||||
"loginSuccessful": "Du är inloggad! - laddar…",
|
||||
"placeholder_SocialSecurityNumber": "Ditt personnummer",
|
||||
"subtitle": "Det {{word}} alternativet",
|
||||
"words": {
|
||||
|
|
|
@ -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": "บันทึก",
|
||||
|
|
|
@ -2,13 +2,154 @@
|
|||
"abbrevations": {
|
||||
"preSchool": "дитячий сад",
|
||||
"upperSecondarySchool": "Старша школа",
|
||||
"compulsorySchool": "Початкова/середня школа"
|
||||
"compulsorySchool": "Молодша/середня школа",
|
||||
"leisureTimeCentre": "Група продовженого дня (\"Продленка\")"
|
||||
},
|
||||
"abscense": {
|
||||
"entireDay": "Повний день",
|
||||
"entireDay": "Цілий день",
|
||||
"childsPersonalNumber": "Ідентифікаційний номер дитини",
|
||||
"endTime": "кінцевий час",
|
||||
"endTime": "час закінчення",
|
||||
"invalidPersonalNumber": "Невірний ідентифікаційний номер",
|
||||
"personalNumberMissing": "Ідентифікаційний код відсутній"
|
||||
"personalNumberMissing": "Ідентифікаційний код відсутній",
|
||||
"startTime": "Час початку",
|
||||
"title": "Додати відсутність",
|
||||
"selectAbscenseEndTime": "Виберіть кінцевий час",
|
||||
"selectAbscenseStartTime": "Виберіть час початку"
|
||||
},
|
||||
"auth": {
|
||||
"bankid": {
|
||||
"OpenManually": "Відкрити BankID власноруч",
|
||||
"OpenOnAnotherDevice": "Відкрити BankID на іншому пристрої",
|
||||
"OpenOnThisDevice": "Відкрити BankID на цьому пристрої",
|
||||
"Waiting": "Очікую на BankID…"
|
||||
},
|
||||
"chooseLoginMethod": "Оберіть як увійти",
|
||||
"chooseSchoolPlatform": "Оберіть платформу",
|
||||
"loginFailed": "Не зміг увійти. Спробуйте ще раз.",
|
||||
"placeholder_SocialSecurityNumber": "Ваш ідентифікаційний номер",
|
||||
"loginAsTestUser": "Увійти як тестовий користувач",
|
||||
"subtitle": "{{word}} альтернатива",
|
||||
"words": {
|
||||
"agile": "Гнучка",
|
||||
"awaited": "Очікувана",
|
||||
"better": "Краща",
|
||||
"cheap": "Дешева",
|
||||
"cooler": "Крутіша",
|
||||
"enlightened": "Освічена",
|
||||
"fantastic": "Фантастична",
|
||||
"fast": "Швидка",
|
||||
"first": "Перша",
|
||||
"free": "Безкоштовна",
|
||||
"fun": "Весела",
|
||||
"homemade": "Домашня",
|
||||
"imperfect": "Недосконала",
|
||||
"open": "Відкрита",
|
||||
"rebellious": "Бунтівна",
|
||||
"simple": "Проста",
|
||||
"working": "Робоча"
|
||||
},
|
||||
"a11y_change_language": "Оберіть вашу мову",
|
||||
"a11y_image_two_boys": "Зображення двох людей, які перевіряють свої телефони",
|
||||
"a11y_clear_social_security_input_field": "Очистити поле вводу ідентифікаційного номера",
|
||||
"a11y_select_login_method": "Оберіть як увійти",
|
||||
"freja": {
|
||||
"Waiting": "Очікую на Freja eID+…",
|
||||
"OpenManually": "Відкрити Freja eID+ власноруч",
|
||||
"OpenOnThisDevice": "Відкрити Freja eID+ на цьому пристрої"
|
||||
}
|
||||
},
|
||||
"calender": {
|
||||
"approveAccessToCalender": "Вам потрібно дозволити доступ до вашого календаря",
|
||||
"saveToCalender": "Зберегти у каледарі",
|
||||
"saveToCalenderError": "Помилка збереження у календарі",
|
||||
"saveToCalenderSuccess": "✔️ Збережено у календарі",
|
||||
"showCalenderActions": "Показати дії у календарі",
|
||||
"emptyHeadline": "У вашому календарі немає записів",
|
||||
"emptyText": "Нічого показати"
|
||||
},
|
||||
"children": {
|
||||
"loadingErrorHeading": "Помилка!",
|
||||
"loadingErrorInformationText": "Неможливо завантажити цю сторінку. Спробуйте ще раз або дізнайтеся статус на skolplattformen.org.",
|
||||
"noKids_description": "На ваш ідентифікаційний номер не зареєстровано жодної дитини в Стокгольмі",
|
||||
"noKids_title": "Немає дітей",
|
||||
"title": "Ваші діти",
|
||||
"tryAgain": "Спробуйте ще",
|
||||
"viewStatus": "Дізнайтеся статус на skolplattformen.org"
|
||||
},
|
||||
"general": {
|
||||
"cancel": "Скасувати",
|
||||
"changeLanguage": "Змінити мову",
|
||||
"confirm": "Підтвердити",
|
||||
"loading": "Завантаження…",
|
||||
"logout": "Вийти",
|
||||
"logoutAndClearPersonalData": "Вийти та очистити персональні дані",
|
||||
"send": "Відправити",
|
||||
"settings": "Налаштування",
|
||||
"socialSecurityNumber": "Ідентифікаційний номер",
|
||||
"title": "Відкрити skolplattformen",
|
||||
"tomorrow": "Завтра",
|
||||
"logoutAndClearAllDataInclSettings": "Вийти та очистити дані, включаючи налаштування"
|
||||
},
|
||||
"language": {
|
||||
"changeLanguage": "Змінити мову",
|
||||
"changeLanguageButton": "Зберегти"
|
||||
},
|
||||
"menu": {
|
||||
"emptyHeadline": "Нічого немає в меню на обід",
|
||||
"emptyText": "На цьому тижні нічого немає"
|
||||
},
|
||||
"navigation": {
|
||||
"calender": "Календар",
|
||||
"menu": "Обід",
|
||||
"news": "Новини",
|
||||
"notifications": "Повідомлення",
|
||||
"classmates": "Однокласники"
|
||||
},
|
||||
"settings": {
|
||||
"settings": "Налаштування",
|
||||
"appearance": "Зовнішній вигляд",
|
||||
"theme": "Тема",
|
||||
"licenses": "Ліцензії",
|
||||
"language": "Мова",
|
||||
"themeAuto": "Автоматично",
|
||||
"useSystemTheme": "Використати системну світлу/темну тему"
|
||||
},
|
||||
"themes": {
|
||||
"light": "Світла",
|
||||
"dark": "Темна"
|
||||
},
|
||||
"news": {
|
||||
"backToChild": "Назад до дитини",
|
||||
"noNewNewsItemsThisWeek": "Цього тижня новин немає.",
|
||||
"notificationTitle": "Новини: {{header}} ({{published}})",
|
||||
"published": "Опубліковано",
|
||||
"title": "Новини від Skolplattformen",
|
||||
"updated": "Оновлено",
|
||||
"search": {
|
||||
"placeholder": "Шукати у новинах…"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"notificationTitle": "Повідомлення: {{message}} ({{dateCreated}})"
|
||||
},
|
||||
"schedule": {
|
||||
"start": "Початок",
|
||||
"end": "Кінець",
|
||||
"lunch": "Обід",
|
||||
"week": "Тиждень",
|
||||
"gymBag": "Спортивна сумка"
|
||||
},
|
||||
"classmates": {
|
||||
"class": "Клас",
|
||||
"child": "Дитина",
|
||||
"contactsForGuardiansFor": "Контактна інформація для опікунів для"
|
||||
},
|
||||
"contact": {
|
||||
"a11y_show_contact_info_button_hint": "Показує контактну інформацію",
|
||||
"a11y_show_contact_info_button_label": "Показати контактну інформацію",
|
||||
"call": "Дзвінок",
|
||||
"sms": "СМС",
|
||||
"email": "Е-мейл",
|
||||
"home": "Адреса"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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": "课堂",
|
||||
|
|
|
@ -149,7 +149,7 @@ export const languages: Language[] = [
|
|||
languageName: 'Ukrainian',
|
||||
languageLocalName: 'український',
|
||||
locale: 'uk',
|
||||
active: false,
|
||||
active: true,
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
k8s
|
||||
k8s
|
|
@ -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"]
|
|
@ -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>
|
||||
|
|
|
@ -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 = [
|
||||
{
|
||||
|
|
|
@ -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 så 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>
|
||||
|
|
|
@ -87,7 +87,7 @@ const Privacy = () => {
|
|||
<p>
|
||||
Denna integritetspolicy gäller fr.o.m. 2021-09-13. Ändringar i denna
|
||||
policy finns dokumenterade på vår{' '}
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen-app/">
|
||||
<Link.External href="https://github.com/kolplattformen/skolplattformen/">
|
||||
GitHub
|
||||
</Link.External>
|
||||
.
|
||||
|
|
|
@ -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 på ren svenska)</h3>
|
||||
<p>
|
||||
All information i appen kommer från Skolplattformen. Informationen
|
||||
lämnar aldrig din telefon. Vi är snudd på 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 gå 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 på 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 så sker kommer loggad data att vara strikt begränsad till
|
||||
systeminformation såsom namn på 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 på säkerheten i det systemet. I fall då vi, i arbetet
|
||||
med att bygga denna app, har upptäckt potentiella svagheter i
|
||||
Skolplattformen har vi vidtagit steg för att rapportera detta på 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 så sker. Vi kommer dock informera om det i appen. Om
|
||||
du vill vara på den säkra sidan kan du återbesöka den här sidan då och
|
||||
då.
|
||||
</p>
|
||||
<p>
|
||||
Denna integritetspolicy gäller fr.o.m. 2024-04-29. Ändringar i denna
|
||||
policy finns dokumenterade på 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
|
|
@ -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 på 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 på egen fritid med något som förbättrar det kommunen lagt en
|
||||
miljard av allmänna medel på.
|
||||
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 på långa vägar den tid
|
||||
vi lagt ner. Just nu jobbar vi på egen fritid med något som förbättrar
|
||||
det kommunen lagt en miljard av allmänna medel på.
|
||||
</p>
|
||||
<h3>
|
||||
Är det moraliskt att tjäna pengar på något som kommunen borde erbjuda
|
||||
|
@ -311,13 +309,13 @@ const QA = () => {
|
|||
Det är en anspelning på hur GNU-projektet beskriver fri programvara:
|
||||
To understand the concept, you should think of “free” as in “free
|
||||
speech,” not as in “free beer”. Då 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>
|
||||
|
|
|
@ -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>{' '}
|
||||
🥇
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- web.yaml
|
|
@ -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
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "skolplattformen-site",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.4",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { NextPage } from 'next'
|
||||
import PrivacyElevApp from '../components/PrivacyElevApp'
|
||||
|
||||
const IntegrityElevAppPage: NextPage = () => {
|
||||
return <PrivacyElevApp />
|
||||
}
|
||||
|
||||
export default IntegrityElevAppPage
|
|
@ -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: {}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
Fetch,
|
||||
Fetcher,
|
||||
FetcherOptions,
|
||||
FrejaLoginStatusChecker,
|
||||
LoginStatusChecker,
|
||||
MenuItem,
|
||||
NewsItem,
|
||||
|
@ -603,4 +604,8 @@ export class ApiHjarntorget extends EventEmitter implements Api {
|
|||
emitter.token = 'fake'
|
||||
return emitter
|
||||
}
|
||||
|
||||
async loginFreja(): Promise<FrejaLoginStatusChecker> {
|
||||
throw new Error('Not implemented...')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Features } from '@skolplattformen/api'
|
|||
|
||||
export const features: Features = {
|
||||
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: false,
|
||||
LOGIN_FREJA_EID: false,
|
||||
FOOD_MENU: false,
|
||||
CLASS_LIST: false,
|
||||
}
|
||||
|
|
|
@ -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": [
|
||||
{
|
||||
|
|
|
@ -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"`;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import QueueFetcher from '../queue/queueFetcher'
|
||||
|
||||
let sut : QueueFetcher
|
||||
let sut: QueueFetcher
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers('legacy')
|
||||
sut = new QueueFetcher(async () => '')
|
||||
|
|
|
@ -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'))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
Fetch,
|
||||
Fetcher,
|
||||
FetcherOptions,
|
||||
FrejaLoginStatusChecker,
|
||||
LoginStatusChecker,
|
||||
MenuItem,
|
||||
NewsItem,
|
||||
|
@ -31,6 +32,7 @@ import { DateTime } from 'luxon'
|
|||
import * as html from 'node-html-parser'
|
||||
import * as fake from './fakeData'
|
||||
import { checkStatus, DummyStatusChecker } from './loginStatusChecker'
|
||||
import { checkStatus as checkFrejaStatus } from './frejaLoginStatusChecker'
|
||||
import * as parse from './parse/index'
|
||||
import queueFetcherWrapper from './queueFetcherWrapper'
|
||||
import * as routes from './routes'
|
||||
|
@ -42,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',
|
||||
},
|
||||
}
|
||||
|
@ -97,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
|
||||
|
@ -154,7 +157,12 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
const status = checkStatus(this.fetch, ticket)
|
||||
status.on('OK', async () => {
|
||||
await this.retrieveSessionCookie()
|
||||
await this.retrieveXsrfToken()
|
||||
|
||||
const [user] = await Promise.all([
|
||||
this.getUser(),
|
||||
this.retrieveXsrfToken(),
|
||||
])
|
||||
this.personalNumber = user.personalNumber
|
||||
|
||||
this.isLoggedIn = true
|
||||
this.emit('login')
|
||||
|
@ -166,6 +174,52 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
return status
|
||||
}
|
||||
|
||||
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}]`
|
||||
// )
|
||||
// }
|
||||
|
||||
const appSwitchUrl: string = await loginResponse.text()
|
||||
const cleanAppSwitchUrl = this.cleanFrejaAppSwitchUrl(appSwitchUrl)
|
||||
|
||||
console.log('getting freja login url: ' + cleanAppSwitchUrl)
|
||||
|
||||
const checkStatusSession = await this.getSession(loginUrl, {
|
||||
redirect: 'manual',
|
||||
})
|
||||
|
||||
const status = checkFrejaStatus(
|
||||
this.fetch,
|
||||
cleanAppSwitchUrl,
|
||||
checkStatusSession
|
||||
)
|
||||
status.on('APPROVED', async () => {
|
||||
await this.retrieveFrejaSessionCookie()
|
||||
const [user] = await Promise.all([
|
||||
this.getUser(),
|
||||
this.retrieveXsrfToken(),
|
||||
])
|
||||
this.personalNumber = user.personalNumber
|
||||
|
||||
this.isLoggedIn = true
|
||||
this.emit('login')
|
||||
})
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
private cleanFrejaAppSwitchUrl(url: string): string {
|
||||
const parts = url.split('&')
|
||||
return parts[0]
|
||||
}
|
||||
|
||||
public async setSessionCookie(sessionCookie: string): Promise<void> {
|
||||
// Manually set cookie in this call and let the cookieManager
|
||||
// handle it from here
|
||||
|
@ -194,6 +248,22 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
await this.fetch('login-cookie', url)
|
||||
}
|
||||
|
||||
private async retrieveFrejaSessionCookie(): Promise<void> {
|
||||
try {
|
||||
const url = routes.frejaReturnUrl
|
||||
await this.fetch('freja-login-return-url', url)
|
||||
} catch (error) {
|
||||
console.log(JSON.stringify(error))
|
||||
}
|
||||
|
||||
try {
|
||||
const url2 = routes.frejaLoginCookie
|
||||
await this.fetch('freja-login-cookie', url2)
|
||||
} catch (error2) {
|
||||
console.log(JSON.stringify(error2))
|
||||
}
|
||||
}
|
||||
|
||||
private async retrieveXsrfToken(): Promise<void> {
|
||||
const url = routes.hemPage
|
||||
const session = this.getRequestInit()
|
||||
|
@ -237,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)
|
||||
|
@ -253,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
|
||||
|
@ -290,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()
|
||||
|
@ -342,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
|
||||
|
@ -363,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()
|
||||
|
@ -489,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({
|
||||
|
@ -505,7 +586,6 @@ export class ApiSkolplattformen extends EventEmitter implements Api {
|
|||
getPersonalTimetablesResponse: { childrenTimetables },
|
||||
},
|
||||
} = await response.json()
|
||||
|
||||
return childrenTimetables as Skola24Child[]
|
||||
}
|
||||
|
||||
|
@ -538,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,
|
||||
|
@ -552,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,
|
||||
|
@ -568,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()
|
||||
|
@ -591,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
|
||||
}
|
||||
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
]
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
],
|
||||
],
|
||||
]
|
||||
])
|
||||
|
|
|
@ -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[] =>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
],
|
||||
]
|
||||
],
|
||||
])
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
],
|
||||
],
|
||||
])
|
||||
|
|
|
@ -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: '',
|
||||
},
|
||||
],
|
||||
],
|
||||
])
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
],
|
||||
],
|
||||
])
|
||||
|
|
|
@ -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',
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Features } from '@skolplattformen/api'
|
|||
|
||||
export const features: Features = {
|
||||
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: true,
|
||||
LOGIN_FREJA_EID: true,
|
||||
FOOD_MENU: true,
|
||||
CLASS_LIST: true,
|
||||
}
|
||||
|
|
|
@ -0,0 +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
|
||||
|
||||
private fetcher: Fetcher
|
||||
private url: string
|
||||
|
||||
private cancelled = false
|
||||
|
||||
constructor(fetcher: Fetcher, token: string) {
|
||||
super()
|
||||
this.fetcher = fetcher
|
||||
|
||||
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()
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
export const checkStatus = (
|
||||
fetch: Fetcher,
|
||||
token: string,
|
||||
session: RequestInit
|
||||
): FrejaLoginStatusChecker => new FrejaChecker(fetch, token)
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></div></div>',
|
||||
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></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="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></div></div>',
|
||||
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></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="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></div></div>',
|
||||
Body: '<div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":4,"id":"1212fc8d-dd6b-408a-8d5d-9f1cc787efbb","position":{"controlIndex":2,"sectionIndex":1,"sectionFactor":12,"zoneIndex":1,"layoutIndex":1},"addedFromPersistedData":true,"emphasis":{}}"><div data-sp-rte=""><p>Hej,</p><p>Nu är problemet löst! Alla betyg syns som de ska. </p><p>God jul!</p></div></div><div data-sp-canvascontrol="" data-sp-canvasdataversion="1.0" data-sp-controldata="{"controlType":0,"pageSettingsSlice":{"isDefaultDescription":true,"isDefaultThumbnail":true}}"></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://www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-cke-saved-href="https://www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-interception="on" title="https://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://www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-cke-saved-href="https://www.1177.se/sjukdomar--besvar/hud-har-och-naglar/harbotten-och-harsackar/huvudloss/" data-interception="on" title="https://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 </strong>',
|
||||
Body: '<i>italic</i> <b>bold</b> <em>emphasis </em><br/><strong>strong</strong><strong>nbsp </strong>',
|
||||
BodyNoHtml: null,
|
||||
AuthorDisplayName: 'Tieto Evry',
|
||||
altText: null,
|
||||
|
@ -330,4 +327,4 @@ describe('newsItem', () => {
|
|||
expect(item.body).toContain('**strong**')
|
||||
expect(item.body).toContain('**nbsp**')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
])
|
||||
})
|
||||
|
|
|
@ -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'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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}`,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) =>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { User } from "@skolplattformen/api";
|
||||
import { User } from '@skolplattformen/api'
|
||||
|
||||
export const user = ({
|
||||
socialSecurityNumber,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -1,16 +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 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=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=IfNE0iMOtzq2TcxFADHylR6rkmFtwzoxRKh5nRMO9NBqIxHrc38jFyt56FASdxk1&TARGET=-SM-HTTPS%3a%2f%2flogin001%2estockholm%2ese%2fNECSadc%2fmbid%2fb64startpage%2ejsp%3fstartpage%3daHR0cHM6Ly9ldGphbnN0LnN0b2NraG9sbS5zZS92YXJkbmFkc2hhdmFyZS9pbmxvZ2dhZDIvR2V0Q2hpbGRyZW4%3d'
|
||||
'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'
|
||||
|
||||
const urlLoggedIn = `https://etjanst.stockholm.se/vardnadshavare/inloggad2`
|
||||
// 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%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://etjanster.stockholm.se/vardnadshavare/inloggad2`
|
||||
|
||||
export const children = `${urlLoggedIn}/GetChildren`
|
||||
|
||||
|
@ -27,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}`
|
||||
|
@ -38,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}`
|
||||
|
@ -52,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'
|
||||
|
|
|
@ -1 +1 @@
|
|||
import '@testing-library/jest-native/extend-expect';
|
||||
import '@testing-library/jest-native/extend-expect'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Language } from '@skolplattformen/curriculum'
|
||||
import { EventEmitter } from 'events'
|
||||
import { DateTime } from 'luxon'
|
||||
import { LoginStatusChecker } from './loginStatus'
|
||||
import { LoginStatusChecker, FrejaLoginStatusChecker } from './loginStatus'
|
||||
import {
|
||||
CalendarItem,
|
||||
Classmate,
|
||||
|
@ -22,6 +22,7 @@ export interface Api extends EventEmitter {
|
|||
isLoggedIn: boolean
|
||||
getPersonalNumber(): string | undefined
|
||||
login(personalNumber?: string): Promise<LoginStatusChecker>
|
||||
loginFreja(): Promise<FrejaLoginStatusChecker>
|
||||
setSessionCookie(sessionCookie: string): Promise<void>
|
||||
getSessionHeaders(url: string): Promise<{ [index: string]: string }>
|
||||
getUser(): Promise<User>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
export interface Features {
|
||||
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: boolean
|
||||
LOGIN_BANK_ID_SAME_DEVICE_WITHOUT_ID: boolean,
|
||||
LOGIN_FREJA_EID: boolean,
|
||||
FOOD_MENU: boolean,
|
||||
CLASS_LIST: boolean
|
||||
CLASS_LIST: boolean,
|
||||
|
||||
}
|
||||
|
||||
export type FeatureType = keyof Features
|
||||
|
|
|
@ -2,7 +2,7 @@ import wrap from './fetcher'
|
|||
|
||||
export { toMarkdown } from './parseHtml'
|
||||
export * from './types'
|
||||
export { LoginStatusChecker } from './loginStatus'
|
||||
export { LoginStatusChecker, FrejaLoginStatusChecker } from './loginStatus'
|
||||
export { Api } from './api'
|
||||
export { FetcherOptions, Fetcher } from './fetcher'
|
||||
export {
|
||||
|
|
|
@ -15,3 +15,12 @@ export interface LoginStatusChecker {
|
|||
) => LoginStatusChecker
|
||||
cancel: () => Promise<void>
|
||||
}
|
||||
|
||||
export interface FrejaLoginStatusChecker {
|
||||
token: string
|
||||
on: (
|
||||
event: 'APPROVED' | 'STARTED' | 'UNKNOWN' | 'DELIVERED_TO_MOBILE' | 'CANCELLED' | 'EXPIRED' | 'RP_CANCELED' | 'ERROR',
|
||||
listener: (...args: any[]) => void
|
||||
) => FrejaLoginStatusChecker
|
||||
cancel: () => Promise<void>
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ describe('parse', () => {
|
|||
expect(parse('MLACH')).toEqual({
|
||||
code: 'MLACH',
|
||||
category: 'Modersmål',
|
||||
name: 'Acoli',
|
||||
name: 'Acholi',
|
||||
})
|
||||
expect(parse('MLAAR')).toEqual({
|
||||
code: 'MLAAR',
|
||||
|
|
|
@ -47,16 +47,16 @@
|
|||
"TY": "German"
|
||||
},
|
||||
"languages": {
|
||||
"ACE": "Acehnesic",
|
||||
"ACH": "Acoli",
|
||||
"ACE": "Acehnese",
|
||||
"ACH": "Acholi",
|
||||
"AAR": "Afar, Danakil",
|
||||
"AFR": "Afrikaans",
|
||||
"AKA": "Akan, Asante, Fante",
|
||||
"SQI": "Albanian",
|
||||
"AMH": "Amharic",
|
||||
"ARA": "Arabic",
|
||||
"HYE": "Armenic",
|
||||
"AII": "Assyric, New arameic",
|
||||
"HYE": "Armenian",
|
||||
"AII": "Assyric, Neo-Aramaic",
|
||||
"AYM": "Aymara",
|
||||
"AZE": "Azerbaijani",
|
||||
"BAL": "Baluchi, Baloci, Baluci, Makrani",
|
||||
|
|
|
@ -24,6 +24,8 @@ const translations: Translations = {
|
|||
nb_NO: require('./nb_NO.json'),
|
||||
pl: require('./pl.json'),
|
||||
pt: require('./pt.json'),
|
||||
th: require('./th.json'),
|
||||
uk: require('./uk.json'),
|
||||
zh_Hans: require('./zh_Hans.json'),
|
||||
}
|
||||
const languageList: string[] = Object.keys(translations)
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
},
|
||||
"languages": {
|
||||
"ACE": "Acehnesiska",
|
||||
"ACH": "Acoli",
|
||||
"ACH": "Acholi",
|
||||
"AAR": "Afar, Danakil",
|
||||
"AFR": "Afrikaans",
|
||||
"AKA": "Akan",
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"languages": {
|
||||
"SQI": "ภาษาแอลเบเนีย",
|
||||
"FRA": "ภาษาฝรั่งเศส",
|
||||
"MYA": "ภาษาพม่า",
|
||||
"AII": "ภาษาอัสซีเรีย",
|
||||
"AAR": "ภาษา Afar ดานาคิล",
|
||||
"AFR": "ภาษาแอฟริกัน",
|
||||
"ACE": "ภาษาอาเจะห์",
|
||||
"ACH": "ภาษาอโชลี",
|
||||
"AKA": "ภาษาอะกัน",
|
||||
"ARA": "ภาษาอารบ",
|
||||
"HYE": "ภาษาอาร์เมเนีย",
|
||||
"AYM": "ภาษาไอมารา",
|
||||
"AZE": "ภาษาอาเซอร์ไบจัน",
|
||||
"DAN": "ภาษาเดนมาร์ก",
|
||||
"ENG": "ภาษาอังกฤษ",
|
||||
"GRE": "ภาษากรีก",
|
||||
"ITA": "ภาษาอิตาลี",
|
||||
"JPN": "ภาษาญี่ปุ่น",
|
||||
"ZHO": "ภาษาจีน",
|
||||
"AMH": "ภาษาอัมฮาริก"
|
||||
},
|
||||
"subjects": {
|
||||
"BL": "ศิลปะศึกษา",
|
||||
"EN": "ภาษาอังกฤษ",
|
||||
"MA": "คณิตศาสตร์",
|
||||
"NO": "วิทยาศาสตร์ธรรมชาติ",
|
||||
"FY": "ฟิสิกส์",
|
||||
"SO": "สังคมศึกษา",
|
||||
"HI": "ประวัติศาสตร์",
|
||||
"RE": "ศาสนา",
|
||||
"SH": "หน้าที่พลเมืองศึกษา",
|
||||
"SV": "ภาษาสวีเดน",
|
||||
"IDH": "กีฬาและสุขภาพ",
|
||||
"GE": "ภูมิศาสตร์",
|
||||
"SL": "งานฝีมือ",
|
||||
"SVA": "ภาษาสวีเดนเป็นภาษาที่สอง",
|
||||
"TN": "ภาษามือ",
|
||||
"TK": "เทคโนโลยี",
|
||||
"ES": "สุนทรียภาพ",
|
||||
"MU": "ดนตรี",
|
||||
"KE": "เคมี",
|
||||
"BI": "ชีววิทยา"
|
||||
},
|
||||
"traningsskolaSubjects": {
|
||||
"KOM": "การสื่อสาร"
|
||||
},
|
||||
"specialLanguages": {
|
||||
"EN": "ภาษาอังกฤษ",
|
||||
"FR": "ภาษาฝรั่งเศส",
|
||||
"FI": "ภาษาฟินแลนด์",
|
||||
"IT": "ภาษาอิตาลี",
|
||||
"JAP": "ภาษาญี่ปุ่น",
|
||||
"KI": "ภาษาจีน",
|
||||
"PO": "ภาษาโปรตุเกส",
|
||||
"SP": "ภาษาสเปน",
|
||||
"SV": "ภาษาสวีเดน",
|
||||
"SVA": "ภาษาสวีเดนเป็นภาษาที่สอง",
|
||||
"TN": "ภาษามือ",
|
||||
"TY": "ภาษาเยอรมัน",
|
||||
"RY": "ภาษารัสเซีย",
|
||||
"SAM": "ภาษาซามิ"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
{
|
||||
"languages": {
|
||||
"MON": "Монгольська",
|
||||
"ROM": "Румуньська",
|
||||
"SLV": "Словенська",
|
||||
"SOM": "Сомалійська",
|
||||
"SPA": "Іспанська",
|
||||
"TAT": "Татарська",
|
||||
"SPK": "Інша мова",
|
||||
"SQI": "Албанська",
|
||||
"ARA": "Арабська",
|
||||
"AZE": "Азербайджанська",
|
||||
"BEN": "Бенгальська",
|
||||
"BOS": "Боснійська",
|
||||
"BUL": "Болгарська",
|
||||
"DAN": "Датська",
|
||||
"ENG": "Англійська",
|
||||
"EST": "Естонська",
|
||||
"FIJ": "Фіджійська",
|
||||
"FIN": "Фінська",
|
||||
"VLS": "Фламандська",
|
||||
"FRA": "Французська",
|
||||
"HEB": "Іврит",
|
||||
"HIN": "Хінді",
|
||||
"IND": "Індонезійська",
|
||||
"ISL": "Ісландська",
|
||||
"ITA": "Італійська",
|
||||
"JPN": "Японська",
|
||||
"YID": "Ідіш",
|
||||
"CAT": "Каталанська",
|
||||
"ZHO": "Китайська",
|
||||
"YUE": "Китайська, Кантонійська",
|
||||
"HRV": "Хорватська",
|
||||
"KUR": "Курдська",
|
||||
"LAV": "Латвійська",
|
||||
"LIT": "Литовська",
|
||||
"MKD": "Македонська",
|
||||
"MLT": "Мальтійська",
|
||||
"AFR": "Південно-африканська",
|
||||
"HYE": "Армянська",
|
||||
"GRE": "Грецька",
|
||||
"CMN": "Китайська, Мандаринська",
|
||||
"NEP": "Непальська",
|
||||
"NOR": "Норвезька",
|
||||
"FAS": "Персійська",
|
||||
"KAT": "Грузинська",
|
||||
"KOR": "Корейська",
|
||||
"POR": "Португальська",
|
||||
"RON": "Румунська",
|
||||
"NSM": "Самі",
|
||||
"TIB": "Тібетська",
|
||||
"KAL": "Гренладська",
|
||||
"KAZ": "Казахська",
|
||||
"KIR": "Киргизська",
|
||||
"NLD": "Нідерландська",
|
||||
"SMI": "Самі",
|
||||
"POL": "Польська",
|
||||
"DEU": "Німецька",
|
||||
"RUS": "Російська",
|
||||
"TUR": "Турецька",
|
||||
"SRP": "Сербська",
|
||||
"HBS": "Сербо-хорватська",
|
||||
"SLK": "Словацька",
|
||||
"SWA": "Суахілі",
|
||||
"SYR": "Сирійська",
|
||||
"THA": "Тайська",
|
||||
"CES": "Чеська",
|
||||
"UKR": "Українська",
|
||||
"HUN": "Угорська",
|
||||
"UZB": "Узбекська",
|
||||
"VIE": "В'єтнамська"
|
||||
},
|
||||
"categories": {
|
||||
"modernLanguages": "Сучасні мови",
|
||||
"modernLanguagesA1": "CEFR принаймні A1+",
|
||||
"modernLanguagesA2": "CEFR принаймні A2",
|
||||
"modernLanguagesAlt": "Інша сучасна мова, CEFR принаймні A2",
|
||||
"unknown": "Невідома",
|
||||
"misc": "Різне"
|
||||
},
|
||||
"misc": {
|
||||
"RAST": "Перерва",
|
||||
"LUNCH": "Обід",
|
||||
"PRANDIUM": "Обід"
|
||||
},
|
||||
"subjects": {
|
||||
"BL": "Мистецтво",
|
||||
"MA": "Математика",
|
||||
"MU": "Музика",
|
||||
"NO": "Наука",
|
||||
"FY": "Фізика",
|
||||
"TN": "Мова жестів",
|
||||
"ES": "Естетика",
|
||||
"IDH": "Фізичне виховання",
|
||||
"SV": "Шведська",
|
||||
"TK": "Технології",
|
||||
"EN": "Англійська",
|
||||
"BI": "Біологія",
|
||||
"KE": "Хімія",
|
||||
"GE": "Географія",
|
||||
"RE": "Релігія",
|
||||
"HI": "Історія",
|
||||
"SVA": "Шведська як друга мова"
|
||||
},
|
||||
"traningsskolaSubjects": {
|
||||
"VAA": "Щоденні справи",
|
||||
"VEU": "Сприйняття",
|
||||
"KOM": "Комунікації",
|
||||
"MOT": "Фізична координація"
|
||||
},
|
||||
"specialLanguages": {
|
||||
"FR": "Французська",
|
||||
"IT": "Італійська",
|
||||
"KI": "Китайська",
|
||||
"PO": "Португальська",
|
||||
"RY": "Російська",
|
||||
"SAM": "Мова Самі",
|
||||
"SP": "Іспанська",
|
||||
"TN": "Мова жестів",
|
||||
"EN": "Англійська",
|
||||
"JAP": "Японська",
|
||||
"SVA": "Шведська як друга мова",
|
||||
"TY": "Німецька",
|
||||
"FI": "Фінська",
|
||||
"SV": "Шведська"
|
||||
}
|
||||
}
|
|
@ -51,8 +51,8 @@ export const apiMiddleware: IMiddleware =
|
|||
}
|
||||
storeApi.dispatch(errorAction)
|
||||
|
||||
// Retry 3 times
|
||||
if (retries < 3) {
|
||||
// Retry 7 times
|
||||
if (retries < 7) {
|
||||
const retryAction: EntityAction<any> = {
|
||||
...action,
|
||||
type: 'GET_FROM_API',
|
||||
|
@ -63,14 +63,13 @@ export const apiMiddleware: IMiddleware =
|
|||
}
|
||||
setTimeout(() => {
|
||||
storeApi.dispatch(retryAction)
|
||||
}, retries * 500)
|
||||
}, 2 ** retries * 100)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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)
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "skolplattformen",
|
||||
"version": "2.13.0",
|
||||
"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",
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue