Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stores for data #22

Merged
merged 40 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7623939
add some prototype data for the stores
MaHaWo Aug 26, 2024
0e4087a
add childrenskeleton
MaHaWo Aug 26, 2024
dfd3d6f
work on childrendata skeleton
MaHaWo Aug 26, 2024
90c0e5e
use typescript
MaHaWo Aug 26, 2024
dba2aaf
add typscript stuff
MaHaWo Aug 26, 2024
597bd29
finish typescript stuff
MaHaWo Aug 27, 2024
98efe89
finish ts stuff, add test files, add tests for userstore
MaHaWo Aug 27, 2024
0e13f41
work on tests
MaHaWo Aug 27, 2024
36b21a2
add tests
MaHaWo Aug 27, 2024
db7486a
finish tests
MaHaWo Aug 27, 2024
d903627
correct name of tests
MaHaWo Aug 27, 2024
1c3a035
Merge branch 'main' into add-stores-for-data
MaHaWo Aug 27, 2024
386b6b5
add dummy data and more functions to childrenstore
MaHaWo Aug 27, 2024
926228d
use childrenstore in childrenpage overview
MaHaWo Aug 27, 2024
a4376d0
add comments
MaHaWo Aug 27, 2024
890fae5
correct existing tests
MaHaWo Aug 27, 2024
84473ff
add more tests
MaHaWo Aug 27, 2024
1f1b6c1
add more tests
MaHaWo Aug 27, 2024
66a8268
use subscribe in childrenpage
MaHaWo Aug 28, 2024
315107d
add unsubscribe
MaHaWo Aug 28, 2024
9d97258
finish childrenstore test
MaHaWo Aug 28, 2024
549aacb
correct some mistatkes
MaHaWo Aug 28, 2024
7c92a17
make dummy data random and generate programmatically
MaHaWo Aug 28, 2024
a73a161
add dynamic routing
MaHaWo Aug 28, 2024
7610c20
implement dynamic routing with data loading
MaHaWo Aug 28, 2024
61f5c59
correct some mistakes, change some routign
MaHaWo Aug 28, 2024
31c80fa
remove userstore because usage too unclear, add dynamic routing for s…
MaHaWo Aug 28, 2024
292646f
... actually add dynamic routing and remove userstore...
MaHaWo Aug 28, 2024
e50138a
undo changes to the user login page
MaHaWo Aug 28, 2024
449737f
add docstrings
MaHaWo Aug 28, 2024
751cefa
add docstrings
MaHaWo Aug 28, 2024
7934701
remove dummy dropdowns
MaHaWo Aug 28, 2024
93480cc
fix contentstore tests
MaHaWo Aug 28, 2024
faff33f
fix tests
MaHaWo Aug 28, 2024
c57f056
remove unused functions
MaHaWo Aug 28, 2024
1a91e50
add some comments
MaHaWo Aug 28, 2024
638da33
remove repeated data generation
MaHaWo Aug 28, 2024
4d88ab7
fix error in test
MaHaWo Aug 28, 2024
e729eb4
fix build error wrt static rendering
MaHaWo Aug 28, 2024
dd89446
remove some code
MaHaWo Aug 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 30 additions & 47 deletions src/lib/components/Childrenpage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
header: item.name,
summary: item.info,
image: item.image,
href: item.href ? item.href : '/'
href: `/childLand/${item.user}/${item.id}`
};
});

Expand All @@ -20,6 +20,7 @@

