Can create artists.

pull/7/head
Sander Vocke 5 years ago
parent d7af28d802
commit 9e5fa87a6a
  1. 64
      client/src/App.tsx
  2. 34
      client/src/components/ArtistTable.tsx
  3. 46
      client/src/components/EditArtistDialog.tsx

@ -4,15 +4,22 @@ import { Box, Button } from '@material-ui/core';
import * as serverApi from './api'; import * as serverApi from './api';
import SongTable, { Entry as SongEntry } from './components/SongTable'; 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';
function App() { function App() {
const [songs, setSongs] = useState<SongEntry[]>([]); const [songs, setSongs] = useState<SongEntry[]>([]);
const [artists, setArtists] = useState<ArtistEntry[]>([]);
const [editSongDialogOpen, setEditSongDialogOpen] = useState<boolean>(false); const [editSongDialogOpen, setEditSongDialogOpen] = useState<boolean>(false);
const [songDialogProperties, setSongDialogProperties] = useState<SongProperties>({ const [songDialogProperties, setSongDialogProperties] = useState<SongProperties>({
title: "", title: "",
artistId: -1, artistId: -1,
}); });
const [editArtistDialogOpen, setEditArtistDialogOpen] = useState<boolean>(false);
const [artistDialogProperties, setArtistDialogProperties] = useState<ArtistProperties>({
name: ""
});
const fetchSongs = () => { const fetchSongs = () => {
fetch(serverApi.ListSongsEndpoint) fetch(serverApi.ListSongsEndpoint)
@ -27,6 +34,18 @@ 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,
};
}));
});
}
const createSong = (p:SongProperties) => { const createSong = (p:SongProperties) => {
const request:serverApi.CreateSongRequest = { const request:serverApi.CreateSongRequest = {
title: p.title, title: p.title,
@ -40,7 +59,19 @@ function App() {
fetch(serverApi.CreateSongEndpoint, requestOpts) fetch(serverApi.CreateSongEndpoint, requestOpts)
} }
const onClickCreateSong = () => { const createArtist = (p:ArtistProperties) => {
const request:serverApi.CreateArtistRequest = {
name: p.name,
}
const requestOpts = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(request)
};
fetch(serverApi.CreateArtistEndpoint, requestOpts)
}
const openCreateSongDialog = () => {
setSongDialogProperties({ setSongDialogProperties({
title: "", title: "",
artistId: -1, artistId: -1,
@ -48,28 +79,53 @@ function App() {
setEditSongDialogOpen(true); setEditSongDialogOpen(true);
} }
const onCreateCurrentSong = () => { const onSubmitCreateSongDialog = () => {
createSong(songDialogProperties); createSong(songDialogProperties);
fetchSongs(); fetchSongs();
setEditSongDialogOpen(false); setEditSongDialogOpen(false);
} }
const openCreateArtistDialog = () => {
setArtistDialogProperties({
name: "",
});
setEditArtistDialogOpen(true);
}
const onSubmitCreateArtistDialog = () => {
createArtist(artistDialogProperties);
fetchArtists();
setEditArtistDialogOpen(false);
}
useEffect(fetchSongs, []); useEffect(fetchSongs, []);
useEffect(fetchArtists, []);
return ( return (
<div style={{ maxWidth: '100%' }}> <div style={{ maxWidth: '100%' }}>
<Button variant="contained" onClick={onClickCreateSong}>Create Song</Button> <Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button>
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button>
<Box> <Box>
<SongTable <SongTable
songs={songs} songs={songs}
/> />
<ArtistTable
artists={artists}
/>
</Box> </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={onCreateCurrentSong} onSubmit={onSubmitCreateSongDialog}
/>
<EditArtistDialog
dialogOpen={editArtistDialogOpen}
onClose={() => { setEditArtistDialogOpen(false); }}
onChangeArtistProperties={(props:ArtistProperties) => setArtistDialogProperties(props)}
artistProperties={artistDialogProperties}
onSubmit={onSubmitCreateArtistDialog}
/> />
</div> </div>
); );

@ -0,0 +1,34 @@
import React from 'react';
import MaterialTable from 'material-table';
export interface Entry {
name: String
}
export interface IProps {
artists: Entry[]
}
export default function ArtistTable(props: IProps) {
const tableTitle = "Artists";
const tableColumns = [
{ title: "Name", field: 'name' },
];
const tableData = props.artists;
const options = {
filtering: true,
paging: true,
pageSize: 100,
pageSizeOptions: [ 5, 10, 20, 50, 100 ]
};
return (
<MaterialTable
title={tableTitle}
columns={tableColumns}
data={tableData}
options={options}
/>
);
}

@ -0,0 +1,46 @@
import React from 'react';
import { Dialog, Grid, Typography, TextField, Button } from '@material-ui/core';
var cloneDeep = require('lodash/cloneDeep');
export interface ArtistProperties {
name: String,
}
export interface IProps {
dialogOpen: boolean,
onClose?: () => void,
onChangeArtistProperties?: (props: ArtistProperties) => void,
artistProperties: ArtistProperties,
onSubmit?: () => void,
}
export default function EditArtistDialog(props: IProps) {
const onNameChange = (name: String) => {
if (props.onChangeArtistProperties) {
const p = cloneDeep(props.artistProperties);
p.name = name;
props.onChangeArtistProperties(p);
}
};
return <Dialog
open={props.dialogOpen}
onClose={props.onClose}
>
<Typography variant='h6' gutterBottom>
Artist Details
</Typography>
<Grid container spacing={3}>
<Grid item xs={12}>
<TextField
label="Name"
value={props.artistProperties.name}
onChange={(i: any) => onNameChange(i.target.value)}
fullWidth
/>
</Grid>
</Grid>
<Button variant="contained" onClick={props.onSubmit}>Submit</Button>
</Dialog>
}
Loading…
Cancel
Save