Add card from columns

This commit is contained in:
Brieuc Dubois 2024-01-08 22:14:16 +01:00
parent e7b34fc1b4
commit fb70658f23
5 changed files with 104 additions and 88 deletions

View File

@ -1,65 +1,56 @@
<script lang="ts">
import cards from '$lib/stores/cards';
import currentDraggedCard from '$lib/stores/currentDraggedCard';
import type Card from '$lib/types/Card';
import type TagValue from '$lib/types/TagValue';
import { get } from 'svelte/store';
import projectTags from '../../stores/projectTags';
import Card from '$lib/types/Card';
import CardComponent from '../card/Card.svelte';
import AddIcon from '../icons/AddIcon.svelte';
import { import } from { createCardTagApi, deleteCardTagApi, updateCardTagApi };
import type TagOption from '$lib/types/TagOption';
import type ProjectTag from '$lib/types/ProjectTag';
import type Project from '$lib/types/Project';
export let projectId: number;
export let optionId: number | null = null;
export let primary_tag_id: number | null = null;
export let project: Project;
export let option: TagOption | null = null;
export let primaryTag: ProjectTag | null = null;
export let title: string;
export let columnCards: Card[] = [];
let lastTitle = title;
async function onDrop(e: DragEvent) {
e.preventDefault();
if (!$currentDraggedCard || !$currentDraggedCard.tags) return;
for (let tag of $currentDraggedCard.tags) {
if (tag.tag_id !== primary_tag_id) continue;
if (tag.option_id == optionId) return;
// async function onDrop(e: DragEvent) {
// e.preventDefault();
// if (!$currentDraggedCard || !$currentDraggedCard.cardTags) return;
try {
if (tag.option_id && optionId) await deleteCardTagApi(tag.card_id, tag.tag_id);
else if (tag.option_id && optionId)
await createCardTagApi(tag.card_id, tag.tag_id, tag.option_id, tag.value);
else await updateCardTagApi(tag.card_id, tag.tag_id, optionId, tag.value);
// $currentDraggedCard;
tag.option_id = optionId;
cards.reload();
} catch (e) {}
break;
}
currentDraggedCard.set(null);
}
// for (let tag of $currentDraggedCard.cardTags) {
// if (tag.projectTag !== primaryTag) continue;
// if (tag.option == option) return;
// if (!tag.option && !tag.value) await tag.delete();
// else if (tag.option && optionId)
// await createCardTagApi(tag.card_id, tag.tag_id, tag.option_id, tag.value);
// else await updateCardTagApi(tag.card_id, tag.tag_id, optionId, tag.value);
// tag.option_id = optionId;
// cards.reload();
// }
// currentDraggedCard.set(null);
// }
async function addCard() {
const tags: TagValue[] = [];
for (let tag of Object.values(get(projectTags))) {
if (tag.id === primary_tag_id) {
tags.push({
card_id: -1,
tag_id: tag.id,
option_id: optionId,
value: null
});
}
}
const card = await Card.create(project);
await cards.add(projectId, tags);
if (!card) return;
if (!primaryTag) return;
if (!option) return;
await card.addTag(primaryTag, option, null);
}
</script>
<!-- on:drop={onDrop} -->
<div
class="column"
role="listbox"
tabindex="-1"
on:drop={onDrop}
on:dragover={(e) => {
e.preventDefault();
}}
@ -70,16 +61,17 @@
type="text"
on:blur={async () => {
if (lastTitle === title) return;
if (!optionId || !primary_tag_id) return;
await updateTagOptionAPI({
id: optionId,
tag_id: primary_tag_id,
value: title
});
lastTitle = title;
cards.reload();
if (!option || !primaryTag) return;
// option;
// await updateTagOptionAPI({
// id: optionId,
// tag_id: primary_tag_id,
// value: title
// });
// lastTitle = title;
// cards.reload();
}}
disabled={optionId === null}
disabled={option === null}
/>
<span>
<span>{columnCards.length}</span>

View File

