This commit is contained in:
Brieuc Dubois 2024-01-03 20:02:36 +01:00
parent 454fe9b4bc
commit e2e87ce9ec
6 changed files with 87 additions and 37 deletions

View File

@ -16,17 +16,38 @@ export async function newCardApi(projectId: number, tags: TagValue[]): Promise<C
const id: number = response.data.id; const id: number = response.data.id;
tags.forEach((tag) => (tag.card_id = id)); const consistant_tags = [];
for (const tag of tags) {
if ((tag.option_id === -1 && tag.value == '') || tag.tag_id === -1) continue;
await createCardTagApi(id, tag.tag_id, tag.option_id, tag.value);
consistant_tags.push({ ...tag, card_id: id });
}
return { return {
id: id, id: id,
project_id: projectId, project_id: projectId,
title: 'Untitled', title: 'Untitled',
content: '', content: '',
tags: tags tags: consistant_tags
}; };
} }
export async function updateCardApi(card: Card): Promise<boolean> {
const response = await api.put(`/v1/cards/${card.id}`, {
project_id: card.project_id,
title: card.title,
content: card.content
});
if (response.status !== status.NoContent) {
processError(response, 'Failed to update card');
return false;
}
return true;
}
export async function deleteCardApi(cardID: number): Promise<void> { export async function deleteCardApi(cardID: number): Promise<void> {
const response = await api.delete(`/v1/cards/${cardID}`); const response = await api.delete(`/v1/cards/${cardID}`);
@ -36,6 +57,25 @@ export async function deleteCardApi(cardID: number): Promise<void> {
} }
} }
export async function createCardTagApi(
cardId: number,
tagId: number,
optionId: number,
value: string
): Promise<boolean> {
const response = await api.post(`/v1/cards/${cardId}/tags/${tagId}`, {
option_id: optionId,
value: value
});
if (response.status !== status.Created) {
processError(response, 'Failed to create card tag');
return false;
}
return true;
}
export async function updateCardTagApi( export async function updateCardTagApi(
cardID: number, cardID: number,
tagID: number, tagID: number,

View File

@ -1,34 +1,28 @@
<script lang="ts"> <script lang="ts">
import type { Card } from '../../../stores/interfaces'; import type { Card } from '../../../stores/interfaces';
import { currentModalCard, cards } from '../../../stores/smallStore'; import { currentModalCard, cards } from '../../../stores/smallStore';
import api, { processError } from '../../../utils/api';
import status from '../../../utils/status';
import CloseIcon from '../../icons/closeIcon.svelte'; import CloseIcon from '../../icons/closeIcon.svelte';
import TrashIcon from '../../icons/trashIcon.svelte'; import TrashIcon from '../../icons/trashIcon.svelte';
import ModalTags from './modal_tags.svelte'; import ModalTags from './modal_tags.svelte';
export let card: Card; export let card: Card;
let tempCard: Card = { ...card }; let newTitle = card.title;
let newContent = card.content;
async function save(closeModal: boolean = true) { async function save(closeModal: boolean = true) {
if (card.title !== newTitle || card.content !== newContent) {
console.log('saving');
if ( if (
card.project_id != tempCard.project_id || await cards.edit({
card.title !== tempCard.title || ...card,
card.content !== tempCard.content title: newTitle,
content: newContent
})
) { ) {
const response = await api.put(`/v1/cards/${card.id}`, { card.title = newTitle;
project_id: tempCard.project_id, card.content = newContent;
title: tempCard.title,
content: tempCard.content
});
if (response.status !== status.NoContent) {
processError(response, 'Failed to update card');
return;
} }
card = { ...tempCard };
} }
if (closeModal) currentModalCard.set(-1); if (closeModal) currentModalCard.set(-1);
} }
@ -40,7 +34,7 @@
<div class="modal" on:click={() => save(true)}> <div class="modal" on:click={() => save(true)}>
<div class="content" on:click|stopPropagation> <div class="content" on:click|stopPropagation>
<div class="header"> <div class="header">
<input class="title" bind:value={tempCard.title} on:blur={() => save(false)} /> <input class="title" bind:value={newTitle} on:blur={() => save(false)} />
<div class="buttons"> <div class="buttons">
<button on:click={() => cards.remove(card)}> <button on:click={() => cards.remove(card)}>
<TrashIcon /> <TrashIcon />
@ -55,7 +49,7 @@
</div> </div>
<div class="body"> <div class="body">
<textarea <textarea
bind:value={tempCard.content} bind:value={newContent}
placeholder="Add a description" placeholder="Add a description"
on:blur={() => save(false)} on:blur={() => save(false)}
/> />

View File

@ -68,13 +68,15 @@
async function addCard() { async function addCard() {
const tags: TagValue[] = []; const tags: TagValue[] = [];
for (let tag of Object.values(get(projectTags))) { for (let tag of Object.values(get(projectTags))) {
if (tag.id === option.tag_id) {
tags.push({ tags.push({
card_id: -1, card_id: -1,
tag_id: tag.id, tag_id: tag.id,
option_id: tag.id === option.tag_id ? option.id : -1, option_id: option.id,
value: '' value: ''
}); });
} }
}
await cards.add(projectId, tags); await cards.add(projectId, tags);
} }

View File

@ -4,18 +4,25 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import api, { processError } from '../utils/api'; import api, { processError } from '../utils/api';
import SelectProject from '../components/projects/selectProject.svelte'; import SelectProject from '../components/projects/selectProject.svelte';
import { toastAlert } from '../utils/toasts';
let projects: Project[]; let projects: Project[];
onMount(async () => { onMount(async () => {
try {
const response = await api.get(`/v1/projects`); const response = await api.get(`/v1/projects`);
if (response.status !== 200) { if (response.status !== 200) {
processError(response, 'Failed to fetch projects'); processError(response, 'Failed to fetch projects');
return; return;
} }
projects = response.data || []; projects = response.data || [];
} catch (e: any) {
toastAlert('Failed to fetch projects', e);
setTimeout(() => {
window.location.reload();
}, 11000);
}
}); });
async function deleteProject(project: Project) { async function deleteProject(project: Project) {

View File

@ -1 +1 @@
export const backend = process.env.BACKEND || 'http://127.0.0.1:3000'; export const backend = 'http://127.0.0.1:3000';

View File

@ -1,6 +1,6 @@
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { parseCards, type Card, type View, type TagValue } from './interfaces'; import { parseCards, type Card, type View, type TagValue } from './interfaces';
import { deleteCardApi, newCardApi } from '../api/cards'; import { deleteCardApi, newCardApi, updateCardApi } from '../api/cards';
import { getProjectCardsAPI } from '../api/projects'; import { getProjectCardsAPI } from '../api/projects';
import api, { processError } from '../utils/api'; import api, { processError } from '../utils/api';
import status from '../utils/status'; import status from '../utils/status';
@ -52,6 +52,13 @@ export const cards = (() => {
currentModalCard.set(-1); currentModalCard.set(-1);
}); });
}, },
edit: async (card: Card): Promise<boolean> => {
if (await updateCardApi(card)) {
update((cards) => cards.map((c) => (c.id === card.id ? card : c)));
return true;
}
return false;
},
reload: () => { reload: () => {
update((cards) => cards); update((cards) => cards);
} }