diff --git a/client/package.json b/client/package.json
index 19e3121..bc0f19a 100644
--- a/client/package.json
+++ b/client/package.json
@@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.0",
+ "@material-ui/lab": "^4.0.0-alpha.56",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 8b1dc43..2ec6189 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -21,8 +21,8 @@ function App() {
name: ""
});
- const fetchSongs = () => {
- fetch(serverApi.ListSongsEndpoint)
+ const updateSongs = () => {
+ return fetch(serverApi.ListSongsEndpoint)
.then((response: any) => response.json())
.then((result: serverApi.ListSongsResponse) => {
setSongs(result.map((item: serverApi.ListSongsResponseItem) => {
@@ -35,18 +35,29 @@ function App() {
}
const fetchArtists = () => {
- fetch(serverApi.ListArtistsEndpoint)
- .then((response: any) => response.json())
- .then((result: serverApi.ListArtistsResponse) => {
- setArtists(result.map((item: serverApi.ListArtistsResponseItem) => {
- return {
- name: item.name,
- };
- }));
+ return fetch(serverApi.ListArtistsEndpoint)
+ .then((response: any) => response.json())
+ .then((result: serverApi.ListArtistsResponse) => {
+ return result.map((item: serverApi.ListArtistsResponseItem) => {
+ return {
+ name: item.name,
+ id: item.id,
+ };
});
+ });
+ }
+
+ const updateArtists = () => {
+ return fetchArtists()
+ .then((artists: any[]) => {
+ setArtists(artists);
+ });
}
const createSong = (p:SongProperties) => {
+ if(!p.artistId) {
+ throw "Undefined artist ID for song to be created.";
+ }
const request:serverApi.CreateSongRequest = {
title: p.title,
artistId: p.artistId,
@@ -56,7 +67,7 @@ function App() {
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(request)
};
- fetch(serverApi.CreateSongEndpoint, requestOpts)
+ return fetch(serverApi.CreateSongEndpoint, requestOpts)
}
const createArtist = (p:ArtistProperties) => {
@@ -68,7 +79,7 @@ function App() {
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(request)
};
- fetch(serverApi.CreateArtistEndpoint, requestOpts)
+ return fetch(serverApi.CreateArtistEndpoint, requestOpts)
}
const openCreateSongDialog = () => {
@@ -80,9 +91,9 @@ function App() {
}
const onSubmitCreateSongDialog = () => {
- createSong(songDialogProperties);
- fetchSongs();
- setEditSongDialogOpen(false);
+ createSong(songDialogProperties)
+ .then(updateSongs)
+ .then(() => { setEditSongDialogOpen(false); })
}
const openCreateArtistDialog = () => {
@@ -93,13 +104,13 @@ function App() {
}
const onSubmitCreateArtistDialog = () => {
- createArtist(artistDialogProperties);
- fetchArtists();
- setEditArtistDialogOpen(false);
+ createArtist(artistDialogProperties)
+ .then(updateArtists)
+ .then(() => { setEditArtistDialogOpen(false); })
}
- useEffect(fetchSongs, []);
- useEffect(fetchArtists, []);
+ useEffect(() => { updateSongs(); }, []);
+ useEffect(() => { updateArtists(); }, []);
return (
@@ -119,6 +130,7 @@ function App() {
onChangeSongProperties={(props:SongProperties) => setSongDialogProperties(props)}
songProperties={songDialogProperties}
onSubmit={onSubmitCreateSongDialog}
+ artists={artists}
/>
{};
export function checkListArtistsRequest(req:any): boolean {
diff --git a/client/src/components/ArtistTable.tsx b/client/src/components/ArtistTable.tsx
index dbcfcc7..ceef43e 100644
--- a/client/src/components/ArtistTable.tsx
+++ b/client/src/components/ArtistTable.tsx
@@ -2,7 +2,8 @@ import React from 'react';
import MaterialTable from 'material-table';
export interface Entry {
- name: String
+ name: String,
+ id: Number,
}
export interface IProps {
diff --git a/client/src/components/EditSongDialog.tsx b/client/src/components/EditSongDialog.tsx
index 598987d..151bf2c 100644
--- a/client/src/components/EditSongDialog.tsx
+++ b/client/src/components/EditSongDialog.tsx
@@ -1,11 +1,17 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import { Dialog, Grid, Typography, TextField, Button } from '@material-ui/core';
+import { Autocomplete } from '@material-ui/lab';
var cloneDeep = require('lodash/cloneDeep');
export interface SongProperties {
title: String,
- artistId: Number,
+ artistId: Number | undefined,
+}
+
+export interface ArtistProperties {
+ name: String,
+ id: Number,
}
export interface IProps {
@@ -14,6 +20,7 @@ export interface IProps {
onChangeSongProperties?: (props: SongProperties) => void,
songProperties: SongProperties,
onSubmit?: () => void,
+ artists: ArtistProperties[],
}
export default function EditSongDialog(props: IProps) {
@@ -24,10 +31,10 @@ export default function EditSongDialog(props: IProps) {
props.onChangeSongProperties(p);
}
};
- const onArtistChange = (artist: Number) => {
+ const onArtistChange = (artist: Number | undefined) => {
if (props.onChangeSongProperties) {
const p = cloneDeep(props.songProperties);
- p.artistHash = artist;
+ p.artistId = artist;
props.onChangeSongProperties(p);
}
};
@@ -49,11 +56,24 @@ export default function EditSongDialog(props: IProps) {
/>
- onArtistChange(parseInt(i.target.value))}
- fullWidth
+ option.name as string}
+ onChange={(event, newValue) => {
+ console.log("Change: ", newValue)
+ if(newValue) {
+ onArtistChange(newValue.id);
+ } else {
+ onArtistChange(undefined);
+ }
+ }}
+ renderInput={
+ (params) =>
+
+ }
/>
diff --git a/client/yarn.lock b/client/yarn.lock
index ee55a4c..0ed8022 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -1321,6 +1321,17 @@
react-is "^16.8.0"
react-transition-group "^4.4.0"
+"@material-ui/lab@^4.0.0-alpha.56":
+ version "4.0.0-alpha.56"
+ resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34"
+ integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==
+ dependencies:
+ "@babel/runtime" "^7.4.4"
+ "@material-ui/utils" "^4.10.2"
+ clsx "^1.0.4"
+ prop-types "^15.7.2"
+ react-is "^16.8.0"
+
"@material-ui/pickers@^3.2.2":
version "3.2.10"
resolved "https://registry.yarnpkg.com/@material-ui/pickers/-/pickers-3.2.10.tgz#19df024895876eb0ec7cd239bbaea595f703f0ae"
diff --git a/server/package.json b/server/package.json
index e5d114e..63c3495 100644
--- a/server/package.json
+++ b/server/package.json
@@ -2,8 +2,7 @@
"name": "mudbase-server",
"version": "1.0.0",
"scripts": {
- "start": "ts-node server.ts",
- "start:watch": "nodemon",
+ "start": "nodemon server.ts",
"build": "tsc"
},
"dependencies": {
diff --git a/server/server.ts b/server/server.ts
index 5222ab0..9a3ad4d 100644
--- a/server/server.ts
+++ b/server/server.ts
@@ -20,8 +20,8 @@ app.post(api.CreateSongEndpoint, (req: any, res: any) => {
const reqObject: api.CreateSongRequest = req.body;
console.log("Request create song: ", reqObject); // TODO: remove
// First check that the artist exists.
- models.Song.findAll({
- where: { artistId: reqObject.artistId }
+ models.Artist.findAll({
+ where: { id: reqObject.artistId }
})
.then((artist: any[]) => {
if (artist.length != 1) {
@@ -32,7 +32,7 @@ app.post(api.CreateSongEndpoint, (req: any, res: any) => {
}
const song = models.Song.create({
title: reqObject.title,
- artistId: reqObject.artistId
+ ArtistId: reqObject.artistId
});
const responseObject: api.CreateSongResponse = {
id: song.id
@@ -51,12 +51,13 @@ app.get(api.ListSongsEndpoint, (req: any, res: any) => {
include: [models.Artist]
})
.then((songs: any[]) => {
+ console.log(songs);
const response: api.ListSongsResponse = songs.map((song: any) => {
return {
title: song.title,
id: song.id,
- artistName: "", // TODO: fetch artist details
- artistId: song.artistId,
+ artistName: song.Artist.name,
+ artistId: song.ArtistId,
};
});
res.send(response);