Skip to content

Commit

Permalink
Survey plugin tweaks & bug fixes (#8188)
Browse files Browse the repository at this point in the history
* Survey plugin tweaks & bug fixes

Signed-off-by: Victor Ilyushchenko <[email protected]>

* ff

Signed-off-by: Victor Ilyushchenko <[email protected]>

---------

Signed-off-by: Victor Ilyushchenko <[email protected]>
  • Loading branch information
mr1name authored Mar 11, 2025
1 parent f94d8bf commit 248cb26
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 349 deletions.
3 changes: 2 additions & 1 deletion common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions packages/ui/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,23 @@ export class ThrottledCaller {
}
}

/**
* @public
*/
export class DebouncedCaller {
timeout?: any
constructor (readonly delay: number = 50) {}
call (op: () => void): void {
if (this.timeout !== undefined) {
clearTimeout(this.timeout)
}
this.timeout = setTimeout(() => {
op()
this.timeout = undefined
}, this.delay)
}
}

export const testing = (localStorage.getItem('#platform.testing.enabled') ?? 'false') === 'true'

export const rootBarExtensions = writable<
Expand Down
3 changes: 2 additions & 1 deletion plugins/survey-resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@hcengineering/view": "^0.6.13",
"@hcengineering/view-resources": "^0.6.0",
"@hcengineering/ui": "^0.6.15",
"svelte": "^4.2.19"
"svelte": "^4.2.19",
"fast-equals": "^5.2.2"
}
}
26 changes: 12 additions & 14 deletions plugins/survey-resources/src/components/EditPoll.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
//
-->
<script lang="ts">
import { getClient } from '@hcengineering/presentation'
import { Question, QuestionKind, Poll, PollData } from '@hcengineering/survey'
import PollQuestion from './PollQuestion.svelte'
import { Poll, PollData, Question, QuestionKind } from '@hcengineering/survey'
import { createEventDispatcher } from 'svelte'
import { hasText } from '../utils'
import PollQuestion from './PollQuestion.svelte'
const client = getClient()
const dispatch = createEventDispatcher()
export let object: Poll | PollData
export let canSubmit: boolean = false
Expand All @@ -47,16 +47,14 @@
return true
}
function isPreviewMode (): boolean {
return (object as Poll)._id === undefined
function handleChange (patch: Partial<Poll>): void {
dispatch('change', patch)
}
async function saveAnswers (): Promise<void> {
if (isPreviewMode()) {
return
}
const poll = object as Poll
await client.updateDoc(poll._class, poll.space, poll._id, { questions: object.questions })
function handleQuestionChange (index: number, patch: Partial<PollQuestion>): Promise<void> | void {
const questions = (object.questions ?? []).slice()
questions[index] = { ...questions[index], ...patch }
handleChange({ questions })
}
</script>

Expand All @@ -68,13 +66,13 @@
</span>
</div>
{/if}
{#each object.questions ?? [] as question, index}
{#each object.questions ?? [] as question, index (index)}
{#if isQuestionValid(question)}
<PollQuestion
bind:this={questionNodes[index]}
bind:isAnswered={isAnswered[index]}
{readonly}
on:answered={saveAnswers}
on:change={(e) => handleQuestionChange(index, e.detail)}
{question}
/>
{/if}
Expand Down
68 changes: 59 additions & 9 deletions plugins/survey-resources/src/components/EditPollPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,55 @@
<script lang="ts">
import { Ref } from '@hcengineering/core'
import { Panel } from '@hcengineering/panel'
import { MessageBox, createQuery, getClient } from '@hcengineering/presentation'
import { createQuery, getClient } from '@hcengineering/presentation'
import { Poll } from '@hcengineering/survey'
import { Button, IconMoreH, showPopup } from '@hcengineering/ui'
import { Button, DebouncedCaller, IconMoreH, ThrottledCaller } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { DocNavLink, ParentsNavigator, showMenu } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import EditPoll from './EditPoll.svelte'
import { createEventDispatcher, onDestroy } from 'svelte'
import survey from '../plugin'
import EditPoll from './EditPoll.svelte'
const client = getClient()
const dispatch = createEventDispatcher()
const query = createQuery()
const throttle = new ThrottledCaller(250)
const debounce = new DebouncedCaller(1000)
export let _id: Ref<Poll>
export let embedded: boolean = false
export let readonly: boolean = false
let object: Poll | undefined = undefined
interface Patch {
id: number
patch: Partial<Poll>
}
function combinedPatch (patches: Patch[]): Partial<Poll> {
return patches.reduce((r, c) => Object.assign(r, c.patch), {})
}
let patchCounter = 0
let patches: Patch[] = []
let objectState: Poll | undefined = undefined
$: object = objectState ? { ...objectState, ...combinedPatch(patches) } : undefined
let canSubmit = false
let requestUpdate = false
$: isCompleted = object?.isCompleted ?? false
$: editable = (!readonly && !isCompleted) || requestUpdate
$: updateObject(_id)
$: void queryObject(_id)
function updateObject (_id: Ref<Poll>): void {
async function queryObject (_id: Ref<Poll>): Promise<void> {
await flush()
objectState = undefined
patches = []
query.query(survey.class.Poll, { _id }, (result) => {
object = result[0]
objectState = result[0]
})
}
Expand All @@ -68,8 +89,30 @@
// )
await getClient().updateDoc(object._class, object.space, object._id, { isCompleted: true })
}
function handleChange (patch: Partial<Poll>): void {
patches = [...patches, { id: patchCounter++, patch }]
throttle.call(() => {
void flush()
})
}
async function flush (): Promise<void> {
if (!object?._id || patches.length < 1) return
const patchesToApply = patches.slice()
const patchIds = new Set(patchesToApply.map((p) => p.id))
const update: Partial<Poll> = combinedPatch(patchesToApply)
await client.updateDoc(object._class, object.space, object._id, update)
debounce.call(() => {
patches = patches.filter((p) => !patchIds.has(p.id))
})
}
onDestroy(flush)
</script>

<svelte:window on:beforeunload={flush} />
{#if object}
<Panel
isHeader={false}
Expand Down Expand Up @@ -120,7 +163,14 @@
</svelte:fragment>

<div class="flex-col flex-grow flex-no-shrink">
<EditPoll {object} readonly={!editable} bind:canSubmit />
<EditPoll
{object}
readonly={!editable}
bind:canSubmit
on:change={(e) => {
handleChange(e.detail)
}}
/>
</div>
</Panel>
{/if}
Loading

0 comments on commit 248cb26

Please sign in to comment.