diff --git a/client/package.json b/client/package.json index f410ede..a7858e3 100644 --- a/client/package.json +++ b/client/package.json @@ -12,7 +12,8 @@ "dependencies": { "bulma": "^0.9.4", "sass": "^1.25.0", - "vue": "^3.2.47" + "vue": "^3.2.47", + "vue-router": "4" }, "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", diff --git a/client/src/App.vue b/client/src/App.vue index b7adb44..5f48482 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,14 +1,11 @@ - - diff --git a/client/src/components/NavBar.vue b/client/src/components/NavBar.vue new file mode 100644 index 0000000..e11af91 --- /dev/null +++ b/client/src/components/NavBar.vue @@ -0,0 +1,28 @@ + + \ No newline at end of file diff --git a/client/src/components/Table.vue b/client/src/components/Table.vue index 338bd0b..1f1ddec 100644 --- a/client/src/components/Table.vue +++ b/client/src/components/Table.vue @@ -2,7 +2,9 @@ - + @@ -18,6 +20,7 @@ + \ No newline at end of file diff --git a/client/src/main.ts b/client/src/main.ts index 26bcf20..90cdedc 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -1,6 +1,12 @@ import { createApp } from 'vue' import './style.scss' -import App from './App.vue' +import router from './router' +import { state } from "./state"; import 'bulma/css/bulma.css' +import App from './App.vue' -createApp(App).mount('#app') + +const app = createApp(App) +app.use(router) +app.mount('#app') +state.populate() diff --git a/client/src/router.ts b/client/src/router.ts new file mode 100644 index 0000000..806e60d --- /dev/null +++ b/client/src/router.ts @@ -0,0 +1,15 @@ +import { createRouter, createWebHistory } from 'vue-router' +import TableView from './views/TableView.vue' +import NewTrackView from './views/NewTrackView.vue' + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { path: '/', component: TableView }, + { path: '/new-track', component: NewTrackView } + // for other pages: + // {path: '/', component: import('./views/TableView.vue')} + ] +}) + +export default router \ No newline at end of file diff --git a/client/src/state.ts b/client/src/state.ts index 1b3506b..8d7b479 100644 --- a/client/src/state.ts +++ b/client/src/state.ts @@ -1,5 +1,6 @@ import { reactive } from "vue" import { Track } from "./track" +import { Tick } from './ticks' import { error } from "./error" enum State { @@ -26,7 +27,7 @@ export const state = reactive({ source.addEventListener('message', event => console.log(event)) source.addEventListener('TickAdded', event => { console.log(event) - const tick: Tick = JSON.parse(event.data) + const tick: Tick = Tick.fromJSON(JSON.parse(event.data)) const tracks = this.tracks.map(track => { if (track.id === tick.track_id) { const ticks = track.ticks ?? [] @@ -38,9 +39,12 @@ export const state = reactive({ }) this.tracks = tracks }) + source.addEventListener('TrackAdded', ({ data }) => { + const track: Track = Track.fromJSON(JSON.parse(data)) + this.tracks = [track, ...this.tracks] + }) source.addEventListener('TickDropped', event => { - console.log(event) - const tick: Tick = JSON.parse(event.data) + const tick: Tick = Tick.fromJSON(JSON.parse(event.data)) const tracks = this.tracks.map(track => { if (track.id === tick.track_id) { track.ticks = track.ticks?.filter($tick => $tick.id !== tick.id) @@ -49,6 +53,14 @@ export const state = reactive({ }) this.tracks = tracks }) + source.addEventListener('TrackDropped', ({ data }) => { + const track: Track = Track.fromJSON(JSON.parse(data)) + this.tracks = this.tracks.filter($track => $track.id !== track.id) + }) + source.addEventListener('TrackChanged', ({ data }) => { + const track: Track = Track.fromJSON(JSON.parse(data)) + this.tracks = this.tracks.map($track => $track.id === track.id ? track : $track) + }) source.addEventListener('Lagged', event => { console.log(event) // Refresh the page, refetching the list of tracks and ticks @@ -85,5 +97,19 @@ export const state = reactive({ const { ok, status, statusText } = await fetch(`/api/v1/tracks/${track.id}/all-ticks?${query.toString()}`, { method: 'DELETE' }) if (!ok) error(`error deleting ticks for ${track.id}: ${statusText} (${status})`) + }, + async addTrack(track: Track): Promise { + const response = await fetch('/api/v1/tracks', { + method: "POST", + body: JSON.stringify(track), + headers: { "Content-Type": "application/json" } + }) + if (!response.ok) + error(`error submitting track: ${track}: ${response.statusText} (${response.status})`) + return response.ok + }, + async removeTrack(trackID: number) { + const response = await fetch(`/api/v1/tracks/${trackID}`, { method: "DELETE" }) + if (!response.ok) error(`error deleting track with ID ${trackID}: ${response.statusText} (${response.status})`) } }) diff --git a/client/src/ticks.ts b/client/src/ticks.ts index 895682b..d50b9ba 100644 --- a/client/src/ticks.ts +++ b/client/src/ticks.ts @@ -1,4 +1,4 @@ -interface ITick { +export interface ITick { id: number track_id?: number year?: number @@ -10,7 +10,7 @@ interface ITick { has_time_info?: number } -class Tick implements ITick { +export class Tick implements ITick { id: number track_id?: number year?: number diff --git a/client/src/track.ts b/client/src/track.ts index 14f7567..83947a3 100644 --- a/client/src/track.ts +++ b/client/src/track.ts @@ -1,7 +1,7 @@ import { error } from "./error" export interface ITrack { - id: number + id?: number name: String description: String icon: String @@ -13,7 +13,7 @@ export interface ITrack { } export class Track implements ITrack { - id: number + id?: number name: String description: String icon: String @@ -24,7 +24,7 @@ export class Track implements ITrack { ticks?: Array constructor( - id: number, + id: number | undefined, name: String, description: String, icon: String, diff --git a/client/src/views/NewTrackView.vue b/client/src/views/NewTrackView.vue new file mode 100644 index 0000000..8b2ed62 --- /dev/null +++ b/client/src/views/NewTrackView.vue @@ -0,0 +1,91 @@ + + \ No newline at end of file diff --git a/client/src/views/TableView.vue b/client/src/views/TableView.vue new file mode 100644 index 0000000..053df35 --- /dev/null +++ b/client/src/views/TableView.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/client/yarn.lock b/client/yarn.lock index 47e9ec4..a06ffcf 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -213,6 +213,11 @@ "@vue/compiler-dom" "3.3.4" "@vue/shared" "3.3.4" +"@vue/devtools-api@^6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07" + integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q== + "@vue/reactivity-transform@3.3.4": version "3.3.4" resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929" @@ -522,6 +527,13 @@ vite@^4.3.9: optionalDependencies: fsevents "~2.3.2" +vue-router@4: + version "4.2.2" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.2.2.tgz#b0097b66d89ca81c0986be03da244c7b32a4fd81" + integrity sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ== + dependencies: + "@vue/devtools-api" "^6.5.0" + vue-template-compiler@^2.7.14: version "2.7.14" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz#4545b7dfb88090744c1577ae5ac3f964e61634b1"
Date{{ track.icon }} + +