New Kanban card layout, fix error position in Card (#274)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov
2021-10-13 22:04:18 +02:00
committed by GitHub
parent 8013bc086c
commit aa397a1ae7
12 changed files with 231 additions and 121 deletions
@@ -80,6 +80,7 @@
.error {
position: absolute;
display: flex;
top: 3.25rem;
left: 1.75rem;
right: 1.75rem;
+27
View File
@@ -136,6 +136,25 @@ table {
align-items: stretch;
}
/* --------- */
.sm-tool-icon {
display: flex;
align-items: center;
color: var(--theme-caption-color);
cursor: pointer;
.icon {
margin-right: .25rem;
color: var(--theme-content-dark-color);
}
&:hover .icon { color: var(--theme-caption-color); }
}
.step-lr75 + .step-lr75 { margin-left: .75rem; }
.step-tb75 + .step-tb75 { margin-top: .75rem; }
.ml-2 { margin-left: .5rem; }
/* --------- */
.relative { position: relative; }
.abs-lt-content {
position: absolute;
@@ -187,8 +206,16 @@ table {
width: 1.715em;
height: 1.715em;
}
.svg-small, .svg-medium, .svg-large { flex-shrink: 0; }
/* Text */
.fs-title {
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
}
.fs-subtitle { font-size: .75rem; }
.hidden-text {
position: absolute;
visibility: hidden;
@@ -16,7 +16,7 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+1 -1
View File
@@ -16,7 +16,7 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
@@ -16,7 +16,7 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--theme-caption-color)'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
@@ -35,8 +35,8 @@
{#if value.attachments && Object.keys(value.attachments).length > 0}
<Tooltip label={'Attachments (' + Object.values(value.attachments).length + ')'} component={AttachmentPopup} props={{ files: value.attachments }}>
<div class="flex-row-center">
<IconAttachment size="small"/>&nbsp;{Object.keys(value.attachments).length}
<div class="sm-tool-icon">
<span class="icon"><IconAttachment size="small"/></span>{Object.keys(value.attachments).length}
</div>
</Tooltip>
{/if}
@@ -100,11 +100,8 @@
spacePlaceholder={'Select vacancy'}
bind:space={_space}
on:close={() => { dispatch('close') }}>
<svelte:fragment slot="error">
{#if status !== OK}
<StatusControl {status} />
{/if}
</svelte:fragment>
<StatusControl slot="error" {status} />
<Grid column={1} rowGap={1.75}>
{#if !preserveCandidate}
<UserBox _class={recruit.class.Candidate} title='Candidate' caption='Candidates' bind:value={candidate} />
@@ -0,0 +1,169 @@
<!--
// 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, Avatar } from '@anticrm/presentation'
import { showPopup, Label, IconThread, IconAttachment } from '@anticrm/ui'
import type { WithLookup } from '@anticrm/core'
import type { Applicant } from '@anticrm/recruit'
import EditCandidate from './EditCandidate.svelte'
import EditApplication from './EditApplication.svelte'
import { AttachmentPresenter } from '@anticrm/chunter-resources'
import { formatName } from '@anticrm/contact'
export let object: WithLookup<Applicant>
export let draggable: boolean
function showCandidate() {
showPopup(EditCandidate, { _id: object.candidate }, 'full')
}
function showApplication() {
showPopup(EditApplication, { _id: object._id }, 'full')
}
</script>
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
<div class="card-bg" />
<div class="content">
<div class="flex-center">
<div class="avatar">
<Avatar size={'large'} />
</div>
</div>
<div class="flex-col">
<div class="name" on:click={showCandidate}>{formatName(object.$lookup?.candidate?.name)}</div>
<div class="city">{object.$lookup?.candidate?.city ?? ''}</div>
<div class="tags">
<div class="tag" on:click={showApplication}><Label label={'Application'} /></div>
<!-- <div class="tag"><Label label={'Resume'} /></div> -->
</div>
</div>
</div>
<div class="footer">
<Avatar size={'small'} />
<div class="flex-row-center">
<div class="flex-row-center caption-color tool">
<!-- <span class="icon"><IconAttachment size={'small'} /></span>
4 -->
<AttachmentPresenter value={object} />
</div>
<div class="flex-row-center caption-color tool">
<span class="icon"><IconThread size={'small'} /></span>
5
</div>
</div>
</div>
</div>
<style lang="scss">
@import '../node_modules/@anticrm/theme/styles/mixins.scss';
.card-container {
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
border-radius: .75rem;
overflow: hidden;
user-select: none;
backdrop-filter: blur(30px);
.content {
display: flex;
align-items: center;
padding: 1.25rem;
.avatar {
position: relative;
margin-right: 1rem;
width: 5rem;
height: 5rem;
border-radius: 50%;
&::after {
content: '';
@include bg-layer(transparent, .1);
border: 2px solid #fff;
border-radius: 50%;
}
}
.name {
margin: .25rem 0;
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
cursor: pointer;
&:hover { text-decoration: underline; }
}
.city {
font-weight: 500;
font-size: .75rem;
}
.tags {
display: flex;
margin-top: .5rem;
.tag {
position: relative;
display: flex;
align-items: center;
padding: .375rem .5rem;
font-weight: 500;
font-size: .625rem;
text-align: center;
color: var(--theme-caption-color);
cursor: pointer;
&::after {
content: '';
@include bg-layer(#fff, .04);
border-radius: .5rem;
}
}
.tag + .tag { margin-left: .5rem; }
}
}
.footer {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: .75rem 1.25rem;
width: 100%;
min-height: 3rem;
&::after {
content: '';
@include bg-layer(#fff, .04);
z-index: -1;
}
.tool .icon {
margin-right: .25rem;
opacity: .4;
}
.tool + .tool { margin-left: .75rem; }
}
.card-bg {
@include bg-layer(var(--theme-card-bg), .06);
z-index: -1;
}
&.draggable { cursor: grab; }
}
:global(.card-container + .card-container) { margin-top: .75rem; }
</style>
@@ -15,7 +15,7 @@
<script lang="ts">
import { UserInfo, Avatar } from '@anticrm/presentation'
import { showPopup, Label, IconThread, IconAttachment } from '@anticrm/ui'
import { showPopup, Label, IconThread, ActionIcon, IconMoreH, IconFile } from '@anticrm/ui'
import type { WithLookup } from '@anticrm/core'
import type { Applicant } from '@anticrm/recruit'
@@ -38,132 +38,49 @@
</script>
<div class="card-container" {draggable} class:draggable on:dragstart on:dragend>
<div class="card-bg" />
<div class="content">
<div class="flex-center">
<div class="avatar">
<Avatar size={'large'} />
</div>
</div>
<div class="flex-col">
<div class="name" on:click={showCandidate}>{formatName(object.$lookup?.candidate?.name)}</div>
<div class="city">{object.$lookup?.candidate?.city ?? ''}</div>
<div class="tags">
<div class="tag" on:click={showApplication}><Label label={'Application'} /></div>
<!-- <div class="tag"><Label label={'Resume'} /></div> -->
</div>
</div>
</div>
<div class="footer">
<Avatar size={'small'} />
<div class="flex-row-center">
<div class="flex-row-center caption-color tool">
<!-- <span class="icon"><IconAttachment size={'small'} /></span>
4 -->
<AttachmentPresenter value={object} />
<Avatar size={'medium'} />
<div class="flex-col ml-2">
<div class="fs-title"><Label label={formatName(object.$lookup?.candidate?.name)} /></div>
<div class="fs-subtitle"><Label label={formatName(object.$lookup?.candidate?.title)} /></div>
</div>
<div class="flex-row-center caption-color tool">
</div>
<ActionIcon label={'More...'} icon={IconMoreH} size={'small'} />
</div>
<div class="flex-between">
<div class="flex-row-center">
<div class="sm-tool-icon step-lr75" on:click={showApplication}>
<span class="icon"><IconFile size={'small'} /></span>
APP-542
</div>
{#if object.attachments && Object.keys(object.attachments).length > 0}
<div class="step-lr75"><AttachmentPresenter value={object} /></div>
{/if}
<div class="sm-tool-icon step-lr75">
<span class="icon"><IconThread size={'small'} /></span>
5
</div>
</div>
<Avatar size={'x-small'} />
</div>
</div>
<style lang="scss">
@import '../node_modules/@anticrm/theme/styles/mixins.scss';
.card-container {
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
padding: 1rem 1.25rem;
background-color: rgba(222, 222, 240, .06);
border-radius: .75rem;
overflow: hidden;
user-select: none;
backdrop-filter: blur(30px);
backdrop-filter: blur(10px);
.content {
display: flex;
align-items: center;
padding: 1.25rem;
.avatar {
position: relative;
margin-right: 1rem;
width: 5rem;
height: 5rem;
border-radius: 50%;
&::after {
content: '';
@include bg-layer(transparent, .1);
border: 2px solid #fff;
border-radius: 50%;
}
}
.name {
margin: .25rem 0;
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
cursor: pointer;
&:hover { text-decoration: underline; }
}
.city {
font-weight: 500;
font-size: .75rem;
}
.tags {
display: flex;
margin-top: .5rem;
.tag {
position: relative;
display: flex;
align-items: center;
padding: .375rem .5rem;
font-weight: 500;
font-size: .625rem;
text-align: center;
color: var(--theme-caption-color);
cursor: pointer;
&::after {
content: '';
@include bg-layer(#fff, .04);
border-radius: .5rem;
}
}
.tag + .tag { margin-left: .5rem; }
}
}
.footer {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
padding: .75rem 1.25rem;
width: 100%;
min-height: 3rem;
&::after {
content: '';
@include bg-layer(#fff, .04);
z-index: -1;
}
.tool .icon {
margin-right: .25rem;
opacity: .4;
}
.tool + .tool { margin-left: .75rem; }
}
.card-bg {
@include bg-layer(var(--theme-card-bg), .06);
z-index: -1;
margin-bottom: 1rem;
}
&.draggable { cursor: grab; }
}
:global(.card-container + .card-container) { margin-top: .75rem; }
</style>
@@ -23,7 +23,7 @@
export let addAction: () => void | undefined
</script>
<div class="panel-container" on:dragover on:drop>
<div class="panel-container step-lr75" on:dragover on:drop>
<div class="header">
<div class="bar" style="background-color: {color}" />
<div class="flex-between label">
@@ -84,10 +84,8 @@
}
.scroll {
margin: .5rem .75rem .75rem;
margin: 0 .75rem .75rem;
height: 100%;
}
}
:global(.panel-container + .panel-container) { margin-left: .75rem; }
</style>
@@ -21,7 +21,7 @@
export let label: IntlString
</script>
<div class="panel-container">
<div class="panel-container step-lr75">
<div class="circle">
<div class="icon">
<IconAdd size={'large'} />
@@ -178,6 +178,7 @@
{#each objects as object, j}
{#if object.state === state._id}
<div
class="step-tb75"
on:dragover|preventDefault={(ev) => {
dragover(ev, object)
}}