fix: rename and fix imports

This commit is contained in:
Jonathan Edenström 2021-10-05 17:44:14 +02:00
parent d90cfd2a3b
commit 18ed8620af
55 changed files with 424 additions and 9075 deletions

View File

@ -31,5 +31,8 @@
"extends": ["plugin:@nrwl/nx/javascript"],
"rules": {}
}
]
],
"globals": {
"__DEV__": true
}
}

View File

@ -1,8 +1,8 @@
import * as eva from '@eva-design/eva'
import AsyncStorage from '@react-native-async-storage/async-storage'
import CookieManager from '@react-native-community/cookies'
import { ApiProvider } from '@skolplattformen/api-hooks'
import init from '@skolplattformen/embedded-api'
import init from '@skolplattformen/api-skolplattformen'
import { ApiProvider } from '@skolplattformen/hooks'
import { ApplicationProvider, IconRegistry } from '@ui-kitten/components'
import { EvaIconsPack } from '@ui-kitten/eva-icons'
import React from 'react'

View File

@ -1,15 +1,15 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { useRoute } from '@react-navigation/native'
import { useUser } from '@skolplattformen/hooks'
import { fireEvent, waitFor } from '@testing-library/react-native'
import Mockdate from 'mockdate'
import React from 'react'
import { useSMS } from '../../utils/SMS'
import { render } from '../../utils/testHelpers'
import Absence from '../absence.component'
import { useUser } from '@skolplattformen/api-hooks'
import AsyncStorage from '@react-native-async-storage/async-storage'
jest.mock('@react-navigation/native')
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
jest.mock('../../utils/SMS')
let sendSMS

View File

