Skip to content

Commit

Permalink
[wip] feat: use drafts via frontend
Browse files Browse the repository at this point in the history
[skip ci]

Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
  • Loading branch information
Antreesy committed Oct 11, 2024
1 parent 06413e0 commit 5ad83f9
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 26 deletions.
73 changes: 70 additions & 3 deletions src/components/NewMessage/NewMessagePollEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@
:close-on-click-outside="!isFilled"
v-on="$listeners"
@update:open="emit('close')">
<!-- Draft imports -->
<div v-if="supportPollDrafts && isModerator" class="poll-editor__wrapper">
<NcSelect v-model="selectedDraft"
class="poll-editor__select"
name="poll_drafts_select"
label="question"
:options="pollDrafts"
:input-label="t('spreed', 'Choose poll from drafts:')"
:placeholder="t('spreed', 'Select a draft')"
:loading="!pollsStore.drafts[props.token]" />
</div>

<!-- Poll Question -->
<p class="poll-editor__caption">
{{ t('spreed', 'Question') }}
Expand Down Expand Up @@ -58,6 +70,9 @@
<NcButton type="tertiary" @click="emit('close')">
{{ t('spreed', 'Dismiss') }}
</NcButton>
<NcButton type="secondary" :disabled="!isFilled" @click="createPollDraft">
{{ t('spreed', 'Save as draft') }}
</NcButton>
<NcButton type="primary" :disabled="!isFilled" @click="createPoll">
{{ t('spreed', 'Create poll') }}
</NcButton>
Expand All @@ -66,19 +81,23 @@
</template>

<script setup lang="ts">
import { computed, nextTick, reactive, ref } from 'vue'
import { computed, nextTick, reactive, ref, watch } from 'vue'
import Close from 'vue-material-design-icons/Close.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import { showSuccess } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import { useStore } from '../../composables/useStore.js'
import { POLL } from '../../constants.js'
import { hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import { usePollsStore } from '../../stores/polls.ts'
import type { createPollParams } from '../../types/index.ts'
Expand All @@ -89,16 +108,20 @@ const emit = defineEmits<{
(event: 'close'): void,
}>()
const supportPollDrafts = hasTalkFeature(props.token, 'talk-polls-drafts')
const store = useStore()
const pollsStore = usePollsStore()
const pollOption = ref(null)
const pollForm = reactive<createPollParams>({
const POLL_FORM: createPollParams = {
question: '',
options: ['', ''],
resultMode: POLL.MODE.PUBLIC,
maxVotes: POLL.ANSWER_TYPE.SINGLE,
})
}
const pollForm = reactive({ ...POLL_FORM })
const isFilled = computed(() => !!pollForm.question || pollForm.options.some(option => option))
Expand All @@ -120,6 +143,17 @@ const isMultipleAnswer = computed({
}
})
/**
* Receive poll drafts for the current conversation as owner/moderator
*/
const isModerator = computed(() => (store.getters as unknown).isModerator)
if (supportPollDrafts && isModerator.value) {
pollsStore.getPollDrafts(props.token)
}
const pollDrafts = computed(() => supportPollDrafts ? pollsStore.getDrafts(props.token) : [])
const selectedDraft = ref(null)
watch(selectedDraft, (value) => fillPollForm(value !== null ? value : { ...POLL_FORM }))
/**
* Remove a previously added option
* @param index option index
Expand Down Expand Up @@ -150,6 +184,29 @@ async function createPoll() {
emit('close')
}
}
/**
* Insert data into form fields
* @param payload data to fill with
*/
function fillPollForm(payload: createPollParams) {
for (const key of Object.keys(pollForm)) {
pollForm[key] = payload[key]
}
}
/**
* Saves a poll draft for this conversation
*/
async function createPollDraft() {
const poll = await pollsStore.createPollDraft({
token: props.token,
form: pollForm,
})
if (poll) {
showSuccess(t('spreed', 'Poll draft has been saved'))
}
}
</script>

<style lang="scss" scoped>
Expand All @@ -160,6 +217,16 @@ async function createPoll() {
color: var(--color-primary-element);
}
&__wrapper {
display: flex;
align-items: flex-end;
gap: var(--default-grid-baseline);
}
&__select {
width: 100%;
}
&__option {
display: flex;
align-items: flex-end;
Expand Down
64 changes: 41 additions & 23 deletions src/components/PollViewer/PollViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@
@click="modalPage = 'voting'">
{{ t('spreed', 'Change your vote') }}
</NcButton>
<!-- End poll button-->
<NcActions v-if="canEndPoll" force-menu>
<NcActionButton @click="createPollDraft">
<template #icon>
<IconFileEdit :size="20" />
</template>
{{ t('spreed', 'Save as draft') }}
</NcActionButton>
<NcActionButton class="critical" @click="endPoll">
{{ t('spreed', 'End poll') }}
<template #icon>
Expand All @@ -81,17 +86,27 @@
</NcActionButton>
</NcActions>
</div>
<div v-else-if="selfIsOwnerOrModerator" class="poll-modal__actions">
<NcButton type="tertiary" @click="createPollDraft">
<template #icon>
<IconFileEdit :size="20" />
</template>
{{ t('spreed', 'Save as draft') }}
</NcButton>
</div>
</div>
<NcLoadingIcon v-else class="poll-modal__loading" />
</NcModal>
</template>

<script>
import { ref } from 'vue'
import { computed, ref } from 'vue'
import IconFileEdit from 'vue-material-design-icons/FileEdit.vue'
import FileLock from 'vue-material-design-icons/FileLock.vue'
import PollIcon from 'vue-material-design-icons/Poll.vue'
import { showSuccess } from '@nextcloud/dialogs'
import { t, n } from '@nextcloud/l10n'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
Expand Down Expand Up @@ -124,6 +139,7 @@ export default {
PollVotersDetails,
// icons
FileLock,
IconFileEdit,
PollIcon,
},
Expand All @@ -133,37 +149,29 @@ export default {
const loading = ref(false)
const dialogHeaderId = `guest-welcome-header-${useId()}`
const pollsStore = usePollsStore()
const activePoll = computed(() => pollsStore.activePoll)
const name = computed(() => activePoll.value?.name)
const id = computed(() => activePoll.value?.id)
const token = computed(() => activePoll.value?.token)
const poll = computed(() => pollsStore.getPoll(token.value, id.value))
return {
isInCall: useIsInCall(),
pollsStore: usePollsStore(),
pollsStore,
voteToSubmit,
modalPage,
loading,
dialogHeaderId,
name,
id,
token,
poll,
}
},
computed: {
activePoll() {
return this.pollsStore.activePoll
},
name() {
return this.activePoll?.name
},
id() {
return this.activePoll?.id
},
token() {
return this.activePoll?.token
},
poll() {
return this.pollsStore.getPoll(this.token, this.id)
},
selfHasVoted() {
return this.poll?.votedSelf?.length > 0
},
Expand Down Expand Up @@ -324,6 +332,16 @@ export default {
this.loading = false
},
async createPollDraft() {
const poll = await this.pollsStore.createPollDraft({
token: this.token,
form: this.poll,
})
if (poll) {
showSuccess(t('spreed', 'Poll draft has been saved'))
}
},
selfHasVotedOption(index) {
return this.poll?.votedSelf.includes(index)
},
Expand Down

0 comments on commit 5ad83f9

Please sign in to comment.