Move API calls from state to Track methods
This commit is contained in:
parent
cd16208dd7
commit
89b0180989
|
@ -1,6 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterLink } from 'vue-router';
|
import { RouterLink } from 'vue-router';
|
||||||
import { error } from '../error'
|
|
||||||
import { state } from '../state'
|
import { state } from '../state'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,8 +15,8 @@ const className = computed(() => isSet.value ? "button is-rounded is-info" : "bu
|
||||||
|
|
||||||
async function toggle() {
|
async function toggle() {
|
||||||
if (isSet.value) {
|
if (isSet.value) {
|
||||||
await state.taskMarkedIncomplete(props.track, props.date)
|
await props.track.markIncomplete(props.date)
|
||||||
} else
|
} else
|
||||||
await state.taskCompleted(props.track, props.date)
|
await props.track.markComplete(props.date)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,12 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { state } from '../state';
|
import { Track } from '../track';
|
||||||
|
|
||||||
const props = defineProps<{icon: String, id: number|undefined}>()
|
const props = defineProps<{icon: String, id: number|undefined}>()
|
||||||
|
|
||||||
const del = () => {
|
const del = () => {
|
||||||
if(props.id)
|
if(props.id)
|
||||||
if(confirm("are you sure you want to delete this track?"))
|
if(confirm("are you sure you want to delete this track?"))
|
||||||
state.removeTrack(props.id)
|
Track.deleteById(props.id)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { reactive } from "vue"
|
||||||
import { Track } from "./track"
|
import { Track } from "./track"
|
||||||
import { Tick } from './ticks'
|
import { Tick } from './ticks'
|
||||||
import { error } from "./error"
|
import { error } from "./error"
|
||||||
import { getCookie, dateQuery } from "./util";
|
import { getCookie } from "./util";
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -92,36 +92,6 @@ class AppState {
|
||||||
if (this.state != State.Unfetched) return
|
if (this.state != State.Unfetched) return
|
||||||
await this.repopulate()
|
await this.repopulate()
|
||||||
}
|
}
|
||||||
async taskCompleted(track: Track, date: Date): Promise<Tick> {
|
|
||||||
const query = dateQuery(date)
|
|
||||||
const response: Response = await fetch(`/api/v1/tracks/${track.id}/ticked?${query.toString()}`, { method: "PATCH" })
|
|
||||||
const body = await response.text()
|
|
||||||
if (!response.ok) {
|
|
||||||
error(body)
|
|
||||||
throw new Error(`error setting tick for track ${track.id} ("${track.name}"): ${response.status} ${response.statusText}`)
|
|
||||||
}
|
|
||||||
return JSON.parse(body)
|
|
||||||
}
|
|
||||||
async taskMarkedIncomplete(track: Track, date: Date) {
|
|
||||||
const query = dateQuery(date)
|
|
||||||
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<boolean> {
|
|
||||||
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})`)
|
|
||||||
}
|
|
||||||
async logOut() {
|
async logOut() {
|
||||||
const result = await fetch('/api/v1/auth', {method: 'DELETE'})
|
const result = await fetch('/api/v1/auth', {method: 'DELETE'})
|
||||||
if(!result.ok) return error('failed to log out')
|
if(!result.ok) return error('failed to log out')
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { error } from "./error"
|
import { error } from "./error"
|
||||||
import { Tick, ITick } from './ticks'
|
import { Tick, ITick } from './ticks'
|
||||||
|
import { dateQuery } from "./util"
|
||||||
|
|
||||||
export interface ITrack {
|
export interface ITrack {
|
||||||
id?: number
|
id?: number
|
||||||
|
@ -48,6 +49,34 @@ export class Track implements ITrack {
|
||||||
this.fetchTicks = this.fetchTicks.bind(this)
|
this.fetchTicks = this.fetchTicks.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add this track to the database. A `TrackAdded` event should have been
|
||||||
|
* received from the server on the event stream by the time this returns.
|
||||||
|
*
|
||||||
|
* @returns whether or not the query succeeded
|
||||||
|
*/
|
||||||
|
async create(): Promise<boolean> {
|
||||||
|
// note that this.id is expected to be `undefined` here.
|
||||||
|
const response = await fetch('/api/v1/tracks', {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(this),
|
||||||
|
headers: { "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!response.ok)
|
||||||
|
error(`error submitting track ${this.name}: ${response.statusText} (${response.status})`)
|
||||||
|
return response.ok
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete() {
|
||||||
|
const id = this.id
|
||||||
|
if (id) await Track.deleteById(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async deleteById(id: number) {
|
||||||
|
const response = await fetch(`/api/v1/tracks/${id}`, { method: "DELETE" })
|
||||||
|
if (!response.ok) error(`error deleting track with ID ${id}: ${response.statusText} (${response.status})`)
|
||||||
|
}
|
||||||
|
|
||||||
static fromJSON(track: ITrack): Track {
|
static fromJSON(track: ITrack): Track {
|
||||||
return new Track(track.id, track.name, track.description, track.icon, track.enabled, track.multiple_entries_per_day, track.color, track.order)
|
return new Track(track.id, track.name, track.description, track.icon, track.enabled, track.multiple_entries_per_day, track.color, track.order)
|
||||||
}
|
}
|
||||||
|
@ -98,4 +127,36 @@ export class Track implements ITrack {
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Mark this track as being completed on the given date. A `TickAdded` event
|
||||||
|
* should have been received from the server on the event stream by the time
|
||||||
|
* this returns.
|
||||||
|
*
|
||||||
|
* @param date the date the task was completed
|
||||||
|
* @returns the decoded server API response
|
||||||
|
*/
|
||||||
|
async markComplete(date: Date) {
|
||||||
|
const query = dateQuery(date)
|
||||||
|
const response: Response = await fetch(`/api/v1/tracks/${this.id}/ticked?${query.toString()}`, { method: "PATCH" })
|
||||||
|
const body = await response.text()
|
||||||
|
if (!response.ok) {
|
||||||
|
error(body)
|
||||||
|
throw new Error(`error setting tick for track ${this.id} ("${this.name}"): ${response.status} ${response.statusText}`)
|
||||||
|
}
|
||||||
|
return JSON.parse(body)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Mark this track as being incomplete on the given date. A `TickAdded` event
|
||||||
|
* should have been received from the server on the event stream by the time
|
||||||
|
* this returns.
|
||||||
|
*
|
||||||
|
* @param date the date the task was completed
|
||||||
|
* @returns the decoded server API response
|
||||||
|
*/
|
||||||
|
async markIncomplete(date: Date) {
|
||||||
|
const query = dateQuery(date)
|
||||||
|
const { ok, status, statusText } = await fetch(`/api/v1/tracks/${this.id}/all-ticks?${query.toString()}`, { method: 'DELETE' })
|
||||||
|
if (!ok)
|
||||||
|
error(`error deleting ticks for ${this.id}: ${statusText} (${status})`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { RouterLink, useRouter } from 'vue-router';
|
import { RouterLink, useRouter } from 'vue-router';
|
||||||
import { Track } from '../track';
|
import { Track } from '../track';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { state } from '../state';
|
|
||||||
|
|
||||||
const props = defineProps<{ initialState?: Track }>()
|
const props = defineProps<{ initialState?: Track }>()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -26,7 +25,7 @@ const submit = async () => {
|
||||||
const track = new Track(undefined, name.value, description.value,
|
const track = new Track(undefined, name.value, description.value,
|
||||||
icon.value, Number(enabled.value), Number(multipleEntriesPerDay.value),
|
icon.value, Number(enabled.value), Number(multipleEntriesPerDay.value),
|
||||||
color.value, order.value)
|
color.value, order.value)
|
||||||
if (await state.addTrack(track))
|
if (await track.create())
|
||||||
router.push('/')
|
router.push('/')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue