diff --git a/frontend/src/lib/types/Card.ts b/frontend/src/lib/types/Card.ts index 8f786d7..b228ccf 100644 --- a/frontend/src/lib/types/Card.ts +++ b/frontend/src/lib/types/Card.ts @@ -1,9 +1,113 @@ -import type TagValue from './TagValue'; +import cardsApi from '$lib/api/cardsApi'; +import { get, writable } from 'svelte/store'; +import CardTag from './CardTag'; -export default interface Card { - id: number; - project_id: number; - title: string; - content: string; - tags: TagValue[]; +const cards = writable([] as Card[]); + +export default class Card { + private _id: number; + private _project_id: number; + private _title: string; + private _content: string; + private _tags: CardTag[]; + + private constructor( + id: number, + project_id: number, + title: string, + content: string, + tags: CardTag[] + ) { + this._id = id; + this._project_id = project_id; + this._title = title; + this._content = content; + this._tags = tags; + } + + get id(): number { + return this._id; + } + + get project_id(): number { + return this._project_id; + } + + get title(): string { + return this._title; + } + + get content(): string { + return this._content; + } + + get tags(): CardTag[] { + return this._tags; + } + + static getAll(): Card[] { + return get(cards); + } + + static fromId(id: number): Card | null { + for (const card of get(cards)) { + if (card.id === id) { + return card; + } + } + + return null; + } + + static async create(project_id: number): Promise { + const id = await cardsApi.create(project_id); + + if (!id) return null; + + const card = new Card(id, project_id, 'Untilted', '', []); + + cards.update((cards) => [...cards, card]); + + return card; + } + + async delete(): Promise { + const res = await cardsApi.delete(this.id); + + if (!res) return false; + + cards.update((cards) => cards.filter((c) => c.id !== this.id)); + + return true; + } + + static parse(json: any): Card | null { + if (json === null) { + return null; + } + + const card = new Card(json.id, json.project_id, json.title, json.content, []); + + card._tags = CardTag.parseAll(json.tags, card); + + cards.update((cards) => [...cards, card]); + + return card; + } + + static parseAll(json: any): Card[] { + if (json === null) { + return []; + } + + const cards: Card[] = []; + + for (const jsonCard of json) { + const card = this.parse(jsonCard); + if (!card) continue; + cards.push(card); + } + + return cards; + } } diff --git a/frontend/src/lib/types/CardTag.ts b/frontend/src/lib/types/CardTag.ts new file mode 100644 index 0000000..5a1e370 --- /dev/null +++ b/frontend/src/lib/types/CardTag.ts @@ -0,0 +1,83 @@ +import cardsTagsApi from '$lib/api/cardsTagsApi'; +import Card from './Card'; +import ProjectTag from './ProjectTag'; +import TagOption from './TagOption'; + +export default class CardTag { + private _card: Card; + private _tag: ProjectTag; + private _option: TagOption | null; + private _value: string | null; + + private constructor(card: Card, tag: ProjectTag, option: TagOption | null, value: string | null) { + this._card = card; + this._tag = tag; + this._option = option; + this._value = value; + } + + get card(): number { + return this.card; + } + + get tag(): number { + return this.tag; + } + + get option(): number | null { + return this.option; + } + + get value(): string | null { + return this._value; + } + + static async create( + card: Card, + tag: ProjectTag, + option: TagOption | null, + value: string | null + ): Promise { + const id = await cardsTagsApi.create(card.id, tag.id, option ? option.id : null, value); + + if (!id) return null; + + return new CardTag(card, tag, option, value); + } + + static parse(json: any): CardTag | null; + static parse(json: any, card: Card | null | undefined): CardTag | null; + + static parse(json: any, card?: Card | null | undefined): CardTag | null { + if (!json) return null; + + if (!card) card = Card.fromId(json.card_id); + if (!card) return null; + + const tag = ProjectTag.fromId(json.tag_id); + if (!tag) return null; + + const option = tag.options.find((option) => option.id === json.option_id); + if (!option) return null; + + return new CardTag(card, tag, option, json.value); + } + + static parseAll(json: any): CardTag[]; + static parseAll(json: any, card: Card | null): CardTag[]; + + static parseAll(json: any, card?: Card | null): CardTag[] { + if (!json) return []; + + const cardTags: CardTag[] = []; + + for (const cardTag of json) { + const parsed = this.parse(cardTag, card); + if (parsed) { + cardTags.push(parsed); + } + } + + return cardTags; + } +} diff --git a/frontend/src/lib/types/MeTag.ts b/frontend/src/lib/types/MeTag.ts deleted file mode 100644 index 8095216..0000000 --- a/frontend/src/lib/types/MeTag.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type TagOption from './TagOption'; - -export default interface MeTag { - id: number; - project_id: number; - title: string; - type: number; - options: TagOption[]; -} diff --git a/frontend/src/lib/types/Project.ts b/frontend/src/lib/types/Project.ts index bde79f6..9b71a26 100644 --- a/frontend/src/lib/types/Project.ts +++ b/frontend/src/lib/types/Project.ts @@ -1,4 +1,54 @@ -export default interface Project { - id: number; - title: string; +import { get, writable } from 'svelte/store'; + +const projects = writable([] as Project[]); + +export default class Project { + private _id: number; + private _title: string; + + private constructor(id: number, title: string) { + this._id = id; + this._title = title; + } + + get id(): number { + return this._id; + } + + get title(): string { + return this._title; + } + + static getAll(): Project[] { + return get(projects); + } + + static fromId(id: number): Project | null { + for (const project of get(projects)) { + if (project.id === id) { + return project; + } + } + + return null; + } + + static parse(json: any): Project | null { + if (!json) return null; + + return new Project(json.id, json.title); + } + + static parseAll(json: any): Project[] { + if (!json) return []; + + const projects: Project[] = []; + + for (const project of json) { + const parsed = Project.parse(project); + if (parsed) projects.push(parsed); + } + + return projects; + } } diff --git a/frontend/src/lib/types/ProjectTag.ts b/frontend/src/lib/types/ProjectTag.ts new file mode 100644 index 0000000..80dda31 --- /dev/null +++ b/frontend/src/lib/types/ProjectTag.ts @@ -0,0 +1,87 @@ +// import type TagOption from './TagOption'; + +import { get, writable } from 'svelte/store'; +import TagOption from './TagOption'; + +const projectTags = writable([] as ProjectTag[]); + +export default class ProjectTag { + private _id: number; + private _projectId: number; + private _title: string; + private _type: number; + private _options: TagOption[]; + + private constructor( + id: number, + projectId: number, + title: string, + type: number, + options: TagOption[] + ) { + this._id = id; + this._projectId = projectId; + this._title = title; + this._type = type; + this._options = options; + } + + get id(): number { + return this._id; + } + + get projectId(): number { + return this._projectId; + } + + get title(): string { + return this._title; + } + + get type(): number { + return this._type; + } + + get options(): TagOption[] { + return this._options; + } + + static getAll(): ProjectTag[] { + return get(projectTags); + } + + static fromId(id: number): ProjectTag | null { + for (const projectTag of get(projectTags)) { + if (projectTag.id === id) { + return projectTag; + } + } + + return null; + } + + static parse(json: any): ProjectTag | null { + if (!json) return null; + + const projectTag = new ProjectTag(json.id, json.project_id, json.title, json.type, []); + + const options = TagOption.parseAll(json.options, projectTag); + + projectTag._options = options; + + return projectTag; + } + + static parseAll(json: any): ProjectTag[] { + if (!json) return []; + + const projectTags: ProjectTag[] = []; + + for (const projectTag of json) { + const parsed = ProjectTag.parse(projectTag); + if (parsed) projectTags.push(parsed); + } + + return projectTags; + } +} diff --git a/frontend/src/lib/types/TagOption.ts b/frontend/src/lib/types/TagOption.ts index 789ca0c..5f9be81 100644 --- a/frontend/src/lib/types/TagOption.ts +++ b/frontend/src/lib/types/TagOption.ts @@ -1,5 +1,53 @@ -export default interface TagOption { - id: number; - tag_id: number; - value: string; +import ProjectTag from './ProjectTag'; + +export default class TagOption { + private _id: number; + private _projectTag: ProjectTag; + private _value: string; + + private constructor(id: number, projectTag: ProjectTag, value: string) { + this._id = id; + this._projectTag = projectTag; + this._value = value; + } + + get id(): number { + return this._id; + } + + get tagId(): ProjectTag { + return this._projectTag; + } + + get value(): string { + return this._value; + } + + static parse(json: any): TagOption | null; + static parse(json: any, projectTag: ProjectTag | null | undefined): TagOption | null; + + static parse(json: any, projectTag?: ProjectTag | null | undefined): TagOption | null { + if (!json) return null; + + if (!projectTag) projectTag = ProjectTag.fromId(json.tag_id); + if (!projectTag) return null; + + return new TagOption(json.id, projectTag, json.value); + } + + static parseAll(json: any): TagOption[]; + static parseAll(json: any, projectTag: ProjectTag | null): TagOption[]; + + static parseAll(json: any, projectTag?: ProjectTag | null): TagOption[] { + if (!json) return []; + + const options: TagOption[] = []; + + for (const option of json) { + const parsed = TagOption.parse(option, projectTag); + if (parsed) options.push(parsed); + } + + return options; + } } diff --git a/frontend/src/lib/types/TagValue.ts b/frontend/src/lib/types/TagValue.ts deleted file mode 100644 index 0e2542e..0000000 --- a/frontend/src/lib/types/TagValue.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface TagValue { - card_id: number; - tag_id: number; - option_id: number | null; - value: string | null; -} diff --git a/frontend/src/lib/types/View.ts b/frontend/src/lib/types/View.ts index 93fde85..eda8706 100644 --- a/frontend/src/lib/types/View.ts +++ b/frontend/src/lib/types/View.ts @@ -1,9 +1,97 @@ -export default interface View { - id: number; - project_id: number; - primary_tag_id: number | null; - secondary_tag_id: number | null; - title: string; - sort_tag_id: number | null; - sort_direction: number | null; +// export default interface View { +// id: number; +// projectId: number; +// primaryTagId: number | null; +// secondaryTagId: number | null; +// title: string; +// sortTagId: number | null; +// sortDirection: number | null; +// } + +import Project from './Project'; +import ProjectTag from './ProjectTag'; + +export default class View { + private _id: number; + private _project: Project; + private _pimaryTag: ProjectTag | null; + private _secondaryTag: ProjectTag | null; + private _title: string; + private _sortTag: ProjectTag | null; + private _sortDirection: number | null; + + private constructor( + id: number, + project: Project, + primaryTag: ProjectTag | null, + secondaryTag: ProjectTag | null, + title: string, + sortTag: ProjectTag | null, + sortDirection: number | null + ) { + this._id = id; + this._project = project; + this._pimaryTag = primaryTag; + this._secondaryTag = secondaryTag; + this._title = title; + this._sortTag = sortTag; + this._sortDirection = sortDirection; + } + + get id(): number { + return this._id; + } + + get project(): Project { + return this._project; + } + + get primaryTag(): ProjectTag | null { + return this._pimaryTag; + } + + get secondaryTag(): ProjectTag | null { + return this._secondaryTag; + } + + get title(): string { + return this._title; + } + + get sortTag(): ProjectTag | null { + return this._sortTag; + } + + get sortDirection(): number | null { + return this._sortDirection; + } + + static parse(json: any): View | null; + static parse(json: any, project: Project | null | undefined): View | null; + + static parse(json: any, project?: Project | null | undefined): View | null { + if (!json) return null; + + if (!project) project = Project.fromId(json.project_id); + if (!project) return null; + + const primaryTag = ProjectTag.fromId(json.primary_tag_id); + if (!primaryTag) return null; + + const secondaryTag = ProjectTag.fromId(json.secondary_tag_id); + if (!secondaryTag) return null; + + const sortTag = ProjectTag.fromId(json.sort_tag_id); + if (!sortTag) return null; + + return new View( + json.id, + project, + primaryTag, + secondaryTag, + json.title, + sortTag, + json.sort_direction + ); + } }