Skip to content

Commit

Permalink
Added the ability to delete tracks from the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Nov 23, 2023
1 parent aa9db63 commit bccb965
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 3 deletions.
4 changes: 2 additions & 2 deletions docker/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:latest
COPY musiccatalogue.api-1.21.0.0 /opt/musiccatalogue.api-1.21.0.0
WORKDIR /opt/musiccatalogue.api-1.21.0.0/bin
COPY musiccatalogue.api-1.22.0.0 /opt/musiccatalogue.api-1.22.0.0
WORKDIR /opt/musiccatalogue.api-1.22.0.0/bin
ENTRYPOINT [ "./MusicCatalogue.Api" ]
45 changes: 45 additions & 0 deletions src/music-catalogue-ui/components/deleteTrackActionIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { apiDeleteTrack } from "@/helpers/apiTracks";
import { apiFetchAlbumById } from "@/helpers/apiAlbums";
import { useCallback } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrashAlt } from "@fortawesome/free-solid-svg-icons";

/**
* Icon and associated action to delete a track
* @param {*} track
* @param {*} logout
* @param {*} setTracks
* @returns
*/
const DeleteTrackActionIcon = ({ track, logout, setTracks }) => {
/* Callback to prompt for confirmation and delete an album */
const confirmDeleteTrack = useCallback(async (e, track) => {
// Prevent the default action associated with the click event
e.preventDefault();

// Show a confirmation message and get the user response
const message = `This will delete the track "${track.title}" - click OK to confirm`;
const result = confirm(message);

// If they've confirmed the deletion ...
if (result) {
// ... cdelete the track and confirm the API call was successful
const result = await apiDeleteTrack(track.id, logout);
if (result) {
// Successful, so get the album from the service and set the tracks to
// the appropriate member of the returned object
var fetchedAlbum = await apiFetchAlbumById(track.albumId, logout);
setTracks(fetchedAlbum.tracks);
}
}
}, []);

return (
<FontAwesomeIcon
icon={faTrashAlt}
onClick={(e) => confirmDeleteTrack(e, track)}
/>
);
};

export default DeleteTrackActionIcon;
3 changes: 3 additions & 0 deletions src/music-catalogue-ui/components/trackList.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const TrackList = ({ artist, album, isWishList, navigate, logout }) => {
<th>No.</th>
<th>Track</th>
<th>Duration</th>
<th />
</tr>
</thead>
<tbody>
Expand All @@ -54,6 +55,8 @@ const TrackList = ({ artist, album, isWishList, navigate, logout }) => {
track={t}
isWishList={isWishList}
navigate={navigate}
logout={logout}
setTracks={setTracks}
/>
))}
</tbody>
Expand Down
18 changes: 17 additions & 1 deletion src/music-catalogue-ui/components/trackRow.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DeleteTrackActionIcon from "./deleteTrackActionIcon";
import styles from "./trackRow.module.css";
import pages from "@/helpers/navigation";

Expand All @@ -6,7 +7,15 @@ import pages from "@/helpers/navigation";
* @param {*} param0
* @returns
*/
const TrackRow = ({ artist, album, track, isWishList, navigate }) => {
const TrackRow = ({
artist,
album,
track,
isWishList,
navigate,
logout,
setTracks,
}) => {
return (
<tr>
<td>{album.title}</td>
Expand All @@ -25,6 +34,13 @@ const TrackRow = ({ artist, album, track, isWishList, navigate }) => {
<td>{track.number}</td>
<td>{track.title}</td>
<td>{track.formattedDuration}</td>
<td>
<DeleteTrackActionIcon
track={track}
logout={logout}
setTracks={setTracks}
/>
</td>
</tr>
);
};
Expand Down
91 changes: 91 additions & 0 deletions src/music-catalogue-ui/helpers/apiTracks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import config from "../config.json";
import { apiReadResponseData } from "./apiUtils";
import { apiGetPostHeaders, apiGetHeaders } from "./apiHeaders";

/**
* Create a track
* @param {*} title
* @param {*} number
* @param {*} duration
* @param {*} albumId
* @param {*} logout
* @returns
*/
const apiCreateTrack = async (title, number, duration, albumId, logout) => {
// Create the request body
const body = JSON.stringify({
title: title,
number: number,
duration: duration,
albumId: albumId,
});

// Call the API to create the retailer. This will just return the current
// record if it already exists
const url = `${config.api.baseUrl}/tracks`;
const response = await fetch(url, {
method: "POST",
headers: apiGetPostHeaders(),
body: body,
});

const track = await apiReadResponseData(response, logout);
return track;
};

/**
* Update track details
* @param {*} id
* @param {*} title
* @param {*} number
* @param {*} duration
* @param {*} albumId
* @param {*} logout
* @returns
*/
const apiUpdateTrack = async (id, title, number, duration, albumId, logout) => {
// Construct the body
const body = JSON.stringify({
id: id,
title: title,
number: number,
duration: duration,
albumId: albumId,
});

// Call the API to set the wish list flag for a given album
const url = `${config.api.baseUrl}/tracks`;
const response = await fetch(url, {
method: "PUT",
headers: apiGetPostHeaders(),
body: body,
});

const updatedTrack = await apiReadResponseData(response, logout);
return updatedTrack;
};

/**
* Delete the track with the specified ID
* @param {*} trackId
* @param {*} logout
* @returns
*/
const apiDeleteTrack = async (trackId, logout) => {
// Call the API to delete the specified album
const url = `${config.api.baseUrl}/tracks/${trackId}`;
const response = await fetch(url, {
method: "DELETE",
headers: apiGetHeaders(),
});

if (response.status == 401) {
// Unauthorized so the token's likely expired - force a login
logout();
} else {
// Return the response status code
return response.ok;
}
};

export { apiCreateTrack, apiUpdateTrack, apiDeleteTrack };

0 comments on commit bccb965

Please sign in to comment.