Move to $lib
|
@ -1,21 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { Card } from '../../../stores/interfaces';
|
||||
import projectTags from '../../../stores/projectTags';
|
||||
import ModalTag from './modal_tag.svelte';
|
||||
import ModalNewTag from './modal_tag/modal_new_tag.svelte';
|
||||
|
||||
export let card: Card;
|
||||
</script>
|
||||
|
||||
<table>
|
||||
{#if card.tags}
|
||||
{#each Object.values($projectTags) as projectTag}
|
||||
<ModalTag
|
||||
tagValue={card.tags.find((t) => t.tag_id === projectTag.id)}
|
||||
bind:projectTag
|
||||
{card}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
<ModalNewTag projectId={card.project_id} />
|
||||
</table>
|
|
@ -0,0 +1,103 @@
|
|||
import type { Card, TagValue } from '../stores/interfaces';
|
||||
import api, { processError } from '../utils/api';
|
||||
import status from '../utils/status';
|
||||
|
||||
export async function newCardApi(projectId: number, tags: TagValue[]): Promise<Card> {
|
||||
const response = await api.post(`/v1/cards`, {
|
||||
project_id: projectId,
|
||||
title: 'Untitled',
|
||||
content: ''
|
||||
});
|
||||
|
||||
if (response.status !== status.Created) {
|
||||
processError(response, 'Failed to create card');
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
const id: number = response.data.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 {
|
||||
id: id,
|
||||
project_id: projectId,
|
||||
title: 'Untitled',
|
||||
content: '',
|
||||
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> {
|
||||
const response = await api.delete(`/v1/cards/${cardID}`);
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to delete card');
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
|
||||
export async function createCardTagApi(
|
||||
cardId: number,
|
||||
tagId: number,
|
||||
optionId: number | null,
|
||||
value: string | null
|
||||
): 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 deleteCardTagApi(cardID: number, tagID: number): Promise<void> {
|
||||
const response = await api.delete(`/v1/cards/${cardID}/tags/${tagID}`);
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to delete tag');
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateCardTagApi(
|
||||
cardID: number,
|
||||
tagID: number,
|
||||
option_id: number | null,
|
||||
value: string | null
|
||||
): Promise<void> {
|
||||
const response = await api.put(`/v1/cards/${cardID}/tags/${tagID}`, {
|
||||
option_id: option_id == -1 ? null : option_id,
|
||||
value: value == '' ? null : value
|
||||
});
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to update card tag');
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { parseCards, type Card, type Project } from '$lib/stores/interfaces';
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
|
||||
export async function getProjectAPI(projectId: number): Promise<Project> {
|
||||
const response = await api.get(`/v1/projects/${projectId}`);
|
||||
|
||||
if (response.status !== status.OK) {
|
||||
processError(response, 'Failed to fetch project');
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function getProjectCardsAPI(projectId: number): Promise<Card[]> {
|
||||
const response = await api.get(`/v1/projects/${projectId}/cards`);
|
||||
|
||||
if (response.status !== status.OK) {
|
||||
processError(response, 'Failed to fetch cards');
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return parseCards(response.data);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import type { MeTag, TagOption } from '$lib/stores/interfaces';
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
|
||||
export async function updateTagAPI(option: TagOption): Promise<boolean> {
|
||||
const response =
|
||||
option.value === ''
|
||||
? await api.delete(`/v1/tags/${option.tag_id}/options/${option.id}`)
|
||||
: await api.put(`/v1/tags/${option.tag_id}/options/${option.id}`, option);
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to update tag option');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 217 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import type { Card } from '../../../stores/interfaces';
|
||||
import projectTags from '../../../stores/projectTags';
|
||||
import { currentModalCard, currentDraggedCard } from '../../../stores/smallStore';
|
||||
import type { Card } from '$lib/stores/interfaces';
|
||||
import project_tags from '$lib/stores/project_tags';
|
||||
import { currentDraggedCard, currentModalCard } from '$lib/stores/smallStore';
|
||||
import ModalCard from './modal_card.svelte';
|
||||
|
||||
export let card: Card;
|
||||
|
@ -12,11 +12,11 @@
|
|||
tabindex="0"
|
||||
draggable={true}
|
||||
on:dragstart={() => currentDraggedCard.set(card)}
|
||||
on:click={() => ($currentModalCard = card.id)}
|
||||
on:click={() => currentModalCard.set(card.id)}
|
||||
role="button"
|
||||
on:keydown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
$currentModalCard = card.id;
|
||||
currentModalCard.set(card.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -25,9 +25,9 @@
|
|||
<div class="tags">
|
||||
{#each card.tags as tag}
|
||||
{#if tag.option_id}
|
||||
{#if $projectTags[tag.tag_id]}
|
||||
{#if $project_tags[tag.tag_id]}
|
||||
<span class="tag" style="border: 1px solid #333"
|
||||
>{$projectTags[tag.tag_id]?.options.find((o) => o.id == tag.option_id)?.value}</span
|
||||
>{$project_tags[tag.tag_id]?.options.find((o) => o.id == tag.option_id)?.value}</span
|
||||
>
|
||||
{/if}
|
||||
{:else if tag.value}
|
|
@ -45,7 +45,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<ModalTags bind:card />
|
||||
<ModalTags {card} />
|
||||
</div>
|
||||
<div class="body">
|
||||
<textarea
|
|
@ -11,6 +11,6 @@
|
|||
{#if projectTag}
|
||||
<tr>
|
||||
<ModalTagTitle {projectTag} />
|
||||
<ModalTagValue {projectTag} bind:tagValue {card} />
|
||||
<ModalTagValue {projectTag} {tagValue} {card} />
|
||||
</tr>
|
||||
{/if}
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { tick } from 'svelte';
|
||||
import AddIcon from '../../../icons/addIcon.svelte';
|
||||
import Menu from '../../../utils/menu.svelte';
|
||||
import ModalTagTypes from './modal_tag_types.svelte';
|
||||
import projectTags from '../../../../stores/projectTags';
|
||||
import { toastAlert } from '../../../../utils/toasts';
|
||||
import { toastAlert } from '$lib/utils/toasts';
|
||||
import project_tags from '$lib/stores/project_tags';
|
||||
import AddIcon from '$lib/components/icons/addIcon.svelte';
|
||||
import Menu from '$lib/components/utils/menu.svelte';
|
||||
|
||||
export let projectId: number;
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
|||
toastAlert('Failed to create tag', `ProjectId is ${projectId}`);
|
||||
return;
|
||||
}
|
||||
await projectTags.add(projectId, title, typeId);
|
||||
await project_tags.add(projectId, title, typeId);
|
||||
isOpen = false;
|
||||
}
|
||||
</script>
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { tick } from 'svelte';
|
||||
import type { MeTag } from '../../../../stores/interfaces';
|
||||
import Menu from '../../../utils/menu.svelte';
|
||||
import projectTags from '../../../../stores/projectTags';
|
||||
import { toastAlert } from '../../../../utils/toasts';
|
||||
import ModalTagTypes from './modal_tag_types.svelte';
|
||||
import type { MeTag } from '$lib/stores/interfaces';
|
||||
import { toastAlert } from '$lib/utils/toasts';
|
||||
import project_tags from '$lib/stores/project_tags';
|
||||
import Menu from '$lib/components/utils/menu.svelte';
|
||||
|
||||
export let projectTag: MeTag;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
await projectTags.update(projectTag);
|
||||
await project_tags.update(projectTag);
|
||||
|
||||
lastTitle = projectTag.title;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@
|
|||
onChoice={async (id) => {
|
||||
projectTag.type = id;
|
||||
|
||||
await projectTags.update(projectTag);
|
||||
await project_tags.update(projectTag);
|
||||
}}
|
||||
/>
|
||||
{#if askConfirm}
|
||||
|
@ -80,7 +80,7 @@
|
|||
<div>
|
||||
<button
|
||||
on:click={() => {
|
||||
projectTags.delete(projectTag.id);
|
||||
project_tags.delete(projectTag.id);
|
||||
isMenuOpen = false;
|
||||
}}>✓</button
|
||||
>
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { getTagTypeFromId, tagTypes } from '../../../../utils/tagTypes';
|
||||
import Menu from '../../../utils/menu.svelte';
|
||||
import Menu from '$lib/components/utils/menu.svelte';
|
||||
import { getTagTypeFromId, tagTypes } from '$lib/utils/tagTypes';
|
||||
|
||||
export let type: number;
|
||||
export let isTagMenuOpen: boolean = false;
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import type { Card, MeTag, TagValue } from '../../../../stores/interfaces';
|
||||
import { getTagTypeFromId } from '../../../../utils/tagTypes';
|
||||
import type { MeTag, TagValue, Card } from '$lib/stores/interfaces';
|
||||
import { getTagTypeFromId } from '$lib/utils/tagTypes';
|
||||
import SelectTags from './select_tags.svelte';
|
||||
|
||||
export let projectTag: MeTag;
|
||||
|
@ -13,7 +13,7 @@
|
|||
{#if tagType}
|
||||
<td>
|
||||
{#if tagType?.hasOptions}
|
||||
<SelectTags multiple={false} {projectTag} {card} bind:tagValue />
|
||||
<SelectTags multiple={false} {projectTag} {card} {tagValue} />
|
||||
{:else if !tagType?.hasOptions}
|
||||
<input />
|
||||
{/if}
|
|
@ -1,12 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { updateCardTagApi } from '../../../../api/cards';
|
||||
import type { Card, MeTag, TagOption, TagValue } from '../../../../stores/interfaces';
|
||||
import projectTags from '../../../../stores/projectTags';
|
||||
import { cards } from '../../../../stores/smallStore';
|
||||
import api, { processError } from '../../../../utils/api';
|
||||
import status from '../../../../utils/status';
|
||||
import TrashIcon from '../../../icons/trashIcon.svelte';
|
||||
import Menu from '../../../utils/menu.svelte';
|
||||
import { updateCardTagApi } from '$lib/api/cards';
|
||||
import TrashIcon from '$lib/components/icons/trashIcon.svelte';
|
||||
import Menu from '$lib/components/utils/menu.svelte';
|
||||
import type { Card, MeTag, TagValue } from '$lib/stores/interfaces';
|
||||
import project_tags from '$lib/stores/project_tags';
|
||||
import { cards } from '$lib/stores/smallStore';
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
|
||||
export const multiple: boolean = false;
|
||||
export let card: Card;
|
||||
|
@ -81,7 +81,7 @@
|
|||
|
||||
function createOption() {
|
||||
if (!newOption) return;
|
||||
projectTags.addOption(projectTag.id, newOption);
|
||||
project_tags.addOption(projectTag.id, newOption);
|
||||
newOption = '';
|
||||
}
|
||||
</script>
|
||||
|
@ -127,7 +127,7 @@
|
|||
<span class="value">{option.value}</span>
|
||||
<button
|
||||
on:click|stopPropagation={() => {
|
||||
projectTags.deleteOption(projectTag.id, option.id);
|
||||
project_tags.deleteOption(projectTag.id, option.id);
|
||||
}}><TrashIcon size={16} /></button
|
||||
>
|
||||
</div>
|
|
@ -0,0 +1,17 @@
|
|||
<script lang="ts">
|
||||
import type { Card } from '$lib/stores/interfaces';
|
||||
import ModalTag from './modal_tag.svelte';
|
||||
import ModalNewTag from './modal_tag/modal_new_tag.svelte';
|
||||
import ProjectTags from '$lib/stores/project_tags';
|
||||
|
||||
export let card: Card;
|
||||
</script>
|
||||
|
||||
<table>
|
||||
{#if card.tags}
|
||||
{#each Object.values($ProjectTags) as projectTag}
|
||||
<ModalTag tagValue={card.tags.find((t) => t.tag_id === projectTag.id)} {projectTag} {card} />
|
||||
{/each}
|
||||
{/if}
|
||||
<ModalNewTag projectId={card.project_id} />
|
||||
</table>
|
|
@ -1,12 +1,12 @@
|
|||
<script lang="ts">
|
||||
import type { Card, TagValue } from '../../stores/interfaces';
|
||||
import { cards, currentDraggedCard } from '../../stores/smallStore';
|
||||
import CardC from './card/card.svelte';
|
||||
import AddIcon from '../icons/addIcon.svelte';
|
||||
import projectTags from '../../stores/projectTags';
|
||||
import { updateTagAPI as updateTagOptionAPI } from '../../api/tags';
|
||||
import { get } from 'svelte/store';
|
||||
import { createCardTagApi, deleteCardTagApi, updateCardTagApi } from '../../api/cards';
|
||||
import type { Card, TagValue } from '../../stores/interfaces';
|
||||
import projectTags from '../../stores/project_tags';
|
||||
import { cards, currentDraggedCard } from '../../stores/smallStore';
|
||||
|
||||
export let projectId: number;
|
||||
export let optionId: number | null = null;
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import type { Project, TagValue, View } from '../../stores/interfaces';
|
||||
import { cards, currentView, views } from '../../stores/smallStore';
|
||||
import projectTags from '../../stores/projectTags';
|
||||
import projectTags from '../../stores/project_tags';
|
||||
import GroupMenu from './card/header/menus/group_menu.svelte';
|
||||
import SortMenu from './card/header/menus/sort_menu.svelte';
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import Column from './column.svelte';
|
||||
import type { Project, View } from '../../stores/interfaces';
|
||||
import projectTags from '../../stores/projectTags';
|
||||
import { cards, currentView, views } from '../../stores/smallStore';
|
||||
import type { Project, View } from '$lib/stores/interfaces';
|
||||
import projectTags from '$lib/stores/project_tags';
|
||||
import { cards, currentView } from '$lib/stores/smallStore';
|
||||
import Header from './header.svelte';
|
||||
|
||||
export let project: Project;
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
import type { Project } from '../../stores/interfaces';
|
||||
import api, { processError } from '../../utils/api';
|
||||
import status from '../../utils/status';
|
||||
|
||||
export let project: Project;
|
||||
export let deleteProject: (project: Project) => void;
|
|
@ -1,13 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { onMount, tick } from 'svelte';
|
||||
import api, { processError } from '../utils/api';
|
||||
import { onMount } from 'svelte';
|
||||
import type { Project, View } from '../stores/interfaces';
|
||||
import { currentView, views } from '../stores/smallStore';
|
||||
import ViewIcon from './icons/viewIcon.svelte';
|
||||
import projectTags from '../stores/projectTags';
|
||||
import EditIcon from './icons/editIcon.svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import MenuOpener from './icons/menu_opener.svelte';
|
||||
import projectTags from '../stores/project_tags';
|
||||
|
||||
export let project: Project;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { get, writable } from 'svelte/store';
|
||||
import type { MeTag, TagOption } from './interfaces';
|
||||
import api, { processError } from '../utils/api';
|
||||
import status from '../utils/status';
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
import { cards } from './smallStore';
|
||||
|
||||
const { subscribe, set, update } = writable({} as { [key: number]: MeTag });
|
|
@ -1,9 +1,9 @@
|
|||
import { writable } from 'svelte/store';
|
||||
import { parseCards, type Card, type View, type TagValue } from './interfaces';
|
||||
import { deleteCardApi, newCardApi, updateCardApi } from '../api/cards';
|
||||
import { getProjectCardsAPI } from '../api/projects';
|
||||
import api, { processError } from '../utils/api';
|
||||
import status from '../utils/status';
|
||||
import api, { processError } from '$lib/utils/api';
|
||||
import status from '$lib/utils/status';
|
||||
import { getProjectCardsAPI } from '$lib/api/projects';
|
||||
import { deleteCardApi, newCardApi, updateCardApi } from '$lib/api/cards';
|
||||
|
||||
export const currentView = (() => {
|
||||
const { subscribe, set, update } = writable(null as View | null);
|
||||
|
@ -82,7 +82,11 @@ export const views = (() => {
|
|||
|
||||
return true;
|
||||
};
|
||||
const add = async (projectId: number, title: string, primaryTagId: number | null): Promise<View> => {
|
||||
const add = async (
|
||||
projectId: number,
|
||||
title: string,
|
||||
primaryTagId: number | null
|
||||
): Promise<View> => {
|
||||
const response = await api.post(`/v1/views`, {
|
||||
title,
|
||||
project_id: projectId,
|
|
@ -1,7 +1,7 @@
|
|||
import axios, { Axios, type AxiosResponse } from 'axios';
|
||||
import { backend } from '../stores/config';
|
||||
import { toastAlert } from './toasts';
|
||||
import { setupCache } from 'axios-cache-interceptor';
|
||||
import { backend } from '$lib/stores/config';
|
||||
|
||||
export default setupCache(
|
||||
new Axios({
|
|
@ -1,10 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { SvelteToast } from '@zerodevx/svelte-toast';
|
||||
import type { Project } from '../stores/interfaces';
|
||||
import type { Project } from '../lib/stores/interfaces';
|
||||
import { onMount } from 'svelte';
|
||||
import api, { processError } from '../utils/api';
|
||||
import SelectProject from '../components/projects/selectProject.svelte';
|
||||
import { toastAlert } from '../utils/toasts';
|
||||
import api, { processError } from '../lib/utils/api';
|
||||
import SelectProject from '../lib/components/projects/selectProject.svelte';
|
||||
import { toastAlert } from '../lib/utils/toasts';
|
||||
|
||||
let projects: Project[];
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
import { page } from '$app/stores';
|
||||
import { SvelteToast } from '@zerodevx/svelte-toast';
|
||||
import { onMount } from 'svelte';
|
||||
import { getProjectAPI } from '../../api/projects';
|
||||
import { type Project as P } from '../../stores/interfaces';
|
||||
import Sidebar from '../../components/sidebar.svelte';
|
||||
import Project from '../../components/project/project.svelte';
|
||||
import { getProjectAPI } from '$lib/api/projects';
|
||||
import { type Project as P } from '$lib/stores/interfaces';
|
||||
import Sidebar from '$lib/components/sidebar.svelte';
|
||||
import Project from '$lib/components/project/project.svelte';
|
||||
|
||||
let projectId: number = +$page.params.project;
|
||||
|
||||
|
|