Add card from columns
This commit is contained in:
parent
e7b34fc1b4
commit
fb70658f23
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class TagOption {
|
|||
return this._id;
|
||||
}
|
||||
|
||||
get tagId(): ProjectTag {
|
||||
get projectTag(): ProjectTag {
|
||||
return this._projectTag;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue