From d1adf71e57c1ff2b966216745996d82f204b3aa1 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Mon, 2 Oct 2023 15:55:16 +0700 Subject: [PATCH 1/5] UBER-963: Related issues * UBER-963: Related issues * UBER-961: Comment content doesn't fit. * A bit of scroller and resize performance improvements Signed-off-by: Andrey Sobolev --- models/lead/src/index.ts | 20 ++ models/recruit/src/index.ts | 40 +++- packages/theme/styles/popups.scss | 7 + packages/ui/src/components/Lazy.svelte | 31 +-- packages/ui/src/components/Scroller.svelte | 38 ++-- packages/ui/src/components/SelectPopup.svelte | 15 +- .../ui/src/components/TooltipInstance.svelte | 204 +++++++++++++----- packages/ui/src/lazy.ts | 11 +- packages/ui/src/resize.ts | 23 +- packages/ui/src/utils.ts | 18 ++ plugins/recruit-assets/lang/en.json | 1 - plugins/recruit-assets/lang/ru.json | 1 - .../src/components/EditVacancy.svelte | 2 +- .../src/components/Organizations.svelte | 5 +- .../src/components/Vacancies.svelte | 7 +- .../components/VacancyTemplateEditor.svelte | 2 +- plugins/recruit-resources/src/plugin.ts | 1 - plugins/task/src/utils.ts | 2 +- plugins/tracker-assets/lang/en.json | 1 + plugins/tracker-assets/lang/ru.json | 1 + .../issues/edit/SubIssueSelector.svelte | 106 ++++----- .../issues/edit/SubIssuesSelector.svelte | 103 +++++---- .../related/RelatedIssueSelector.svelte | 104 ++++----- plugins/tracker-resources/src/plugin.ts | 1 + plugins/tracker-resources/src/utils.ts | 10 +- .../src/components/EditDoc.svelte | 18 +- .../src/components/Table.svelte | 41 ++-- .../src/components/Workbench.svelte | 10 +- 28 files changed, 536 insertions(+), 287 deletions(-) diff --git a/models/lead/src/index.ts b/models/lead/src/index.ts index 011552ddd65..8bfba3750e0 100644 --- a/models/lead/src/index.ts +++ b/models/lead/src/index.ts @@ -213,6 +213,9 @@ export function createModel (builder: Builder): void { { key: '', presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, label: tracker.string.Relations }, 'comments', @@ -252,6 +255,9 @@ export function createModel (builder: Builder): void { { key: '', presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, label: tracker.string.Issues }, 'status', @@ -551,6 +557,20 @@ export function createModel (builder: Builder): void { filters: ['_class'] }) + builder.mixin(lead.mixin.Customer, core.class.Class, view.mixin.ObjectEditorFooter, { + editor: tracker.component.RelatedIssuesSection, + props: { + label: tracker.string.RelatedIssues + } + }) + + builder.mixin(lead.class.Lead, core.class.Class, view.mixin.ObjectEditorFooter, { + editor: tracker.component.RelatedIssuesSection, + props: { + label: tracker.string.RelatedIssues + } + }) + createAction(builder, { action: workbench.actionImpl.Navigate, actionProps: { diff --git a/models/recruit/src/index.ts b/models/recruit/src/index.ts index 2afccfa4ec1..0e7d0f8fdbb 100644 --- a/models/recruit/src/index.ts +++ b/models/recruit/src/index.ts @@ -407,6 +407,9 @@ export function createModel (builder: Builder): void { { key: '', presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, label: tracker.string.Relations }, 'comments', @@ -487,6 +490,14 @@ export function createModel (builder: Builder): void { label: recruit.string.Applications }, 'comments', + { + key: '', + presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, + label: tracker.string.Issues + }, '$lookup.company', '$lookup.company.$lookup.channels', 'location', @@ -523,6 +534,12 @@ export function createModel (builder: Builder): void { label: recruit.string.Applications }, 'comments', + { + key: '', + presenter: tracker.component.RelatedIssueSelector, + label: tracker.string.Issues, + props: { size: 'small', kind: 'link' } + }, '$lookup.channels', { key: '@applications.modifiedOn', @@ -558,6 +575,9 @@ export function createModel (builder: Builder): void { { key: '', presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, label: tracker.string.Issues }, 'status', @@ -606,6 +626,9 @@ export function createModel (builder: Builder): void { { key: '', presenter: tracker.component.RelatedIssueSelector, + props: { + kind: 'link' + }, label: tracker.string.Issues }, 'status', @@ -864,6 +887,12 @@ export function createModel (builder: Builder): void { props: { kind: 'list', size: 'small', shouldShowName: false } }, { key: 'comments', displayProps: { key: 'comments', suffix: true } }, + { + key: '', + presenter: tracker.component.RelatedIssueSelector, + label: tracker.string.Issues, + props: { size: 'small' } + }, { key: '$lookup.channels', label: contact.string.ContactInfo, @@ -914,6 +943,11 @@ export function createModel (builder: Builder): void { }, 'description', { key: 'comments', displayProps: { key: 'comments', suffix: true } }, + { + key: '', + presenter: tracker.component.RelatedIssueSelector, + label: tracker.string.Issues + }, { key: '', displayProps: { grow: true } }, { key: '$lookup.company', @@ -1601,19 +1635,19 @@ export function createModel (builder: Builder): void { builder.mixin(recruit.mixin.Candidate, core.class.Class, view.mixin.ObjectEditorFooter, { editor: tracker.component.RelatedIssuesSection, props: { - label: recruit.string.RelatedIssues + label: tracker.string.RelatedIssues } }) builder.mixin(recruit.class.Vacancy, core.class.Class, view.mixin.ObjectEditorFooter, { editor: tracker.component.RelatedIssuesSection, props: { - label: recruit.string.RelatedIssues + label: tracker.string.RelatedIssues } }) builder.mixin(recruit.class.Applicant, core.class.Class, view.mixin.ObjectEditorFooter, { editor: tracker.component.RelatedIssuesSection, props: { - label: recruit.string.RelatedIssues + label: tracker.string.RelatedIssues } }) diff --git a/packages/theme/styles/popups.scss b/packages/theme/styles/popups.scss index c81971483f5..6d35bfd4740 100644 --- a/packages/theme/styles/popups.scss +++ b/packages/theme/styles/popups.scss @@ -22,11 +22,18 @@ min-width: 12.5rem; max-width: 17rem; max-height: 22rem; + background: var(--theme-popup-color); border: 1px solid var(--theme-popup-divider); border-radius: .5rem; box-shadow: var(--theme-popup-shadow); + &.noShadow { + background: none; + border: none; + box-shadow: none; + } + &.full-width { flex-grow: 1; background: none; diff --git a/packages/ui/src/components/Lazy.svelte b/packages/ui/src/components/Lazy.svelte index 3dedf80a0c8..17f08cb6e92 100644 --- a/packages/ui/src/components/Lazy.svelte +++ b/packages/ui/src/components/Lazy.svelte @@ -2,27 +2,28 @@ import { createEventDispatcher } from 'svelte' const dispatch = createEventDispatcher() - import { lazyObserver } from '../lazy' + import { lazyObserver, isLazyDisabled } from '../lazy' - let visible = false + let visible = isLazyDisabled() -
{ - if (val) { - visible = true - dispatch('visible') - } - }} -> - {#if visible} - - {:else} +{#if !visible} +
{ + if (val) { + visible = true + dispatch('visible') + unsubscribe?.() + } + }} + > {#if $$slots.loading} {:else} ​ {/if} - {/if} -
+
+{:else} + +{/if} diff --git a/packages/ui/src/components/Scroller.svelte b/packages/ui/src/components/Scroller.svelte index 2c7ba0be150..eb536b10d81 100644 --- a/packages/ui/src/components/Scroller.svelte +++ b/packages/ui/src/components/Scroller.svelte @@ -22,6 +22,7 @@ import IconUpOutline from './icons/UpOutline.svelte' import IconDownOutline from './icons/DownOutline.svelte' import HalfUpDown from './icons/HalfUpDown.svelte' + import { DelayedCaller } from '../utils' export let padding: string | undefined = undefined export let autoscroll: boolean = false @@ -249,20 +250,16 @@ } } - let checkBarTimeout: any | undefined = undefined - let checkHBarTimeout: any | undefined = undefined + const delayedCaller = new DelayedCaller(25) - const delayCall = (op: () => void, h?: boolean) => { - if (h) { - clearTimeout(checkHBarTimeout) - checkHBarTimeout = setTimeout(op, 5) - } else { - clearTimeout(checkBarTimeout) - checkBarTimeout = setTimeout(op, 5) - } + const delayCall = (op: () => void) => { + delayedCaller.call(op) } const checkFade = (): void => { + delayCall(_checkFade) + } + const _checkFade = (): void => { if (divScroll) { beforeContent = divScroll.scrollTop belowContent = divScroll.scrollHeight - divScroll.clientHeight - beforeContent @@ -279,11 +276,18 @@ else if (rightContent > 2) maskH = 'left' else maskH = 'none' } - if (inter.size) checkIntersectionFade() + if (inter.size) { + checkIntersectionFade() + } renderFade() } - if (!isScrolling) delayCall(checkBar) - if (!isScrolling && horizontal) delayCall(checkBarH, true) + + if (!isScrolling) { + checkBar() + } + if (!isScrolling && horizontal) { + checkBarH() + } } function checkAutoScroll () { @@ -383,8 +387,12 @@ if (divScroll && divBox) { divScroll.addEventListener('wheel', wheelEvent) divScroll.addEventListener('scroll', checkFade) - delayCall(checkBar) - if (horizontal) delayCall(checkBarH, true) + delayCall(() => { + checkBar() + if (horizontal) { + checkBarH() + } + }) } }) onDestroy(() => { diff --git a/packages/ui/src/components/SelectPopup.svelte b/packages/ui/src/components/SelectPopup.svelte index 20ddf2c7095..f472e4a5cfd 100644 --- a/packages/ui/src/components/SelectPopup.svelte +++ b/packages/ui/src/components/SelectPopup.svelte @@ -50,6 +50,8 @@ export let value: Array export let width: 'medium' | 'large' | 'full' = 'medium' export let size: 'small' | 'medium' | 'large' = 'small' + export let onSelect: ((value: ValueType['id']) => void) | undefined = undefined + export let showShadow: boolean = true let search: string = '' @@ -60,6 +62,14 @@ let selection = 0 let list: ListView + function sendSelect (id: ValueType['id']): void { + if (onSelect) { + onSelect(value[selection].id) + } else { + dispatch('close', value[selection].id) + } + } + function onKeydown (key: KeyboardEvent): void { if (key.code === 'ArrowUp') { key.stopPropagation() @@ -74,7 +84,7 @@ if (key.code === 'Enter') { key.preventDefault() key.stopPropagation() - dispatch('close', value[selection].id) + sendSelect(value[selection].id) } } const manager = createFocusManager() @@ -88,6 +98,7 @@
{ @@ -121,7 +132,7 @@ > {@const item = filteredObjects[itemId]} -