mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-21 07:46:24 +00:00
Update DatePicker. Add and update presenters. Fix Activity layout. (#1162)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
773022cfae
commit
92c9732b52
@ -199,7 +199,10 @@ p:last-child { margin-block-end: 0; }
|
|||||||
line-clamp: 2;
|
line-clamp: 2;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
&.nowrap { white-space: nowrap; }
|
&.nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.action {
|
.action {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
@ -434,6 +434,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
flex-shrink: 0;
|
||||||
width: 2.25rem;
|
width: 2.25rem;
|
||||||
height: 2.25rem;
|
height: 2.25rem;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@ -487,7 +488,24 @@
|
|||||||
margin-left: .75rem;
|
margin-left: .75rem;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.wrap {
|
|
||||||
|
.divider {
|
||||||
|
margin: 0 .125rem;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: .75em;
|
||||||
|
color: var(--theme-content-dark-color);
|
||||||
|
|
||||||
|
&.inter { font-size: 1em; }
|
||||||
|
&.max {
|
||||||
|
margin: 0 .5rem;
|
||||||
|
font-size: .75rem;
|
||||||
|
color: var(--theme-content-trans-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wraps */
|
||||||
|
.antiWrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -511,19 +529,6 @@
|
|||||||
clip-path: path('M0,6h6v-6h-1v5h-5z');
|
clip-path: path('M0,6h6v-6h-1v5h-5z');
|
||||||
}
|
}
|
||||||
&.wraped::before, &.wraped::after { content: ''; }
|
&.wraped::before, &.wraped::after { content: ''; }
|
||||||
}
|
&.focusWI:focus-within::before, &.focusWI:focus-within::after { content: ''; }
|
||||||
|
&.focus:focus::before, &.focus:focus::after { content: ''; }
|
||||||
.divider {
|
|
||||||
margin: 0 .125rem;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: .75em;
|
|
||||||
color: var(--theme-content-dark-color);
|
|
||||||
|
|
||||||
&.inter { font-size: 1em; }
|
|
||||||
&.max {
|
|
||||||
margin: 0 .5rem;
|
|
||||||
font-size: .75rem;
|
|
||||||
color: var(--theme-content-trans-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"string": {
|
"string": {
|
||||||
"EditBoxPlaceholder": "placeholder",
|
"EditBoxPlaceholder": "placeholder",
|
||||||
|
"Ok": "Ok",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
"Minutes": "{minutes, plural, =0 {less than a minute ago} =1 {a minute ago} other {# minutes ago}}",
|
"Minutes": "{minutes, plural, =0 {less than a minute ago} =1 {a minute ago} other {# minutes ago}}",
|
||||||
"Hours": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
|
"Hours": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"string": {
|
"string": {
|
||||||
"EditBoxPlaceholder": "Введите текст здесь",
|
"EditBoxPlaceholder": "Введите текст здесь",
|
||||||
|
"Ok": "Ок",
|
||||||
"Cancel": "Отменить",
|
"Cancel": "Отменить",
|
||||||
"Minutes": "{minutes, plural, =0 {меньше минуты назад} =1 {минуту назад} other {# минут назад}}",
|
"Minutes": "{minutes, plural, =0 {меньше минуты назад} =1 {минуту назад} other {# минут назад}}",
|
||||||
"Hours": "{hours, plural, =0 {меньше часа назад} =1 {час назад} other {# часов назад}}",
|
"Hours": "{hours, plural, =0 {меньше часа назад} =1 {час назад} other {# часов назад}}",
|
||||||
|
@ -30,9 +30,10 @@
|
|||||||
export let width: string | undefined = undefined
|
export let width: string | undefined = undefined
|
||||||
export let focus: boolean = false
|
export let focus: boolean = false
|
||||||
|
|
||||||
let input: HTMLButtonElement
|
export let input: HTMLButtonElement | undefined = undefined
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (focus) {
|
if (focus && input) {
|
||||||
input.focus()
|
input.focus()
|
||||||
focus = false
|
focus = false
|
||||||
}
|
}
|
||||||
|
@ -22,40 +22,29 @@
|
|||||||
|
|
||||||
export let title: IntlString
|
export let title: IntlString
|
||||||
export let value: Date | null | undefined = null
|
export let value: Date | null | undefined = null
|
||||||
export let range: Date | null | undefined = undefined
|
export let withTime: boolean = false
|
||||||
export let bigDay: boolean = false
|
export let bigDay: boolean = false
|
||||||
export let show: boolean = false
|
export let show: boolean = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let opened: boolean = false
|
let opened: boolean = false
|
||||||
let secondSelect: boolean = false
|
|
||||||
let container: HTMLElement
|
let container: HTMLElement
|
||||||
let btn: HTMLElement
|
let btn: HTMLElement
|
||||||
|
|
||||||
|
const changeValue = (result: any): void => {
|
||||||
|
if (result !== undefined) {
|
||||||
|
value = result
|
||||||
|
dispatch('change', result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (btn && show) {
|
if (btn && show) {
|
||||||
btn.click()
|
btn.click()
|
||||||
show = false
|
show = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const splitRes = (result: any): void => {
|
|
||||||
if (result !== undefined) {
|
|
||||||
if (result[0] !== value) value = result[0]
|
|
||||||
if (result[1] !== range) range = result[1]
|
|
||||||
dispatch('change', [value, range])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const onClosePopup = (result: any): void => {
|
|
||||||
splitRes(result)
|
|
||||||
opened = false
|
|
||||||
secondSelect = false
|
|
||||||
}
|
|
||||||
const onUpdatePopup = (result: any): void => {
|
|
||||||
secondSelect = true
|
|
||||||
splitRes(result)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="antiSelect"
|
<div class="antiSelect"
|
||||||
@ -64,7 +53,10 @@
|
|||||||
btn.focus()
|
btn.focus()
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
opened = true
|
opened = true
|
||||||
showPopup(DatePopup, { title, value, range }, container, onClosePopup, onUpdatePopup)
|
showPopup(DatePopup, { title, value, withTime }, container, (ev) => {
|
||||||
|
changeValue(ev)
|
||||||
|
opened = false
|
||||||
|
}, changeValue)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -81,13 +73,7 @@
|
|||||||
<div class="group">
|
<div class="group">
|
||||||
<span class="label"><Label label={title} /></span>
|
<span class="label"><Label label={title} /></span>
|
||||||
{#if value !== undefined}
|
{#if value !== undefined}
|
||||||
<div class="flex-row-center">
|
<DatePresenter {value} withTime={withTime} {bigDay} wraped={opened} />
|
||||||
<DatePresenter {value} {bigDay} wraped={opened && !secondSelect} />
|
|
||||||
{#if range !== undefined}
|
|
||||||
<span class="divider max"> — </span>
|
|
||||||
<DatePresenter value={range} {bigDay} wraped={opened && secondSelect} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{:else}
|
{:else}
|
||||||
<span class="result not-selected"><Label label={ui.string.NotSelected} /></span>
|
<span class="result not-selected"><Label label={ui.string.NotSelected} /></span>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
import Back from './icons/Back.svelte'
|
import Back from './icons/Back.svelte'
|
||||||
import Forward from './icons/Forward.svelte'
|
import Forward from './icons/Forward.svelte'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import ui, { Label } from '..'
|
import ui, { Label, Button } from '..'
|
||||||
import type { TSelectDate, TCellStyle, ICell } from '../types'
|
import type { TSelectDate, TCellStyle, ICell } from '../types'
|
||||||
|
|
||||||
export let title: IntlString
|
export let title: IntlString
|
||||||
export let value: TSelectDate = null
|
export let value: TSelectDate
|
||||||
export let range: TSelectDate = undefined
|
export let withTime: boolean = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
@ -55,8 +55,12 @@
|
|||||||
]
|
]
|
||||||
let monthYear: string
|
let monthYear: string
|
||||||
let days: Array<ICell> = []
|
let days: Array<ICell> = []
|
||||||
let firstClick: boolean = true
|
let result: TSelectDate = value
|
||||||
let result: Array<TSelectDate> = [value, range]
|
let prevDiv: HTMLElement
|
||||||
|
let nextDiv: HTMLElement
|
||||||
|
let hourDiv: HTMLElement
|
||||||
|
let minDiv: HTMLElement
|
||||||
|
let okDiv: HTMLButtonElement
|
||||||
|
|
||||||
const daysInMonth = (date: Date): number => {
|
const daysInMonth = (date: Date): number => {
|
||||||
return 33 - new Date(date.getFullYear(), date.getMonth(), 33).getDate()
|
return 33 - new Date(date.getFullYear(), date.getMonth(), 33).getDate()
|
||||||
@ -69,12 +73,7 @@
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const getDateStyle = (date: Date): TCellStyle => {
|
const getDateStyle = (date: Date): TCellStyle => {
|
||||||
if (value !== undefined && value !== null && compareDates(value, date)) return 'selected-start'
|
if (value !== undefined && value !== null && compareDates(value, date)) return 'selected'
|
||||||
else if (value && value < date && range) {
|
|
||||||
if (range && compareDates(range, date)) return 'selected-end'
|
|
||||||
else if (date < range) return 'selected'
|
|
||||||
else return 'not-selected'
|
|
||||||
}
|
|
||||||
return 'not-selected'
|
return 'not-selected'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,14 +93,56 @@
|
|||||||
|
|
||||||
$: monthYear = months[view.getMonth()] + ' ' + view.getFullYear()
|
$: monthYear = months[view.getMonth()] + ' ' + view.getFullYear()
|
||||||
$: if (value) renderCellStyles()
|
$: if (value) renderCellStyles()
|
||||||
$: if (range) renderCellStyles()
|
|
||||||
|
const zeroLead = (n: number): string => {
|
||||||
|
if (n < 10) return '0' + n.toString()
|
||||||
|
return n.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyPress = (ev: KeyboardEvent, isHour: boolean): void => {
|
||||||
|
if (ev.key >= '0' && ev.key <= '9') {
|
||||||
|
const keyNumber: number = parseInt(ev.key, 10)
|
||||||
|
let number: number = isHour ? view.getHours() : view.getMinutes()
|
||||||
|
let newNumber: number = ((isHour && number > 2) || (!isHour && number > 5))
|
||||||
|
? keyNumber
|
||||||
|
: number * 10 + keyNumber
|
||||||
|
|
||||||
|
if (isHour) {
|
||||||
|
if (newNumber > 23) newNumber = 23
|
||||||
|
view.setHours(newNumber)
|
||||||
|
} else {
|
||||||
|
if (newNumber > 59) newNumber = 59
|
||||||
|
view.setMinutes(newNumber)
|
||||||
|
}
|
||||||
|
view = view
|
||||||
|
value = view
|
||||||
|
if (isHour && newNumber > 9) minDiv.focus()
|
||||||
|
if (!isHour && newNumber > 9) okDiv.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyDown = (ev: KeyboardEvent, isHour: boolean): void => {
|
||||||
|
if (ev.key === 'Backspace') {
|
||||||
|
console.log('BACKSPACE')
|
||||||
|
if (isHour) view.setHours(0)
|
||||||
|
else view.setMinutes(0)
|
||||||
|
view = view
|
||||||
|
value = view
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const navKey = (ev: KeyboardEvent): void => {
|
||||||
|
if (ev.code === 'ArrowLeft') prevDiv.click()
|
||||||
|
if (ev.code === 'ArrowRight') nextDiv.click()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:keydown={navKey} />
|
||||||
<div class="popup">
|
<div class="popup">
|
||||||
<div class="flex-col caption-color">
|
<div class="flex-col caption-color">
|
||||||
<div class="title"><Label label={title} /></div>
|
<div class="title"><Label label={title} /></div>
|
||||||
<div class="flex-between nav">
|
<div class="flex-between nav">
|
||||||
<button
|
<button
|
||||||
|
bind:this={prevDiv}
|
||||||
class="focused-button arrow"
|
class="focused-button arrow"
|
||||||
on:click|preventDefault={() => {
|
on:click|preventDefault={() => {
|
||||||
view.setMonth(view.getMonth() - 1)
|
view.setMonth(view.getMonth() - 1)
|
||||||
@ -112,6 +153,7 @@
|
|||||||
{monthYear}
|
{monthYear}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
bind:this={nextDiv}
|
||||||
class="focused-button arrow"
|
class="focused-button arrow"
|
||||||
on:click|preventDefault={() => {
|
on:click|preventDefault={() => {
|
||||||
view.setMonth(view.getMonth() + 1)
|
view.setMonth(view.getMonth() + 1)
|
||||||
@ -136,26 +178,45 @@
|
|||||||
data-today={day.today ? todayString : ''}
|
data-today={day.today ? todayString : ''}
|
||||||
style="grid-column: {day.dayOfWeek}/{day.dayOfWeek + 1};"
|
style="grid-column: {day.dayOfWeek}/{day.dayOfWeek + 1};"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (firstClick) {
|
result = new Date(view.getFullYear(), view.getMonth(), i + 1, view.getHours(), view.getMinutes())
|
||||||
result[0] = new Date(view.getFullYear(), view.getMonth(), i + 1)
|
view = value = result
|
||||||
value = result[0]
|
if (withTime) {
|
||||||
firstClick = false
|
dispatch('update', result)
|
||||||
if (result[1] === undefined) dispatch('close', result)
|
hourDiv.focus()
|
||||||
else dispatch('update', result)
|
} else dispatch('close', result)
|
||||||
} else {
|
|
||||||
result[1] = new Date(view.getFullYear(), view.getMonth(), i + 1)
|
|
||||||
if (result[0] && result[1] && result[0].getTime() > result[1].getTime())
|
|
||||||
[result[0], result[1]] = [result[1], result[0]]
|
|
||||||
value = result[0]
|
|
||||||
range = result[1]
|
|
||||||
dispatch('close', result)
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i + 1}
|
{i + 1}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{#if withTime}
|
||||||
|
<div class="calendar-divider" />
|
||||||
|
<div class="flex-row-center flex-reverse">
|
||||||
|
<div class="ml-2">
|
||||||
|
<Button bind:input={okDiv} label={ui.string.Ok} size={'small'} primary on:click={() => { dispatch('close', view) }} />
|
||||||
|
</div>
|
||||||
|
<div class="time-container">
|
||||||
|
<button
|
||||||
|
bind:this={hourDiv}
|
||||||
|
class="time-digit antiWrapper focus hours"
|
||||||
|
on:keypress={(ev) => { keyPress(ev, true) }}
|
||||||
|
on:keydown={(ev) => { keyDown(ev, true) }}
|
||||||
|
>
|
||||||
|
{zeroLead(view.getHours())}
|
||||||
|
</button>
|
||||||
|
<div class="time-divider">:</div>
|
||||||
|
<button
|
||||||
|
bind:this={minDiv}
|
||||||
|
class="time-digit antiWrapper focus minutes"
|
||||||
|
on:keypress={(ev) => { keyPress(ev, false) }}
|
||||||
|
on:keydown={(ev) => { keyDown(ev, false) }}
|
||||||
|
>
|
||||||
|
{zeroLead(view.getMinutes())}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -215,16 +276,10 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: var(--primary-button-disabled);
|
|
||||||
border-color: transparent;
|
|
||||||
color: var(--theme-content-accent-color);
|
|
||||||
|
|
||||||
&-start, &-end {
|
|
||||||
background-color: var(--primary-button-enabled);
|
background-color: var(--primary-button-enabled);
|
||||||
border-color: var(--primary-button-focused-border);
|
border-color: var(--primary-button-focused-border);
|
||||||
color: var(--primary-button-color);
|
color: var(--primary-button-color);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
&.today {
|
&.today {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-color: var(--theme-content-color);
|
border-color: var(--theme-content-color);
|
||||||
@ -245,4 +300,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-divider {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: .5rem 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--theme-menu-divider);
|
||||||
|
}
|
||||||
|
.time-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid var(--theme-button-border-enabled);
|
||||||
|
border-radius: .75rem;
|
||||||
|
}
|
||||||
|
.time-digit, .time-divider {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.time-divider {
|
||||||
|
margin: 0 .5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--theme-content-dark-color);
|
||||||
|
}
|
||||||
|
.time-digit {
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--theme-caption-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -19,13 +19,19 @@
|
|||||||
export let value: TSelectDate
|
export let value: TSelectDate
|
||||||
export let bigDay: boolean = false
|
export let bigDay: boolean = false
|
||||||
export let wraped: boolean = false
|
export let wraped: boolean = false
|
||||||
|
export let withTime: boolean = false
|
||||||
|
|
||||||
const { currentLanguage } = getContext('lang')
|
const { currentLanguage } = getContext('lang')
|
||||||
let inter: boolean = (currentLanguage === 'ru') ?? false
|
let inter: boolean = (currentLanguage === 'ru') ?? false
|
||||||
|
|
||||||
|
const zeroLead = (n: number): string => {
|
||||||
|
if (n < 10) return '0' + n.toString()
|
||||||
|
return n.toString()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value !== undefined}
|
{#if value !== undefined}
|
||||||
<div class="wrap" class:wraped>
|
<div class="antiWrapper" class:wraped>
|
||||||
<span class="result" class:selected={value !== null} class:not-selected={value === null} class:highlight={inter && bigDay}>
|
<span class="result" class:selected={value !== null} class:not-selected={value === null} class:highlight={inter && bigDay}>
|
||||||
{#if value === null}--{:else}{inter ? value.getDate() : value.getMonth() + 1}{/if}
|
{#if value === null}--{:else}{inter ? value.getDate() : value.getMonth() + 1}{/if}
|
||||||
</span>
|
</span>
|
||||||
@ -37,5 +43,15 @@
|
|||||||
<span class="result" class:selected={value !== null} class:not-selected={value === null}>
|
<span class="result" class:selected={value !== null} class:not-selected={value === null}>
|
||||||
{#if value === null}--{:else}{value.getFullYear()}{/if}
|
{#if value === null}--{:else}{value.getFullYear()}{/if}
|
||||||
</span>
|
</span>
|
||||||
|
{#if withTime}
|
||||||
|
<span class="divider max"> — </span>
|
||||||
|
<span class="result" class:selected={value !== null} class:not-selected={value === null} class:highlight={!inter && bigDay}>
|
||||||
|
{#if value === null}--{:else}{zeroLead(value.getHours())}{/if}
|
||||||
|
</span>
|
||||||
|
<span class="divider">:</span>
|
||||||
|
<span class="result" class:selected={value !== null} class:not-selected={value === null}>
|
||||||
|
{#if value === null}--{:else}{zeroLead(value.getMinutes())}{/if}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
24
packages/ui/src/components/DateTimePresenter.svelte
Normal file
24
packages/ui/src/components/DateTimePresenter.svelte
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!--
|
||||||
|
// Copyright © 2020 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 { TSelectDate } from '../types'
|
||||||
|
import DatePresenter from './DatePresenter.svelte'
|
||||||
|
|
||||||
|
export let value: TSelectDate
|
||||||
|
export let bigDay: boolean = false
|
||||||
|
export let wraped: boolean = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DatePresenter {value} {bigDay} {wraped} withTime />
|
@ -75,7 +75,7 @@
|
|||||||
<Icon {icon} size={'small'}/>
|
<Icon {icon} size={'small'}/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="wrap">
|
<div class="antiWrapper focusWI">
|
||||||
{#if format === 'password'}
|
{#if format === 'password'}
|
||||||
<input bind:this={input} type='passsword' bind:value placeholder={phTraslate} {style} on:input={(ev) => ev.target && computeSize(ev.target)} on:change/>
|
<input bind:this={input} type='passsword' bind:value placeholder={phTraslate} {style} on:input={(ev) => ev.target && computeSize(ev.target)} on:change/>
|
||||||
{:else if format === 'number'}
|
{:else if format === 'number'}
|
||||||
@ -94,28 +94,6 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrap {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after, &::before {
|
|
||||||
position: absolute;
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
background-color: var(--primary-button-enabled);
|
|
||||||
}
|
|
||||||
&::before {
|
|
||||||
top: -2px;
|
|
||||||
left: -4px;
|
|
||||||
clip-path: path('M0,6v-6h6v1h-5v5z');
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
bottom: -2px;
|
|
||||||
right: -4px;
|
|
||||||
clip-path: path('M0,6h6v-6h-1v5h-5z');
|
|
||||||
}
|
|
||||||
&:focus-within::before, &:focus-within::after { content: ''; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
margin-bottom: .25rem;
|
margin-bottom: .25rem;
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
||||||
import { IntlString, translate } from '@anticrm/platform'
|
import { translate } from '@anticrm/platform'
|
||||||
import { ticker } from '..'
|
import { ticker } from '..'
|
||||||
import ui from '../plugin'
|
import ui from '../plugin'
|
||||||
import Tooltip from './Tooltip.svelte'
|
import Tooltip from './Tooltip.svelte'
|
||||||
|
@ -47,6 +47,7 @@ export { default as Section } from './components/Section.svelte'
|
|||||||
export { default as DatePicker } from './components/DatePicker.svelte'
|
export { default as DatePicker } from './components/DatePicker.svelte'
|
||||||
export { default as DatePopup } from './components/DatePopup.svelte'
|
export { default as DatePopup } from './components/DatePopup.svelte'
|
||||||
export { default as DatePresenter } from './components/DatePresenter.svelte'
|
export { default as DatePresenter } from './components/DatePresenter.svelte'
|
||||||
|
export { default as DateTimePresenter } from './components/DateTimePresenter.svelte'
|
||||||
export { default as StylishEdit } from './components/StylishEdit.svelte'
|
export { default as StylishEdit } from './components/StylishEdit.svelte'
|
||||||
export { default as Grid } from './components/Grid.svelte'
|
export { default as Grid } from './components/Grid.svelte'
|
||||||
export { default as Row } from './components/Row.svelte'
|
export { default as Row } from './components/Row.svelte'
|
||||||
|
@ -26,6 +26,7 @@ export const uiId = 'ui' as Plugin
|
|||||||
export default plugin(uiId, {
|
export default plugin(uiId, {
|
||||||
string: {
|
string: {
|
||||||
EditBoxPlaceholder: '' as IntlString,
|
EditBoxPlaceholder: '' as IntlString,
|
||||||
|
Ok: '' as IntlString,
|
||||||
Cancel: '' as IntlString,
|
Cancel: '' as IntlString,
|
||||||
Minutes: '' as IntlString,
|
Minutes: '' as IntlString,
|
||||||
Hours: '' as IntlString,
|
Hours: '' as IntlString,
|
||||||
|
@ -88,7 +88,7 @@ export interface DropdownTextItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type TSelectDate = Date | null | undefined
|
export type TSelectDate = Date | null | undefined
|
||||||
export type TCellStyle = 'not-selected' | 'selected' | 'selected-start' | 'selected-end'
|
export type TCellStyle = 'not-selected' | 'selected'
|
||||||
export interface ICell {
|
export interface ICell {
|
||||||
dayOfWeek: number
|
dayOfWeek: number
|
||||||
style: TCellStyle
|
style: TCellStyle
|
||||||
|
@ -20,23 +20,27 @@
|
|||||||
<div class="flex-row-center flex-grow flex-wrap content">
|
<div class="flex-row-center flex-grow flex-wrap content">
|
||||||
{#each filterTx([tx, ...tx.txes], core.class.TxCreateDoc) as ctx, i}
|
{#each filterTx([tx, ...tx.txes], core.class.TxCreateDoc) as ctx, i}
|
||||||
{#if i === 0}
|
{#if i === 0}
|
||||||
<div class="mr-1"><IconAdd size={'small'} /></div>
|
<div class="mr-2"><IconAdd size={'small'} /></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<div class="mr-2">
|
||||||
{#if typeof viewlet?.component === 'string'}
|
{#if typeof viewlet?.component === 'string'}
|
||||||
<Component is={viewlet?.component} props={getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
<Component is={viewlet?.component} props={getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
||||||
{:else}
|
{:else}
|
||||||
<svelte:component this={viewlet?.component} {...getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
<svelte:component this={viewlet?.component} {...getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#each filterTx([tx, ...tx.txes], core.class.TxRemoveDoc) as ctx, i}
|
{#each filterTx([tx, ...tx.txes], core.class.TxRemoveDoc) as ctx, i}
|
||||||
{#if i === 0}
|
{#if i === 0}
|
||||||
<div class="mr-1"><IconDelete size={'small'} /></div>
|
<div class="mr-2"><IconDelete size={'small'} /></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<div class="mr-2">
|
||||||
{#if typeof viewlet?.component === 'string'}
|
{#if typeof viewlet?.component === 'string'}
|
||||||
<Component is={viewlet?.component} props={getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
<Component is={viewlet?.component} props={getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
||||||
{:else}
|
{:else}
|
||||||
<svelte:component this={viewlet?.component} {...getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
<svelte:component this={viewlet?.component} {...getProps(getDTxProps(ctx), edit)} on:close={onCancelEdit} />
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -46,6 +50,6 @@
|
|||||||
color: var(--theme-caption-color);
|
color: var(--theme-caption-color);
|
||||||
background: var(--theme-bg-accent-color);
|
background: var(--theme-bg-accent-color);
|
||||||
border: 1px solid var(--theme-bg-accent-color);
|
border: 1px solid var(--theme-bg-accent-color);
|
||||||
border-radius: 0.75rem;
|
border-radius: .75rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -103,6 +103,8 @@
|
|||||||
class="channels {length}"
|
class="channels {length}"
|
||||||
class:one={displayItems?.length === 1}
|
class:one={displayItems?.length === 1}
|
||||||
class:reverse
|
class:reverse
|
||||||
|
class:small-gap={size === 'small'}
|
||||||
|
class:normal-gap={size !== 'small'}
|
||||||
>
|
>
|
||||||
{#each displayItems as item,i}
|
{#each displayItems as item,i}
|
||||||
<div class='channel-item'>
|
<div class='channel-item'>
|
||||||
@ -131,9 +133,5 @@
|
|||||||
&.reverse { grid-auto-flow: dense; }
|
&.reverse { grid-auto-flow: dense; }
|
||||||
&.small-gap { gap: .25rem; }
|
&.small-gap { gap: .25rem; }
|
||||||
&.normal-gap { gap: .5rem; }
|
&.normal-gap { gap: .5rem; }
|
||||||
|
|
||||||
.channel-item {
|
|
||||||
margin: 0.125rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -28,8 +28,13 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={onClick}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={onClick}
|
||||||
|
>
|
||||||
<div class="icon"><Company size={'small'} /></div>
|
<div class="icon"><Company size={'small'} /></div>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -29,10 +29,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={onClick}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, Hierarchy.mixinOrClass(value)].join('|'))}"
|
||||||
|
on:click={onClick}
|
||||||
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Avatar size={'x-small'} avatar={value.avatar} />
|
<Avatar size={'x-small'} avatar={value.avatar} />
|
||||||
</div>
|
</div>
|
||||||
<span class="label">{formatName(value.name)}</span>
|
<span class="label">{formatName(value.name)}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -29,8 +29,13 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={show}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
<div class="icon"><Icon icon={inventory.icon.Products} size={'small'} /></div>
|
<div class="icon"><Icon icon={inventory.icon.Products} size={'small'} /></div>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -20,14 +20,23 @@
|
|||||||
import lead from '../plugin'
|
import lead from '../plugin'
|
||||||
|
|
||||||
export let value: Lead
|
export let value: Lead
|
||||||
|
export let inline: boolean = false
|
||||||
|
|
||||||
function show () {
|
async function show () {
|
||||||
showPanel(view.component.EditDoc, value._id, value._class, 'full')
|
showPanel(view.component.EditDoc, value._id, value._class, 'full')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="sm-tool-icon" on:click={show}>
|
<a
|
||||||
<span class="icon"><Icon icon={lead.icon.Lead} size={'small'} /></span>{value.title}
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
|
<div class="icon">
|
||||||
|
<Icon icon={lead.icon.Lead} size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
|
<span class="label">{value.title}</span>
|
||||||
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -74,7 +74,6 @@
|
|||||||
"ReviewShortLabel": "RVE",
|
"ReviewShortLabel": "RVE",
|
||||||
"StartDate": "Start date",
|
"StartDate": "Start date",
|
||||||
"DueDate": "Due date",
|
"DueDate": "Due date",
|
||||||
"Period": "Period",
|
|
||||||
"ReviewCategoryTitle":"Category",
|
"ReviewCategoryTitle":"Category",
|
||||||
"Verdict": "Verdict",
|
"Verdict": "Verdict",
|
||||||
"OpinionSave": "Save",
|
"OpinionSave": "Save",
|
||||||
|
@ -75,7 +75,6 @@
|
|||||||
"ReviewShortLabel": "RVE",
|
"ReviewShortLabel": "RVE",
|
||||||
"StartDate": "Дата начала",
|
"StartDate": "Дата начала",
|
||||||
"DueDate": "Дата конца",
|
"DueDate": "Дата конца",
|
||||||
"Period": "Период",
|
|
||||||
"ReviewCategoryTitle":"Категория",
|
"ReviewCategoryTitle":"Категория",
|
||||||
"Verdict": "Вердикт",
|
"Verdict": "Вердикт",
|
||||||
"OpinionSave": "Сохранить",
|
"OpinionSave": "Сохранить",
|
||||||
|
@ -33,10 +33,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value && shortLabel}
|
{#if value && shortLabel}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={show}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Application} size={'small'} />
|
<Icon icon={recruit.icon.Application} size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
<span class="label nowrap">{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}</span>
|
<span class="label nowrap">{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -28,10 +28,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value}
|
{#if value}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={show}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([recruit.component.EditVacancy, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Vacancy} size={'small'} />
|
<Icon icon={recruit.icon.Vacancy} size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
<span class="label">{value.name}</span>
|
<span class="label">{value.name}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -155,6 +155,7 @@
|
|||||||
allowDeselect
|
allowDeselect
|
||||||
titleDeselect={recruit.string.UnAssignRecruiter}
|
titleDeselect={recruit.string.UnAssignRecruiter}
|
||||||
/>
|
/>
|
||||||
<DatePicker title={recruit.string.Period} bind:value={startDate} bind:range={dueDate} />
|
<DatePicker title={recruit.string.StartDate} bind:value={startDate} withTime />
|
||||||
|
<DatePicker title={recruit.string.DueDate} bind:value={dueDate} withTime />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -42,10 +42,15 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if value && shortLabel}
|
{#if value && shortLabel}
|
||||||
<div class="flex-presenter" class:inline-presenter={inline} on:click={show}>
|
<a
|
||||||
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={recruit.icon.Application} size={'small'} />
|
<Icon icon={recruit.icon.Application} size={'small'} />
|
||||||
</div>
|
</div>
|
||||||
<span class="label nowrap">{shortLabel}-{value.number}</span>
|
<span class="label nowrap">{shortLabel}-{value.number}</span>
|
||||||
</div>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -100,7 +100,6 @@ export default mergeIds(recruitId, recruit, {
|
|||||||
ReviewShortLabel: '' as IntlString,
|
ReviewShortLabel: '' as IntlString,
|
||||||
StartDate: '' as IntlString,
|
StartDate: '' as IntlString,
|
||||||
DueDate: '' as IntlString,
|
DueDate: '' as IntlString,
|
||||||
Period: '' as IntlString,
|
|
||||||
CandidateReviews: '' as IntlString,
|
CandidateReviews: '' as IntlString,
|
||||||
Participants: '' as IntlString,
|
Participants: '' as IntlString,
|
||||||
NoParticipants: '' as IntlString,
|
NoParticipants: '' as IntlString,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
import task from '../plugin'
|
import task from '../plugin'
|
||||||
|
|
||||||
export let value: Issue
|
export let value: Issue
|
||||||
|
export let inline: boolean = false
|
||||||
|
|
||||||
const client = getClient()
|
const client = getClient()
|
||||||
const shortLabel = client.getHierarchy().getClass(value._class).shortLabel
|
const shortLabel = client.getHierarchy().getClass(value._class).shortLabel
|
||||||
@ -30,6 +31,16 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="sm-tool-icon" on:click={show}>
|
{#if value && shortLabel}
|
||||||
<span class="icon"><Icon icon={task.icon.Task} size={'small'} /></span>{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}
|
<a
|
||||||
</div>
|
class="flex-presenter"
|
||||||
|
class:inline-presenter={inline}
|
||||||
|
href="#{encodeURIComponent([view.component.EditDoc, value._id, value._class].join('|'))}"
|
||||||
|
on:click={show}
|
||||||
|
>
|
||||||
|
<div class="icon">
|
||||||
|
<Icon icon={task.icon.Task} size={'small'} />
|
||||||
|
</div>
|
||||||
|
<span class="label nowrap">{#if shortLabel}<Label label={shortLabel} />-{/if}{value.number}</span>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user