Replace -1 by nullable values
This commit is contained in:
parent
e2e87ce9ec
commit
98e54f94a6
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
var db *sql.DB
|
||||
|
||||
const DB_VERSION = 1
|
||||
|
||||
func InitDB(driver string, connStr string) error {
|
||||
var err error
|
||||
db, err = sql.Open(driver, connStr)
|
||||
|
@ -14,16 +16,13 @@ func InitDB(driver string, connStr string) error {
|
|||
}
|
||||
|
||||
_, err = db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS schema_version (
|
||||
version INTEGER PRIMARY KEY,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS projects (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS lists (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
project_id INTEGER,
|
||||
title TEXT,
|
||||
color TEXT,
|
||||
FOREIGN KEY(project_id) REFERENCES projects(id)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS cards (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
@ -61,13 +60,47 @@ func InitDB(driver string, connStr string) error {
|
|||
primary_tag_id INTEGER,
|
||||
secondary_tag_id INTEGER,
|
||||
title TEXT,
|
||||
sort_tag_id INTEGER,
|
||||
sort_direction INTEGER,
|
||||
FOREIGN KEY(project_id) REFERENCES projects(id),
|
||||
FOREIGN KEY(primary_tag_id) REFERENCES tags(id),
|
||||
FOREIGN KEY(secondary_tag_id) REFERENCES tags(id)
|
||||
);
|
||||
`)
|
||||
|
||||
INSERT INTO schema_version (version)
|
||||
SELECT ? WHERE NOT EXISTS (SELECT 1 FROM schema_version);
|
||||
`, DB_VERSION)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return updateDB()
|
||||
}
|
||||
|
||||
func updateDB() error {
|
||||
|
||||
var currentVersion int
|
||||
|
||||
err := db.QueryRow("SELECT MAX(version) FROM schema_version").Scan(¤tVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if currentVersion < 2 {
|
||||
_, err := db.Exec(`
|
||||
ALTER TABLE views
|
||||
ADD COLUMN sort_tag_id INTEGER;
|
||||
ALTER TABLE views
|
||||
ADD COLUMN sort_direction INTEGER;
|
||||
|
||||
INSERT INTO schema_version (version)
|
||||
SELECT ? WHERE NOT EXISTS (SELECT 1 FROM schema_version WHERE version = ?);
|
||||
`, 2, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package db
|
|||
import "git.bhasher.com/bhasher/focus/backend/types"
|
||||
|
||||
func CreateView(v types.View) (int, error) {
|
||||
res, err := db.Exec("INSERT INTO views (project_id, primary_tag_id, secondary_tag_id, title) VALUES (?, ?, ?, ?)", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title)
|
||||
res, err := db.Exec("INSERT INTO views (project_id, primary_tag_id, secondary_tag_id, title, sort_tag_id, sort_direction) VALUES (?, ?, ?, ?, ?, ?)", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func GetProjectViews(projectID int) ([]types.View, error) {
|
|||
var views []types.View
|
||||
for rows.Next() {
|
||||
var v types.View
|
||||
if err := rows.Scan(&v.ID, &v.ProjectID, &v.PrimaryTagID, &v.SecondaryTagID, &v.Title); err != nil {
|
||||
if err := rows.Scan(&v.ID, &v.ProjectID, &v.PrimaryTagID, &v.SecondaryTagID, &v.Title, &v.SortTagID, &v.SortDirection); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -52,13 +52,13 @@ func GetView(id int) (*types.View, error) {
|
|||
}
|
||||
|
||||
var v types.View
|
||||
rows.Scan(&v.ID, &v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title)
|
||||
rows.Scan(&v.ID, &v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection)
|
||||
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func UpdateView(v types.View) (int64, error) {
|
||||
res, err := db.Exec("UPDATE views SET project_id = ?, primary_tag_id = ?, secondary_tag_id = ?, title = ? WHERE id = ?", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.ID)
|
||||
res, err := db.Exec("UPDATE views SET project_id = ?, primary_tag_id = ?, secondary_tag_id = ?, title = ?, sort_tag_id = ?, sort_direction = ? WHERE id = ?", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection, v.ID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
package types
|
||||
|
||||
type CardTag struct {
|
||||
CardID int `json:"card_id"`
|
||||
TagID int `json:"tag_id"`
|
||||
OptionID int `json:"option_id"`
|
||||
Value string `json:"value"`
|
||||
CardID int `json:"card_id"`
|
||||
TagID int `json:"tag_id"`
|
||||
OptionID *int `json:"option_id"`
|
||||
Value *string `json:"value"`
|
||||
}
|
||||
|
||||
type FullCardTag struct {
|
||||
CardID int `json:"card_id"`
|
||||
TagID int `json:"tag_id"`
|
||||
TagTitle string `json:"tag_title"`
|
||||
TagType int `json:"tag_type"`
|
||||
OptionID int `json:"option_id"`
|
||||
Value string `json:"value"`
|
||||
CardID int `json:"card_id"`
|
||||
TagID int `json:"tag_id"`
|
||||
TagTitle string `json:"tag_title"`
|
||||
TagType int `json:"tag_type"`
|
||||
OptionID *int `json:"option_id"`
|
||||
Value *string `json:"value"`
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package types
|
||||
|
||||
type List struct {
|
||||
ID int `json:"id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Color string `json:"color"`
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
package types
|
||||
|
||||
type View struct {
|
||||
ID int `json:"id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
PrimaryTagID int `json:"primary_tag_id"`
|
||||
SecondaryTagID int `json:"secondary_tag_id"`
|
||||
Title string `json:"title"`
|
||||
ID int `json:"id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
PrimaryTagID *int `json:"primary_tag_id"`
|
||||
SecondaryTagID *int `json:"secondary_tag_id"`
|
||||
SortTagID *int `json:"sort_tag_id"`
|
||||
SortDirection *string `json:"sort_direction"`
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
"devDependencies": {
|
||||
"@playwright/test": "^1.28.1",
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/adapter-static": "^3.0.1",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@types/eslint": "8.56.0",
|
||||
|
@ -836,15 +835,6 @@
|
|||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/adapter-static": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz",
|
||||
"integrity": "sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/kit": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.0.6.tgz",
|
||||
|
|
|
@ -60,8 +60,8 @@ export async function deleteCardApi(cardID: number): Promise<void> {
|
|||
export async function createCardTagApi(
|
||||
cardId: number,
|
||||
tagId: number,
|
||||
optionId: number,
|
||||
value: string
|
||||
optionId: number | null,
|
||||
value: string | null
|
||||
): Promise<boolean> {
|
||||
const response = await api.post(`/v1/cards/${cardId}/tags/${tagId}`, {
|
||||
option_id: optionId,
|
||||
|
@ -76,15 +76,24 @@ export async function createCardTagApi(
|
|||
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,
|
||||
value: string
|
||||
option_id: number | null,
|
||||
value: string | null
|
||||
): Promise<void> {
|
||||
const response = await api.put(`/v1/cards/${cardID}/tags/${tagID}`, {
|
||||
option_id: option_id,
|
||||
value: value
|
||||
option_id: option_id == -1 ? null : option_id,
|
||||
value: value == '' ? null : value
|
||||
});
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{#if card.tags}
|
||||
<div class="tags">
|
||||
{#each card.tags as tag}
|
||||
{#if tag.option_id && tag.option_id !== -1}
|
||||
{#if tag.option_id}
|
||||
{#if $projectTags[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
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
card.content = newContent;
|
||||
}
|
||||
}
|
||||
if (closeModal) currentModalCard.set(-1);
|
||||
if (closeModal) currentModalCard.set(null);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
<button on:click={() => cards.remove(card)}>
|
||||
<TrashIcon />
|
||||
</button>
|
||||
<button on:click={() => currentModalCard.set(-1)}>
|
||||
<button on:click={() => currentModalCard.set(null)}>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<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';
|
||||
|
@ -7,7 +8,7 @@
|
|||
import TrashIcon from '../../../icons/trashIcon.svelte';
|
||||
import Menu from '../../../tuils/menu.svelte';
|
||||
|
||||
export let multiple: boolean = false;
|
||||
export const multiple: boolean = false;
|
||||
export let card: Card;
|
||||
export let projectTag: MeTag;
|
||||
export let tagValue: TagValue | undefined;
|
||||
|
@ -19,21 +20,14 @@
|
|||
|
||||
let isOpen = false;
|
||||
|
||||
async function selectOption(option_id: number) {
|
||||
async function selectOption(option_id: number | null) {
|
||||
if (lastTagValue.option_id === option_id) {
|
||||
isOpen = false;
|
||||
return;
|
||||
}
|
||||
if (tagValue) {
|
||||
const response = await api.put(`/v1/cards/${card.id}/tags/${projectTag.id}`, {
|
||||
option_id,
|
||||
value: ''
|
||||
});
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to update tag');
|
||||
return;
|
||||
}
|
||||
if (tagValue) {
|
||||
await updateCardTagApi(card.id, projectTag.id, option_id, tagValue.value);
|
||||
|
||||
card.tags = card.tags.map((t) => {
|
||||
if (t.tag_id === projectTag.id) {
|
||||
|
@ -70,7 +64,7 @@
|
|||
cards.reload();
|
||||
}
|
||||
|
||||
async function deleteOption(_: number | undefined) {
|
||||
async function deleteOption() {
|
||||
const response = await api.delete(`/v1/cards/${card.id}/tags/${projectTag.id}`);
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
|
@ -107,7 +101,7 @@
|
|||
{#if tagValue}
|
||||
<span class="tag">
|
||||
{tagOption?.value}
|
||||
<button class="real" on:click={() => deleteOption(tagValue?.option_id)}>✗</button>
|
||||
<button class="real" on:click={() => deleteOption()}>✗</button>
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -1,79 +1,51 @@
|
|||
<script lang="ts">
|
||||
import type { TagOption, Card, MeTag, TagValue } from '../../stores/interfaces';
|
||||
import type { Card, TagValue } from '../../stores/interfaces';
|
||||
import { cards, currentDraggedCard } from '../../stores/smallStore';
|
||||
import api, { processError } from '../../utils/api';
|
||||
import status from '../../utils/status';
|
||||
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';
|
||||
|
||||
export let projectId: number;
|
||||
export let editable: boolean = true;
|
||||
export let option: TagOption;
|
||||
export let optionId: number | null = null;
|
||||
export let primary_tag_id: number | null = null;
|
||||
export let title: string;
|
||||
export let columnCards: Card[] = [];
|
||||
|
||||
let lastOptionValue = option.value;
|
||||
let lastTitle = title;
|
||||
|
||||
async function onDrop(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
if ($currentDraggedCard && $currentDraggedCard.tags) {
|
||||
for (let tag of $currentDraggedCard.tags) {
|
||||
if (tag.tag_id == option.tag_id) {
|
||||
try {
|
||||
if (tag.option_id == option.id) return;
|
||||
// DELETE
|
||||
if (tag.option_id !== -1 && option.id === -1) {
|
||||
const response = await api.delete(`/v1/cards/${tag.card_id}/tags/${tag.tag_id}`);
|
||||
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;
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to delete tag');
|
||||
return;
|
||||
}
|
||||
}
|
||||
// CREATE
|
||||
else if (tag.option_id == -1 && option.id !== -1) {
|
||||
const response = await api.post(`/v1/cards/${tag.card_id}/tags/${tag.tag_id}`, {
|
||||
value: tag.value,
|
||||
option_id: option.id
|
||||
});
|
||||
if (response.status !== status.Created) {
|
||||
processError(response, 'Failed to create tag');
|
||||
return;
|
||||
}
|
||||
}
|
||||
// UPDATE
|
||||
else {
|
||||
const response = await api.put(`/v1/cards/${tag.card_id}/tags/${tag.tag_id}`, {
|
||||
value: tag.value,
|
||||
option_id: option.id
|
||||
});
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to update tag');
|
||||
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);
|
||||
|
||||
tag.option_id = option.id;
|
||||
cards.reload();
|
||||
} catch (e) {}
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentDraggedCard.set(null);
|
||||
tag.option_id = optionId;
|
||||
cards.reload();
|
||||
} catch (e) {}
|
||||
break;
|
||||
}
|
||||
currentDraggedCard.set(null);
|
||||
}
|
||||
|
||||
async function addCard() {
|
||||
const tags: TagValue[] = [];
|
||||
for (let tag of Object.values(get(projectTags))) {
|
||||
if (tag.id === option.tag_id) {
|
||||
if (tag.id === primary_tag_id) {
|
||||
tags.push({
|
||||
card_id: -1,
|
||||
tag_id: tag.id,
|
||||
option_id: option.id,
|
||||
value: ''
|
||||
option_id: optionId,
|
||||
value: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -93,15 +65,20 @@
|
|||
>
|
||||
<header>
|
||||
<input
|
||||
bind:value={option.value}
|
||||
bind:value={title}
|
||||
type="text"
|
||||
on:blur={async () => {
|
||||
if (lastOptionValue === option.value) return;
|
||||
await updateTagOptionAPI(option);
|
||||
lastOptionValue = option.value;
|
||||
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();
|
||||
}}
|
||||
disabled={!editable}
|
||||
disabled={optionId === null}
|
||||
/>
|
||||
<span>
|
||||
<span>{columnCards.length}</span>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
export let isOpen = false;
|
||||
export let choices: { id: number; value: string }[] = [];
|
||||
export let onChoice = (id: number) => {};
|
||||
export let currentChoice: number;
|
||||
export let currentChoice: number | null;
|
||||
</script>
|
||||
|
||||
<Menu {isOpen}>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
import { get } from 'svelte/store';
|
||||
import type { Project, TagValue, View } from '../../stores/interfaces';
|
||||
import { cards, currentView, views } from '../../stores/smallStore';
|
||||
import projectTags from '../../stores/projectTags';
|
||||
|
@ -9,19 +8,6 @@
|
|||
export let view: View;
|
||||
let groupMenuOpen = false;
|
||||
|
||||
function getEmptyTags(): TagValue[] {
|
||||
const tags: TagValue[] = [];
|
||||
for (let tag of Object.values(get(projectTags))) {
|
||||
tags.push({
|
||||
card_id: -1,
|
||||
tag_id: tag.id,
|
||||
option_id: -1,
|
||||
value: ''
|
||||
});
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
async function setGroup(id: number): Promise<boolean> {
|
||||
if ($currentView == null) return false;
|
||||
|
||||
|
@ -44,7 +30,7 @@
|
|||
<div>
|
||||
<button
|
||||
on:click={() => (groupMenuOpen = !groupMenuOpen)}
|
||||
class:defined={$currentView?.primary_tag_id !== -1}>Group</button
|
||||
class:defined={$currentView?.primary_tag_id}>Group</button
|
||||
>
|
||||
<GroupMenu
|
||||
isOpen={groupMenuOpen}
|
||||
|
@ -59,7 +45,7 @@
|
|||
<button class:disabled={true}>Sub-group</button>
|
||||
<button class:disabled={true}>Filter</button>
|
||||
<button class:disabled={true}>Sort</button>
|
||||
<button id="newButton" on:click={async () => cards.add(project.id, getEmptyTags())}>New</button>
|
||||
<button id="newButton" on:click={async () => cards.add(project.id, [])}>New</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
|
|
@ -29,10 +29,12 @@
|
|||
<Header {project} {view} />
|
||||
{#if cards}
|
||||
<div class="grid">
|
||||
{#if view.primary_tag_id !== -1}
|
||||
{#if view.primary_tag_id}
|
||||
{#each $projectTags[view.primary_tag_id].options as option}
|
||||
<Column
|
||||
{option}
|
||||
optionId={option.id}
|
||||
primary_tag_id={view.primary_tag_id}
|
||||
title={option.value}
|
||||
columnCards={$cards.filter((c) =>
|
||||
c.tags.map((t) => t.option_id).includes(option.id)
|
||||
)}
|
||||
|
@ -41,21 +43,16 @@
|
|||
{/each}
|
||||
{/if}
|
||||
<Column
|
||||
option={{
|
||||
id: -1,
|
||||
tag_id: view.primary_tag_id,
|
||||
value:
|
||||
view.primary_tag_id !== -1
|
||||
? `No ${$projectTags[view.primary_tag_id].title}`
|
||||
: 'No groups'
|
||||
}}
|
||||
columnCards={view.primary_tag_id !== -1
|
||||
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)
|
||||
)
|
||||
: $cards}
|
||||
projectId={project.id}
|
||||
editable={false}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
if (!$views) return;
|
||||
|
||||
const primaryTagId =
|
||||
$currentView?.primary_tag_id || Object.values($projectTags).find((t) => true)?.id || -1;
|
||||
$currentView?.primary_tag_id || Object.values($projectTags).find((t) => true)?.id || null;
|
||||
|
||||
const newView = await views.add(project.id, 'New view', primaryTagId);
|
||||
|
||||
|
@ -233,10 +233,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
span {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
|
|
@ -14,8 +14,8 @@ export interface Card {
|
|||
export interface TagValue {
|
||||
card_id: number;
|
||||
tag_id: number;
|
||||
option_id: number;
|
||||
value: string;
|
||||
option_id: number | null;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export interface MeTag {
|
||||
|
@ -35,9 +35,11 @@ export interface TagOption {
|
|||
export interface View {
|
||||
id: number;
|
||||
project_id: number;
|
||||
primary_tag_id: number;
|
||||
secondary_tag_id: number;
|
||||
primary_tag_id: number | null;
|
||||
secondary_tag_id: number | null;
|
||||
title: string;
|
||||
sort_tag_id: number | null;
|
||||
sort_direction: number | null;
|
||||
}
|
||||
|
||||
export function parseCard(c: any) {
|
||||
|
|
|
@ -26,7 +26,7 @@ export const currentView = (() => {
|
|||
};
|
||||
})();
|
||||
|
||||
export const currentModalCard = writable(-1);
|
||||
export const currentModalCard = writable(null as number | null);
|
||||
|
||||
export const currentDraggedCard = writable(null as Card | null);
|
||||
|
||||
|
@ -49,7 +49,7 @@ export const cards = (() => {
|
|||
remove: async (card: Card) => {
|
||||
await deleteCardApi(card.id).then(() => {
|
||||
update((cards) => cards.filter((c) => c.id !== card.id));
|
||||
currentModalCard.set(-1);
|
||||
currentModalCard.set(null);
|
||||
});
|
||||
},
|
||||
edit: async (card: Card): Promise<boolean> => {
|
||||
|
@ -82,7 +82,7 @@ export const views = (() => {
|
|||
|
||||
return true;
|
||||
};
|
||||
const add = async (projectId: number, title: string, primaryTagId: number): 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,
|
||||
|
@ -99,7 +99,9 @@ export const views = (() => {
|
|||
title: title,
|
||||
project_id: projectId,
|
||||
primary_tag_id: primaryTagId,
|
||||
secondary_tag_id: 0
|
||||
secondary_tag_id: null,
|
||||
sort_tag_id: null,
|
||||
sort_direction: null
|
||||
};
|
||||
|
||||
update((views) => [...views, view]);
|
||||
|
|
Loading…
Reference in New Issue