Skip to content

Commit

Permalink
feat(polls): allow to update drafts
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
  • Loading branch information
Antreesy committed Jan 27, 2025
1 parent cb35184 commit 814c089
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
<span class="poll-card__header poll-card__header--draft">
<IconPoll class="poll-card__header-icon" :size="20" />
<span class="poll-card__header-name">{{ name }}</span>
<NcButton v-if="canEditPollDraft"
type="tertiary"
:title="t('spreed', 'Edit poll draft')"
:aria-label="t('spreed', 'Edit poll draft')"
@click.stop="editDraft">
<template #icon>
<IconPencil :size="20" />
</template>
</NcButton>
<NcButton type="tertiary"
:title="t('spreed', 'Delete poll draft')"
:aria-label="t('spreed', 'Delete poll draft')"
Expand Down Expand Up @@ -50,13 +59,15 @@
import { vIntersectionObserver as IntersectionObserver } from '@vueuse/components'

import IconDelete from 'vue-material-design-icons/Delete.vue'
import IconPencil from 'vue-material-design-icons/Pencil.vue'
import IconPoll from 'vue-material-design-icons/Poll.vue'

import { t, n } from '@nextcloud/l10n'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'

import { POLL } from '../../../../../constants.js'
import { hasTalkFeature } from '../../../../../services/CapabilitiesManager.ts'
import { usePollsStore } from '../../../../../stores/polls.ts'

export default {
Expand All @@ -65,6 +76,7 @@ export default {
components: {
NcButton,
IconDelete,
IconPencil,
IconPoll,
},

Expand Down Expand Up @@ -127,6 +139,10 @@ export default {
: t('spreed', 'Poll')
}
},

canEditPollDraft() {
return this.draft && hasTalkFeature(this.token, 'edit-draft-poll')
}
},

methods: {
Expand All @@ -142,7 +158,11 @@ export default {
},

openDraft() {
this.$emit('click', this.id)
this.$emit('click', { id: this.id, action: 'fill' })
},

editDraft() {
this.$emit('click', { id: this.id, action: 'edit' })
},

deleteDraft() {
Expand Down
10 changes: 6 additions & 4 deletions src/components/PollViewer/PollDraftHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@click="openPollEditor" />
</div>
<template v-if="!props.editorOpened" #actions>
<NcButton @click="openPollEditor(null)">
<NcButton @click="openPollEditor({ id: null, action: 'fill' })">
{{ t('spreed', 'Create new poll') }}
</NcButton>
</template>
Expand Down Expand Up @@ -73,10 +73,12 @@ const pollDraftsLoaded = computed(() => pollsStore.draftsLoaded(props.token))

/**
* Opens poll editor pre-filled from the draft
* @param id poll draft ID
* @param payload method payload
* @param payload.id poll draft ID
* @param payload.action required action ('fill' from draft or 'edit' draft)
*/
function openPollEditor(id: number | null) {
EventBus.emit('poll-editor-open', { id, fromDrafts: !props.editorOpened, selector: props.container })
function openPollEditor({ id, action } : { id: number | null, action?: string }) {
EventBus.emit('poll-editor-open', { id, fromDrafts: !props.editorOpened, action, selector: props.container })
}
</script>

Expand Down
34 changes: 30 additions & 4 deletions src/components/PollViewer/PollEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->

<template>
<NcDialog :name="t('spreed', 'Create new poll')"
<NcDialog :name="dialogName"
:close-on-click-outside="!isFilled"
:container="container"
v-on="$listeners"
Expand Down Expand Up @@ -102,7 +102,7 @@
{{ t('spreed', 'Export draft to file') }}
</NcActionLink>
</NcActions>
<NcButton type="primary" :disabled="!isFilled" @click="createPoll">
<NcButton type="primary" :disabled="!isFilled" @click="handleSubmit">
{{ createPollLabel }}
</NcButton>
</template>
Expand Down Expand Up @@ -157,6 +157,7 @@ const store = useStore()
const pollsStore = usePollsStore()

const isOpenedFromDraft = ref(false)
const editingDraftId = ref<number | null>(null)
const pollOption = ref(null)
const pollImport = ref(null)

Expand All @@ -168,7 +169,14 @@ const pollForm = reactive<createPollParams>({
})

const isFilled = computed(() => Boolean(pollForm.question) && pollForm.options.filter(option => Boolean(option)).length >= 2)
const dialogName = computed(() => {
return editingDraftId.value ? t('spreed', 'Edit poll draft') : t('spreed', 'Create new poll')
})
const createPollLabel = computed(() => {
if (editingDraftId.value) {
return t('spreed', 'Save')
}

return store.getters.getToken() !== props.token
? t('spreed', 'Create poll in {name}', { name: store.getters.conversation(props.token).displayName },
undefined, { escape: false, sanitize: false })
Expand Down Expand Up @@ -217,7 +225,20 @@ function addOption() {
/**
* Post a poll into conversation
*/
async function createPoll() {
async function handleSubmit() {
if (editingDraftId.value) {
await pollsStore.updatePollDraft({
token: props.token,
pollId: editingDraftId.value,
form: pollForm,
})
openPollDraftHandler()
nextTick(() => {
emit('close')
})
return
}

const poll = await pollsStore.createPoll({
token: props.token,
form: pollForm,
Expand All @@ -231,12 +252,17 @@ async function createPoll() {
* Pre-fills form from the draft
* @param id poll draft ID
* @param fromDrafts whether editor was opened from drafts handler
* @param action required action ('fill' from draft or 'edit' draft)
*/
function fillPollEditorFromDraft(id: number | null, fromDrafts: boolean) {
function fillPollEditorFromDraft(id: number | null, fromDrafts: boolean, action?: string) {
if (fromDrafts) {
// Show 'Back' button, do not reset until closed
isOpenedFromDraft.value = true
}
if (action === 'edit') {
// Show Edit interface
editingDraftId.value = id
}

if (id && pollsStore.drafts[props.token][id]) {
fillPollForm(pollsStore.drafts[props.token][id])
Expand Down
5 changes: 3 additions & 2 deletions src/components/PollViewer/PollManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,14 @@ function openPollDraftHandler({ selector }: Events['poll-drafts-open']) {
* @param payload event payload
* @param payload.id poll draft ID to fill form with (null for empty form)
* @param payload.fromDrafts whether editor was opened from PollDraftHandler dialog
* @param payload.action required action ('fill' from draft or 'edit' draft)
* @param [payload.selector] selector to mount dialog to (body by default)
*/
function openPollEditor({ id, fromDrafts, selector }: Events['poll-editor-open']) {
function openPollEditor({ id, fromDrafts, action, selector }: Events['poll-editor-open']) {
container.value = selector
showPollEditor.value = true
nextTick(() => {
pollEditorRef.value?.fillPollEditorFromDraft(id, fromDrafts)
pollEditorRef.value?.fillPollEditorFromDraft(id, fromDrafts, action)
// Wait for editor to be mounted and filled before unmounting drafts dialog to avoid issues when inserting nodes
showPollDraftHandler.value = false
})
Expand Down
2 changes: 1 addition & 1 deletion src/services/EventBus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type Events = Record<EventType, unknown> & {
'joined-conversation': { token: string },
'message-height-changed': { heightDiff: number },
'poll-drafts-open': { selector?: string },
'poll-editor-open': { id: number | null, fromDrafts: boolean, selector?: string },
'poll-editor-open': { id: number | null, fromDrafts: boolean, action?: string, selector?: string },
'refresh-peer-list': void,
'retry-message': number,
'route-change': { from: Route, to: Route },
Expand Down

0 comments on commit 814c089

Please sign in to comment.