Revize 7c4cd2cd
Přidáno uživatelem Fantič před téměř 2 roky(ů)
App.tsx | ||
---|---|---|
13 | 13 |
<VStack space={4} alignItems="center"> |
14 | 14 |
{/* TODO: remove placeholder pro navbar */} |
15 | 15 |
<Center w="100%" h="40" bg="indigo.300" rounded="md" shadow={3} /> |
16 |
<ItemViewPage itemId={'PrgA-811'} /> |
|
16 |
{/* <ItemViewPage itemId={'BxlA-2'} /> */} |
|
17 |
<ItemViewPage itemId={'BxlA-5'} /> |
|
17 | 18 |
</VStack> |
18 | 19 |
</NativeBaseProvider> |
19 | 20 |
</Provider> |
src/pages/ItemViewPage.tsx | ||
---|---|---|
1 | 1 |
import { Center, Box, Heading, VStack, FormControl, Link, Input, Button, HStack, Text, StatusBar, Container, Divider, Spacer } from "native-base" |
2 |
import React, { useState } from "react" |
|
2 |
import React, { useState, useEffect } from "react"
|
|
3 | 3 |
import { useDispatch, useSelector } from "react-redux" |
4 | 4 |
import { AppDispatch } from "../stores/store" |
5 | 5 |
import { getPreviousConcordance, getNextConcordance, getItem } from "../stores/actions/itemThunks" |
6 |
import { Item, ItemState } from "../stores/reducers/itemSlice" |
|
6 |
import { Item, ItemState } from "../types/item" |
|
7 |
import { login } from "../stores/actions/userThunks" |
|
7 | 8 |
|
8 | 9 |
interface ItemViewProps { |
9 | 10 |
itemId: string |
... | ... | |
13 | 14 |
|
14 | 15 |
const dispatch = useDispatch<AppDispatch>(); |
15 | 16 |
|
16 |
const itemState = useSelector((state: ItemState) => state) |
|
17 |
|
|
18 |
useEffect(() => { |
|
19 |
dispatch(getItem(props.itemId)); |
|
20 |
}, []); |
|
17 |
const itemViewState = useSelector((itemState: ItemState) => itemState) |
|
21 | 18 |
|
22 | 19 |
const handleGetPreviousConcordance = async () => { |
23 |
await dispatch(getPreviousConcordance());
|
|
20 |
dispatch(getPreviousConcordance()); |
|
24 | 21 |
}; |
25 | 22 |
|
26 | 23 |
const handleGetNextConcordance = async () => { |
27 |
await dispatch(getNextConcordance());
|
|
24 |
dispatch(getNextConcordance()); |
|
28 | 25 |
}; |
29 | 26 |
|
27 |
useEffect(() => { |
|
28 |
dispatch(login({ username: "Viktorie", password: "Golem123." })); |
|
29 |
dispatch(getItem(props.itemId)); |
|
30 |
}, []); |
|
30 | 31 |
|
32 |
console.log(itemViewState.item); |
|
31 | 33 |
|
32 | 34 |
return ( |
33 | 35 |
<VStack> |
... | ... | |
38 | 40 |
color="coolGray.800" |
39 | 41 |
_dark={{ color: "warmGrey.50" }} |
40 | 42 |
> |
41 |
{item.authorName} |
|
43 |
{itemViewState.item.authorName}
|
|
42 | 44 |
</Heading> |
43 | 45 |
|
44 | 46 |
<Text fontSize="xl" mt="2"> |
45 |
{item.caption}
|
|
47 |
{itemViewState.item.workName}
|
|
46 | 48 |
</Text> |
47 | 49 |
|
48 | 50 |
<HStack> |
... | ... | |
57 | 59 |
); |
58 | 60 |
} |
59 | 61 |
|
60 |
export default ItemViewPage |
|
61 |
|
|
62 |
function useEffect(arg0: () => void, arg1: (string | (import("redux-thunk").ThunkDispatch<{ user: import("../stores/reducers/userSlice").UserState; item: import("../stores/reducers/itemSlice").ItemState }, undefined, import("redux").AnyAction> & import("redux").Dispatch<...>))[]) { |
|
63 |
throw new Error("Function not implemented.") |
|
64 |
} |
|
62 |
export default ItemViewPage; |
src/stores/actions/itemThunks.ts | ||
---|---|---|
1 | 1 |
import { createAsyncThunk } from "@reduxjs/toolkit" |
2 | 2 |
import { getItemRequest } from "../../api/itemservice" |
3 | 3 |
import { getItemNotesRequest } from "../../api/notesservice" |
4 |
import { ItemState } from "../reducers/itemSlice" |
|
4 |
import { ItemState } from "../../types/item"; |
|
5 |
|
|
5 | 6 |
|
6 | 7 |
export const getItem = createAsyncThunk( |
7 | 8 |
"item/getItem", |
8 | 9 |
async (itemId: string) => { |
9 | 10 |
try { |
11 |
|
|
12 |
console.log("¨GET item/getItem/" + itemId); |
|
13 |
|
|
10 | 14 |
const response = await getItemRequest(itemId) |
11 |
console.log(response) |
|
12 |
if (response.status === 200) { |
|
15 |
|
|
16 |
|
|
17 |
// data with image |
|
18 |
if (response.status === 200 && response.data.object.length > 1) { |
|
19 |
return { |
|
20 |
fullView: true, |
|
21 |
|
|
22 |
concordances: response.data.concordances, |
|
23 |
|
|
24 |
authorDisplayName: response.data.object[0].name[0].getty_data.display_name, |
|
25 |
workName: response.data.object[0].caption, |
|
26 |
|
|
27 |
inventoryItem: response.data.text, |
|
28 |
searchSubjects: response.data.search_subject, |
|
29 |
|
|
30 |
// additional fields |
|
31 |
authorName: response.data.object[1].name[0].getty_data.display_name, |
|
32 |
|
|
33 |
imageUrl: response.data.object[1].images[0].file, |
|
34 |
title: response.data.object[1].images[0].text, |
|
35 |
|
|
36 |
institution: { |
|
37 |
name :response.data.object[1].institution, |
|
38 |
inventoryNumber: response.data.object[1].id_number, |
|
39 |
country: response.data.object[1].country, |
|
40 |
city: response.data.object[1].city |
|
41 |
}, |
|
42 |
repository: response.data.object[1].repository, |
|
43 |
provenance: response.data.object[1].provenance, |
|
44 |
description: response.data.object[1].physical_description |
|
45 |
} |
|
46 |
} |
|
47 |
// data without image |
|
48 |
else if (response.status === 200 && response.data.object.length == 1) { |
|
13 | 49 |
return { |
14 |
authorName: response.data.object[0].getty_data.display_name, |
|
15 |
caption: response.data.object[0].caption, |
|
16 |
concordances: response.data.concordances |
|
50 |
fullView: false, |
|
51 |
|
|
52 |
concordances: response.data.concordances, |
|
53 |
|
|
54 |
authorName: response.data.object[0].name[0].getty_data.display_name, |
|
55 |
workName: response.data.object[0].caption, |
|
17 | 56 |
} |
18 |
} else {
|
|
57 |
} { |
|
19 | 58 |
return Promise.reject(response.data ? response.data : "Error") |
20 | 59 |
} |
21 | 60 |
} catch (err: any) { |
src/stores/actions/userThunks.ts | ||
---|---|---|
5 | 5 |
"user/login", |
6 | 6 |
async (payload: { username: string, password: string }) => { |
7 | 7 |
try { |
8 |
console.log("POST user/login"); |
|
8 | 9 |
const response = await loginRequest(payload.username, payload.password) |
9 |
console.log(response) |
|
10 | 10 |
if (response.status === 200) { |
11 | 11 |
return { |
12 | 12 |
username: payload.username, |
src/stores/reducers/itemSlice.ts | ||
---|---|---|
1 | 1 |
import { PayloadAction, createSlice } from "@reduxjs/toolkit" |
2 | 2 |
import { getItem, getItemNotes, getNextConcordance, getPreviousConcordance } from "../actions/itemThunks" |
3 |
import { Note } from "./notesSlice"
|
|
3 |
import { Certainty, ItemState, Item } from "../../types/item";
|
|
4 | 4 |
|
5 | 5 |
|
6 |
export interface Item { |
|
7 |
authorName: string |
|
8 |
caption: string |
|
9 |
|
|
10 |
|
|
11 |
concordances: Concordance[] |
|
12 |
} |
|
13 |
|
|
14 |
export interface ItemState { |
|
15 |
item: Item |
|
16 |
concordances: Concordance[] |
|
17 |
selectedConcordance: number |
|
18 |
notes: Note[] |
|
19 |
lastError?: string |
|
20 |
} |
|
21 |
|
|
22 |
export interface Concordance { |
|
23 |
id: string |
|
24 |
certainty: Certainty |
|
25 |
} |
|
26 |
|
|
27 |
enum Certainty { |
|
28 |
SameAs = "same_as", |
|
29 |
High = "high", |
|
30 |
Medium = "medium", |
|
31 |
Low = "low", |
|
32 |
} |
|
33 |
|
|
34 | 6 |
export const CertaintyWithColors: Record<Certainty, { certainty: Certainty; color: string }> = { |
35 | 7 |
same_as: { certainty: Certainty.SameAs, color: "#000000" }, |
36 | 8 |
high: { certainty: Certainty.High, color: "#FF0000" }, |
... | ... | |
53 | 25 |
}, |
54 | 26 |
extraReducers: (builder) => { |
55 | 27 |
// getItem |
56 |
builder.addCase(getItem.fulfilled, (state, action) => { |
|
28 |
builder.addCase(getItem.fulfilled, (state, action) => {
|
|
57 | 29 |
|
58 | 30 |
// set concordances from item, if selected concordance is 0 |
59 | 31 |
if (state.selectedConcordance === 0) { |
60 | 32 |
state.concordances = action.payload.concordances; |
61 | 33 |
} |
62 | 34 |
|
63 |
state.item = { |
|
64 |
authorName: action.payload.authorName, |
|
65 |
caption: action.payload.caption, |
|
66 |
concordances: action.payload.concordances |
|
35 |
if(action.payload.fullView){ |
|
36 |
state.item = { |
|
37 |
fullView: true, |
|
38 |
|
|
39 |
authorDisplayName: action.payload.authorDisplayName, |
|
40 |
workName: action.payload.workName, |
|
41 |
concordances: action.payload.concordances, |
|
42 |
searchSubjects: action.payload.searchSubjects, |
|
43 |
inventoryItem: action.payload.inventoryItem, |
|
44 |
|
|
45 |
// additional |
|
46 |
institution: action.payload.institution, |
|
47 |
authorName: action.payload.authorName, |
|
48 |
imageUrl: action.payload.imageUrl, |
|
49 |
title: action.payload.title, |
|
50 |
repository: action.payload.repository, |
|
51 |
provenance: action.payload.provenance, |
|
52 |
description: action.payload.description |
|
53 |
} |
|
54 |
} |
|
55 |
else{ |
|
56 |
state.item = { |
|
57 |
fullView: false, |
|
58 |
authorDisplayName: action.payload.authorDisplayName, |
|
59 |
workName: action.payload.workName, |
|
60 |
concordances: action.payload.concordances, |
|
61 |
searchSubjects: action.payload.searchSubjects, |
|
62 |
inventoryItem: action.payload.inventoryItem |
|
63 |
} |
|
67 | 64 |
} |
68 |
|
|
69 | 65 |
}) |
70 | 66 |
builder.addCase(getItem.rejected, (state, action) => { |
71 | 67 |
state.lastError = action.error.message |
src/stores/reducers/notesSlice.ts | ||
---|---|---|
1 |
|
|
2 |
export interface Note { |
|
3 |
username: string |
|
4 |
userId: string |
|
5 |
avatarUrl: string |
|
6 |
items: string[] |
|
7 |
createdTime: Date |
|
8 |
updatedTime: Date |
|
9 |
noteColor: string |
|
10 |
lastError?: string |
|
11 |
} |
src/types/item.ts | ||
---|---|---|
1 |
import { Note } from "./note" |
|
2 |
|
|
3 |
export type Item = { |
|
4 |
concordances: Concordance[] |
|
5 |
|
|
6 |
authorDisplayName: string |
|
7 |
workName: string |
|
8 |
|
|
9 |
inventoryItem: string |
|
10 |
searchSubjects: string[] |
|
11 |
|
|
12 |
fullView : boolean |
|
13 |
|
|
14 |
authorName?: string |
|
15 |
imageUrl?: string |
|
16 |
|
|
17 |
title?: string |
|
18 |
institution?: { |
|
19 |
name :string, |
|
20 |
inventoryNumber: number, |
|
21 |
country: string, |
|
22 |
city: string |
|
23 |
} |
|
24 |
repository?: string |
|
25 |
provenance?: string |
|
26 |
description?: string |
|
27 |
} |
|
28 |
|
|
29 |
export type ItemState = { |
|
30 |
item: Item |
|
31 |
concordances: Concordance[] |
|
32 |
selectedConcordance: number |
|
33 |
notes: Note[] |
|
34 |
lastError?: string |
|
35 |
} |
|
36 |
|
|
37 |
export type Concordance = { |
|
38 |
id: string |
|
39 |
cert: Certainty |
|
40 |
} |
|
41 |
|
|
42 |
export enum Certainty { |
|
43 |
SameAs = "same_as", |
|
44 |
High = "high", |
|
45 |
Medium = "medium", |
|
46 |
Low = "low", |
|
47 |
} |
src/types/note.ts | ||
---|---|---|
1 |
export interface Note { |
|
2 |
username: string |
|
3 |
userId: string |
|
4 |
avatarUrl: string |
|
5 |
items: string[] |
|
6 |
createdTime: Date |
|
7 |
updatedTime: Date |
|
8 |
noteColor: string |
|
9 |
lastError?: string |
|
10 |
} |
Také k dispozici: Unified diff
re #10454: ItemView: getting all required fields from api