diff --git a/frontend/src/lib/api/viewsApi.ts b/frontend/src/lib/api/viewsApi.ts new file mode 100644 index 0000000..518f299 --- /dev/null +++ b/frontend/src/lib/api/viewsApi.ts @@ -0,0 +1,52 @@ +import type Project from '$lib/types/Project'; +import type View from '$lib/types/View'; +import api, { processError } from '$lib/utils/api'; +import status from '$lib/utils/status'; + +async function create(project: Project): Promise { + const response = await api.post('/views', { + project: project.id + }); + + if (response.status !== status.Created) { + processError(response, 'Failed to create view'); + return null; + } + + return response.data.id; +} + +async function update(view: View): Promise { + const response = await api.put(`/views/${view.id}`, { + project: view.project.id, + primary_tag_id: view.primaryTag?.id, + secondary_tag_id: view.secondaryTag?.id, + title: view.title, + sort_tag_id: view.sortTag?.id, + sort_direction: view.sortDirection + }); + + if (response.status !== status.OK) { + processError(response, 'Failed to update view'); + return false; + } + + return true; +} + +async function delete_(viewId: number): Promise { + const response = await api.delete(`/views/${viewId}`); + + if (response.status !== status.OK) { + processError(response, 'Failed to delete view'); + return false; + } + + return true; +} + +export default { + create, + update, + delete: delete_ +}; diff --git a/frontend/src/lib/types/CardTag.ts b/frontend/src/lib/types/CardTag.ts index 5a1e370..7738d71 100644 --- a/frontend/src/lib/types/CardTag.ts +++ b/frontend/src/lib/types/CardTag.ts @@ -45,6 +45,10 @@ export default class CardTag { return new CardTag(card, tag, option, value); } + async delete() { + return cardsTagsApi.delete(this._card.id, this._tag.id); + } + static parse(json: any): CardTag | null; static parse(json: any, card: Card | null | undefined): CardTag | null; diff --git a/frontend/src/lib/types/ProjectTag.ts b/frontend/src/lib/types/ProjectTag.ts index 80dda31..8a360d9 100644 --- a/frontend/src/lib/types/ProjectTag.ts +++ b/frontend/src/lib/types/ProjectTag.ts @@ -2,25 +2,26 @@ import { get, writable } from 'svelte/store'; import TagOption from './TagOption'; +import Project from './Project'; const projectTags = writable([] as ProjectTag[]); export default class ProjectTag { private _id: number; - private _projectId: number; + private _project: Project; private _title: string; private _type: number; private _options: TagOption[]; private constructor( id: number, - projectId: number, + project: Project, title: string, type: number, options: TagOption[] ) { this._id = id; - this._projectId = projectId; + this._project = project; this._title = title; this._type = type; this._options = options; @@ -30,8 +31,8 @@ export default class ProjectTag { return this._id; } - get projectId(): number { - return this._projectId; + get project(): Project { + return this._project; } get title(): string { @@ -60,25 +61,36 @@ export default class ProjectTag { return null; } - static parse(json: any): ProjectTag | null { + static parse(json: any): ProjectTag | null; + static parse(json: any, project: Project | null | undefined): ProjectTag | null; + + static parse(json: any, project?: Project | null): ProjectTag | null { if (!json) return null; - const projectTag = new ProjectTag(json.id, json.project_id, json.title, json.type, []); + if (!project) project = Project.fromId(json.project); + if (!project) return null; + + const projectTag = new ProjectTag(json.id, json.project, json.title, json.type, []); const options = TagOption.parseAll(json.options, projectTag); projectTag._options = options; + projectTags.update((projectTags) => [...projectTags, projectTag]); + return projectTag; } - static parseAll(json: any): ProjectTag[] { + static parseAll(json: any): ProjectTag[]; + static parseAll(json: any, project: Project | null): ProjectTag[]; + + static parseAll(json: any, project?: Project | null): ProjectTag[] { if (!json) return []; const projectTags: ProjectTag[] = []; for (const projectTag of json) { - const parsed = ProjectTag.parse(projectTag); + const parsed = ProjectTag.parse(projectTag, project); if (parsed) projectTags.push(parsed); } diff --git a/frontend/src/lib/types/View.ts b/frontend/src/lib/types/View.ts index eda8706..185104a 100644 --- a/frontend/src/lib/types/View.ts +++ b/frontend/src/lib/types/View.ts @@ -1,15 +1,9 @@ -// export default interface View { -// id: number; -// projectId: number; -// primaryTagId: number | null; -// secondaryTagId: number | null; -// title: string; -// sortTagId: number | null; -// sortDirection: number | null; -// } - +import { writable } from 'svelte/store'; import Project from './Project'; import ProjectTag from './ProjectTag'; +import viewsApi from '$lib/api/viewsApi'; + +const views = writable([] as View[]); export default class View { private _id: number; @@ -66,6 +60,26 @@ export default class View { return this._sortDirection; } + static async create(project: Project) { + const id = await viewsApi.create(project); + + if (!id) return null; + + const view = new View(id, project, null, null, 'New view', null, null); + + views.update((views) => [...views, view]); + + return view; + } + + async delete(): Promise { + if (!(await viewsApi.delete(this.id))) return false; + + views.update((views) => views.filter((view) => view.id !== this.id)); + + return true; + } + static parse(json: any): View | null; static parse(json: any, project: Project | null | undefined): View | null; @@ -84,7 +98,7 @@ export default class View { const sortTag = ProjectTag.fromId(json.sort_tag_id); if (!sortTag) return null; - return new View( + const view = new View( json.id, project, primaryTag, @@ -93,5 +107,9 @@ export default class View { sortTag, json.sort_direction ); + + views.update((views) => [...views, view]); + + return view; } }