// dynamically create the styles for individual gallery tiles based on the data.
// The 'Neu' element needs to be styled differently in particular
// FIXME: this needs to go. styles have no business being defined in <script>
export function createStyle(data) {
return data.map((item) => ({
card:
Expand Down Expand Up @@ -47,58 +48,40 @@
}
</script>

<script>
<script lang="ts">
import CardDisplay from '$lib/components/DataDisplay/CardDisplay.svelte';
import GalleryDisplay from '$lib/components/DataDisplay/GalleryDisplay.svelte';
import {
createDummyData,
fetchChildrenDataforUser,
type ChildData
} from '$lib/stores/childrenStore';
import { Heading } from 'flowbite-svelte';
import AbstractContent from './AbstractContent.svelte';
import { onMount } from 'svelte';
// create data and

const rawdata = [
{
name: 'Anna',
info: 'A child that is making a mess and is doing good. Click to view more.',
image: 'child_avatar.png',
href: '/surveyfeedback'
},
{
name: 'Ben',
image: 'children.png',
info: 'A child that is making a mess and is doing good. Click to view more.',
href: '/surveyfeedback'
},
{
name: 'C',
info: 'A child that is making a mess and is doing good. Click to view more.',
href: '/surveyfeedback',
image: 'child_avatar.png'
},
{
name: 'Dora',
image: '/children.png',
info: 'A child that is making a mess and is doing good. Click to view more.',
href: '/surveyfeedback'
},
{
name: 'E',
image: 'children.png',
info: 'A child that is making a mess and is doing good. Click to view more.',
href: '/surveyfeedback'
},
{
name: 'F',
image: 'children.png',
info: 'A child that is making a mess and is doing good. Click to view more.',
href: '/surveyfeedback'
}
];
let data: ChildData[] = [];
let loading = true;

const data = convertData(rawdata);
async function init() {
loading = true;
await createDummyData();
let rawdata = await fetchChildrenDataforUser('dummyUser');
data = convertData(rawdata);
loading = false;
}

// this fetches dummy child data for the dummy user whenever the component is mounted into the dom
// it is conceptualized as emulating an API call that would normally fetch this from the server.
onMount(init);
</script>

<AbstractContent showNavIcons={false} iconProps={{ class: 'w-10 h-10' }}>
<Heading tag="h1" class="mb-2" color="text-gray-700 dark:text-gray-400">Übersicht</Heading>
<Heading tag="h1" class="mb-2" color="text-gray-700 dark:text-gray-400">Übersicht</Heading>

<div class="cols-1 grid gap-y-8">
<div class="cols-1 grid gap-y-8">
{#if loading}
<p>Daten werden geladen...</p>
{:else}
<p class="text-lg text-gray-700 dark:text-gray-400">
Wählen sie ein Kind zur Beobachtung aus oder legen melden sie ein neues Kind an.
</p>
Expand All @@ -108,5 +91,5 @@
searchableCol={'header'}
componentProps={createStyle(data)}
/>
</div>
</AbstractContent>
{/if}
</div>
1 change: 0 additions & 1 deletion src/lib/components/DataInput/AbstractDropdownItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { Select, Tooltip } from 'flowbite-svelte';
// have the data processing here to coerce the input into the format that the component expects

console.log($$props);
const items = $$props.items.map((item) => ({ name: item, value: item }));
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
export let heading = null;
export let buttons = null;
export let description = null;
console.log('props: ', props);
</script>

<div class="m-1 items-center justify-center pb-6">
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/Frontpage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import CardDisplay from './DataDisplay/CardDisplay.svelte';
import GalleryDisplay from './DataDisplay/GalleryDisplay.svelte';
export let getStarted = '/firstdropdown';
export let getStarted = '';

export let items = [
{
Expand Down
216 changes: 216 additions & 0 deletions src/lib/stores/childrenStore.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { get } from 'svelte/store';
import { describe, expect, it } from 'vitest';
import {
addChildData,
addChildObservation,
children,
fetchChildData,
fetchChildrenDataforUser,
fetchObservationData,
fetchObservationDataForUser,
removeChildData,
type ChildObject,
type ObservationData
} from './childrenStore';

describe('normal functionality', () => {
const mockObservationData: ObservationData = {
id: 'child1',
user: 'alpha',
current: ['a', 'b', 'c'],
summary: ['x', 'y']
};
const mockObservationData2: ObservationData = {
id: 'child1',
user: 'beta',
current: ['a', 'b', 'c'],
summary: ['x', 'y']
};
const mockChildData: ChildObject = {
childData: {
id: 'childfoo',
user: 'alpha',
name: 'foo',
age: 3,
nationality: 'turkish'
},
observationData: mockObservationData
};
const mockChildData2: ChildObject = {
childData: {
id: 'childbar',
user: 'alpha',
name: 'bar',
age: 5,
nationality: 'german'
},
observationData: mockObservationData
};

const mockChildData3: ChildObject = {
childData: {
id: 'childbaz',
user: 'beta',
name: 'baz',
age: 2,
nationality: 'british'
},
observationData: mockObservationData2
};

function reset() {
children.set({
alpha: {
childfoo: mockChildData,
childbar: mockChildData2
},
beta: {
childfoo: mockChildData3
}
});
}

it('should add child successfully', async () => {
reset();
await addChildData('alpha', 'childC', mockChildData3.childData);
expect(get(children)['alpha']['childC'].childData).toEqual(mockChildData3.childData);
});

it('should add child observationdata successfully', async () => {
reset();

await addChildData('alpha', 'childC', mockChildData3.childData);
await addChildObservation('alpha', 'childC', mockChildData3.observationData);

expect(get(children)['alpha']['childC'].observationData).toEqual(
mockChildData3.observationData
);
});

it('cannot assign observationdata when childData is missing', async () => {
reset();
try {
await addChildObservation('alpha', 'childC', mockChildData3.observationData);
} catch (error: Error | unknown) {
expect((error as Error).message).toBe(
'Child token childC does not exist for user token alpha'
);
}
});

it('cannot assign observationdata for unknown user', async () => {
reset();
try {
await addChildObservation('x', 'childC', mockChildData3.observationData);
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('User token x not found');
}
});

it('should remove child successfully', async () => {
reset();
await removeChildData('beta', 'childfoo');
expect(get(children)['beta']['childfoo']).toEqual(undefined);
});

it('should throw when adding with nonexistant user or existing child key', async () => {
reset();
try {
await addChildData('alpha', 'childA', mockChildData3.childData);
} catch (error: Error | unknown) {
expect((error as Error).message).toBe(
'Child token childA already exists for user token alpha'
);
}

try {
await addChildData('x', 'childA', mockChildData3.childData);
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('User token x not found');
}
});

it('should throw when removing with nonexistant user or nonexisting child key', async () => {
reset();
try {
await removeChildData('x', 'childA');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('User token x not found');
}

try {
await removeChildData('alpha', 'notthere');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('Child token notthere not found for user token alpha');
}
});

it('should fetch observation data', async () => {
reset();
expect(await fetchObservationData('alpha', 'childfoo')).toEqual(mockObservationData);
});

it('should fetch child data', async () => {
reset();
expect(await fetchChildData('alpha', 'childfoo')).toEqual({
name: 'foo',
age: 3,
nationality: 'turkish',
id: 'childfoo',
user: 'alpha'
});
});

it('cannot fetch from unknown keys', async () => {
reset();

try {
await fetchObservationData('x', 'childA');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('No such user in the childrenstore');
}

try {
await fetchObservationData('alpha', 'unknown');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('No such child in the childrenstore for user alpha');
}
});

it('should fetch list of childrendata', async () => {
reset();
const data = await fetchChildrenDataforUser('alpha');

expect(data).toEqual([mockChildData2.childData, mockChildData.childData]);
});

it('should fetch list of observationdata successfully', async () => {
reset();
const data = await fetchObservationDataForUser('alpha');

expect(data).toEqual([
['childfoo', mockObservationData],
['childbar', mockObservationData]
]);
});

it('cannot fetch childrendata from uknown', async () => {
reset();

try {
await fetchChildrenDataforUser('x');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('No such user in the childrenstore');
}
});

it('cannot fetch observationdata from uknown', async () => {
reset();

try {
await fetchObservationDataForUser('x');
} catch (error: Error | unknown) {
expect((error as Error).message).toBe('No such user in the childrenstore');
}
});
});
Loading