{"version":3,"sources":["C:/PersonalSource/bolaget-frontend/app/src/components/CollapsingPanel.tsx","C:/PersonalSource/bolaget-frontend/app/src/style/MediaPxWidths.tsx","C:/PersonalSource/bolaget-frontend/app/App.tsx","C:/PersonalSource/bolaget-frontend/app/src/screens/changes/ChangesScreen.tsx","C:/PersonalSource/bolaget-frontend/app/src/components/LoadingSpinner.tsx","C:/PersonalSource/bolaget-frontend/app/src/screens/changes/ChangeModel.ts","C:/PersonalSource/bolaget-frontend/app/src/screens/changes/ChangesListItem.tsx","C:/PersonalSource/bolaget-frontend/app/src/screens/changes/ChangesListFilter.tsx","C:/PersonalSource/bolaget-frontend/app/src/services/Change.ts","C:/PersonalSource/bolaget-frontend/app/src/services/ChangeCollection.ts","C:/PersonalSource/bolaget-frontend/app/src/services/ChangeFeedItem.ts","C:/PersonalSource/bolaget-frontend/app/src/services/ChangeFeed.ts","C:/PersonalSource/bolaget-frontend/app/src/services/Article.ts","C:/PersonalSource/bolaget-frontend/app/src/services/ChangeFeedService.ts","C:/PersonalSource/bolaget-frontend/app/src/lib/clock.ts","C:/PersonalSource/bolaget-frontend/app/src/Dependencies.ts","C:/PersonalSource/bolaget-frontend/app/src/screens/splash/SplashScreen.tsx","C:/PersonalSource/bolaget-frontend/app/src/AppContainer.tsx","C:/PersonalSource/bolaget-frontend/app/web-build/register-service-worker.js"],"names":["styles","summaryRow","flexDirection","justifyContent","alignItems","summary","flex","icon","fontSize","parentHr","height","width","child","padding","CollapsingPanel","props","state","resolvedDetail","undefined","detailEvaluated","expanded","toggleExpand","expanding","setState","ensureResolved","detail","this","style","onPress","name","prevProps","rerenderOnData","force","invoked","Promise","resolve","then","element","Component","TabletsInLandscape","global","serviceLocator","ConfigureDependencies","appSettingsJson","AppContainer","createMyAppContainer","App","paddingTop","Constants","statusBarHeight","FilterableType","ChangesScreen","changeFeed","filterOptions","key","alcohol","text","checked","vintage","price","type","isLoading","refreshing","updateFilterOptions","bind","changeFeedService","get","clock","Dimensions","addEventListener","e","window","loadChangeFeed","responsiveStyles","StyleSheet","create","container","marginRight","MediaPxWidths","marginLeft","sectionHeader","paddingLeft","backgroundColor","color","paddingBottom","emptySectionHeader","marginBottom","loadingContainer","ListHeaderComponent","items","updated","renderItem","obj","model","item","index","renderSectionHeader","section","h4","data","length","renderSectionFooter","sections","toAgeInDaysSections","filterByType","toModel","slice","keyExtractor","toString","refreshControl","onRefresh","getChangeFeed","console","error","map","o","feed","models","changes","change","push","ChangeModel","Make","feedModels","currentTime","now","today","yesterday","lastSevenDays","lastThirtyDays","older","ageInDays","diff","timeStamp","selected","filter","toUpperCase","fm","includes","changeName","LoadingSpinner","display","timeout","setTimeout","size","clearTimeout","id","name2","category","uri","oldValue","newValue","changeCollection","timestamp","ChangesListItem","renderFeedItemTitle","renderFeedItemDetail","feedItemTitle","feedItem","borderBottomWidth","hairlineWidth","borderColor","a","async","itemTitle","fontWeight","itemSubtitle","fontStyle","title","subtitle","rightSubtitle","itemKey","getArticle","article","value","producer","importer","origin","countryOfOrigin","packaging","pricePerLitre","volume","checkBoxStyles","paddingRight","borderRadius","ChangesListFilter","renderCheckboxes","containerStyle","textStyle","numColumns","extraData","pressedItem","updatedItems","p","Change","dto","createDayJs","dayJs","ChangeCollection","c","ChangeFeedItem","ChangeFeed","Article","expired","history","ChangeFeedService","injectable","baseUri","fetch","response","json","responseJson","Clock","settings","Container","toConstantValue","baseUrl","to","textBlock","hexagonStyles","hexagon","hexagonInner","hexagonAfter","position","bottom","left","borderStyle","borderLeftWidth","borderLeftColor","borderRightWidth","borderRightColor","borderTopWidth","borderTopColor","hexagonBefore","top","borderBottomColor","SplashScreen","View","Text","navigation","navigate","AppNavigator","createSwitchNavigator","Splash","Main","Platform","select","default","initialRouteName","web","createAppContainer","navigator","serviceWorker","register","scope","info","catch"],"mappings":"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","file":"static/js/app.96e234f0.chunk.js","sourcesContent":["\r\nimport React, { Component, ReactElement, ReactNode } from 'react';\r\nimport { View, TouchableOpacity, ViewStyle, TextStyle } from \"react-native\";\r\nimport { Icon } from 'react-native-elements';\r\n\r\nconst styles: {\r\n    summaryRow: ViewStyle,\r\n    summary: ViewStyle,\r\n    icon: TextStyle,\r\n    parentHr: ViewStyle,\r\n    child: ViewStyle,\r\n} = {\r\n    summaryRow: {\r\n        flexDirection: 'row',\r\n        justifyContent: 'space-between',\r\n        alignItems: 'center',\r\n    },\r\n    summary: {\r\n        flex: 1\r\n    },\r\n    icon: {\r\n        fontSize: 30\r\n    },\r\n    parentHr: {\r\n        height: 1,\r\n        width: '100%'\r\n    },\r\n    child: {\r\n        padding: 16,\r\n    },\r\n};\r\n\r\ntype Props = {\r\n    /** The part of this Component which is always shown */\r\n    summary: ReactElement;\r\n    /** The initially hidden part of this Component. Can be passed as a value, as a function or as asynchronous function.\r\n     * The latter two will be evaluated only as the component is expanded\r\n     */\r\n    detail: (ReactElement) | (() => ReactElement) | (() => Promise<ReactElement>);\r\n    /**\r\n     * A marker property for triggering a re-render. Not neccesary when detail is changed.\r\n     * But when using a invokable (lazy) detail, you may want this component to call the same function again because you expect different\r\n     * results.\r\n     */\r\n    rerenderOnData?: {};\r\n};\r\n\r\ntype State = {\r\n    resolvedDetail: ReactElement;\r\n    detailEvaluated: boolean;\r\n    expanded: boolean;\r\n};\r\n\r\nexport class CollapsingPanel extends Component<Props, State> {\r\n    public state: State = {\r\n        resolvedDetail: undefined,\r\n        detailEvaluated: false,\r\n        expanded: false\r\n    };\r\n\r\n    constructor(props:\r\n        {\r\n            summary: ReactElement,\r\n            detail: (ReactElement) | (() => ReactElement) | (() => Promise<ReactElement>),\r\n            rerenderOnData?: {}\r\n        }\r\n    ) {\r\n        super(props);\r\n\r\n        if (props.detail[\"call\"] == null) {\r\n            this.state.detailEvaluated = true;\r\n            this.state.resolvedDetail = this.props.detail as ReactElement;\r\n        }\r\n    }\r\n\r\n    public render(): ReactNode {\r\n        const { summary } = this.props;\r\n        const { resolvedDetail } = this.state;\r\n\r\n        return <View>\r\n            <TouchableOpacity style={styles.summaryRow} onPress={this.toggleExpand}>\r\n                <View style={styles.summary}>{summary}</View>\r\n                <Icon name={this.state.expanded ? 'keyboard-arrow-up' : 'keyboard-arrow-down'} style={styles.icon} />\r\n            </TouchableOpacity>\r\n            <View style={styles.parentHr} />\r\n            {\r\n                this.state.expanded &&\r\n                <View style={styles.child}>\r\n                    {resolvedDetail}\r\n                </View>\r\n            }\r\n        </View>;\r\n    }\r\n\r\n    public componentDidUpdate(prevProps: Props): void {\r\n        if (!this.state.detailEvaluated) {\r\n            return;\r\n        }\r\n\r\n        if (prevProps.detail !== this.props.detail ||\r\n            prevProps.rerenderOnData !== this.props.rerenderOnData) {\r\n            if (this.state.expanded) {\r\n                this.ensureResolved(true);\r\n            } else {\r\n                this.state.detailEvaluated = false;\r\n                this.state.resolvedDetail = undefined;\r\n            }\r\n        }\r\n    }\r\n\r\n    private toggleExpand = () => {\r\n        const expanding: boolean = !this.state.expanded;\r\n        this.setState({ expanded: expanding });\r\n\r\n        if (expanding) {\r\n            this.ensureResolved();\r\n        }\r\n    }\r\n\r\n    private ensureResolved(force: boolean = false): void {\r\n        if (!force && this.state.detailEvaluated) {\r\n            return;\r\n        }\r\n\r\n        if (this.props.detail[\"call\"] == null) {\r\n            this.setState({ detailEvaluated: true, resolvedDetail: this.props.detail as ReactElement });\r\n        } else {\r\n            const invoked: ReactElement | Promise<ReactElement> =\r\n                (this.props.detail as (() => ReactElement | Promise<ReactElement>))();\r\n            Promise.resolve(invoked).then(element => {\r\n                this.setState({\r\n                    detailEvaluated: true, resolvedDetail: element\r\n                });\r\n            });\r\n        }\r\n    }\r\n}\r\n","export const Phones: number = 320;\r\nexport const SmallTablets: number = 481;\r\nexport const TabletsInPortrait: number = 641;\r\nexport const TabletsInLandscape: number = 961;\r\nexport const Laptops: number = 1025;\r\nexport const BigLaptops: number = 1281;\r\n","// Import once in application. Global singleton for inversify\r\nimport \"reflect-metadata\";\r\n\r\nimport React, { Component, ReactNode } from \"react\";\r\nimport { NavigationContainer } from \"react-navigation\";\r\nimport { StatusBar, View } from \"react-native\";\r\nimport Constants from 'expo-constants';\r\nimport { Container } from \"inversify\";\r\n\r\nimport { createMyAppContainer } from \"./src/AppContainer\";\r\nimport { ConfigureDependencies } from './src/Dependencies';\r\nimport { Appsettings } from './src/AppSettings';\r\n\r\nimport appSettingsJson from \"./appsettings.json\";\r\n\r\ndeclare global {\r\n  const global: {\r\n    serviceLocator: Container\r\n  };\r\n}\r\n\r\nglobal.serviceLocator = ConfigureDependencies(appSettingsJson as Appsettings);\r\n\r\nconst AppContainer: NavigationContainer = createMyAppContainer();\r\n\r\nexport default class App extends Component {\r\n  public render(): ReactNode {\r\n    return (\r\n      <View style={{ flex: 1, paddingTop: Constants.statusBarHeight }}>\r\n        <StatusBar/>\r\n        <AppContainer />\r\n      </View>\r\n    );\r\n  }\r\n}\r\n","import React, { Component, ReactNode } from \"react\";\r\nimport { View, SectionList, SectionListData, StyleSheet, Dimensions, ViewStyle, TextStyle, RefreshControl } from \"react-native\";\r\nimport { Text, Divider } from \"react-native-elements\";\r\nimport { Container } from \"inversify\";\r\nimport { Dayjs } from \"dayjs\";\r\n\r\nimport { IClock } from \"../../lib/clock\";\r\nimport { IChangeFeedService } from \"../../services/ChangeFeedService\";\r\nimport { ChangeFeed } from \"../../services/ChangeFeed\";\r\nimport * as MediaPxWidths from \"../../style/MediaPxWidths\";\r\nimport { LoadingSpinner } from \"../../components/LoadingSpinner\";\r\n\r\nimport { ChangeModel } from \"./ChangeModel\";\r\nimport { ChangesListItem } from \"./ChangesListItem\";\r\nimport { ChangesListFilter, Item } from \"./ChangesListFilter\";\r\n\r\ntype State = {\r\n    changeFeed: ChangeFeed;\r\n    filterOptions: Item<FilterableType>[];\r\n    isLoading: boolean;\r\n    width: number;\r\n    refreshing: boolean;\r\n};\r\n\r\nexport class ChangesScreen extends Component<{}, State> {\r\n    public state: State = {\r\n        changeFeed: undefined,\r\n        filterOptions: [\r\n            { key: FilterableType.alcohol, text: \"Alcohol\", checked: false },\r\n            { key: FilterableType.vintage, text: \"Vintage\", checked: false },\r\n            { key: FilterableType.price, text: \"Price\", checked: false },\r\n            { key: FilterableType.type, text: \"Type\", checked: false }\r\n        ],\r\n        isLoading: true,\r\n        width: undefined,\r\n        refreshing: false\r\n    };\r\n\r\n    private readonly changeFeedService: IChangeFeedService;\r\n    private readonly clock: IClock;\r\n\r\n    constructor(props: {}) {\r\n        super(props);\r\n\r\n        this.updateFilterOptions = this.updateFilterOptions.bind(this);\r\n\r\n        const serviceLocator: Container = global.serviceLocator;\r\n        this.changeFeedService = serviceLocator.get(\"IChangeFeedService\");\r\n        this.clock = serviceLocator.get(\"IClock\");\r\n\r\n        const { width } = Dimensions.get(\"window\");\r\n        this.state.width = width;\r\n        Dimensions.addEventListener(\"change\", (e) => { this.setState({ width: e.window.width }); });\r\n    }\r\n\r\n    public async componentDidMount(): Promise<void> { await this.loadChangeFeed(); }\r\n\r\n    public render(): ReactNode {\r\n        const { changeFeed, isLoading, width, refreshing, filterOptions } = this.state;\r\n\r\n        const responsiveStyles: any = StyleSheet.create({\r\n            container: {\r\n                marginRight: width > MediaPxWidths.TabletsInLandscape ? \"calc((50%) * (2 / 3) )\" : undefined,\r\n                marginLeft: width > MediaPxWidths.TabletsInLandscape ? \"calc((50%) * (1 / 3))\" : undefined\r\n            }\r\n        });\r\n\r\n        const styles: {\r\n            container: ViewStyle,\r\n            sectionHeader: TextStyle,\r\n            emptySectionHeader: TextStyle,\r\n            loadingContainer: ViewStyle\r\n        } = {\r\n            container: {\r\n                flex: 1\r\n            },\r\n            sectionHeader: {\r\n                paddingLeft: 10,\r\n                backgroundColor: \"mediumslateblue\",\r\n                color: \"white\",\r\n                paddingTop: 12,\r\n                paddingBottom: 8\r\n            },\r\n            emptySectionHeader: {\r\n                marginBottom: 12,\r\n                color: \"darkgray\"\r\n            },\r\n            loadingContainer: {\r\n                flex: 1,\r\n                justifyContent: \"center\"\r\n            },\r\n        };\r\n\r\n        if (!isLoading) {\r\n            return <View style={[styles.container, responsiveStyles.container]}>\r\n                <SectionList\r\n                    ListHeaderComponent={\r\n                        <ChangesListFilter<FilterableType> items={filterOptions} onPress={\r\n                            (items, updated) => { this.updateFilterOptions(updated); }\r\n                        } />\r\n                    }\r\n                    renderItem={(obj) => <ChangesListItem model={obj.item} index={obj.index} />}\r\n                    renderSectionHeader={({ section }) => {\r\n\r\n                        return <Text h4={true}\r\n                            style={[styles.sectionHeader, section.data.length === 0 ? styles.emptySectionHeader : undefined]}\r\n                        >{section.key}</Text>;\r\n                    }}\r\n                    renderSectionFooter={() => <Divider />}\r\n                    sections={toAgeInDaysSections(filterByType(toModel(changeFeed), filterOptions).slice(0, 100), this.clock)}\r\n                    keyExtractor={(item, index) => index.toString()}\r\n                    refreshControl={<RefreshControl refreshing={refreshing} onRefresh={() => this.loadChangeFeed()} />}\r\n                />\r\n            </View>;\r\n        } else {\r\n            return <View style={styles.loadingContainer}>\r\n                <LoadingSpinner />\r\n            </View>;\r\n        }\r\n    }\r\n\r\n    private async loadChangeFeed(): Promise<void> {\r\n        try {\r\n            const changeFeed: ChangeFeed = await this.changeFeedService.getChangeFeed();\r\n\r\n            this.setState({ changeFeed, isLoading: false });\r\n        } catch (error) {\r\n            console.error(\"Error fetching change feed in ChangeScreen.loadChangeFeed\", error);\r\n        }\r\n    }\r\n\r\n    private updateFilterOptions(updated: Item<FilterableType>): void {\r\n        const filterOptions: Item<FilterableType>[] =\r\n            this.state.filterOptions.map(o => ({ key: o.key, text: o.text, checked: o.key === updated.key ? updated.checked : o.checked }));\r\n\r\n        this.setState({ filterOptions });\r\n    }\r\n}\r\n\r\nfunction toModel(feed: ChangeFeed): ChangeModel[] {\r\n    const models: ChangeModel[] = [];\r\n    for (const item of feed.data) {\r\n        for (const change of item.changes.changes) {\r\n            models.push(\r\n                ChangeModel.Make(item, item.changes, change)\r\n            );\r\n        }\r\n    }\r\n\r\n    return models;\r\n}\r\n\r\nfunction toAgeInDaysSections(feedModels: ChangeModel[], clock: IClock): SectionListData<any>[] {\r\n    const currentTime: Dayjs = clock.now();\r\n    const today: ChangeModel[] = [];\r\n    const yesterday: ChangeModel[] = [];\r\n    const lastSevenDays: ChangeModel[] = [];\r\n    const lastThirtyDays: ChangeModel[] = [];\r\n    const older: ChangeModel[] = [];\r\n\r\n    for (const model of feedModels) {\r\n        const ageInDays: number = currentTime.diff(model.timeStamp, \"day\");\r\n        if (ageInDays < 1) {\r\n            today.push(model);\r\n            continue;\r\n        }\r\n        if (ageInDays < 2) {\r\n            yesterday.push(model);\r\n            continue;\r\n        }\r\n        if (ageInDays < 7) {\r\n            lastSevenDays.push(model);\r\n            continue;\r\n        }\r\n        if (ageInDays < 30) {\r\n            lastThirtyDays.push(model);\r\n            continue;\r\n        }\r\n        older.push(model);\r\n    }\r\n\r\n    return ([\r\n        { data: today, key: \"Today\" },\r\n        { data: yesterday, key: \"Yesterday\" },\r\n        { data: lastSevenDays, key: \"Last 7 Days\" },\r\n        { data: lastThirtyDays, key: \"Last 30 Days\" },\r\n        { data: older, key: \"Older\" }\r\n    ]);\r\n}\r\n\r\nfunction filterByType(feedModels: ChangeModel[], filterOptions: Item<FilterableType>[]): ChangeModel[] {\r\n    const selected: string[] = filterOptions.filter(o => o.checked).map(o => o.key.toUpperCase());\r\n    if (selected.length === 0) {\r\n        return feedModels;\r\n    }\r\n\r\n    return feedModels.filter(fm => selected.includes(fm.changeName.toUpperCase()));\r\n}\r\n\r\nenum FilterableType {\r\n    alcohol = \"alcohol\",\r\n    vintage = \"vintage\",\r\n    price = \"price\",\r\n    type = \"type\",\r\n    packaging = \"packaging\",\r\n    producer = \"producer\"\r\n}\r\n","import React, { Component, ReactNode } from \"react\";\r\nimport { ActivityIndicator, View } from \"react-native\";\r\n\r\ntype State = {\r\n    display: boolean;\r\n};\r\n\r\nexport class LoadingSpinner extends Component<{}, State> {\r\n    public state: State = {\r\n        display: false\r\n    };\r\n\r\n    private timeout: number;\r\n\r\n    constructor(props: {}) {\r\n        super(props);\r\n\r\n        this.timeout = setTimeout(() => {\r\n            this.setState({ display: true });\r\n        }, 1000);\r\n    }\r\n\r\n    public render(): ReactNode {\r\n        const {display} = this.state;\r\n\r\n        return display ? <ActivityIndicator size={100}/> : <View/>;\r\n    }\r\n\r\n    public componentWillUnmount(): void {\r\n        clearTimeout(this.timeout);\r\n    }\r\n}\r\n","import { Dayjs } from \"dayjs\";\r\n\r\nimport { ChangeFeedItem } from \"../../services/ChangeFeedItem\";\r\nimport { ChangeCollection } from \"../../services/ChangeCollection\";\r\n\r\nimport { Change } from \"../../services/Change\";\r\n\r\nexport class ChangeModel {\r\n    public static Make(item: ChangeFeedItem, changeCollection: ChangeCollection, change: Change): ChangeModel {\r\n        return new ChangeModel(\r\n            item.id, item.name, item.name2, item.category, item.uri,\r\n            changeCollection.timestamp,\r\n            change.name, change.oldValue, change.newValue\r\n        );\r\n    }\r\n\r\n    constructor(\r\n        public id: number,\r\n        public name: string,\r\n        public name2: string,\r\n        public category: string,\r\n        public uri: string,\r\n        public timeStamp: Dayjs,\r\n        public changeName: string,\r\n        public oldValue: string,\r\n        public newValue: string\r\n    ) { }\r\n}\r\n","import React, { Component, ReactElement, ReactNode } from 'react';\r\nimport { View, ViewStyle, StyleSheet, TextStyle, FlatList } from 'react-native';\r\nimport { ListItem, Text } from 'react-native-elements';\r\nimport { Container } from 'inversify';\r\n\r\nimport { IChangeFeedService } from '../../services/ChangeFeedService';\r\nimport { Article } from '../../services/Article';\r\nimport { CollapsingPanel } from '../../components/CollapsingPanel';\r\n\r\nimport { ChangeModel } from './ChangeModel';\r\n\r\n\r\ntype Props = {\r\n    model: ChangeModel,\r\n    index: number\r\n};\r\n\r\nexport class ChangesListItem extends Component<Props> {\r\n\r\n    private readonly changeFeedService: IChangeFeedService;\r\n\r\n    constructor(props: Props) {\r\n        super(props);\r\n\r\n        this.renderFeedItemTitle = this.renderFeedItemTitle.bind(this);\r\n        this.renderFeedItemDetail = this.renderFeedItemDetail.bind(this);\r\n\r\n        const serviceLocator: Container = global.serviceLocator;\r\n        this.changeFeedService = serviceLocator.get(\"IChangeFeedService\");\r\n    }\r\n\r\n    public render(): ReactNode {\r\n        const feedItemTitle: ReactElement = this.renderFeedItemTitle();\r\n        const feedItemDetail: () => Promise<ReactElement> = async () => this.renderFeedItemDetail();\r\n\r\n        const styles: { feedItem: ViewStyle } = {\r\n            feedItem: {\r\n                borderBottomWidth: StyleSheet.hairlineWidth,\r\n                borderColor: \"rgba(0, 0, 0, 0.12)\"\r\n            }\r\n        };\r\n\r\n        return <View style={styles.feedItem}><CollapsingPanel summary={feedItemTitle} detail={feedItemDetail} /></View>;\r\n    }\r\n\r\n    private renderFeedItemTitle(): ReactElement {\r\n        const styles: {\r\n            itemTitle: TextStyle,\r\n            itemSubtitle: TextStyle\r\n        } = {\r\n            itemTitle: {\r\n                fontWeight: \"bold\"\r\n            },\r\n            itemSubtitle: {\r\n                fontStyle: \"italic\"\r\n            },\r\n        };\r\n\r\n        const { model, index } = this.props;\r\n\r\n        const renderNames: () => ReactElement = () => {\r\n            return model.name2 != null && model.name2.length > 0 ?\r\n                <Text><Text style={styles.itemTitle}>{`${model.name2},  `}</Text>{`${model.name}`}</Text> :\r\n                <Text style={styles.itemTitle}>{`${model.name}`}</Text>;\r\n        };\r\n\r\n        const renderCategory: () => ReactElement = () => {\r\n            return <Text style={styles.itemSubtitle}>{`${model.category}`}</Text>;\r\n        };\r\n\r\n        const renderChange: () => ReactElement = () => {\r\n            return <Text>{`${model.changeName}`}</Text>;\r\n        };\r\n\r\n        return <ListItem\r\n            key={index}\r\n            title={\r\n                <View>{renderNames()}{renderCategory()}</View>\r\n            }\r\n            subtitle={`${model.changeName} changed from \"${model.oldValue}\" to \"${model.newValue}\"`}\r\n            rightSubtitle={renderChange()}\r\n        />;\r\n    }\r\n\r\n    private async renderFeedItemDetail(): Promise<ReactElement> {\r\n        const styles: { itemKey: TextStyle } = {\r\n            itemKey: {\r\n                fontStyle: \"italic\"\r\n            }\r\n        };\r\n\r\n        const { model } = this.props;\r\n\r\n        try {\r\n            const article: Article = await this.changeFeedService.getArticle(model.id);\r\n\r\n            return <View>\r\n                <FlatList\r\n                    data={[\r\n                        { key: \"producer\", value: article.producer },\r\n                        { key: \"importer\", value: article.importer },\r\n                        { key: \"origin\", value: article.origin },\r\n                        { key: \"country of origin\", value: article.countryOfOrigin },\r\n                        { key: \"packaging\", value: article.packaging },\r\n                        { key: \"vintage\", value: article.vintage },\r\n                        { key: \"price\", value: article.price },\r\n                        { key: \"price per litre\", value: article.pricePerLitre },\r\n                        { key: \"alcohol\", value: article.alcohol },\r\n                        { key: \"volume\", value: article.volume },\r\n                    ]}\r\n                    renderItem={({ item }) =>\r\n                        <Text><Text style={styles.itemKey}>{item.key}</Text> : <Text>{item.value}</Text></Text>}\r\n                />\r\n            </View>;\r\n        } catch (error) {\r\n            console.error(\"Error fetching article \" + model.id + \" in ChangeScreen.loadArticle\", error);\r\n            return <View />;\r\n        }\r\n    }\r\n}\r\n","import React, { Component, ReactNode, ReactElement } from 'react';\r\nimport { View, TextStyle, FlatList, ViewStyle } from 'react-native';\r\nimport { Text, CheckBox } from 'react-native-elements';\r\n\r\nimport { CollapsingPanel } from '../../components/CollapsingPanel';\r\n\r\nconst styles: { container: TextStyle, title: TextStyle } = {\r\n    container: {\r\n        backgroundColor: \"#DFDFDF\",\r\n        paddingLeft: 10,\r\n        paddingTop: 12,\r\n        paddingBottom: 8,\r\n        marginBottom: 10\r\n    },\r\n    title: {\r\n        color: \"slategrey\",\r\n        fontWeight: \"bold\"\r\n    }\r\n};\r\n\r\nexport type Item<T> = {\r\n    key: T,\r\n    text: string,\r\n    checked: boolean\r\n};\r\n\r\ntype Props<T> = {\r\n    items: Item<T>[],\r\n    onPress: (items: Item<T>[], updated: Item<T>) => void\r\n};\r\n\r\ntype State<T> = {\r\n    items: Item<T>[]\r\n};\r\n\r\nconst checkBoxStyles: { container: ViewStyle, text: TextStyle } = {\r\n    container: {\r\n        paddingTop: 5,\r\n        paddingRight: 5,\r\n        paddingBottom: 5,\r\n        paddingLeft: 5,\r\n        borderRadius: 20,\r\n        backgroundColor: \"#DFDFDF\",\r\n        borderColor: \"slategrey\"\r\n    },\r\n    text: {\r\n        fontSize: 14,\r\n        marginLeft: 5,\r\n        marginRight: 5,\r\n        fontWeight: \"normal\"\r\n    }\r\n};\r\n\r\nexport class ChangesListFilter<T> extends Component<Props<T>, State<T>> {\r\n    public state: State<T> = {\r\n        items: []\r\n    };\r\n\r\n    constructor(props: Props<T>) {\r\n        super(props);\r\n\r\n        this.renderCheckboxes = this.renderCheckboxes.bind(this);\r\n\r\n        this.state.items = props.items;\r\n    }\r\n\r\n    public render(): ReactNode {\r\n        return <View style={styles.container}>\r\n            {<CollapsingPanel\r\n                summary={<Text style={styles.title}>Filter results</Text>}\r\n                detail={this.renderCheckboxes()}/>}\r\n        </View>;\r\n    }\r\n\r\n    private renderCheckboxes(): ReactElement {\r\n        const { items } = this.state;\r\n\r\n        return <FlatList\r\n            data={items}\r\n            renderItem={({ item }) => {\r\n                return <CheckBox containerStyle={checkBoxStyles.container} textStyle={checkBoxStyles.text} title={item.text}\r\n                    checked={item.checked} onPress={() => this.onPress(item)}\r\n                />;\r\n            }} numColumns={3} extraData={this.state}/>;\r\n    }\r\n\r\n    private onPress(pressedItem: Item<T>): void {\r\n        const updatedItems: Item<T>[] = this.state.items.map(p => (\r\n            { key: p.key, text: p.text, checked: p.key === pressedItem.key ? !p.checked : p.checked }\r\n        ));\r\n\r\n        this.setState({\r\n            items: updatedItems\r\n        });\r\n\r\n        this.props.onPress(updatedItems, { key: pressedItem.key, text: pressedItem.text, checked: !pressedItem.checked });\r\n    }\r\n}\r\n","export class Change {\r\n    public static Make(dto: any): Change {\r\n        return new Change(dto.name, dto.oldValue, dto.newValue);\r\n    }\r\n    constructor(\r\n        public name: string,\r\n        public oldValue: string,\r\n        public newValue: string\r\n    ) { }\r\n}\r\n","import * as dayJs from \"dayjs\";\r\nexport const createDayJs: (date: Date) => dayJs.Dayjs = (dayJs)[\"default\"] || dayJs;\r\n\r\nimport { Change } from \"./Change\";\r\n\r\nexport class ChangeCollection {\r\n    public static Make(dto: any): ChangeCollection {\r\n        return new ChangeCollection(createDayJs(dto.timestamp), (dto.changes as any[]).map(c => Change.Make(c)));\r\n    }\r\n    \r\n    constructor(\r\n        public timestamp: dayJs.Dayjs,\r\n        public changes: Change[]\r\n    ) { }\r\n}\r\n","import { ChangeCollection } from \"./ChangeCollection\";\r\n\r\nexport class ChangeFeedItem {\r\n    public static Make(dto: any): ChangeFeedItem {\r\n        return new ChangeFeedItem(dto.id, dto.name, dto.name2, dto.category, ChangeCollection.Make(dto.changes), dto.uri);\r\n    }\r\n    constructor(\r\n        public id: number,\r\n        public name: string,\r\n        public name2: string,\r\n        public category: string,\r\n        public changes: ChangeCollection,\r\n        public uri: string\r\n    ) { }\r\n}\r\n","import * as dayJs from \"dayjs\";\r\nexport const createDayJs: (date: Date) => dayJs.Dayjs = (dayJs)[\"default\"] || dayJs;\r\n\r\nimport { ChangeFeedItem } from \"./ChangeFeedItem\";\r\n\r\nexport class ChangeFeed {\r\n    public static Make(dto: any): ChangeFeed {\r\n        return new ChangeFeed(\r\n            createDayJs(dto.timestamp), (dto.data as any[]).map(c => ChangeFeedItem.Make(c))\r\n        );\r\n    }\r\n\r\n    constructor(\r\n        public timestamp: dayJs.Dayjs,\r\n        public data: ChangeFeedItem[]\r\n    ) { }\r\n}\r\n","import * as dayJs from \"dayjs\";\r\nexport const createDayJs: (date: Date) => dayJs.Dayjs = (dayJs)[\"default\"] || dayJs;\r\n\r\nimport { ChangeCollection } from \"./ChangeCollection\";\r\n\r\nexport class Article {\r\n    public static Make(dto: any): Article {\r\n        return new Article(dto.id, dto.name, dto.name2, dto.producer, dto.importer, dto.type, dto.category, dto.origin, dto.countryOfOrigin,\r\n            dto.packaging, dto.vintage, dto.price, dto.pricePerLitre, dto.alcohol, dto.volume, dto.expired, dto.history, dto.timestamp,\r\n            dto.uri);\r\n    }\r\n\r\n    constructor(\r\n        public id: number,\r\n        public name: string,\r\n        public name2: string,\r\n        public producer: string,\r\n        public importer: string,\r\n        public type: string,\r\n        public category: string,\r\n        public origin: string,\r\n        public countryOfOrigin: string,\r\n        public packaging: string,\r\n        public vintage: string,\r\n        public price: number,\r\n        public pricePerLitre: number,\r\n        public alcohol: string,\r\n        public volume: number,\r\n        public expired: boolean,\r\n        public history: ChangeCollection,\r\n        public timestamp: dayJs.Dayjs,\r\n        public uri: string\r\n    ) { }\r\n}\r\n","import { injectable } from \"inversify\";\r\n\r\nimport { ChangeFeed } from \"./ChangeFeed\";\r\nimport { Article } from \"./Article\";\r\n\r\nexport interface IChangeFeedService {\r\n    getChangeFeed(): Promise<ChangeFeed>;\r\n    getArticle(id: number): Promise<Article>;\r\n}\r\n\r\n@injectable()\r\nexport class ChangeFeedService implements IChangeFeedService {\r\n    constructor(private baseUri: string) { }\r\n\r\n    public async getChangeFeed(): Promise<ChangeFeed> {\r\n        const response: Response = await fetch(this.baseUri + \"/change/recent/\");\r\n        const responseJson: any = await response.json();\r\n        return ChangeFeed.Make(responseJson);\r\n    }\r\n\r\n    public async getArticle(id: number): Promise<Article> {\r\n        const response: Response = await fetch(this.baseUri + \"/article/\" + id);\r\n        const responseJson: any = await response.json();\r\n        return Article.Make(responseJson);\r\n    }\r\n}\r\n","import * as dayJs from \"dayjs\";\r\nimport { injectable } from \"inversify\";\r\nconst createDayJs: () => dayJs.Dayjs = (dayJs)[\"default\"] || dayJs;\r\n\r\nexport interface IClock {\r\n    now(): dayJs.Dayjs;\r\n}\r\n\r\n@injectable()\r\nexport class Clock implements IClock {\r\n    public now(): dayJs.Dayjs {\r\n        return createDayJs();\r\n    }\r\n}\r\n","import { Container } from \"inversify\";\r\nimport { IChangeFeedService, ChangeFeedService } from \"./services/ChangeFeedService\";\r\nimport { Appsettings } from \"./AppSettings\";\r\nimport { IClock, Clock } from \"./lib/clock\";\r\n\r\nexport function ConfigureDependencies(settings: Appsettings): Container {\r\n    const container: Container = new Container();\r\n\r\n    container.bind<IChangeFeedService>(\"IChangeFeedService\").toConstantValue(new ChangeFeedService(settings.baseUrl));\r\n    container.bind<IClock>(\"IClock\").to(Clock);\r\n\r\n    return container;\r\n}\r\n","import React, { Component, ReactNode } from \"react\";\r\nimport { Text, View, StyleSheet } from 'react-native';\r\n\r\nconst styles: any = StyleSheet.create({\r\n  container: {\r\n    flex: 1,\r\n    alignItems: \"center\",\r\n    justifyContent: \"center\",\r\n    backgroundColor: \"lightslategrey\"\r\n  },\r\n  textBlock: {\r\n    alignItems: \"center\"\r\n  },\r\n  title: {\r\n    fontSize: 30,\r\n    fontWeight: \"bold\"\r\n  },\r\n  subtitle: {\r\n    fontSize: 20\r\n  }\r\n});\r\n\r\nconst hexagonStyles: any = StyleSheet.create({\r\n  hexagon: {\r\n    width: 300,\r\n    height: 165\r\n  },\r\n  hexagonInner: {\r\n    width: 300,\r\n    height: 165,\r\n    backgroundColor: '#fae1e6'\r\n  },\r\n  hexagonAfter: {\r\n    position: 'absolute',\r\n    bottom: -75,\r\n    left: 0,\r\n    width: 0,\r\n    height: 0,\r\n    borderStyle: 'solid',\r\n    borderLeftWidth: 150,\r\n    borderLeftColor: 'transparent',\r\n    borderRightWidth: 150,\r\n    borderRightColor: 'transparent',\r\n    borderTopWidth: 75,\r\n    borderTopColor: '#fae1e6'\r\n  },\r\n  hexagonBefore: {\r\n    position: 'absolute',\r\n    top: -75,\r\n    left: 0,\r\n    width: 0,\r\n    height: 0,\r\n    borderStyle: 'solid',\r\n    borderLeftWidth: 150,\r\n    borderLeftColor: 'transparent',\r\n    borderRightWidth: 150,\r\n    borderRightColor: 'transparent',\r\n    borderBottomWidth: 75,\r\n    borderBottomColor: '#fae1e6'\r\n  }\r\n});\r\n\r\nexport class SplashScreen extends Component<{\r\n  navigation: any;\r\n}> {\r\n  public render(): ReactNode {\r\n    return (<View style={styles.container}>\r\n      <View style={hexagonStyles.hexagon}>\r\n        <View style={hexagonStyles.hexagonInner}>\r\n          <View style={styles.textBlock}>\r\n            <Text style={styles.title}>BOLAGET</Text>\r\n            <Text>+/-</Text>\r\n            <Text style={styles.subtitle}>Inventory Change Tracker</Text>\r\n          </View>\r\n        </View>\r\n        <View style={hexagonStyles.hexagonBefore} />\r\n        <View style={hexagonStyles.hexagonAfter} />\r\n      </View>\r\n    </View>);\r\n  }\r\n  public componentDidMount(): void {\r\n    setTimeout(() => {\r\n      this.props.navigation.navigate('Main');\r\n    }, 2000);\r\n  }\r\n}\r\n","import React from 'react';\r\nimport { Platform } from 'react-native';\r\nimport { createAppContainer, createSwitchNavigator, NavigationContainer } from 'react-navigation';\r\n\r\nimport { ChangesScreen } from './screens/changes/ChangesScreen';\r\nimport { SplashScreen } from './screens/splash/SplashScreen';\r\n\r\nexport function createMyAppContainer(): NavigationContainer {\r\n    const AppNavigator: NavigationContainer = createSwitchNavigator(\r\n        {\r\n            Splash: SplashScreen,\r\n            Main: ChangesScreen,\r\n        },\r\n        {\r\n            ...Platform.select({\r\n                default: {\r\n                    initialRouteName: \"Splash\"\r\n                },\r\n                web: {\r\n                    initialRouteName: \"Main\"\r\n                }\r\n            })\r\n        }\r\n    );\r\n\r\n    return createAppContainer(AppNavigator);\r\n}\r\n","/* eslint-env browser */\n\nif ('serviceWorker' in navigator) {\n  window.addEventListener('load', function() {\n    navigator.serviceWorker\n      .register('/expo-service-worker.js', { scope: '/' })\n      .then(function(info) {\n        // console.info('Registered service-worker', info);\n      })\n      .catch(function(error) {\n        console.info('Failed to register service-worker', error);\n      });\n  });\n}\n"],"sourceRoot":""}