Skip to content

Commit

Permalink
feat: allow owners and moderators to export poll to JSON file
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
  • Loading branch information
Antreesy authored and backportbot[bot] committed Oct 21, 2024
1 parent 11691c0 commit f120568
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 8 deletions.
13 changes: 13 additions & 0 deletions src/components/NewMessage/NewMessagePollEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@
</template>
{{ t('spreed', 'Save as draft') }}
</NcActionButton>
<NcActionLink :href="exportPollURI" :download="exportPollFileName">
<template #icon>
<IconFileDownload :size="20" />
</template>
{{ t('spreed', 'Export draft to file') }}
</NcActionLink>
</NcActions>
<NcButton type="primary" :disabled="!isFilled" @click="createPoll">
{{ t('spreed', 'Create poll') }}
Expand All @@ -107,6 +113,7 @@ import { computed, nextTick, reactive, ref } from 'vue'
import IconArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'
import Close from 'vue-material-design-icons/Close.vue'
import IconFileDownload from 'vue-material-design-icons/FileDownload.vue'
import IconFileEdit from 'vue-material-design-icons/FileEdit.vue'
import IconFileUpload from 'vue-material-design-icons/FileUpload.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
Expand All @@ -115,6 +122,7 @@ import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
Expand All @@ -127,6 +135,7 @@ import { hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import { EventBus } from '../../services/EventBus.js'
import { usePollsStore } from '../../stores/polls.ts'
import type { createPollParams } from '../../types/index.ts'
import { convertToJSONDataURI } from '../../utils/fileDownload.ts'
import { validatePollForm } from '../../utils/validatePollForm.ts'
const props = defineProps<{
Expand Down Expand Up @@ -176,6 +185,10 @@ const isMultipleAnswer = computed({
})
const isModerator = computed(() => (store.getters as unknown).isModerator)
const exportPollURI = computed(() => convertToJSONDataURI(pollForm))
const exportPollFileName = `Talk Poll ${new Date().toISOString().slice(0, 10)}`
/**
* Remove a previously added option
* @param index option index
Expand Down
44 changes: 36 additions & 8 deletions src/components/PollViewer/PollViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
</template>
{{ t('spreed', 'Save as draft') }}
</NcActionButton>
<NcActionLink v-if="supportPollDrafts" :href="exportPollURI" :download="exportPollFileName">
<template #icon>
<IconFileDownload :size="20" />
</template>
{{ t('spreed', 'Export draft to file') }}
</NcActionLink>
<NcActionButton class="critical" @click="endPoll">
{{ t('spreed', 'End poll') }}
<template #icon>
Expand All @@ -86,13 +92,21 @@
</NcActionButton>
</NcActions>
</div>
<div v-else-if="supportPollDrafts && isModerator" class="poll-modal__actions">
<NcButton type="tertiary" @click="createPollDraft">
<template #icon>
<IconFileEdit :size="20" />
</template>
{{ t('spreed', 'Save as draft') }}
</NcButton>
<div v-else-if="supportPollDrafts && selfIsOwnerOrModerator" class="poll-modal__actions">
<NcActions force-menu>
<NcActionButton v-if="isModerator" @click="createPollDraft">
<template #icon>
<IconFileEdit :size="20" />
</template>
{{ t('spreed', 'Save as draft') }}
</NcActionButton>
<NcActionLink :href="exportPollURI" :download="exportPollFileName">
<template #icon>
<IconFileDownload :size="20" />
</template>
{{ t('spreed', 'Export draft to file') }}
</NcActionLink>
</NcActions>
</div>
</div>
<NcLoadingIcon v-else class="poll-modal__loading" />
Expand All @@ -102,14 +116,15 @@
<script>
import { computed, ref } from 'vue'
import IconFileDownload from 'vue-material-design-icons/FileDownload.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'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
Expand All @@ -125,13 +140,15 @@ import { POLL } from '../../constants.js'
import { hasTalkFeature } from '../../services/CapabilitiesManager.ts'
import { EventBus } from '../../services/EventBus.js'
import { usePollsStore } from '../../stores/polls.ts'
import { convertToJSONDataURI } from '../../utils/fileDownload.ts'
export default {
name: 'PollViewer',
components: {
NcActions,
NcActionButton,
NcActionLink,
NcCheckboxRadioSwitch,
NcLoadingIcon,
NcModal,
Expand All @@ -140,6 +157,7 @@ export default {
PollVotersDetails,
// icons
FileLock,
IconFileDownload,
IconFileEdit,
PollIcon,
},
Expand All @@ -159,6 +177,14 @@ export default {
const poll = computed(() => pollsStore.getPoll(token.value, id.value))
const supportPollDrafts = computed(() => hasTalkFeature(token.value, 'talk-polls-drafts'))
const exportPollURI = computed(() => convertToJSONDataURI({
question: poll.value.question,
options: poll.value.options,
resultMode: poll.value.resultMode,
maxVotes: poll.value.maxVotes,
}))
const exportPollFileName = `Talk Poll ${new Date().toISOString().slice(0, 10)}`
return {
isInCall: useIsInCall(),
pollsStore,
Expand All @@ -171,6 +197,8 @@ export default {
token,
poll,
supportPollDrafts,
exportPollURI,
exportPollFileName,
}
},
Expand Down
30 changes: 30 additions & 0 deletions src/utils/fileDownload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/**
* Converts given payload to Data URI scheme
* data:[<mediatype>][;base64],<data>
*
* @param payload data to convert
* @param mediatype a MIME type string
* @param base64Token an optional base64 token if non-textual data is given
*/
const convertToDataURI = function(payload: string, mediatype: string = 'text/plain;charset=US-ASCII', base64Token: string = ''): string {
return 'data:' + mediatype + base64Token + ',' + encodeURIComponent(payload)
}

/**
* Converts given JS object to Data URI scheme
*
* @param payload JS object to convert
*/
const convertToJSONDataURI = function(payload: object): string {
return convertToDataURI(JSON.stringify(payload, null, 2), 'application/json;charset=utf-8')
}

export {
convertToDataURI,
convertToJSONDataURI,
}

0 comments on commit f120568

Please sign in to comment.