mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 16:56:07 +00:00
HR: Update Schedule layout. Fix tooltip and popup. (#2388)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
3ae814cf21
commit
23b4987998
@ -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; }
|
||||||
|
@ -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 => {
|
||||||
|
@ -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 {
|
||||||
|
@ -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} />
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user