Group button
This commit is contained in:
parent
e8ec7919d9
commit
5bc43aaba2
|
@ -5,6 +5,7 @@
|
|||
<link rel="icon" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/global.css" />
|
||||
<title>Focus.</title>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<script lang="ts">
|
||||
export let isOpen = false;
|
||||
export let choices: { id: number; value: string }[] = [];
|
||||
export let onChoice = (id: number) => {};
|
||||
export let currentChoice: number = -1;
|
||||
</script>
|
||||
|
||||
{#if isOpen}
|
||||
<div class="menu">
|
||||
{#each choices as choice}
|
||||
<div
|
||||
class="menu-item"
|
||||
on:click={() => onChoice(choice.id)}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
on:keypress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
onChoice(choice.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span>{choice.value}</span>
|
||||
{#if currentChoice === choice.id}
|
||||
<span class="mark"> ✓ </span>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="less">
|
||||
.menu {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #222;
|
||||
border: 1px solid #666;
|
||||
padding: 10px 0;
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 5px 20px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.mark {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,10 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { get } from 'svelte/store';
|
||||
import type { Project, TagValue } from '../../stores/interfaces';
|
||||
import { cards } from '../../stores/smallStore';
|
||||
import type { Project, TagValue, View } from '../../stores/interfaces';
|
||||
import { cards, currentView } from '../../stores/smallStore';
|
||||
import projectTags from '../../stores/projectTags';
|
||||
import GroupMenu from './groupMenu.svelte';
|
||||
|
||||
export let project: Project;
|
||||
export let currentTagId: number;
|
||||
let groupMenuOpen = false;
|
||||
|
||||
function getEmptyTags(): TagValue[] {
|
||||
const tags: TagValue[] = [];
|
||||
|
@ -18,16 +21,41 @@
|
|||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
async function setGroup(id: number): Promise<boolean> {
|
||||
if ($currentView == null) return false;
|
||||
|
||||
return await currentView.update({
|
||||
...$currentView,
|
||||
primary_tag_id: id
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<h2>{project.title}</h2>
|
||||
<nav>
|
||||
<span>Group</span>
|
||||
<span>Sub-group</span>
|
||||
<span>Filter</span>
|
||||
<span>Sort</span>
|
||||
<button on:click={async () => cards.add(project.id, getEmptyTags())}>New</button>
|
||||
<div>
|
||||
<button
|
||||
on:click={() => (groupMenuOpen = !groupMenuOpen)}
|
||||
class:defined={$currentView?.primary_tag_id}>Group</button
|
||||
>
|
||||
<GroupMenu
|
||||
isOpen={groupMenuOpen}
|
||||
choices={Object.values($projectTags).map((tag) => ({ id: tag.id, value: tag.title }))}
|
||||
onChoice={async (id) => {
|
||||
if (!(await setGroup(id))) return;
|
||||
groupMenuOpen = false;
|
||||
}}
|
||||
currentChoice={currentTagId}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button class:disabled={true}>Sub-group</button>
|
||||
</div>
|
||||
<button>Filter</button>
|
||||
<button>Sort</button>
|
||||
<button id="newButton" on:click={async () => cards.add(project.id, getEmptyTags())}>New</button>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
@ -45,32 +73,34 @@
|
|||
}
|
||||
|
||||
nav {
|
||||
* {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-right: 10px;
|
||||
color: #aaa;
|
||||
padding: 5px 10px;
|
||||
border-radius: 7px;
|
||||
|
||||
&:hover {
|
||||
// background-color: #fff2;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
background: #324067;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
color: #aaa;
|
||||
padding: 5px 10px;
|
||||
margin-left: 10px;
|
||||
border-radius: 7px;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 10px 20px;
|
||||
background-color: transparent;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
// background-color: #3a4a77;
|
||||
&.defined {
|
||||
color: #6481cc;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #555;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
#newButton {
|
||||
background: #324067;
|
||||
border-radius: 10px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
{#if project}
|
||||
<section>
|
||||
<Header {project} />
|
||||
{#if view && $projectTags[view.primary_tag_id] && $cards}
|
||||
<Header {project} currentTagId={view.primary_tag_id} />
|
||||
<div class="grid">
|
||||
{#each $projectTags[view.primary_tag_id].options as option}
|
||||
<Column
|
||||
|
|
|
@ -2,8 +2,29 @@ import { writable } from 'svelte/store';
|
|||
import { parseCards, type Card, type View, type TagValue } from './interfaces';
|
||||
import { deleteCardApi, newCardApi } from '../api/cards';
|
||||
import { getProjectCardsAPI } from '../api/projects';
|
||||
import api, { processError } from '../utils/api';
|
||||
import status from '../utils/status';
|
||||
|
||||
export const currentView = writable(null as View | null);
|
||||
export const currentView = (() => {
|
||||
const { subscribe, set, update } = writable(null as View | null);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set,
|
||||
update: async (view: View): Promise<boolean> => {
|
||||
const response = await api.put(`/v1/views/${view.id}`, view);
|
||||
|
||||
if (response.status !== status.NoContent) {
|
||||
processError(response, 'Failed to update view');
|
||||
return false;
|
||||
}
|
||||
|
||||
set(view);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export const currentModalCard = writable(-1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue