mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-22 01:25:00 +02:00
Add KanbanView. Move icons. (#143)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { UserInfo } from '@anticrm/presentation'
|
||||
import { ActionIcon, Label, IconMoreH, IconFile } from '@anticrm/ui'
|
||||
|
||||
interface ICard {
|
||||
_id: number
|
||||
firstName: string
|
||||
lastName: string
|
||||
description: string
|
||||
state: number
|
||||
}
|
||||
|
||||
export let card: ICard
|
||||
export let draggable: boolean
|
||||
|
||||
</script>
|
||||
|
||||
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
|
||||
<div class="header">
|
||||
<UserInfo value={{firstName: card.firstName, lastName: card.lastName }} subtitle={'Candidate'} size={'small'} />
|
||||
<ActionIcon icon={IconMoreH} label={'More..'} direction={'left'} />
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="flex-row-center item">
|
||||
<IconFile size={'large'} />
|
||||
<span>Team Interview</span>
|
||||
</div>
|
||||
<div class="description">{card.description}</div>
|
||||
<div class="tags">
|
||||
<div class="tag">
|
||||
<IconFile size={'small'} />
|
||||
<span><Label label={'Application'} /></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
background-color: var(--theme-button-bg-hovered);
|
||||
border: 1px solid var(--theme-bg-accent-color);
|
||||
border-radius: .75rem;
|
||||
user-select: none;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: .75rem 1rem;
|
||||
width: 100%;
|
||||
min-height: 3.75rem;
|
||||
background-color: var(--theme-button-bg-focused);
|
||||
border-radius: .75rem .75rem 0 0;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 1rem;
|
||||
|
||||
.item {
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
color: var(--theme-caption-color);
|
||||
span { margin-left: .5em; }
|
||||
}
|
||||
.description {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
.tags {
|
||||
display: flex;
|
||||
margin-top: 1rem;
|
||||
|
||||
.tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .5rem .75rem;
|
||||
font-size: .75rem;
|
||||
text-align: center;
|
||||
background-color: var(--theme-bg-accent-color);
|
||||
color: var(--theme-caption-color);
|
||||
border-radius: .5rem;
|
||||
|
||||
span { margin-left: .3em; }
|
||||
}
|
||||
.tag + .tag { margin-left: .75rem; }
|
||||
}
|
||||
}
|
||||
|
||||
&.draggable {
|
||||
cursor: grab;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.card-container + .card-container) { margin-top: .75rem; }
|
||||
</style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { Label } from '@anticrm/ui'
|
||||
import { IconAdd } from '@anticrm/ui'
|
||||
|
||||
export let label: IntlString
|
||||
</script>
|
||||
|
||||
<div class="card-container">
|
||||
<div class="icon">
|
||||
<IconAdd size={'small'} />
|
||||
</div>
|
||||
<Label {label} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: .75rem 1.5rem;
|
||||
color: var(--theme-content-dark-color);
|
||||
background-color: var(--theme-button-bg-hovered);
|
||||
border: 1px dotted var(--theme-bg-accent-color);
|
||||
border-radius: .75rem;
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
margin-bottom: .25rem;
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--theme-caption-color);
|
||||
.icon { opacity: 1; }
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { Label, ScrollBox } from '@anticrm/ui'
|
||||
|
||||
export let label: IntlString
|
||||
export let color: string
|
||||
export let counter: number
|
||||
</script>
|
||||
|
||||
<div class="panel-container" on:dragover on:drop>
|
||||
<div class="header" style="background-color: {color}">
|
||||
<div class="title"><Label {label} /></div>
|
||||
<div class="counter">{counter}</div>
|
||||
</div>
|
||||
<div class="scroll">
|
||||
<ScrollBox vertical>
|
||||
<slot />
|
||||
</ScrollBox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.panel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
background-color: var(--theme-button-bg-enabled);
|
||||
border: 1px solid var(--theme-bg-accent-color);
|
||||
border-radius: .75rem;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: .75rem;
|
||||
padding: .5rem;
|
||||
min-height: 2.75rem;
|
||||
font-weight: 500;
|
||||
border: 1px solid rgba(0, 0, 0, .1);
|
||||
border-radius: .5rem;
|
||||
|
||||
.title {
|
||||
padding-left: .5rem;
|
||||
color: var(--theme-caption-color);
|
||||
}
|
||||
.counter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
color: var(--theme-contnet-accent-color);
|
||||
background-color: rgba(0, 0, 0, .08);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll {
|
||||
margin: .5rem .75rem .75rem;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.panel-container + .panel-container) { margin-left: .75rem; }
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<!--
|
||||
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { Label } from '@anticrm/ui'
|
||||
import { IconAdd } from '@anticrm/ui'
|
||||
|
||||
export let label: IntlString
|
||||
</script>
|
||||
|
||||
<div class="panel-container">
|
||||
<div class="circle">
|
||||
<div class="icon">
|
||||
<IconAdd size={'large'} />
|
||||
</div>
|
||||
</div>
|
||||
<Label {label} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.panel-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
padding: .75rem;
|
||||
color: var(--theme-caption-color);
|
||||
background-color: var(--theme-button-bg-enabled);
|
||||
border: 1px dotted var(--theme-bg-accent-color);
|
||||
border-radius: .75rem;
|
||||
cursor: pointer;
|
||||
|
||||
.circle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 1.25rem;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
background-color: var(--theme-bg-accent-color);
|
||||
border-radius: 50%;
|
||||
|
||||
.icon { opacity: .6; }
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-bg-accent-hover);
|
||||
box-shadow: 0 .75rem 2.5rem rgba(0, 0, 0, .15);
|
||||
|
||||
.circle .icon { opacity: 1; }
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
import { createQuery } from '@anticrm/presentation'
|
||||
|
||||
import KanbanPanel from './KanbanPanel.svelte'
|
||||
import KanbanPanelEmpty from './KanbanPanelEmpty.svelte'
|
||||
import KanbanCard from './KanbanCard.svelte'
|
||||
import KanbanCardEmpty from './KanbanCardEmpty.svelte'
|
||||
|
||||
export let _class: Ref<Class<Doc>>
|
||||
export let space: Ref<Space>
|
||||
export let open: AnyComponent
|
||||
@@ -52,78 +57,79 @@
|
||||
function onClick(object: Doc) {
|
||||
showPopup(open, { object, space }, 'float')
|
||||
}
|
||||
|
||||
interface ICard {
|
||||
_id: number
|
||||
firstName: string
|
||||
lastName: string
|
||||
description: string
|
||||
state: number
|
||||
}
|
||||
let dragCard: ICard
|
||||
let states: Array<Object> = [
|
||||
{ _id: 0, label: 'In progress', color: '#7C6FCD' },
|
||||
{ _id: 1, label: 'Under review', color: '#6F7BC5' },
|
||||
{ _id: 2, label: 'Interview', color: '#A5D179' },
|
||||
{ _id: 3, label: 'Offer', color: '#77C07B' },
|
||||
{ _id: 4, label: 'Assigned', color: '#F28469' }
|
||||
]
|
||||
const cards: Array<ICard> = [
|
||||
{ _id: 0, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 0 },
|
||||
{ _id: 1, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 0 },
|
||||
{ _id: 2, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 0 },
|
||||
{ _id: 3, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 1 },
|
||||
{ _id: 4, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 1 },
|
||||
{ _id: 5, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 2 },
|
||||
{ _id: 6, firstName: 'Chen', lastName: 'Rosamund', description: '8:30AM, July 12 Voltron, San Francisco', state: 3 },
|
||||
]
|
||||
</script>
|
||||
|
||||
{#await buildModel(client, _class, config, options)}
|
||||
<Loading/>
|
||||
{:then model}
|
||||
KANBAN
|
||||
<div class="container">
|
||||
<ScrollBox vertical stretch noShift>
|
||||
<table class="table-body">
|
||||
<thead>
|
||||
<tr class="tr-head">
|
||||
{#each model as attribute}
|
||||
<th><Label label = {attribute.label}/></th>
|
||||
<div class="kanban-container">
|
||||
<ScrollBox>
|
||||
<div class="kanban-content">
|
||||
{#each states as state}
|
||||
<KanbanPanel label={state.label} color={state.color} counter={4}
|
||||
on:dragover={(event) => {
|
||||
event.preventDefault()
|
||||
}}
|
||||
on:drop={(event) => {
|
||||
event.preventDefault()
|
||||
if (dragCard) {
|
||||
dragCard.state = state._id
|
||||
dragCard = undefined
|
||||
}
|
||||
}}
|
||||
>
|
||||
<KanbanCardEmpty label={'Create new application'} />
|
||||
{#each cards.filter((c) => c.state === state._id) as card}
|
||||
<KanbanCard {card} draggable={true}
|
||||
on:dragstart={() => {
|
||||
dragCard = card
|
||||
}}
|
||||
on:dragend={() => {
|
||||
dragCard = undefined
|
||||
}}
|
||||
/>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
{#if objects}
|
||||
<tbody>
|
||||
{#each objects as object (object._id)}
|
||||
<tr class="tr-body" on:click={() => onClick(object)}>
|
||||
{#each model as attribute}
|
||||
<td><svelte:component this={attribute.presenter} value={getValue(object, attribute.key)}/></td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
{/if}
|
||||
</table>
|
||||
</KanbanPanel>
|
||||
{/each}
|
||||
<KanbanPanelEmpty label={'Add new column'} />
|
||||
</div>
|
||||
</ScrollBox>
|
||||
</div>
|
||||
{/await}
|
||||
|
||||
<style lang="scss">
|
||||
.container {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
padding-bottom: 2.5rem;
|
||||
.kanban-container {
|
||||
margin-bottom: 1.25rem;
|
||||
height: 100%;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 2.5rem;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background-color: var(--theme-table-bg-color);
|
||||
border-radius: 0 0 1.25rem 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: .5rem 1.5rem;
|
||||
text-align: left;
|
||||
&:first-child { padding-left: 2.5rem; }
|
||||
}
|
||||
|
||||
th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
height: 2.5rem;
|
||||
font-weight: 500;
|
||||
font-size: .75rem;
|
||||
color: var(--theme-content-dark-color);
|
||||
background-color: var(--theme-bg-color);
|
||||
box-shadow: inset 0 -1px 0 0 var(--theme-bg-focused-color);
|
||||
}
|
||||
|
||||
.tr-body {
|
||||
height: 3.75rem;
|
||||
color: var(--theme-caption-color);
|
||||
border-bottom: 1px solid var(--theme-button-border-hovered);
|
||||
&:last-child { border-bottom: none; }
|
||||
&:hover { background-color: var(--theme-table-bg-hover); }
|
||||
.kanban-content {
|
||||
display: flex;
|
||||
margin: 0 2.5rem;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user