@ -1,9 +1,9 @@
import { useApi } from '@skolplattformen/api-hooks'
import { render } from '../../utils/testHelpers'
import { useApi } from '@skolplattformen/hooks'
import React from 'react'
import { render } from '../../utils/testHelpers'
import { Auth } from '../auth.component'
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
jest.mock('react-native-localize')
const setup = () => {

View File

@ -1,22 +1,22 @@
import { useNavigation } from '@react-navigation/core'
import {
useApi,
useChildList,
useCalendar,
useChildList,
useClassmates,
useMenu,
useNews,
useNotifications,
useSchedule,
useMenu,
useTimetable,
useClassmates,
} from '@skolplattformen/api-hooks'
import { render } from '../../utils/testHelpers'
} from '@skolplattformen/hooks'
import React from 'react'
import { Children } from '../children.component'
import { useNavigation } from '@react-navigation/core'
import * as RNLocalize from 'react-native-localize'
import { render } from '../../utils/testHelpers'
import { translate } from '../../utils/translation'
import { Children } from '../children.component'
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
jest.mock('@react-navigation/core')
jest.mock('react-native-localize')
const setup = () => {

View File

@ -1,11 +1,11 @@
import { useClassmates } from '@skolplattformen/api-hooks'
import { useClassmates } from '@skolplattformen/hooks'
import React from 'react'
import { render } from '../../utils/testHelpers'
import { ChildProvider } from '../childContext.component'
import { Classmates } from '../classmates.component'
jest.mock('@react-navigation/native')
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
const defaultClassmates = [
{

View File

@ -1,10 +1,10 @@
import { useMenu } from '@skolplattformen/hooks'
import React from 'react'
import { render } from '../../utils/testHelpers'
import { Menu } from '../menu.component'
import { useMenu } from '@skolplattformen/api-hooks'
import { translate } from '../../utils/translation'
import { Menu } from '../menu.component'
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
const defaultItemList = [
{

View File

@ -1,9 +1,9 @@
import { useApi, useNewsDetails } from '@skolplattformen/api-hooks'
import { useApi, useNewsDetails } from '@skolplattformen/hooks'
import React from 'react'
import { render } from '../../utils/testHelpers'
import { NewsItem } from '../newsItem.component'
jest.mock('@skolplattformen/api-hooks')
jest.mock('@skolplattformen/hooks')
const defaultNewsItem = {
author: 'Köket',

View File

@ -1,13 +1,13 @@
import { useNavigation } from '@react-navigation/native'
import { fireEvent } from '@testing-library/react-native'
import MockDate from 'mockdate'
import React from 'react'
import { render } from '../../utils/testHelpers'
import { NewsListItem } from '../newsListItem.component'
import MockDate from 'mockdate'
import { fireEvent } from '@testing-library/react-native'
import { useNavigation } from '@react-navigation/native'
import { ChildProvider } from '../childContext.component'
import { NewsListItem } from '../newsListItem.component'
jest.mock('@react-navigation/native')
jest.mock('@skolplattformen/api-hooks', () => ({
jest.mock('@skolplattformen/hooks', () => ({
useApi: jest.fn().mockReturnValue({ api: { getSessionCookie: jest.fn() } }),
}))

View File

@ -1,4 +1,5 @@
import { RouteProp, useRoute } from '@react-navigation/native'
import { useUser } from '@skolplattformen/hooks'
import {
Button,
CheckBox,
@ -16,6 +17,7 @@ import DateTimePickerModal from 'react-native-modal-datetime-picker'
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'
import * as Yup from 'yup'
import { defaultStackStyling } from '../design/navigationThemes'
import usePersonalStorage from '../hooks/usePersonalStorage'
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
import { studentName } from '../utils/peopleHelpers'
import { useSMS } from '../utils/SMS'
@ -23,8 +25,6 @@ import { translate } from '../utils/translation'
import { AlertIcon } from './icon.component'
import { RootStackParamList } from './navigation.component'
import { NavigationTitle } from './navigationTitle.component'
import { useUser } from '@skolplattformen/api-hooks'
import usePersonalStorage from '../hooks/usePersonalStorage'
type AbsenceRouteProps = RouteProp<RootStackParamList, 'Absence'>

View File

@ -1,11 +1,11 @@
import { useCalendar } from '@skolplattformen/api-hooks'
import { CalendarItem } from '@skolplattformen/embedded-api'
import { CalendarItem } from '@skolplattformen/api-skolplattformen'
import { useCalendar } from '@skolplattformen/hooks'
import {
Divider,
List,
ListItem,
Text,
StyleService,
Text,
useStyleSheet,
} from '@ui-kitten/components'
import moment from 'moment'

View File

@ -1,4 +1,4 @@
import { Child } from '@skolplattformen/embedded-api'
import { Child } from '@skolplattformen/api-skolplattformen'
import React, { createContext, useContext } from 'react'
interface ChildProviderProps {

View File

@ -1,6 +1,7 @@
/* eslint-disable react-native-a11y/has-accessibility-hint */
import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { Child } from '@skolplattformen/api-skolplattformen'
import {
useCalendar,
useClassmates,
@ -8,8 +9,7 @@ import {
useNews,
useNotifications,
useSchedule,
} from '@skolplattformen/api-hooks'
import { Child } from '@skolplattformen/embedded-api'
} from '@skolplattformen/hooks'
import {
Button,
StyleService,
@ -19,9 +19,9 @@ import {
import moment from 'moment'
import React from 'react'
import { TouchableOpacity, useColorScheme, View } from 'react-native'
import { useTranslation } from '../hooks/useTranslation'
import { Colors, Layout, Sizing } from '../styles'
import { studentName } from '../utils/peopleHelpers'
import { useTranslation } from '../hooks/useTranslation'
import { DaySummary } from './daySummary.component'
import { AlertIcon, RightArrowIcon } from './icon.component'
import { RootStackParamList } from './navigation.component'

View File

@ -1,6 +1,6 @@
import { useNavigation } from '@react-navigation/core'
import { useApi, useChildList } from '@skolplattformen/api-hooks'
import { Child } from '@skolplattformen/embedded-api'
import { Child } from '@skolplattformen/api-skolplattformen'
import { useApi, useChildList } from '@skolplattformen/hooks'
import {
Button,
List,
@ -44,7 +44,7 @@ export const Children = () => {
const navigation = useNavigation()
const { api } = useApi()
let { data: childList, status, reload } = useChildList()
const { data: childList, status, reload } = useChildList()
const reloadChildren = () => {
reload()
}

View File

@ -1,19 +1,19 @@
import React from 'react'
import { StyleSheet, ListRenderItemInfo } from 'react-native'
import { Classmate } from '@skolplattformen/api-skolplattformen'
import { useClassmates } from '@skolplattformen/hooks'
import {
Divider,
List,
ListItem,
Icon,
IconProps,
List,
ListItem,
Text,
} from '@ui-kitten/components'
import React from 'react'
import { ListRenderItemInfo, StyleSheet } from 'react-native'
import { fullName, guardians, sortByFirstName } from '../utils/peopleHelpers'
import { useChild } from './childContext.component'
import { useClassmates } from '@skolplattformen/api-hooks'
import { ContactMenu } from './contactMenu.component'
import { Classmate } from '@skolplattformen/embedded-api'
import { translate } from '../utils/translation'
import { useChild } from './childContext.component'
import { ContactMenu } from './contactMenu.component'
interface ClassmatesProps {
setSelected: (value?: number | null) => void

View File

@ -1,5 +1,5 @@
/* eslint-disable react-native-a11y/has-accessibility-hint */
import { Classmate } from '@skolplattformen/embedded-api'
import { Classmate } from '@skolplattformen/api-skolplattformen'
import {
Button,
MenuGroup,
@ -9,6 +9,7 @@ import {
import React from 'react'
import { Linking, StyleSheet } from 'react-native'
import { fullName } from '../utils/peopleHelpers'
import { translate } from '../utils/translation'
import {
CallIcon,
EmailIcon,
@ -16,7 +17,6 @@ import {
MoreIcon,
SMSIcon,
} from './icon.component'
import { translate } from '../utils/translation'
interface ContactMenuProps {
contact: Classmate

View File

@ -1,5 +1,5 @@
import { useTimetable } from '@skolplattformen/api-hooks'
import { Child } from '@skolplattformen/embedded-api'
import { Child } from '@skolplattformen/api-skolplattformen'
import { useTimetable } from '@skolplattformen/hooks'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import moment, { Moment } from 'moment'
import React from 'react'

View File

@ -1,4 +1,4 @@
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import React, { useEffect, useState } from 'react'
import { Image as ImageBase, ImageStyle, StyleProp } from 'react-native'

View File

@ -1,4 +1,4 @@
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import {
Button,
ButtonGroup,

View File

@ -1,5 +1,5 @@
import { useMenu } from '@skolplattformen/api-hooks'
import { MenuItem } from '@skolplattformen/embedded-api'
import { MenuItem } from '@skolplattformen/api-skolplattformen'
import { useMenu } from '@skolplattformen/hooks'
import {
Divider,
List,

View File

@ -1,4 +1,4 @@
import { MenuItem } from '@skolplattformen/embedded-api'
import { MenuItem } from '@skolplattformen/api-skolplattformen'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import React from 'react'
import { View } from 'react-native'

View File

@ -1,4 +1,4 @@
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import React, { useEffect, useState } from 'react'
import { Linking, Modal, TouchableOpacity, View } from 'react-native'

View File

@ -1,9 +1,9 @@
import { NavigationContainer } from '@react-navigation/native'
import { useApi } from '@skolplattformen/api-hooks'
import {
Child as ChildType,
NewsItem as NewsItemType,
} from '@skolplattformen/embedded-api'
} from '@skolplattformen/api-skolplattformen'
import { useApi } from '@skolplattformen/hooks'
import { useTheme } from '@ui-kitten/components'
import { Library } from 'libraries.json'
import React, { useEffect } from 'react'
@ -153,9 +153,7 @@ export const AppNavigator = () => {
/>
</>
) : (
<>
<Screen name="Login" component={Auth} options={authRouteOptions} />
</>
<Screen name="Login" component={Auth} options={authRouteOptions} />
)}
<Screen
name="SetLanguage"

View File

@ -1,6 +1,6 @@
import { RouteProp } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { useNewsDetails } from '@skolplattformen/api-hooks'
import { useNewsDetails } from '@skolplattformen/hooks'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import moment from 'moment'
import 'moment/locale/sv'

View File

@ -1,4 +1,4 @@
import { useNews } from '@skolplattformen/api-hooks'
import { useNews } from '@skolplattformen/hooks'
import { Input, List, StyleService, useStyleSheet } from '@ui-kitten/components'
import React, { useMemo, useState } from 'react'
import { TouchableOpacity, View } from 'react-native'

View File

@ -1,6 +1,6 @@
import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { NewsItem } from '@skolplattformen/embedded-api'
import { NewsItem } from '@skolplattformen/api-skolplattformen'
import { StyleService, useStyleSheet } from '@ui-kitten/components'
import moment from 'moment'
import React, { ReactNode } from 'react'

View File

@ -1,4 +1,4 @@
import { Notification as NotificationType } from '@skolplattformen/embedded-api'
import { Notification as NotificationType } from '@skolplattformen/api-skolplattformen'
import { StyleService, Text, useStyleSheet } from '@ui-kitten/components'
import moment from 'moment'
import React from 'react'

View File

@ -1,4 +1,4 @@
import { useNotifications } from '@skolplattformen/api-hooks'
import { useNotifications } from '@skolplattformen/hooks'
import { List, StyleService, useStyleSheet } from '@ui-kitten/components'
import React from 'react'
import { Sizing } from '../styles'

View File

@ -1,4 +1,4 @@
import { CalendarItem } from '@skolplattformen/embedded-api'
import { CalendarItem } from '@skolplattformen/api-skolplattformen'
import { Button, MenuItem, OverflowMenu, Text } from '@ui-kitten/components'
import React from 'react'
import RNCalendarEvents from 'react-native-calendar-events'

View File

@ -1,5 +1,5 @@
import { NavigationProp, useNavigation } from '@react-navigation/core'
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import React, { useCallback } from 'react'
import { ScrollView } from 'react-native'
import { NativeStackNavigationOptions } from 'react-native-screens/native-stack'

View File

@ -1,5 +1,9 @@
import { useMenu, useTimetable } from '@skolplattformen/api-hooks'
import { Child, MenuItem, TimetableEntry } from '@skolplattformen/embedded-api'
import {
Child,
MenuItem,
TimetableEntry,
} from '@skolplattformen/api-skolplattformen'
import { useMenu, useTimetable } from '@skolplattformen/hooks'
import {
List,
ListItem,

View File

@ -1,7 +1,7 @@
import { renderHook, act } from '@testing-library/react-hooks'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/api-skolplattformen'
import { act, renderHook } from '@testing-library/react-hooks'
import usePersonalStorage from '../usePersonalStorage'
import { User } from '@skolplattformen/embedded-api'
beforeEach(async () => {
jest.clearAllMocks()

View File

@ -1,4 +1,4 @@
import { User } from '@skolplattformen/embedded-api'
import { User } from '@skolplattformen/api-skolplattformen'
import useAsyncStorage from './useAsyncStorage'
export default function usePersonalStorage<T>(

View File

@ -1,11 +1,6 @@
/**
* @format
*/
import { AppRegistry } from 'react-native'
import 'react-native-gesture-handler'
import { AppRegistry } from 'react-native'
import App from './App'
import { name as appName } from './app.json'
console.log(AppRegistry)
AppRegistry.registerComponent(appName, () => App)

View File

@ -1,6 +1,6 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/api-skolplattformen'
import AppStorage from '../appStorage'
import { User } from '@skolplattformen/embedded-api'
beforeEach(() => {
jest.clearAllMocks()

View File

@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import { User } from '@skolplattformen/embedded-api'
import { User } from '@skolplattformen/api-skolplattformen'
export default class AppStorage {
static settingsStorageKeyPrefix = 'appsetting_'

View File

@ -1,4 +1,4 @@
import { Guardian } from '@skolplattformen/embedded-api'
import { Guardian } from '@skolplattformen/api-skolplattformen'
export const studentName = (name?: string) => name?.replace(/\s?\(\w+\)$/, '')

View File

@ -1,13 +1,13 @@
import React, { useMemo, ReactNode } from 'react'
import { NewsItem } from '@skolplattformen/api-skolplattformen'
import { useNews } from '@skolplattformen/hooks'
import { MatchData, Searcher } from 'fast-fuzzy'
import React, { ReactNode, useMemo } from 'react'
import { Text } from 'react-native'
import { useNews } from '@skolplattformen/api-hooks'
import { NewsItem } from '@skolplattformen/embedded-api'
import { Typography } from '../styles'
import { useChild } from '../components/childContext.component'
import { Typography } from '../styles'
// https://github.com/facebook/react-native/issues/14796#issuecomment-389743259
global.Buffer = global.Buffer || require('buffer').Buffer
import { Searcher, MatchData } from 'fast-fuzzy'
const NUM_CHARS_AROUND_SEARCH_MATCH = 20

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ the concrete implementation of fetch and cookie handler must be injected.
#### react-native
```javascript
import init from '@skolplattformen/embedded-api'
import init from '@skolplattformen/api-skolplattformen'
import CookieManager from '@react-native-community/cookies'
const api = init(fetch, () => CookieManager.clearAll())
@ -25,7 +25,7 @@ const api = init(fetch, () => CookieManager.clearAll())
#### node
```javascript
import init from '@skolplattformen/embedded-api'
import init from '@skolplattformen/api-skolplattformen'
import nodeFetch from 'node-fetch'
import fetchCookie from 'fetch-cookie/node-fetch'
import { CookieJar } from 'tough-cookie'

View File

@ -1,31 +1,31 @@
import { DateTime } from 'luxon'
import { Language } from '@skolplattformen/curriculum'
import { EventEmitter } from 'events'
import { decode } from 'he'
import { DateTime } from 'luxon'
import * as html from 'node-html-parser'
import { Language } from '@skolplattformen/curriculum/dist/translations'
import { URLSearchParams } from './URLSearchParams'
import * as fake from './fakeData'
import wrap, { Fetcher, FetcherOptions } from './fetcher'
import { checkStatus, LoginStatusChecker } from './loginStatus'
import * as parse from './parse/index'
import * as routes from './routes'
import {
AuthTicket,
CalendarItem,
Classmate,
CookieManager,
EtjanstChild,
Fetch,
MenuItem,
NewsItem,
Notification,
RequestInit,
ScheduleItem,
User,
Skola24Child,
EtjanstChild,
SSOSystem,
TimetableEntry
TimetableEntry,
User,
} from './types'
import * as routes from './routes'
import * as parse from './parse/index'
import wrap, { Fetcher, FetcherOptions } from './fetcher'
import * as fake from './fakeData'
import { URLSearchParams } from './URLSearchParams'
const fakeResponse = <T>(data: T): Promise<T> =>
new Promise((res) => setTimeout(() => res(data), 200 + Math.random() * 800))
@ -33,7 +33,8 @@ const fakeResponse = <T>(data: T): Promise<T> =>
const s24Init = {
headers: {
accept: 'application/json, text/javascript, */*; q=0.01',
referer: 'https://fns.stockholm.se/ng/timetable/timetable-viewer/fns.stockholm.se/',
referer:
'https://fns.stockholm.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',
@ -112,7 +113,8 @@ export class Api extends EventEmitter {
}
public async login(personalNumber?: string): Promise<LoginStatusChecker> {
if (personalNumber !== undefined && personalNumber.endsWith('1212121212')) return this.fakeMode()
if (personalNumber !== undefined && personalNumber.endsWith('1212121212'))
return this.fakeMode()
this.isFake = false
@ -256,7 +258,7 @@ export class Api extends EventEmitter {
public async getSchedule(
child: EtjanstChild,
from: DateTime,
to: DateTime,
to: DateTime
): Promise<ScheduleItem[]> {
if (this.isFake) return fakeResponse(fake.schedule(child))
@ -277,7 +279,10 @@ export class Api extends EventEmitter {
return parse.news(data)
}
public async getNewsDetails(child: EtjanstChild, item: NewsItem): Promise<any> {
public async getNewsDetails(
child: EtjanstChild,
item: NewsItem
): Promise<any> {
if (this.isFake) {
return fakeResponse(fake.news(child).find((ni) => ni.id === item.id))
}
@ -329,11 +334,13 @@ export class Api extends EventEmitter {
private async readSAMLRequest(targetSystem: string): Promise<string> {
const url = routes.ssoRequestUrl(targetSystem)
const session = this.getRequestInit({
redirect: 'follow',
redirect: 'follow',
})
const response = await this.fetch('samlRequest', url, session)
const text = await response.text()
const samlRequest = /name="SAMLRequest" value="(\S+)">/gm.exec(text || '')?.[1]
const samlRequest = /name="SAMLRequest" value="(\S+)">/gm.exec(
text || ''
)?.[1]
if (!samlRequest) {
throw new Error('Could not parse SAML Request')
} else {
@ -345,12 +352,14 @@ export class Api extends EventEmitter {
const body = new URLSearchParams({ SAMLRequest: samlRequest }).toString()
const url = routes.ssoResponseUrl
const session = this.getRequestInit({
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
redirect: 'follow',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
redirect: 'follow',
method: 'POST',
body,
})
const response = await this.fetch('samlResponse', url, session)
const response = await this.fetch('samlResponse', url, session)
const text = await response.text()
const samlResponse = /name="SAMLResponse" value="(\S+)">/gm.exec(text)?.[1]
if (!samlResponse) {
@ -366,14 +375,14 @@ export class Api extends EventEmitter {
}
const samlRequest = await this.readSAMLRequest(targetSystem)
const samlResponse = await this.submitSAMLRequest(samlRequest)
const body = new URLSearchParams({ SAMLResponse: samlResponse }).toString()
const url = routes.samlResponseUrl
const session = this.getRequestInit({
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
redirect: 'follow',
redirect: 'follow',
method: 'POST',
body,
})
@ -383,13 +392,15 @@ export class Api extends EventEmitter {
return text
}
public async getSkola24Children(): Promise<Skola24Child[]>{
public async getSkola24Children(): Promise<Skola24Child[]> {
if (this.isFake) return fakeResponse(fake.skola24Children())
await this.ssoAuthorize('TimetableViewer')
const body = { getPersonalTimetablesRequest: {
hostName: 'fns.stockholm.se'
}}
const body = {
getPersonalTimetablesRequest: {
hostName: 'fns.stockholm.se',
},
}
const session = this.getRequestInit({
...s24Init,
body: JSON.stringify(body),
@ -400,10 +411,8 @@ export class Api extends EventEmitter {
const response = await this.fetch('s24children', url, session)
const {
data: {
getPersonalTimetablesResponse: {
childrenTimetables
}
}
getPersonalTimetablesResponse: { childrenTimetables },
},
} = await response.json()
return childrenTimetables as Skola24Child[]
@ -413,18 +422,24 @@ export class Api extends EventEmitter {
const url = routes.renderKey
const session = this.getRequestInit(s24Init)
const response = await this.fetch('renderKey', url, session)
const { data: { key } } = await response.json()
const {
data: { key },
} = await response.json()
return key as string
}
public async getTimetable(child: Skola24Child, week: number, year: number, lang: Language)
: Promise<TimetableEntry[]> {
public async getTimetable(
child: Skola24Child,
week: number,
year: number,
lang: Language
): Promise<TimetableEntry[]> {
if (this.isFake) return fakeResponse(fake.timetable(child))
if(!child.timetableID) {
if (!child.timetableID) {
return new Array<TimetableEntry>()
}
const url = routes.timetable
const renderKey = await this.getRenderKey()
const params = {
@ -452,7 +467,11 @@ export class Api extends EventEmitter {
method: 'POST',
body: JSON.stringify(params),
})
const response = await this.fetch(`timetable_${child.personGuid}_${year}_${week}`, url, session)
const response = await this.fetch(
`timetable_${child.personGuid}_${year}_${week}`,
url,
session
)
const json = await response.json()
return parse.timetable(json, year, week, lang)

View File

@ -1,9 +1,13 @@
import parse from '@skolplattformen/curriculum'
import { Language } from '@skolplattformen/curriculum/dist/translations'
import parse, { Language } from '@skolplattformen/curriculum'
import { DateTime } from 'luxon'
import { TimetableEntry } from '../types'
const calculateDate = (year: number, weekNumber: number, weekday: number, time: string): string => {
const calculateDate = (
year: number,
weekNumber: number,
weekday: number,
time: string
): string => {
const [hours, minutes, seconds] = time.split(':')
return DateTime.local()
.set({
@ -14,7 +18,8 @@ const calculateDate = (year: number, weekNumber: number, weekday: number, time:
minute: parseInt(minutes, 10),
second: parseInt(seconds, 10),
millisecond: 0,
}).toISO()
})
.toISO()
}
interface TimetableResponseEntry {
@ -38,11 +43,26 @@ export interface TimetableResponse {
}
interface EntryParser {
(args: TimetableResponseEntry, year: number, week: number, lang: Language): TimetableEntry
(
args: TimetableResponseEntry,
year: number,
week: number,
lang: Language
): TimetableEntry
}
export const timetableEntry: EntryParser = ({
guidId, texts: [code, teacher, location], timeStart, timeEnd, dayOfWeekNumber, blockName,
}, year, week, lang) => ({
export const timetableEntry: EntryParser = (
{
guidId,
texts: [code, teacher, location],
timeStart,
timeEnd,
dayOfWeekNumber,
blockName,
},
year,
week,
lang
) => ({
...parse(code, lang),
id: guidId,
blockName,
@ -55,9 +75,16 @@ export const timetableEntry: EntryParser = ({
dateEnd: calculateDate(year, week, dayOfWeekNumber, timeEnd),
})
export const timetable = (response: TimetableResponse, year: number, week: number, lang: Language) => {
export const timetable = (
response: TimetableResponse,
year: number,
week: number,
lang: Language
) => {
if (response.error) {
throw new Error(response.error)
}
return response.data.lessonInfo.map((entry) => timetableEntry(entry, year, week, lang))
return response.data.lessonInfo.map((entry) =>
timetableEntry(entry, year, week, lang)
)
}

View File

@ -1,5 +1,5 @@
{
"name": "api-skolplattformen",
"name": "@skolplattformen/api-skolplattformen",
"version": "0.15.0",
"description": "Since the proxy was blocked (and also deemed a bad idea by some), this is a reboot of the API running in process in the app(s).",
"main": "lib/index.ts",

View File

@ -522,9 +522,9 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@skolplattformen/curriculum@^1.4.2":
"curriculum@^1.4.2":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@skolplattformen/curriculum/-/curriculum-1.4.2.tgz#614e17d51e72f4656ad99cf008a610addb124a14"
resolved "https://registry.yarnpkg.com/curriculum/-/curriculum-1.4.2.tgz#614e17d51e72f4656ad99cf008a610addb124a14"
integrity sha512-C81uSvKU5WxCkaAOmaz3qh0iYIOJKhufr0pT0VoMWWfySd9kLSu4Y/7VOgrdd1nAG9tEefDCju2yLBtV6UPAhw==
dependencies:
deepmerge "^4.2.2"

View File

@ -1,4 +1,5 @@
import translate, { Language, Translation } from './translations'
export { Language } from './translations'
export interface Subject {
code: string

View File

@ -1,16 +1,15 @@
# @skolplattformen/api-hooks
# hooks
1. [Installing](#installing)
1. [Login / logout](#login--logout)
1. [Get data](#get-data)
1. [Fake mode](#fake-mode)
## Installing
```npm i -S @skolplattformen/api-hooks @skolplattformen/embedded-api```
`npm i -S hooks @skolplattformen/embedded-api`
```yarn add @skolplattformen/api-hooks @skolplattformen/embedded-api```
`yarn add hooks @skolplattformen/embedded-api`
## ApiProvider
@ -18,8 +17,8 @@ In order to use api hooks, you must wrap your app in an ApiProvider
```javascript
import React from 'react'
import { ApiProvider } from '@skolplattformen/api-hooks'
import init from '@skolplattformen/embedded-api'
import { ApiProvider } from '@skolplattformen/hooks'
import init from '@skolplattformen/api-skolplattformen'
import { CookieManager } from '@react-native-community/cookies'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { RootComponent } from './components/root'
@ -41,7 +40,7 @@ export default () => (
## Login / logout
```javascript
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
export default function LoginController () {
const { api, isLoggedIn } = useApi()
@ -90,12 +89,12 @@ export default function LoginController () {
The data hooks return a `State<T>` object exposing the following properties:
| Property | Description |
|----------|----------------------------------|
| `status` | `pending` `loading` `loaded` |
| `data` | The requested data |
| `error` | Error from the API call if any |
| `reload` | Function that triggers a reload |
| Property | Description |
| -------- | ------------------------------- |
| `status` | `pending` `loading` `loaded` |
| `data` | The requested data |
| `error` | Error from the API call if any |
| `reload` | Function that triggers a reload |
The hook will return a useable default for data at first (usually empty `[]`).
It then checks the cache (`AsyncStorage`) for any value and, if exists, updates data.
@ -108,11 +107,11 @@ their `status`, `data` and `error` updated.
### useCalendar
```javascript
import { useCalendar } from '@skolplattformen/api-hooks'
import { useCalendar } from '@skolplattformen/hooks'
export default function CalendarComponent ({ selectedChild }) => {
const { status, data, error, reload } = useCalendar(selectedChild)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -129,11 +128,11 @@ export default function CalendarComponent ({ selectedChild }) => {
### useChildList
```javascript
import { useChildList } from '@skolplattformen/api-hooks'
import { useChildList } from '@skolplattformen/hooks'
export default function ChildListComponent () => {
const { status, data, error, reload } = useChildList()
return (
<View>
{ status === 'loading' && <Spinner />}
@ -150,11 +149,11 @@ export default function ChildListComponent () => {
### useClassmates
```javascript
import { useClassmates } from '@skolplattformen/api-hooks'
import { useClassmates } from '@skolplattformen/hooks'
export default function ClassmatesComponent ({ selectedChild }) => {
const { status, data, error, reload } = useClassmates(selectedChild)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -171,11 +170,11 @@ export default function ClassmatesComponent ({ selectedChild }) => {
### useMenu
```javascript
import { useMenu } from '@skolplattformen/api-hooks'
import { useMenu } from '@skolplattformen/hooks'
export default function MenuComponent ({ selectedChild }) => {
const { status, data, error, reload } = useMenu(selectedChild)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -192,11 +191,11 @@ export default function MenuComponent ({ selectedChild }) => {
### useNews
```javascript
import { useNews } from '@skolplattformen/api-hooks'
import { useNews } from '@skolplattformen/hooks'
export default function NewsComponent ({ selectedChild }) => {
const { status, data, error, reload } = useNews(selectedChild)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -213,12 +212,12 @@ export default function NewsComponent ({ selectedChild }) => {
To display image from `NewsItem`:
```javascript
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
export default function NewsItem ({ item }) => {
const { api } = useApi()
const cookie = api.getSessionCookie()
return (
<View>
{ cookie &&
@ -231,11 +230,11 @@ export default function NewsItem ({ item }) => {
### useNotifications
```javascript
import { useNotifications } from '@skolplattformen/api-hooks'
import { useNotifications } from '@skolplattformen/hooks'
export default function NotificationsComponent ({ selectedChild }) => {
const { status, data, error, reload } = useNotifications(selectedChild)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -252,12 +251,12 @@ export default function NotificationsComponent ({ selectedChild }) => {
To show content of `NotificationItem` url:
```javascript
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import { WebView } from 'react-native-webview'
export default function Notification ({ item }) => {
const { cookie } = useApi()
return (
<View>
<WebView source={{ uri: item.url, headers: { cookie }}} />
@ -270,13 +269,13 @@ export default function Notification ({ item }) => {
```javascript
import { DateTime } from 'luxon'
import { useSchedule } from '@skolplattformen/api-hooks'
import { useSchedule } from '@skolplattformen/hooks'
export default function ScheduleComponent ({ selectedChild }) => {
const from = DateTime.local()
const to = DateTime.local.plus({ week: 1 })
const { status, data, error, reload } = useSchedule(selectedChild, from, to)
return (
<View>
{ status === 'loading' && <Spinner />}
@ -293,11 +292,11 @@ export default function ScheduleComponent ({ selectedChild }) => {
### useUser
```javascript
import { useUser } from '@skolplattformen/api-hooks'
import { useUser } from '@skolplattformen/hooks'
export default function UserComponent () => {
const { status, data, error, reload } = useUser()
return (
<View>
{ status === 'loading' && <Spinner />}
@ -321,10 +320,10 @@ personal numbers: `12121212121212`, `201212121212` or `1212121212`.
The returned login status will have `token` set to `'fake'`.
```javascript
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
import { useApi } from '@skolplattformen/api-hooks'
import { useApi } from '@skolplattformen/hooks'
export default function LoginController () {
const { api, isLoggedIn } = useApi()

View File

@ -6,4 +6,4 @@ module.exports = {
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/hooks',
};
}

View File

@ -1,5 +1,5 @@
{
"name": "@skolplattformen/api-hooks",
"name": "@skolplattformen/hooks",
"description": "React hooks for accessing api with cached results",
"version": "0.0.1",
"main": "src/index.ts",

View File

@ -1,15 +1,22 @@
import { Child, EtjanstChild, Skola24Child } from '@skolplattformen/embedded-api'
import {
Child,
EtjanstChild,
Skola24Child,
} from '@skolplattformen/api-skolplattformen'
// eslint-disable-next-line import/prefer-default-export
export const merge = (etjanstChildren: EtjanstChild[], skola24Children: Skola24Child[]): Child[] => (
export const merge = (
etjanstChildren: EtjanstChild[],
skola24Children: Skola24Child[]
): Child[] =>
etjanstChildren.map((etjanstChild) => {
const skola24Child: Skola24Child = (
skola24Children.find((s24c) => s24c.firstName && etjanstChild.name.startsWith(s24c.firstName)) || {}
)
const skola24Child: Skola24Child =
skola24Children.find(
(s24c) => s24c.firstName && etjanstChild.name.startsWith(s24c.firstName)
) || {}
const child: Child = {
...etjanstChild,
...skola24Child,
}
return child
})
)

View File

@ -1,5 +1,3 @@
import { useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import {
Api,
CalendarItem,
@ -13,9 +11,15 @@ import {
Skola24Child,
TimetableEntry,
User,
} from '@skolplattformen/embedded-api'
} from '@skolplattformen/api-skolplattformen'
import { Language } from '@skolplattformen/curriculum'
import { DateTime } from 'luxon'
import { Language } from '@skolplattformen/curriculum/dist/translations'
import { useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { loadAction } from './actions'
import { merge } from './childlists'
import { useApi } from './context'
import store from './store'
import {
ApiCall,
EntityHookResult,
@ -24,10 +28,6 @@ import {
EntityStoreRootState,
ExtraActionProps,
} from './types'
import { useApi } from './context'
import { loadAction } from './actions'
import store from './store'
import { merge } from './childlists'
interface StoreSelector<T> {
(state: EntityStoreRootState): EntityMap<T>
@ -38,13 +38,12 @@ const hook = <T>(
key: string,
defaultValue: T,
selector: StoreSelector<T>,
apiCaller: (api: Api) => ApiCall<T>,
apiCaller: (api: Api) => ApiCall<T>
): EntityHookResult<T> => {
const {
api, isLoggedIn, reporter, storage,
} = useApi()
const { api, isLoggedIn, reporter, storage } = useApi()
const getState = (): EntityStoreRootState => store.getState() as unknown as EntityStoreRootState
const getState = (): EntityStoreRootState =>
store.getState() as unknown as EntityStoreRootState
const select = (storeState: EntityStoreRootState) => {
const stateMap = selector(storeState) || {}
const state = stateMap[key] || { status: 'pending', data: defaultValue }
@ -55,7 +54,11 @@ const hook = <T>(
const dispatch = useDispatch()
const load = (force = false) => {
if (isLoggedIn && state.status !== 'loading' && ((force && !api.isFake) || state.status === 'pending')) {
if (
isLoggedIn &&
state.status !== 'loading' &&
((force && !api.isFake) || state.status === 'pending')
) {
const extra: ExtraActionProps<T> = {
key,
defaultValue,
@ -71,27 +74,34 @@ const hook = <T>(
if (state.status === 'pending') {
extra.getFromCache = () => storage.getItem(`${pnr}_${key}`)
}
extra.saveToCache = (value: string) => storage.setItem(`${pnr}_${key}`, value)
extra.saveToCache = (value: string) =>
storage.setItem(`${pnr}_${key}`, value)
}
const action = loadAction<T>(entityName, extra)
dispatch(action)
}
}
useEffect(() => { load() }, [isLoggedIn])
useEffect(() => {
load()
}, [isLoggedIn])
let mounted: boolean
useEffect(() => {
mounted = true
return () => { mounted = false }
return () => {
mounted = false
}
}, [])
const listener = () => {
if (!mounted) return
const newState = select(getState())
if (newState.status !== state.status
|| newState.data !== state.data
|| newState.error !== state.error) {
if (
newState.status !== state.status ||
newState.data !== state.data ||
newState.error !== state.error
) {
setState(newState)
if (newState.error) {
@ -108,99 +118,117 @@ const hook = <T>(
}
}
export const useEtjanstChildren = () => hook<EtjanstChild[]>(
'ETJANST_CHILDREN',
'etjanst_children',
[],
(s) => s.etjanstChildren,
(api) => () => api.getChildren(),
)
export const useEtjanstChildren = () =>
hook<EtjanstChild[]>(
'ETJANST_CHILDREN',
'etjanst_children',
[],
(s) => s.etjanstChildren,
(api) => () => api.getChildren()
)
export const useSkola24Children = () => hook<Skola24Child[]>(
'SKOLA24_CHILDREN',
'skola24_children',
[],
(s) => s.skola24Children,
(api) => () => api.getSkola24Children(),
)
export const useSkola24Children = () =>
hook<Skola24Child[]>(
'SKOLA24_CHILDREN',
'skola24_children',
[],
(s) => s.skola24Children,
(api) => () => api.getSkola24Children()
)
export const useCalendar = (child: Child) => hook<CalendarItem[]>(
'CALENDAR',
`calendar_${child.id}`,
[],
(s) => s.calendar,
(api) => () => api.getCalendar(child),
)
export const useCalendar = (child: Child) =>
hook<CalendarItem[]>(
'CALENDAR',
`calendar_${child.id}`,
[],
(s) => s.calendar,
(api) => () => api.getCalendar(child)
)
export const useClassmates = (child: Child) => hook<Classmate[]>(
'CLASSMATES',
`classmates_${child.id}`,
[],
(s) => s.classmates,
(api) => () => api.getClassmates(child),
)
export const useClassmates = (child: Child) =>
hook<Classmate[]>(
'CLASSMATES',
`classmates_${child.id}`,
[],
(s) => s.classmates,
(api) => () => api.getClassmates(child)
)
export const useMenu = (child: Child) => hook<MenuItem[]>(
'MENU',
`menu_${child.id}`,
[],
(s) => s.menu,
(api) => () => api.getMenu(child),
)
export const useMenu = (child: Child) =>
hook<MenuItem[]>(
'MENU',
`menu_${child.id}`,
[],
(s) => s.menu,
(api) => () => api.getMenu(child)
)
export const useNews = (child: Child) => hook<NewsItem[]>(
'NEWS',
`news_${child.id}`,
[],
(s) => s.news,
(api) => () => api.getNews(child),
)
export const useNews = (child: Child) =>
hook<NewsItem[]>(
'NEWS',
`news_${child.id}`,
[],
(s) => s.news,
(api) => () => api.getNews(child)
)
export const useNewsDetails = (child: Child, news: NewsItem) => hook<NewsItem>(
'NEWS_DETAILS',
`news_details_${news.id}`,
news,
(s) => s.newsDetails,
(api) => () => api.getNewsDetails(child, news),
)
export const useNewsDetails = (child: Child, news: NewsItem) =>
hook<NewsItem>(
'NEWS_DETAILS',
`news_details_${news.id}`,
news,
(s) => s.newsDetails,
(api) => () => api.getNewsDetails(child, news)
)
export const useNotifications = (child: Child) => hook<Notification[]>(
'NOTIFICATIONS',
`notifications_${child.id}`,
[],
(s) => s.notifications,
(api) => () => api.getNotifications(child),
)
export const useNotifications = (child: Child) =>
hook<Notification[]>(
'NOTIFICATIONS',
`notifications_${child.id}`,
[],
(s) => s.notifications,
(api) => () => api.getNotifications(child)
)
export const useSchedule = (child: Child, from: string, to: string) => hook<ScheduleItem[]>(
'SCHEDULE',
`schedule_${child.id}_${from}_${to}`,
[],
(s) => s.schedule,
(api) => () => api.getSchedule(child, DateTime.fromISO(from), DateTime.fromISO(to)),
)
export const useSchedule = (child: Child, from: string, to: string) =>
hook<ScheduleItem[]>(
'SCHEDULE',
`schedule_${child.id}_${from}_${to}`,
[],
(s) => s.schedule,
(api) => () =>
api.getSchedule(child, DateTime.fromISO(from), DateTime.fromISO(to))
)
export const useTimetable = (
child: Skola24Child, week: number, year: number, lang: Language,
) => hook<TimetableEntry[]>(
'TIMETABLE',
`timetable_${child.personGuid}_${week}_${year}_${lang}`,
[],
(s) => s.timetable,
(api) => () => api.getTimetable(child, week, year, lang),
)
child: Skola24Child,
week: number,
year: number,
lang: Language
) =>
hook<TimetableEntry[]>(
'TIMETABLE',
`timetable_${child.personGuid}_${week}_${year}_${lang}`,
[],
(s) => s.timetable,
(api) => () => api.getTimetable(child, week, year, lang)
)
export const useUser = () => hook<User>(
'USER',
'user',
{},
(s) => s.user,
(api) => () => api.getUser(),
)
export const useUser = () =>
hook<User>(
'USER',
'user',
{},
(s) => s.user,
(api) => () => api.getUser()
)
export const useChildList = (): EntityHookResult<Child[]> => {
const {
data: etjanstData, status, error, reload: etjanstReload,
data: etjanstData,
status,
error,
reload: etjanstReload,
} = useEtjanstChildren()
const { data: skola24Data, reload: skola24Reload } = useSkola24Children()
@ -216,6 +244,9 @@ export const useChildList = (): EntityHookResult<Child[]> => {
}, [etjanstData, skola24Data])
return {
data, status, error, reload,
data,
status,
error,
reload,
}
}

View File

@ -1,25 +1,28 @@
/* eslint-disable react/prop-types */
/* eslint-disable import/prefer-default-export */
import { Api } from '@skolplattformen/embedded-api'
import React, {
FC, PropsWithChildren, useEffect, useState,
} from 'react'
import { Api } from '@skolplattformen/api-skolplattformen'
import React, { FC, PropsWithChildren, useEffect, useState } from 'react'
import { Provider } from 'react-redux'
import { ApiContext } from './context'
import store from './store'
import { AsyncStorage, EntityAction, IApiContext, Reporter } from './types'
import { AsyncStorage, IApiContext, Reporter } from './types'
type TApiProvider = FC<PropsWithChildren<{
api: Api,
storage: AsyncStorage,
reporter?: Reporter
}>>
type TApiProvider = FC<
PropsWithChildren<{
api: Api
storage: AsyncStorage
reporter?: Reporter
}>
>
const noopReporter: Reporter = {
log: () => { },
error: () => { },
log: () => {},
error: () => {},
}
export const ApiProvider: TApiProvider = ({
children, api, storage, reporter = noopReporter,
children,
api,
storage,
reporter = noopReporter,
}) => {
const [isLoggedIn, setIsLoggedIn] = useState(api.isLoggedIn)
const [isFake, setIsFake] = useState(api.isFake)
@ -53,9 +56,7 @@ export const ApiProvider: TApiProvider = ({
return (
<ApiContext.Provider value={value}>
<Provider store={store}>
{children}
</Provider>
<Provider store={store}>{children}</Provider>
</ApiContext.Provider>
)
}

View File

@ -2,14 +2,14 @@ import {
CalendarItem,
Classmate,
EtjanstChild,
Skola24Child,
MenuItem,
NewsItem,
Notification,
ScheduleItem,
User,
Skola24Child,
TimetableEntry,
} from '@skolplattformen/embedded-api'
User,
} from '@skolplattformen/api-skolplattformen'
import { EntityName, EntityReducer, EntityState } from './types'
const createReducer = <T>(entity: EntityName): EntityReducer<T> => {

View File

@ -1,16 +1,16 @@
import {
Api,
EtjanstChild,
Skola24Child,
User,
CalendarItem,
Classmate,
EtjanstChild,
MenuItem,
NewsItem,
Notification,
ScheduleItem,
Skola24Child,
TimetableEntry,
} from '@skolplattformen/embedded-api'
User,
} from '@skolplattformen/api-skolplattformen'
import { Action, Reducer } from 'redux'
export interface Reporter {
@ -44,26 +44,28 @@ export interface ExtraActionProps<T> {
getFromCache?: () => Promise<string | null>
saveToCache?: (value: string) => Promise<void>
}
export type EntityActionType = 'GET_FROM_API'
| 'RESULT_FROM_API'
| 'API_ERROR'
| 'GET_FROM_CACHE'
| 'RESULT_FROM_CACHE'
| 'STORE_IN_CACHE'
| 'CLEAR'
export type EntityName = 'USER'
| 'ETJANST_CHILDREN'
| 'SKOLA24_CHILDREN'
| 'CHILDREN'
| 'CALENDAR'
| 'CLASSMATES'
| 'MENU'
| 'NEWS'
| 'NEWS_DETAILS'
| 'NOTIFICATIONS'
| 'SCHEDULE'
| 'TIMETABLE'
| 'ALL'
export type EntityActionType =
| 'GET_FROM_API'
| 'RESULT_FROM_API'
| 'API_ERROR'
| 'GET_FROM_CACHE'
| 'RESULT_FROM_CACHE'
| 'STORE_IN_CACHE'
| 'CLEAR'
export type EntityName =
| 'USER'
| 'ETJANST_CHILDREN'
| 'SKOLA24_CHILDREN'
| 'CHILDREN'
| 'CALENDAR'
| 'CLASSMATES'
| 'MENU'
| 'NEWS'
| 'NEWS_DETAILS'
| 'NOTIFICATIONS'
| 'SCHEDULE'
| 'TIMETABLE'
| 'ALL'
export interface EntityAction<T> extends Action<EntityActionType> {
entity: EntityName
data?: T
@ -79,14 +81,14 @@ export interface EntityStoreRootState {
etjanstChildren: EntityMap<EtjanstChild[]>
skola24Children: EntityMap<Skola24Child[]>
user: EntityMap<User>
calendar: EntityMap<CalendarItem[]>,
classmates: EntityMap<Classmate[]>,
menu: EntityMap<MenuItem[]>,
news: EntityMap<NewsItem[]>,
newsDetails: EntityMap<NewsItem>,
notifications: EntityMap<Notification[]>,
schedule: EntityMap<ScheduleItem[]>,
timetable: EntityMap<TimetableEntry[]>,
calendar: EntityMap<CalendarItem[]>
classmates: EntityMap<Classmate[]>
menu: EntityMap<MenuItem[]>
news: EntityMap<NewsItem[]>
newsDetails: EntityMap<NewsItem>
notifications: EntityMap<Notification[]>
schedule: EntityMap<ScheduleItem[]>
timetable: EntityMap<TimetableEntry[]>
}
export interface EntityHookResult<T> extends EntityState<T> {

View File

@ -1304,9 +1304,9 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@skolplattformen/curriculum@^1.3.0":
"curriculum@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@skolplattformen/curriculum/-/curriculum-1.3.0.tgz#841e2ff0095e39e174cffdd0b8a81a17956de7ed"
resolved "https://registry.yarnpkg.com/curriculum/-/curriculum-1.3.0.tgz#841e2ff0095e39e174cffdd0b8a81a17956de7ed"
integrity sha512-nuwZX45gHe5JaiYfygDP1HmbhAJOEXuuWwR04tNAnl/PaDGqJscfzKt8YD2SL+MHqi3LARjSKLa4ms4SxVQFyw==
"@skolplattformen/embedded-api@^5.1.0":

View File

@ -16,7 +16,7 @@
"baseUrl": ".",
"paths": {
"@skolplattformen/api-skolplattformen": [
"libs/api-skolplattformen/src/index.ts"
"libs/api-skolplattformen/lib/index.ts"
],
"@skolplattformen/curriculum": ["libs/curriculum/src/index.ts"],
"@skolplattformen/hooks": ["libs/hooks/src/index.ts"]