HR: update values on blur (#2161)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2022-06-29 08:53:57 +03:00 committed by GitHub
parent 8b8c992ff0
commit f90ee0ea5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 63 additions and 94 deletions

View File

@ -16,7 +16,7 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { IntlString, Asset } from '@anticrm/platform' import { IntlString, Asset } from '@anticrm/platform'
import { Label, IconEdit, Button, Icon, IconCheck, IconClose } from '@anticrm/ui' import { Label, Icon } from '@anticrm/ui'
import type { AnySvelteComponent } from '@anticrm/ui' import type { AnySvelteComponent } from '@anticrm/ui'
import StyledTextBox from './StyledTextBox.svelte' import StyledTextBox from './StyledTextBox.svelte'
import textEditorPlugin from '../plugin' import textEditorPlugin from '../plugin'
@ -25,15 +25,14 @@
export let label: IntlString = textEditorPlugin.string.FullDescription export let label: IntlString = textEditorPlugin.string.FullDescription
export let icon: Asset | AnySvelteComponent = IconDescription export let icon: Asset | AnySvelteComponent = IconDescription
export let content: string = '' export let content: string = ''
export let emptyMessage: IntlString = textEditorPlugin.string.NoFullDescription
export let editMode: boolean = false
export let alwaysEdit: boolean = false
export let hideButtons: boolean = false
export let maxHeight: string = '40vh' export let maxHeight: string = '40vh'
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let fullDescription: StyledTextBox const checkValue = (evt: CustomEvent): void => {
const res: string | undefined = evt.detail === null ? undefined : evt.detail
if (content !== res) dispatch('save', res)
}
</script> </script>
<div class="antiSection"> <div class="antiSection">
@ -44,57 +43,6 @@
<span class="antiSection-header__title"> <span class="antiSection-header__title">
<Label {label} /> <Label {label} />
</span> </span>
{#if !hideButtons && !alwaysEdit}
<div class="buttons-group xsmall-gap">
{#if editMode}
<Button
icon={IconClose}
kind={'transparent'}
shape={'circle'}
on:click={() => {
fullDescription.cancelEdit()
editMode = false
}}
/>
<Button
icon={IconCheck}
kind={'transparent'}
shape={'circle'}
on:click={() => {
fullDescription.saveEdit()
editMode = false
}}
/>
{:else}
<Button
icon={IconEdit}
kind={'transparent'}
shape={'circle'}
on:click={() => {
editMode = true
fullDescription.startEdit()
}}
/>
{/if}
</div>
{/if}
</div> </div>
{#if !editMode && (content === '' || content === '<p></p>' || content === undefined) && !alwaysEdit} <StyledTextBox {content} alwaysEdit focusable mode={2} hideExtraButtons {maxHeight} on:value={checkValue} />
<div class="antiSection-empty solid">
<Label label={emptyMessage} />
</div>
{:else}
<StyledTextBox
bind:this={fullDescription}
{content}
{alwaysEdit}
focusable
mode={editMode ? 2 : 1}
hideExtraButtons
{maxHeight}
on:value={(evt) => {
dispatch('change', evt.detail)
}}
/>
{/if}
</div> </div>

View File

@ -36,16 +36,21 @@
mode = Mode.View mode = Mode.View
} }
export function cancelEdit (): void { export function cancelEdit (): void {
rawValue = content
mode = Mode.View mode = Mode.View
} }
let rawValue: string let rawValue: string
let oldContent = '' let oldContent = ''
let modified: boolean = false
$: if (oldContent !== content) { $: if (oldContent !== content) {
oldContent = content oldContent = content
rawValue = content rawValue = content
modified = false
} }
$: if (!modified && rawValue !== content) modified = true
$: dispatch('change', modified)
let textEditor: StyledTextEditor let textEditor: StyledTextEditor

View File

@ -127,6 +127,7 @@
on:change on:change
on:keydown on:keydown
on:keypress on:keypress
on:blur
/> />
{:else if format === 'number'} {:else if format === 'number'}
<input <input
@ -140,6 +141,7 @@
on:change on:change
on:keydown on:keydown
on:keypress on:keypress
on:blur
/> />
{:else} {:else}
<input <input
@ -152,6 +154,7 @@
on:change on:change
on:keydown on:keydown
on:keypress on:keypress
on:blur
/> />
{/if} {/if}
</div> </div>

View File

@ -29,6 +29,8 @@
export let _id: Ref<Funnel> export let _id: Ref<Funnel>
let object: Required<Funnel> let object: Required<Funnel>
let rawName: string = ''
let rawDesc: string = ''
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -40,6 +42,8 @@
function updateObject (_id: Ref<Funnel>): void { function updateObject (_id: Ref<Funnel>): void {
query.query(lead.class.Funnel, { _id }, (result) => { query.query(lead.class.Funnel, { _id }, (result) => {
object = result[0] as Required<Funnel> object = result[0] as Required<Funnel>
rawName = object.name
rawDesc = object.description
}) })
} }
@ -85,13 +89,8 @@
kind={'large-style'} kind={'large-style'}
focus focus
focusable focusable
on:change={() => { on:blur={() => {
if (object.name.trim().length > 0) { if (rawName !== object.name) onChange('name', object.name)
onChange('name', object.name)
} else {
// Revert previos object.name
updateObject(_id)
}
}} }}
/> />
<EditBox <EditBox
@ -99,15 +98,14 @@
placeholder={lead.string.Description} placeholder={lead.string.Description}
maxWidth={'39rem'} maxWidth={'39rem'}
focusable focusable
on:change={() => { on:blur={() => {
onChange('description', object.description) if (rawDesc !== object.description) onChange('description', object.description)
}} }}
/> />
<FullDescriptionBox <FullDescriptionBox
content={object.fullDescription} content={object.fullDescription}
alwaysEdit on:save={(res) => {
on:change={(result) => { onChange('fullDescription', res.detail)
if (result.detail !== undefined) onChange('fullDescription', result.detail)
}} }}
/> />
<Attachments <Attachments

View File

@ -26,6 +26,13 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const client = getClient() const client = getClient()
let oldTitle: string = ''
let rawTitle: string = ''
$: if (oldTitle !== object.title) {
oldTitle = object.title
rawTitle = object.title
}
function change (field: string, value: any) { function change (field: string, value: any) {
client.updateDoc(object._class, object.space, object._id, { [field]: value }) client.updateDoc(object._class, object.space, object._id, { [field]: value })
} }
@ -38,12 +45,14 @@
{#if object !== undefined} {#if object !== undefined}
<Grid column={2} rowGap={1}> <Grid column={2} rowGap={1}>
<EditBox <EditBox
bind:value={object.title} bind:value={rawTitle}
placeholder={lead.string.LeadPlaceholder} placeholder={lead.string.LeadPlaceholder}
kind={'large-style'} kind={'large-style'}
maxWidth={'20rem'} maxWidth={'20rem'}
focusable focusable
on:change={() => change('title', object.title)} on:blur={() => {
if (rawTitle !== object.title) change('title', rawTitle)
}}
/> />
<UserBox <UserBox
_class={contact.class.Contact} _class={contact.class.Contact}

View File

@ -29,6 +29,8 @@
export let _id: Ref<Vacancy> export let _id: Ref<Vacancy>
let object: Required<Vacancy> let object: Required<Vacancy>
let rawName: string = ''
let rawDesc: string = ''
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -40,6 +42,8 @@
function updateObject (_id: Ref<Vacancy>): void { function updateObject (_id: Ref<Vacancy>): void {
query.query(recruit.class.Vacancy, { _id }, (result) => { query.query(recruit.class.Vacancy, { _id }, (result) => {
object = result[0] as Required<Vacancy> object = result[0] as Required<Vacancy>
rawName = object.name
rawDesc = object.description
}) })
} }
@ -85,13 +89,8 @@
kind={'large-style'} kind={'large-style'}
focus focus
focusable focusable
on:change={() => { on:blur={() => {
if (object.name.trim().length > 0) { if (rawName !== object.name) onChange('name', object.name)
onChange('name', object.name)
} else {
// Revert previos object.name
updateObject(_id)
}
}} }}
/> />
<EditBox <EditBox
@ -99,15 +98,14 @@
placeholder={recruit.string.VacancyDescription} placeholder={recruit.string.VacancyDescription}
maxWidth={'39rem'} maxWidth={'39rem'}
focusable focusable
on:change={() => { on:blur={() => {
onChange('description', object.description) if (rawDesc !== object.description) onChange('description', object.description)
}} }}
/> />
<FullDescriptionBox <FullDescriptionBox
content={object.fullDescription} content={object.fullDescription}
alwaysEdit on:save={(res) => {
on:change={(result) => { onChange('fullDescription', res.detail)
if (result.detail !== undefined) onChange('fullDescription', result.detail)
}} }}
/> />
<Attachments <Attachments

View File

@ -29,6 +29,13 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const client = getClient() const client = getClient()
let oldTitle: string = ''
let rawTitle: string = ''
$: if (oldTitle !== object.title) {
oldTitle = object.title
rawTitle = object.title
}
onMount(() => { onMount(() => {
dispatch('open', { dispatch('open', {
ignoreKeys: ['number', 'comments', 'title', 'description', 'verdict'], ignoreKeys: ['number', 'comments', 'title', 'description', 'verdict'],
@ -49,11 +56,13 @@
<Grid column={1} rowGap={1.5}> <Grid column={1} rowGap={1.5}>
<Grid column={2} columnGap={1}> <Grid column={2} columnGap={1}>
<EditBox <EditBox
bind:value={object.title} bind:value={rawTitle}
kind={'large-style'} kind={'large-style'}
maxWidth={'20rem'} maxWidth={'20rem'}
focusable focusable
on:change={() => client.update(object, { title: object.title })} on:blur={() => {
if (rawTitle !== object.title) client.update(object, { title: rawTitle })
}}
/> />
<div <div
class="clear-mins" class="clear-mins"
@ -79,9 +88,8 @@
<FullDescriptionBox <FullDescriptionBox
label={recruit.string.Description} label={recruit.string.Description}
content={object.description} content={object.description}
alwaysEdit on:save={(res) => {
on:value={(evt) => { client.update(object, { description: res.detail })
client.update(object, { description: evt.detail })
}} }}
/> />
<EditBox <EditBox

View File

@ -352,9 +352,9 @@
min-width: 0; min-width: 0;
min-height: 0; min-height: 0;
} }
.grow-cell { // .grow-cell {
flex-grow: 1; // flex-grow: 1;
flex-shrink: 0; // flex-shrink: 0;
min-width: 0; // min-width: 0;
} // }
</style> </style>