HR: Update Schedule layout. Fix tooltip and popup. (#2388)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2022-11-22 14:37:44 +03:00 committed by GitHub
parent 3ae814cf21
commit 23b4987998
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 142 additions and 94 deletions

View File

@ -120,6 +120,10 @@ p:last-child { margin-block-end: 0; }
} }
} }
.text-center { text-align: center; }
.firstLetter span::first-letter { text-transform: uppercase; }
.inline-height2 { .inline-height2 {
line-height: 200%; line-height: 200%;
} }
@ -198,6 +202,12 @@ input.search {
flex-wrap: nowrap; flex-wrap: nowrap;
min-height: 0; min-height: 0;
} }
.flex-col-reverse {
display: flex;
flex-direction: column-reverse;
flex-wrap: nowrap;
min-height: 0;
}
.flex-col-center { .flex-col-center {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -516,6 +526,7 @@ input.search {
.min-h-2 { min-height: .5rem; } .min-h-2 { min-height: .5rem; }
.min-h-7 { min-height: 1.75rem; } .min-h-7 { min-height: 1.75rem; }
.min-h-60 { min-height: 15rem; } .min-h-60 { min-height: 15rem; }
.max-w-9 { max-width: 2.25rem; }
.max-w-30 { max-width: 7.5rem; } .max-w-30 { max-width: 7.5rem; }
.max-w-60 { max-width: 15rem; } .max-w-60 { max-width: 15rem; }
.max-w-80 { max-width: 20rem; } .max-w-80 { max-width: 20rem; }

View File

@ -36,7 +36,6 @@
let asideFloat: boolean = false let asideFloat: boolean = false
let asideShown: boolean = false let asideShown: boolean = false
let fullSize: boolean = false let fullSize: boolean = false
let twoRows: boolean = false
$: twoRows = $deviceInfo.minWidth $: twoRows = $deviceInfo.minWidth
const checkPanel = (): void => { const checkPanel = (): void => {

View File

@ -225,6 +225,7 @@ export interface FadeOptions {
} }
export const defaultSP: FadeOptions = { multipler: { top: 0, bottom: 0 } } export const defaultSP: FadeOptions = { multipler: { top: 0, bottom: 0 } }
export const tableSP: FadeOptions = { offset: { top: true }, multipler: { top: 2.5, bottom: 0 } } export const tableSP: FadeOptions = { offset: { top: true }, multipler: { top: 2.5, bottom: 0 } }
export const tableHRscheduleY: FadeOptions = { offset: { top: true }, multipler: { top: 5, bottom: 0 } }
export const issueSP: FadeOptions = { offset: { top: true }, multipler: { top: 3, bottom: 0 } } export const issueSP: FadeOptions = { offset: { top: true }, multipler: { top: 3, bottom: 0 } }
export interface DeviceOptions { export interface DeviceOptions {

View File

@ -18,7 +18,15 @@
import { Ref } from '@hcengineering/core' import { Ref } from '@hcengineering/core'
import { Department } from '@hcengineering/hr' import { Department } from '@hcengineering/hr'
import { createQuery, SpaceSelector } from '@hcengineering/presentation' import { createQuery, SpaceSelector } from '@hcengineering/presentation'
import { Button, Icon, IconBack, IconForward, Label } from '@hcengineering/ui' import {
Button,
Icon,
IconBack,
IconForward,
Label,
deviceOptionsStore as deviceInfo,
TabList
} from '@hcengineering/ui'
import view from '@hcengineering/view' import view from '@hcengineering/view'
import hr from '../plugin' import hr from '../plugin'
import ScheduleMonthView from './ScheduleView.svelte' import ScheduleMonthView from './ScheduleView.svelte'
@ -66,81 +74,108 @@
month: 'long' month: 'long'
}).format(date) }).format(date)
} }
$: twoRows = $deviceInfo.twoRows
const handleSelect = (result: any) => {
if (result.type === 'select') {
const res = result.detail
if (res.id === 'ModeMonth') mode = CalendarMode.Month
else if (res.id === 'ModeYear') mode = CalendarMode.Year
}
}
</script> </script>
<div class="ac-header full divide"> <div class="ac-header divide {twoRows ? 'flex-col-reverse' : 'full'} withSettings">
<div class="ac-header__wrap-title"> <div class="ac-header__wrap-title" class:mt-2={twoRows}>
<div class="ac-header__icon"><Icon icon={calendar.icon.Calendar} size={'small'} /></div> {#if !twoRows}
<span class="ac-header__title"><Label label={hr.string.Schedule} /></span> <div class="ac-header__icon"><Icon icon={calendar.icon.Calendar} size={'small'} /></div>
<div class="flex gap-2 ml-6"> <span class="ac-header__title"><Label label={hr.string.Schedule} /></span>
<Button {:else}
size={'small'} <div class="fs-title mr-4 flex-row-center flex-grow firstLetter">
label={calendar.string.ModeMonth} {#if mode === CalendarMode.Month}
on:click={() => { <span class="mr-2 overflow-label">{getMonthName(currentDate)}</span>
mode = CalendarMode.Month {/if}
}} {currentDate.getFullYear()}
/>
<Button
size={'small'}
label={calendar.string.ModeYear}
on:click={() => {
mode = CalendarMode.Year
}}
/>
<div class="flex ml-4 gap-2">
<Button
icon={IconBack}
size={'small'}
on:click={() => {
inc(-1)
}}
/>
<Button
size={'small'}
label={calendar.string.Today}
on:click={() => {
currentDate = new Date()
}}
/>
<Button
icon={IconForward}
size={'small'}
on:click={() => {
inc(1)
}}
/>
</div> </div>
{/if}
<div class="flex-row-center gap-2 flex-no-shrink" class:ml-6={!twoRows}>
<TabList
items={[
{ id: 'ModeMonth', labelIntl: calendar.string.ModeMonth },
{ id: 'ModeYear', labelIntl: calendar.string.ModeYear }
]}
multiselect={false}
size={'small'}
on:select={handleSelect}
/>
<div class="buttons-divider" />
<Button
icon={IconBack}
size={'small'}
kind={'link-bordered'}
on:click={() => {
inc(-1)
}}
/>
<Button
size={'small'}
label={calendar.string.Today}
kind={'link-bordered'}
on:click={() => {
currentDate = new Date()
}}
/>
<Button
icon={IconForward}
size={'small'}
kind={'link-bordered'}
on:click={() => {
inc(1)
}}
/>
</div> </div>
<div class="fs-title ml-4 flex-row-center"> {#if !twoRows}
{#if mode === CalendarMode.Month} <div class="fs-title ml-4 flex-row-center firstLetter">
{getMonthName(currentDate)} {#if mode === CalendarMode.Month}
{/if} <span class="overflow-label mr-2">{getMonthName(currentDate)}</span>
{currentDate.getFullYear()} {/if}
</div> {currentDate.getFullYear()}
</div>
{/if}
</div> </div>
{#if mode === CalendarMode.Month} <div class="ac-header__wrap-title {twoRows ? 'mt-1' : 'ml-4'}">
<div class="flex ml-4 gap-2"> {#if twoRows}
<Button <div class="ac-header__icon flex-center"><Icon icon={calendar.icon.Calendar} size={'small'} /></div>
icon={view.icon.Views} <span class="ac-header__title" class:flex-grow={twoRows}><Label label={hr.string.Schedule} /></span>
selected={display === 'chart'} {/if}
size={'small'} <div class="flex-row-center gap-2">
on:click={() => { {#if mode === CalendarMode.Month}
display = 'chart' <Button
}} icon={view.icon.Views}
/> selected={display === 'chart'}
<Button size={'small'}
size={'small'} on:click={() => {
icon={view.icon.Table} display = 'chart'
selected={display === 'stats'} }}
on:click={() => { />
display = 'stats' <Button
}} size={'small'}
icon={view.icon.Table}
selected={display === 'stats'}
on:click={() => {
display = 'stats'
}}
/>
{/if}
<SpaceSelector
_class={hr.class.Department}
label={hr.string.Department}
bind:space={department}
kind={'secondary'}
/> />
</div> </div>
{/if} </div>
<SpaceSelector _class={hr.class.Department} label={hr.string.Department} bind:space={department} />
</div> </div>
<ScheduleMonthView {department} {descendants} departmentById={departments} {currentDate} {mode} {display} /> <ScheduleMonthView {department} {descendants} departmentById={departments} {currentDate} {mode} {display} />

View File

@ -15,7 +15,7 @@
<script lang="ts"> <script lang="ts">
import hr, { Request, RequestType } from '@hcengineering/hr' import hr, { Request, RequestType } from '@hcengineering/hr'
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { getPlatformColor, Icon, showPopup } from '@hcengineering/ui' import { closeTooltip, getPlatformColor, Icon, showPopup } from '@hcengineering/ui'
import { ContextMenu } from '@hcengineering/view-resources' import { ContextMenu } from '@hcengineering/view-resources'
export let requests: Request[] export let requests: Request[]
@ -42,6 +42,7 @@
if (!editable) return if (!editable) return
e.stopPropagation() e.stopPropagation()
e.preventDefault() e.preventDefault()
closeTooltip()
showPopup(ContextMenu, { object: request }, e.target as HTMLElement) showPopup(ContextMenu, { object: request }, e.target as HTMLElement)
} }
</script> </script>

View File

@ -112,7 +112,7 @@
</script> </script>
{#if departmentStaff.length} {#if departmentStaff.length}
<Scroller fade={tableSP}> <Scroller fade={tableSP} horizontal>
<table> <table>
<thead class="scroller-thead"> <thead class="scroller-thead">
<tr class="scroller-thead__tr"> <tr class="scroller-thead__tr">
@ -149,13 +149,13 @@
<EmployeePresenter value={employee} /> <EmployeePresenter value={employee} />
</td> </td>
<td <td
class="flex-center p-1 whitespace-nowrap" class="flex-center p-1 whitespace-nowrap text-center"
class:firstLine={row === 0} class:firstLine={row === 0}
class:lastLine={row === departmentStaff.length - 1} class:lastLine={row === departmentStaff.length - 1}
> >
{getTotal(requests, startDate.getMonth(), types)} {getTotal(requests, startDate.getMonth(), types)}
</td> </td>
<td class="p-1"> <td class="p-1 text-center">
{#if rTime !== undefined} {#if rTime !== undefined}
{rTime.value} {rTime.value}
{:else} {:else}
@ -170,6 +170,7 @@
{@const ww = findReports(employee, date, timeReports)} {@const ww = findReports(employee, date, timeReports)}
{#key [tooltipValue, editable]} {#key [tooltipValue, editable]}
<td <td
class="w-9 max-w-9 min-w-9"
class:today={areDatesEqual(todayDate, date)} class:today={areDatesEqual(todayDate, date)}
class:weekend={isWeekend(date)} class:weekend={isWeekend(date)}
class:cursor-pointer={editable} class:cursor-pointer={editable}
@ -211,7 +212,6 @@
td, td,
th { th {
width: auto;
width: 2rem; width: 2rem;
min-width: 1.5rem; min-width: 1.5rem;
border: none; border: none;

View File

@ -17,7 +17,7 @@
import contact from '@hcengineering/contact-resources/src/plugin' import contact from '@hcengineering/contact-resources/src/plugin'
import { Ref } from '@hcengineering/core' import { Ref } from '@hcengineering/core'
import type { Request, RequestType, Staff } from '@hcengineering/hr' import type { Request, RequestType, Staff } from '@hcengineering/hr'
import { Label, LabelAndProps, Scroller, tableSP, tooltip } from '@hcengineering/ui' import { Label, LabelAndProps, Scroller, tableHRscheduleY, tooltip } from '@hcengineering/ui'
import hr from '../../plugin' import hr from '../../plugin'
import { fromTzDate, getMonth, getTotal, weekDays } from '../../utils' import { fromTzDate, getMonth, getTotal, weekDays } from '../../utils'
import RequestsPopup from '../RequestsPopup.svelte' import RequestsPopup from '../RequestsPopup.svelte'
@ -67,7 +67,7 @@
</script> </script>
{#if departmentStaff.length} {#if departmentStaff.length}
<Scroller fade={tableSP}> <Scroller fade={tableHRscheduleY} horizontal>
<table> <table>
<thead class="scroller-thead"> <thead class="scroller-thead">
<tr class="scroller-thead__tr"> <tr class="scroller-thead__tr">
@ -77,7 +77,7 @@
{#each values as value, i} {#each values as value, i}
{@const month = getMonth(currentDate, value)} {@const month = getMonth(currentDate, value)}
<th <th
class="fixed" class="fixed first-row"
class:today={month.getFullYear() === todayDate.getFullYear() && month.getMonth() === todayDate.getMonth()} class:today={month.getFullYear() === todayDate.getFullYear() && month.getMonth() === todayDate.getMonth()}
on:mousemove={() => { on:mousemove={() => {
hoveredIndex = i hoveredIndex = i
@ -91,7 +91,7 @@
{/each} {/each}
</tr> </tr>
<tr> <tr>
<th class="fixed"> <th class="fixed last-row">
<span class="flex-center"> <span class="flex-center">
{departmentStaff.length} {departmentStaff.length}
</span> </span>
@ -99,7 +99,7 @@
{#each values as value, i} {#each values as value, i}
{@const month = getMonth(currentDate, value)} {@const month = getMonth(currentDate, value)}
<th <th
class="fixed" class="fixed last-row"
class:today={month.getFullYear() === todayDate.getFullYear() && month.getMonth() === todayDate.getMonth()} class:today={month.getFullYear() === todayDate.getFullYear() && month.getMonth() === todayDate.getMonth()}
> >
<span class="flex-center"> <span class="flex-center">
@ -111,8 +111,8 @@
</thead> </thead>
<tbody> <tbody>
{#each departmentStaff as employee, row} {#each departmentStaff as employee, row}
<tr> <tr class="tr-body">
<td> <td class="td-body">
<EmployeePresenter value={employee} /> <EmployeePresenter value={employee} />
</td> </td>
{#each values as value, i} {#each values as value, i}
@ -123,7 +123,7 @@
<td <td
class:today={month.getFullYear() === todayDate.getFullYear() && class:today={month.getFullYear() === todayDate.getFullYear() &&
month.getMonth() === todayDate.getMonth()} month.getMonth() === todayDate.getMonth()}
class="fixed" class="fixed td-body"
use:tooltip={tooltipValue} use:tooltip={tooltipValue}
> >
<div class="flex-center"> <div class="flex-center">
@ -146,14 +146,15 @@
<style lang="scss"> <style lang="scss">
table { table {
position: relative; position: relative;
border-collapse: separate;
width: 100%; width: 100%;
td, td,
th { th {
width: auto; padding: 0 0.5rem;
width: 2rem; width: 2.25rem;
min-width: 1.5rem; min-width: 2.25rem;
border: none; border: 1px solid var(--accent-bg-color);
&.fixed { &.fixed {
width: 5rem; width: 5rem;
padding: 0 0.125rem; padding: 0 0.125rem;
@ -175,7 +176,7 @@
font-size: 0.75rem; font-size: 0.75rem;
line-height: 105%; line-height: 105%;
color: var(--dark-color); color: var(--dark-color);
box-shadow: inset 0 -1px 0 0 var(--divider-color); border: none;
user-select: none; user-select: none;
cursor: pointer; cursor: pointer;
@ -195,15 +196,15 @@
&.today { &.today {
background-color: var(--theme-bg-accent-hover); background-color: var(--theme-bg-accent-hover);
} }
&.td-body {
border-bottom: 1px solid var(--divider-color);
&:not(:last-child) {
border-right: 1px solid var(--divider-color);
}
}
} }
td:not(:last-child) { th.last-row {
border-right: 1px solid var(--divider-color);
}
tr:not(.scroller-thead__tr) {
border-bottom: 1px solid var(--divider-color); border-bottom: 1px solid var(--divider-color);
} }
tr.scroller-thead__tr:not(:last-child) {
border-right: 1px solid var(--divider-color);
}
} }
</style> </style>