@ -1,6 +1,8 @@
<script lang="ts">
import currentView from '$lib/stores/currentView';
import { cards } from '$lib/types/Card';
import type Project from '$lib/types/Project';
import Column from './Column.svelte';
import Header from './Header.svelte';
export let project: Project;
@ -12,44 +14,45 @@
<Header {project} />
{#if $cards}
<div class="grid">
{#if view.primary_tag_id}
{#each $projectTags[view.primary_tag_id].options as option}
{#if $currentView.primaryTag}
{#each $currentView.primaryTag.options as option}
<Column
optionId={option.id}
primary_tag_id={view.primary_tag_id}
{option}
primaryTag={$currentView.primaryTag}
title={option.value}
columnCards={$cards
.filter((c) => c.tags.map((t) => t.option_id).includes(option.id))
.filter((c) => c.cardTags.map((t) => t.option).includes(option))
.sort((a, b) => {
if (!view?.sort_tag_id) return 0;
const aTag = a.tags.find((t) => t.tag_id === view?.sort_tag_id);
const bTag = b.tags.find((t) => t.tag_id === view?.sort_tag_id);
if (!$currentView?.sortTag) return 0;
const aTag = a.cardTags.find((t) => t.projectTag === $currentView?.sortTag);
const bTag = b.cardTags.find((t) => t.projectTag === $currentView?.sortTag);
if (!aTag) return -(view?.sort_direction || 1);
if (!bTag) return view?.sort_direction || 1;
if (!aTag) return -($currentView?.sortDirection || 1);
if (!bTag) return $currentView?.sortDirection || 1;
const aValue = aTag.value || aTag.option_id || 0;
const bValue = bTag.value || bTag.option_id || 0;
const aValue = aTag.value || aTag.option?.value || '';
const bValue = bTag.value || bTag.option?.value || '';
return aValue < bValue
? view?.sort_direction || 1
: -(view?.sort_direction || 1);
? $currentView?.sortDirection || 1
: -($currentView?.sortDirection || 1);
})}
projectId={project.id}
{project}
/>
{/each}
{/if}
<Column
primary_tag_id={view.primary_tag_id}
title={view.primary_tag_id
? `No ${$projectTags[view.primary_tag_id].title}`
: 'No groups'}
columnCards={view.primary_tag_id
? $cards.filter(
(c) => !c.tags.map((t) => t.tag_id).includes(view?.primary_tag_id || -2)
)
primaryTag={$currentView.primaryTag}
title={$currentView.primaryTag ? `No ${$currentView.title}` : 'No groups'}
columnCards={$currentView.primaryTag != null
? (() => {
const primaryTag = $currentView.primaryTag;
return $cards.filter(
(c) => !c.cardTags.map((t) => t.projectTag).includes(primaryTag)
);
})()
: $cards}
projectId={project.id}
{project}
/>
</div>
{/if}

View File

@ -3,6 +3,8 @@ import { get, writable } from 'svelte/store';
import CardTag from './CardTag';
import Project from './Project';
import { toastAlert } from '$lib/utils/toasts';
import type TagOption from './TagOption';
import type ProjectTag from './ProjectTag';
export const cards = writable([] as Card[]);
@ -11,20 +13,20 @@ export default class Card {
private _project: Project;
private _title: string;
private _content: string;
private _tags: CardTag[];
private _cardTags: CardTag[];
private constructor(
id: number,
project: Project,
title: string,
content: string,
tags: CardTag[]
cardTags: CardTag[]
) {
this._id = id;
this._project = project;
this._title = title;
this._content = content;
this._tags = tags;
this._cardTags = cardTags;
}
get id(): number {
@ -43,8 +45,8 @@ export default class Card {
return this._content;
}
get tags(): CardTag[] {
return this._tags;
get cardTags(): CardTag[] {
return this._cardTags;
}
static fromId(id: number): Card | null {
@ -79,6 +81,20 @@ export default class Card {
return true;
}
async addTag(
projectTag: ProjectTag,
tagOption: TagOption | null,
value: string | null
): Promise<boolean> {
const cardTag = await CardTag.create(this, projectTag, tagOption, value);
if (!cardTag) return false;
this._cardTags.push(cardTag);
return true;
}
static parse(json: any): Card | null;
static parse(json: any, project: Project | null | undefined): Card | null;
@ -95,7 +111,7 @@ export default class Card {
const card = new Card(json.id, project, json.title, json.content, []);
card._tags = CardTag.parseAll(json.tags, card);
card._cardTags = CardTag.parseAll(json.tags, card);
cards.update((cards) => {
if (!cards.find((c) => c.id === card.id)) {

View File

@ -5,13 +5,18 @@ import TagOption from './TagOption';
export default class CardTag {
private _card: Card;
private _tag: ProjectTag;
private _projectTag: ProjectTag;
private _option: TagOption | null;
private _value: string | null;
private constructor(card: Card, tag: ProjectTag, option: TagOption | null, value: string | null) {
private constructor(
card: Card,
projectTag: ProjectTag,
option: TagOption | null,
value: string | null
) {
this._card = card;
this._tag = tag;
this._projectTag = projectTag;
this._option = option;
this._value = value;
}
@ -20,11 +25,11 @@ export default class CardTag {
return this.card;
}
get tag(): number {
return this.tag;
get projectTag(): ProjectTag {
return this.projectTag;
}
get option(): number | null {
get option(): TagOption | null {
return this.option;
}
@ -46,7 +51,7 @@ export default class CardTag {
}
async delete() {
return cardsTagsApi.delete(this._card.id, this._tag.id);
return cardsTagsApi.delete(this._card.id, this._projectTag.id);
}
static parse(json: any): CardTag | null;

View File

@ -15,7 +15,7 @@ export default class TagOption {
return this._id;
}
get tagId(): ProjectTag {
get projectTag(): ProjectTag {
return this._projectTag;
}