|
|
@ -1,12 +1,23 @@ |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
|
|
|
|
|
|
|
|
import { Box, Button } from '@material-ui/core'; |
|
|
|
import { Box, Button, Paper } from '@material-ui/core'; |
|
|
|
|
|
|
|
|
|
|
|
import * as serverApi from './api'; |
|
|
|
import * as serverApi from './api'; |
|
|
|
import SongTable, { Entry as SongEntry } from './components/SongTable'; |
|
|
|
|
|
|
|
import ArtistTable, { Entry as ArtistEntry } from './components/ArtistTable'; |
|
|
|
|
|
|
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
|
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
|
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
|
|
|
|
import AppBar from './components/AppBar'; |
|
|
|
|
|
|
|
import ItemList from './components/ItemList'; |
|
|
|
|
|
|
|
import ItemListItem from './components/ItemListItem'; |
|
|
|
|
|
|
|
import { SongDisplayItem, LoadingSongDisplayItem } from './types/DisplayItem'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface SongEntry { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface ArtistEntry { |
|
|
|
|
|
|
|
name: String, |
|
|
|
|
|
|
|
id: Number, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function App() { |
|
|
|
function App() { |
|
|
|
const [songs, setSongs] = useState<SongEntry[]>([]); |
|
|
|
const [songs, setSongs] = useState<SongEntry[]>([]); |
|
|
@ -22,61 +33,61 @@ function App() { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const updateSongs = () => { |
|
|
|
const updateSongs = () => { |
|
|
|
return fetch(serverApi.ListSongsEndpoint) |
|
|
|
return fetch(serverApi.QuerySongsEndpoint) |
|
|
|
.then((response: any) => response.json()) |
|
|
|
// .then((response: any) => response.json())
|
|
|
|
.then((result: serverApi.ListSongsResponse) => { |
|
|
|
// .then((result: serverApi.ListSongsResponse) => {
|
|
|
|
setSongs(result.map((item: serverApi.ListSongsResponseItem) => { |
|
|
|
// setSongs(result.map((item: serverApi.ListSongsResponseItem) => {
|
|
|
|
return { |
|
|
|
// return {
|
|
|
|
title: item.title, |
|
|
|
// title: item.title,
|
|
|
|
artistName: item.artistName |
|
|
|
// artistName: item.artistName
|
|
|
|
}; |
|
|
|
// };
|
|
|
|
})); |
|
|
|
// }));
|
|
|
|
}); |
|
|
|
// });
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const fetchArtists = () => { |
|
|
|
const fetchArtists = () => { |
|
|
|
return fetch(serverApi.ListArtistsEndpoint) |
|
|
|
return fetch(serverApi.QueryArtistsEndpoint) |
|
|
|
.then((response: any) => response.json()) |
|
|
|
// .then((response: any) => response.json())
|
|
|
|
.then((result: serverApi.ListArtistsResponse) => { |
|
|
|
// .then((result: serverApi.ListArtistsResponse) => {
|
|
|
|
return result.map((item: serverApi.ListArtistsResponseItem) => { |
|
|
|
// return result.map((item: serverApi.ListArtistsResponseItem) => {
|
|
|
|
return { |
|
|
|
// return {
|
|
|
|
name: item.name, |
|
|
|
// name: item.name,
|
|
|
|
id: item.id, |
|
|
|
// id: item.id,
|
|
|
|
}; |
|
|
|
// };
|
|
|
|
}); |
|
|
|
// });
|
|
|
|
}); |
|
|
|
// });
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const updateArtists = () => { |
|
|
|
const updateArtists = () => { |
|
|
|
return fetchArtists() |
|
|
|
return fetchArtists() |
|
|
|
.then((artists: any[]) => { |
|
|
|
// .then((artists: any[]) => {
|
|
|
|
setArtists(artists); |
|
|
|
// setArtists(artists);
|
|
|
|
}); |
|
|
|
// });
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const createSong = (p:SongProperties) => { |
|
|
|
const createSong = (p: SongProperties) => { |
|
|
|
if(!p.artistId) { |
|
|
|
if (!p.artistId) { |
|
|
|
throw "Undefined artist ID for song to be created."; |
|
|
|
throw "Undefined artist ID for song to be created."; |
|
|
|
} |
|
|
|
} |
|
|
|
const request:serverApi.CreateSongRequest = { |
|
|
|
const request: serverApi.CreateSongRequest = { |
|
|
|
title: p.title, |
|
|
|
title: p.title, |
|
|
|
artistId: p.artistId, |
|
|
|
artistIds: [p.artistId], |
|
|
|
} |
|
|
|
} |
|
|
|
const requestOpts = { |
|
|
|
const requestOpts = { |
|
|
|
method: 'POST', |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
body: JSON.stringify(request) |
|
|
|
body: JSON.stringify(request) |
|
|
|
}; |
|
|
|
}; |
|
|
|
return fetch(serverApi.CreateSongEndpoint, requestOpts) |
|
|
|
return fetch(serverApi.CreateSongEndpoint, requestOpts) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const createArtist = (p:ArtistProperties) => { |
|
|
|
const createArtist = (p: ArtistProperties) => { |
|
|
|
const request:serverApi.CreateArtistRequest = { |
|
|
|
const request: serverApi.CreateArtistRequest = { |
|
|
|
name: p.name, |
|
|
|
name: p.name, |
|
|
|
} |
|
|
|
} |
|
|
|
const requestOpts = { |
|
|
|
const requestOpts = { |
|
|
|
method: 'POST', |
|
|
|
method: 'POST', |
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
body: JSON.stringify(request) |
|
|
|
body: JSON.stringify(request) |
|
|
|
}; |
|
|
|
}; |
|
|
|
return fetch(serverApi.CreateArtistEndpoint, requestOpts) |
|
|
|
return fetch(serverApi.CreateArtistEndpoint, requestOpts) |
|
|
@ -92,8 +103,8 @@ function App() { |
|
|
|
|
|
|
|
|
|
|
|
const onSubmitCreateSongDialog = () => { |
|
|
|
const onSubmitCreateSongDialog = () => { |
|
|
|
createSong(songDialogProperties) |
|
|
|
createSong(songDialogProperties) |
|
|
|
.then(updateSongs) |
|
|
|
.then(updateSongs) |
|
|
|
.then(() => { setEditSongDialogOpen(false); }) |
|
|
|
.then(() => { setEditSongDialogOpen(false); }) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const openCreateArtistDialog = () => { |
|
|
|
const openCreateArtistDialog = () => { |
|
|
@ -105,29 +116,37 @@ function App() { |
|
|
|
|
|
|
|
|
|
|
|
const onSubmitCreateArtistDialog = () => { |
|
|
|
const onSubmitCreateArtistDialog = () => { |
|
|
|
createArtist(artistDialogProperties) |
|
|
|
createArtist(artistDialogProperties) |
|
|
|
.then(updateArtists) |
|
|
|
.then(updateArtists) |
|
|
|
.then(() => { setEditArtistDialogOpen(false); }) |
|
|
|
.then(() => { setEditArtistDialogOpen(false); }) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { updateSongs(); }, []); |
|
|
|
useEffect(() => { updateSongs(); }, []); |
|
|
|
useEffect(() => { updateArtists(); }, []); |
|
|
|
useEffect(() => { updateArtists(); }, []); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const testSong: SongDisplayItem = { |
|
|
|
|
|
|
|
title: "My Song", |
|
|
|
|
|
|
|
artistNames: ["First dude", "Second dude"] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const testLoadingSong: LoadingSongDisplayItem = { |
|
|
|
|
|
|
|
loadingSong: true |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
|
|
|
|
<AppBar /> |
|
|
|
|
|
|
|
<Paper> |
|
|
|
|
|
|
|
<ItemList items={[testSong, testLoadingSong]}> |
|
|
|
|
|
|
|
<ItemListItem item={testSong}/> |
|
|
|
|
|
|
|
<ItemListItem item={testLoadingSong}/> |
|
|
|
|
|
|
|
</ItemList> |
|
|
|
|
|
|
|
</Paper> |
|
|
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
|
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
|
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
|
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
|
|
<Box> |
|
|
|
|
|
|
|
<SongTable |
|
|
|
|
|
|
|
songs={songs} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
<ArtistTable |
|
|
|
|
|
|
|
artists={artists} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</Box> |
|
|
|
|
|
|
|
<EditSongDialog |
|
|
|
<EditSongDialog |
|
|
|
dialogOpen={editSongDialogOpen} |
|
|
|
dialogOpen={editSongDialogOpen} |
|
|
|
onClose={() => { setEditSongDialogOpen(false); }} |
|
|
|
onClose={() => { setEditSongDialogOpen(false); }} |
|
|
|
onChangeSongProperties={(props:SongProperties) => setSongDialogProperties(props)} |
|
|
|
onChangeSongProperties={(props: SongProperties) => setSongDialogProperties(props)} |
|
|
|
songProperties={songDialogProperties} |
|
|
|
songProperties={songDialogProperties} |
|
|
|
onSubmit={onSubmitCreateSongDialog} |
|
|
|
onSubmit={onSubmitCreateSongDialog} |
|
|
|
artists={artists} |
|
|
|
artists={artists} |
|
|
@ -135,7 +154,7 @@ function App() { |
|
|
|
<EditArtistDialog |
|
|
|
<EditArtistDialog |
|
|
|
dialogOpen={editArtistDialogOpen} |
|
|
|
dialogOpen={editArtistDialogOpen} |
|
|
|
onClose={() => { setEditArtistDialogOpen(false); }} |
|
|
|
onClose={() => { setEditArtistDialogOpen(false); }} |
|
|
|
onChangeArtistProperties={(props:ArtistProperties) => setArtistDialogProperties(props)} |
|
|
|
onChangeArtistProperties={(props: ArtistProperties) => setArtistDialogProperties(props)} |
|
|
|
artistProperties={artistDialogProperties} |
|
|
|
artistProperties={artistDialogProperties} |
|
|
|
onSubmit={onSubmitCreateArtistDialog} |
|
|
|
onSubmit={onSubmitCreateArtistDialog} |
|
|
|
/> |
|
|
|
/> |
|
|
|