diff options
author | dartcafe <github@dartcafe.de> | 2022-05-27 22:24:44 +0300 |
---|---|---|
committer | dartcafe <github@dartcafe.de> | 2022-05-27 22:24:44 +0300 |
commit | 54f8ff75da256c3613b473aa50aa3afc7cab8973 (patch) | |
tree | 7fb472690154cdbaff3c77c163e2bb5f4b433a01 /src | |
parent | c6717a07991928c9dd289a7d1d08c9a6e4aeff17 (diff) |
Replacing css icons with md components
Signed-off-by: dartcafe <github@dartcafe.de>
Diffstat (limited to 'src')
23 files changed, 591 insertions, 335 deletions
diff --git a/src/js/assets/scss/icons-md.scss b/src/js/assets/scss/icons-md.scss index 6b53364d..5f49002d 100644 --- a/src/js/assets/scss/icons-md.scss +++ b/src/js/assets/scss/icons-md.scss @@ -22,56 +22,10 @@ } :root { - --icon-md-account-check: url('../icons/material-design/account-check.svg'); - --icon-md-account-group: url('../icons/material-design/account-group.svg'); - --icon-md-account-cog: url('../icons/material-design/account-cog.svg'); - --icon-md-archive: url('../icons/material-design/archive.svg'); - --icon-md-bell: url('../icons/material-design/bell.svg'); - --icon-md-bell-off: url('../icons/material-design/bell-off.svg'); - --icon-md-cancel: url('../icons/material-design/cancel.svg'); - --icon-md-calendar-month: url('../icons/material-design/calendar-month.svg'); - --icon-md-calendar-blank: url('../icons/material-design/calendar-blank.svg'); - --icon-md-calendar-end: url('../icons/material-design/calendar-end.svg'); - --icon-md-check: url('../icons/material-design/check.svg'); - --icon-md-clipboard-arrow-left-outline: url('../icons/material-design/clipboard-arrow-left-outline.svg'); - --icon-md-close: url('../icons/material-design/close.svg'); - --icon-md-clock-outline: url('../icons/material-design/clock-outline.svg'); - --icon-md-checkbox-marked-outline: url('../icons/material-design/checkbox-marked-outline.svg'); - --icon-md-cog: url('../icons/material-design/cog.svg'); - --icon-md-comment-processing: url('../icons/material-design/comment-processing.svg'); - --icon-md-content-copy: url('../icons/material-design/content-copy.svg'); - --icon-md-crown: url('../icons/material-design/crown.svg'); - --icon-md-delete: url('../icons/material-design/delete.svg'); - --icon-md-earth: url('../icons/material-design/earth.svg'); + --icon-md-shield-crown-outline: url('../icons/material-design/shield-crown-outline.svg'); --icon-md-email: url('../icons/material-design/email.svg'); - --icon-md-email-edit-outline: url('../icons/material-design/email-edit-outline.svg'); - --icon-md-exclamation-thick: url('../icons/material-design/exclamation-thick.svg'); - --icon-md-format-list-bulleted-square: url('../icons/material-design/format-list-bulleted-square.svg'); - --icon-md-format-list-checkbox: url('../icons/material-design/format-list-checkbox.svg'); - --icon-md-format-list-numbered: url('../icons/material-design/format-list-numbered.svg'); - --icon-md-format-list-checks: url('../icons/material-design/format-list-checks.svg'); - --icon-md-incognito: url('../icons/material-design/incognito.svg'); - --icon-md-link-variant: url('../icons/material-design/link-variant.svg'); - --icon-md-lock: url('../icons/material-design/lock.svg'); - --icon-md-lock-open-variant: url('../icons/material-design/lock-open-variant.svg'); - --icon-md-key: url('../icons/material-design/key.svg'); - --icon-md-map-clock-outline: url('../icons/material-design/map-clock-outline.svg'); - --icon-md-monitor: url('../icons/material-design/monitor.svg'); - --icon-md-monitor-lock: url('../icons/material-design/monitor-lock.svg'); - --icon-md-monitor-off: url('../icons/material-design/monitor-off.svg'); - --icon-md-offer: url('../icons/material-design/offer.svg'); - --icon-md-poll: url('../icons/material-design/poll.svg'); - --icon-md-polls-maybe: url('../icons/material-design/polls-maybe.svg'); - --icon-md-publish-off: url('../icons/material-design/publish-off.svg'); - --icon-md-recycle: url('../icons/material-design/recycle.svg'); --icon-md-share-variant: url('../icons/material-design/share-variant.svg'); - --icon-md-shield-crown-outline: url('../icons/material-design/shield-crown-outline.svg'); - --icon-md-polls-shield-crown-outline-strike-thru: url('../icons/material-design/polls-shield-crown-outline-strike-thru.svg'); - --icon-md-sort-clock-ascending-outline: url('../icons/material-design/sort-clock-ascending-outline.svg'); - --icon-md-undo: url('../icons/material-design/undo.svg'); - --icon-md-vector-combine: url('../icons/material-design/vector-combine.svg'); - --icon-md-wrench: url('../icons/material-design/wrench.svg'); - + --icon-md-link-variant: url('../icons/material-design/link-variant.svg'); --icon-size: 18px; --icon-md-color-default: #000; @@ -99,80 +53,6 @@ .icon-svg-md-link { @include svg-icon(var(--icon-md-link-variant)); } // mask icons +// UserItem.vue .icon-mask-md-admin { @include masked-icon(var(--icon-md-shield-crown-outline)); } -.icon-mask-md-admin-remove { @include masked-icon(var(--icon-md-shield-crown-outline-strike-thru)); } -.icon-mask-md-anonymous-poll { @include masked-icon(var(--icon-md-incognito)); } -.icon-mask-md-archive-poll { @include masked-icon(var(--icon-md-archive)); } -.icon-mask-md-archived-poll { @include masked-icon(var(--icon-md-archive)); } -.icon-mask-md-clippy { @include masked-icon(var(--icon-md-clipboard-arrow-left-outline)); } -.icon-mask-md-clone-poll { @include masked-icon(var(--icon-md-content-copy)); } -.icon-mask-md-closed-poll { @include masked-icon(var(--icon-md-lock)); } -.icon-mask-md-creation { @include masked-icon(var(--icon-md-clock-outline)); } -.icon-mask-md-date-options { @include masked-icon(var(--icon-md-calendar-month)); } -.icon-mask-md-date-poll { @include masked-icon(var(--icon-md-calendar-blank)); } -.icon-mask-md-delete-poll { @include masked-icon(var(--icon-md-delete)); } -.icon-mask-md-edit-email-address { @include masked-icon(var(--icon-md-email-edit-outline)); } -.icon-mask-md-email { @include masked-icon(var(--icon-md-email)); } -.icon-mask-md-expiration { @include masked-icon(var(--icon-md-calendar-end)); } -.icon-mask-md-hide-results-until-closed { @include masked-icon(var(--icon-md-monitor-lock)); } -.icon-mask-md-navigation-administration { @include masked-icon(var(--icon-md-cog)); } -.icon-mask-md-navigation-all { @include masked-icon(var(--icon-md-poll)); } -.icon-mask-md-navigation-archived { @include masked-icon(var(--icon-md-archive)); } -.icon-mask-md-navigation-closed { @include masked-icon(var(--icon-md-lock)); } -.icon-mask-md-navigation-combo { @include masked-icon(var(--icon-md-vector-combine)); } -.icon-mask-md-navigation-my { @include masked-icon(var(--icon-md-crown)); } -.icon-mask-md-navigation-open { @include masked-icon(var(--icon-md-earth)); } -.icon-mask-md-navigation-participated { @include masked-icon(var(--icon-md-account-check)); } -.icon-mask-md-navigation-personal-settings { @include masked-icon(var(--icon-md-account-cog)); } -.icon-mask-md-navigation-private { @include masked-icon(var(--icon-md-key)); } -.icon-mask-md-navigation-relevant { @include masked-icon(var(--icon-md-exclamation-thick)); } -.icon-mask-md-open-poll { @include masked-icon(var(--icon-md-earth)); } -.icon-mask-md-options { @include masked-icon(var(--icon-md-format-list-checkbox)); } -.icon-mask-md-options-order-date { @include masked-icon(var(--icon-md-sort-clock-ascending-outline)); } -.icon-mask-md-options-order-original { @include masked-icon(var(--icon-md-format-list-bulleted-square)); } -.icon-mask-md-options-order-ranked { @include masked-icon(var(--icon-md-format-list-numbered)); } -.icon-mask-md-owner { @include masked-icon(var(--icon-md-crown)); } -.icon-mask-md-participants { @include masked-icon(var(--icon-md-account-group)); } -.icon-mask-md-private-poll { @include masked-icon(var(--icon-md-key)); } -.icon-mask-md-proposals-allowed { @include masked-icon(var(--icon-md-offer)); } -.icon-mask-md-proposals { @include masked-icon(var(--icon-md-offer)); } -.icon-mask-md-send-link-per-email { @include masked-icon(var(--icon-md-link-variant)); } -.icon-mask-md-show-results { @include masked-icon(var(--icon-md-monitor)); } -.icon-mask-md-show-results-never { @include masked-icon(var(--icon-md-monitor-off)); } -.icon-mask-md-sidebar-comments { @include masked-icon(var(--icon-md-comment-processing)); } -.icon-mask-md-sidebar-configuration { @include masked-icon(var(--icon-md-wrench)); } -.icon-mask-md-sidebar-options { @include masked-icon(var(--icon-md-format-list-checks)); } -.icon-mask-md-sidebar-share { @include masked-icon(var(--icon-md-share-variant)); } -.icon-mask-md-subscribed { @include masked-icon(var(--icon-md-bell)); } -.icon-mask-md-reset-votes { @include masked-icon(var(--icon-md-undo)); } -.icon-mask-md-restore-poll { @include masked-icon(var(--icon-md-recycle)); } -.icon-mask-md-text-poll { @include masked-icon(var(--icon-md-format-list-bulleted-square)); } -.icon-mask-md-timezone { @include masked-icon(var(--icon-md-map-clock-outline)); } -.icon-mask-md-unsubscribed { @include masked-icon(var(--icon-md-bell-off)); } -.icon-mask-md-unpublished-poll { @include masked-icon(var(--icon-md-publish-off)); } - -.icon-mask-md-yes-vote, -.icon-mask-md-yes-votes { - background-color: var(--color-polls-foreground-yes) !important; - @include masked-icon(var(--icon-md-check)); -} - -.icon-mask-md-no-vote, -.icon-mask-md-no-votes { - background-color: var(--color-polls-foreground-no) !important; - @include masked-icon(var(--icon-md-close)); -} -.locked .vote-item.currentuser .icon, -.icon-mask-md-locked-vote { - background-color: var(--color-polls-foreground-no) !important; - @include masked-icon(var(--icon-md-cancel)); - mask-size: 100%; - -webkit-mask-size: 100%; -} - -.icon-mask-md-maybe-vote, -.icon-mask-md-maybe-votes { - background-color: var(--color-polls-foreground-maybe) !important; - @include masked-icon(var(--icon-md-polls-maybe)); -} diff --git a/src/js/components/AppIcons/CirclesAppIcon.vue b/src/js/components/AppIcons/CirclesAppIcon.vue new file mode 100644 index 00000000..10d51961 --- /dev/null +++ b/src/js/components/AppIcons/CirclesAppIcon.vue @@ -0,0 +1,56 @@ +<template> + <span :aria-hidden="!title" + :aria-label="title" + class="material-design-icon circles-app-icon" + role="img" + v-bind="$attrs" + @click="$emit('click', $event)"> + <svg :fill="fillColor" + class="material-design-icon__svg" + :width="size" + :height="size" + viewBox="0 0 57 57"> + <path d="M7.1 28.5A21.4 21.4 0 0 1 28.5 7.1m10.7 40A21.4 21.4 0 0 1 10 39M39.2 10A21.4 21.4 0 0 1 47 39.2" + fill="none" + :stroke="fillcolor" + stroke-width="4" + stroke-linecap="round" + stroke-linejoin="round" /> + <circle cx="28.5" + cy="7.1" + r="6.5" + :fill="fillColor" /> + <circle cx="39.2" + cy="-10" + r="6.5" + transform="rotate(90)" + :fill="fillColor" /> + <circle cx="39.2" + cy="-47" + r="6.5" + transform="rotate(90)" + :fill="fillColor" /> + <title v-if="title">{{ title }}</title> + </svg> + </span> +</template> + +<script> +export default { + name: 'CirclesAppIcon', + props: { + title: { + type: String, + default: 'Circles', + }, + fillColor: { + type: String, + default: 'currentColor', + }, + size: { + type: Number, + default: 24, + }, + }, +} +</script> diff --git a/src/js/components/AppIcons/MaybeIcon.vue b/src/js/components/AppIcons/MaybeIcon.vue new file mode 100644 index 00000000..bfe62844 --- /dev/null +++ b/src/js/components/AppIcons/MaybeIcon.vue @@ -0,0 +1,48 @@ +<template> + <span :aria-hidden="!title" + :aria-label="title" + class="material-design-icon polls-maybe-icon" + role="img" + v-bind="$attrs" + @click="$emit('click', $event)"> + <svg :fill="fillColor" + class="material-design-icon__svg" + :width="size" + :height="size" + viewBox="0 0 16 16"> + <g id="open-brace" + style="font-style:normal;font-weight:normal;font-size:10.03817844px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffc10f;fill-opacity:0.94117647;stroke:none;stroke-width:0.6844213" + transform="matrix(1.2792345,0,0,1.0763308,-0.2918408,-1.3872412)" + aria-label="("> + <path id="path853" style="font-size:9.81086349px;fill:#ffc10f;fill-opacity:0.94117647;stroke-width:0.6844213" d="m 3.7425891,4.3526202 q -0.6419218,1.101806 -0.9533017,2.1796596 -0.31138,1.0778537 -0.31138,2.1844501 0,1.1065964 0.31138,2.1940311 0.3161704,1.082644 0.9533017,2.17966 H 2.9761153 Q 2.2575462,11.964662 1.8982617,10.877228 1.5437676,9.7897931 1.5437676,8.7167299 q 0,-1.0682727 0.3544941,-2.1509169 0.3544941,-1.0826441 1.0778536,-2.2131928 z" /> + </g> + <path id="checkmark" d="M 4.2292965,7.4561992 6.8988209,10.399892 11.770704,5.0276561" style="fill:none;fill-opacity:1;stroke:#ffc10f;stroke-width:1.40162849;stroke-opacity:0.94117647" /> + <g id="close-brace" + style="font-style:normal;font-weight:normal;font-size:10.03817844px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffc10f;fill-opacity:0.94117647;stroke:none;stroke-width:0.6844213" + transform="matrix(-1.2792345,0,0,-1.0763308,-2.4031246,-1.3872405)" + aria-label="("> + <path id="path856" style="font-size:9.81086349px;fill:#ffc10f;fill-opacity:0.94117647;stroke-width:0.6844213" d="m -10.871757,-13.09042 q -0.641921,1.101806 -0.953301,2.179659 -0.31138,1.0778541 -0.31138,2.1844505 0,1.1065964 0.31138,2.194031 0.31617,1.0826441 0.953301,2.1796596 h -0.766473 q -0.718569,-1.1257582 -1.077854,-2.2131928 -0.354494,-1.0874346 -0.354494,-2.1604978 0,-1.0682727 0.354494,-2.1509165 0.354494,-1.082644 1.077854,-2.213193 z" /> + </g> + </svg> + </span> +</template> + +<script> +export default { + name: 'MaybeIcon', + props: { + title: { + type: String, + default: 'Maybe', + }, + fillColor: { + type: String, + default: '#ffc107', + }, + size: { + type: Number, + default: 24, + }, + }, +} +</script> diff --git a/src/js/components/AppIcons/PollsAppIcon.vue b/src/js/components/AppIcons/PollsAppIcon.vue new file mode 100644 index 00000000..8d6bbb85 --- /dev/null +++ b/src/js/components/AppIcons/PollsAppIcon.vue @@ -0,0 +1,50 @@ +<template> + <span :aria-hidden="!title" + :aria-label="title" + class="material-design-icon polls-app-icon" + role="img" + v-bind="$attrs" + @click="$emit('click', $event)"> + <svg :fill="fillColor" + class="material-design-icon__svg" + :width="size" + :height="size" + viewBox="0 0 32 32"> + <g :fill="fillColor"> + <rect y="2" + x="3" + height="26" + width="7" /> + <rect y="12" + x="12" + height="16" + width="7" /> + <rect y="8" + x="21" + height="20" + width="7" /> + <title v-if="title">{{ title }}</title> + </g> + </svg> + </span> +</template> + +<script> +export default { + name: 'PollsAppIcon', + props: { + title: { + type: String, + default: 'Polls', + }, + fillColor: { + type: String, + default: 'currentColor', + }, + size: { + type: Number, + default: 24, + }, + }, +} +</script> diff --git a/src/js/components/AppIcons/PublishOff.vue b/src/js/components/AppIcons/PublishOff.vue new file mode 100644 index 00000000..0c0b63cc --- /dev/null +++ b/src/js/components/AppIcons/PublishOff.vue @@ -0,0 +1,38 @@ +<template> + <span :aria-hidden="!title" + :aria-label="title" + class="material-design-icon publish-off-icon" + role="img" + v-bind="$attrs" + @click="$emit('click', $event)"> + <svg :fill="fillColor" + class="material-design-icon__svg" + :width="size" + :height="size" + viewBox="0 0 24 24"> + <path d="M20.8 22.7L15 16.9V20H9V14H5L8.6 10.4L1.1 3L2.4 1.7L22.1 21.4L20.8 22.7M19 6V4H7.2L9.2 6H19M17.2 14H19L12 7L11.1 7.9L17.2 14Z"> + <title v-if="title">{{ title }}</title> + </path> + </svg> + </span> +</template> + +<script> +export default { + name: 'PublishOff', + props: { + title: { + type: String, + default: 'Circles', + }, + fillColor: { + type: String, + default: 'currentColor', + }, + size: { + type: Number, + default: 24, + }, + }, +} +</script> diff --git a/src/js/components/Base/Badge.vue b/src/js/components/Base/Badge.vue index 8714d43f..81648a87 100644 --- a/src/js/components/Base/Badge.vue +++ b/src/js/components/Base/Badge.vue @@ -22,10 +22,9 @@ <template lang="html"> <Component :is="tag" class="badge"> - <div :class="icon" /> - <span> - {{ title }} - </span> + <div> + <slot name="icon" /> + </div> <span> <slot /> </span> @@ -36,14 +35,6 @@ export default { name: 'Badge', props: { - title: { - type: String, - default: '', - }, - icon: { - type: String, - default: '', - }, tag: { type: String, default: 'span', @@ -55,6 +46,7 @@ export default { <style lang="scss"> .badge { display: flex; + align-items: center; gap: 5px; border-radius: var(--border-radius); padding: 5px; @@ -73,18 +65,12 @@ export default { border-color: var(--color-error); background-color: var(--color-error); color: var(--color-primary-text) !important; - [class*='icon-mask-md-'] { - background-color: #fff; - } } &.success { border-color: var(--color-success); background-color: var(--color-success); color: var(--color-primary-text) !important; - [class*='icon-mask-md-'] { - background-color: #fff; - } } } diff --git a/src/js/components/Export/ExportPoll.vue b/src/js/components/Export/ExportPoll.vue index 4e9f165c..46be3028 100644 --- a/src/js/components/Export/ExportPoll.vue +++ b/src/js/components/Export/ExportPoll.vue @@ -21,7 +21,7 @@ -->
<template lang="html">
- <Actions default-icon="icon-mask-md-export">
+ <Actions>
<template #icon>
<ExportIcon />
</template>
diff --git a/src/js/components/Navigation/PollNavigationItems.vue b/src/js/components/Navigation/PollNavigationItems.vue index e3fd1242..d22e02cb 100644 --- a/src/js/components/Navigation/PollNavigationItems.vue +++ b/src/js/components/Navigation/PollNavigationItems.vue @@ -22,32 +22,43 @@ <template lang="html"> <AppNavigationItem :title="poll.title" - :icon="pollTypeIcon" :to="{name: 'vote', params: {id: poll.id}}" :class="{ closed: closed }"> + <template #icon> + <TextPollIcon v-if="poll.type === 'textPoll'" /> + <DatePollIcon v-else /> + </template> <template #actions> <ActionButton v-if="isPollCreationAllowed" - icon="icon-mask-md-clone-poll" @click="$emit('clone-poll')"> + <template #icon> + <ClonePollIcon /> + </template> {{ t('polls', 'Clone poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && !poll.deleted" - icon="icon-mask-md-archive-poll" @click="$emit('toggle-archive')"> + <template #icon> + <ArchivePollIcon /> + </template> {{ t('polls', 'Archive poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && poll.deleted" - icon="icon-mask-md-restore-poll" @click="$emit('toggle-archive')"> + <template #icon> + <RestorePollIcon /> + </template> {{ t('polls', 'Restore poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && poll.deleted" - icon="icon-mask-md-delete-poll" class="danger" @click="$emit('delete-poll')"> + <template #icon> + <DeletePollIcon /> + </template> {{ t('polls', 'Delete poll') }} </ActionButton> </template> @@ -58,6 +69,12 @@ import { mapState, mapGetters } from 'vuex' import { ActionButton, AppNavigationItem } from '@nextcloud/vue' +import DeletePollIcon from 'vue-material-design-icons/Delete.vue' +import ClonePollIcon from 'vue-material-design-icons/ContentCopy.vue' +import ArchivePollIcon from 'vue-material-design-icons/Archive.vue' +import RestorePollIcon from 'vue-material-design-icons/Recycle.vue' +import TextPollIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' +import DatePollIcon from 'vue-material-design-icons/CalendarBlank.vue' export default { name: 'PollNavigationItems', @@ -65,6 +82,12 @@ export default { components: { ActionButton, AppNavigationItem, + DeletePollIcon, + ClonePollIcon, + ArchivePollIcon, + RestorePollIcon, + TextPollIcon, + DatePollIcon, }, props: { @@ -82,14 +105,6 @@ export default { ...mapGetters({ closed: 'poll/isClosed', }), - - pollTypeIcon() { - if (this.poll.type === 'textPoll') { - return 'icon-mask-md-text-poll' - } - - return 'icon-mask-md-date-poll' - }, }, } </script> diff --git a/src/js/components/Options/OptionsDate.vue b/src/js/components/Options/OptionsDate.vue index 96b09b5e..707e8ab6 100644 --- a/src/js/components/Options/OptionsDate.vue +++ b/src/js/components/Options/OptionsDate.vue @@ -62,11 +62,16 @@ </OptionItem> </transition-group> - <EmptyContent v-else :icon="pollTypeIcon"> - {{ t('polls', 'No vote options') }} + <EmptyContent v-else> + <template #icon> + <DatePollIcon /> + </template> + <template #desc> {{ t('polls', 'Add some!') }} </template> + + {{ t('polls', 'No vote options') }} </EmptyContent> <Modal v-if="cloneModal" size="small" :can-close="false"> @@ -86,6 +91,7 @@ import { dateUnits } from '../../mixins/dateMixins.js' import CloneDateIcon from 'vue-material-design-icons/CalendarMultiple.vue' import UnconfirmIcon from 'vue-material-design-icons/CheckboxMarkedOutline.vue' import ConfirmIcon from 'vue-material-design-icons/CheckboxBlankOutline.vue' +import DatePollIcon from 'vue-material-design-icons/CalendarBlank.vue' export default { name: 'OptionsDate', @@ -102,6 +108,7 @@ export default { OptionCloneDate, OptionItem, VueButton, + DatePollIcon, OptionItemOwner: () => import('./OptionItemOwner.vue'), }, @@ -129,7 +136,6 @@ export default { ...mapGetters({ closed: 'poll/isClosed', countOptions: 'options/count', - pollTypeIcon: 'poll/typeIcon', }), }, diff --git a/src/js/components/Options/OptionsText.vue b/src/js/components/Options/OptionsText.vue index 16c12369..b842d7b2 100644 --- a/src/js/components/Options/OptionsText.vue +++ b/src/js/components/Options/OptionsText.vue @@ -58,11 +58,16 @@ </transition-group> </draggable> - <EmptyContent v-else :icon="pollTypeIcon"> - {{ t('polls', 'No vote options') }} + <EmptyContent v-else> + <template #icon> + <TextPollIcon /> + </template> + <template #desc> {{ t('polls', 'Add some!') }} </template> + + {{ t('polls', 'No vote options') }} </EmptyContent> </div> </template> @@ -77,6 +82,7 @@ import OptionItemOwner from '../Options/OptionItemOwner.vue' import { confirmOption, removeOption } from '../../mixins/optionMixins.js' import UnconfirmIcon from 'vue-material-design-icons/CheckboxMarkedOutline.vue' import ConfirmIcon from 'vue-material-design-icons/CheckboxBlankOutline.vue' +import TextPollIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' export default { name: 'OptionsText', @@ -90,6 +96,7 @@ export default { OptionItem, OptionItemOwner, VueButton, + TextPollIcon, OptionsTextAdd: () => import('./OptionsTextAdd.vue'), }, @@ -115,7 +122,6 @@ export default { ...mapGetters({ closed: 'poll/isClosed', countOptions: 'options/count', - pollTypeIcon: 'poll/typeIcon', }), dragOptions() { diff --git a/src/js/components/Poll/PollInfoLine.vue b/src/js/components/Poll/PollInfoLine.vue index 2d6456dd..71bf329c 100644 --- a/src/js/components/Poll/PollInfoLine.vue +++ b/src/js/components/Poll/PollInfoLine.vue @@ -23,7 +23,7 @@ <template lang="html"> <div class="poll-info-line"> <span v-for="(subText) in subTexts" :key="subText.id" :class="['sub-text', subText.class]"> - <span :class="subText.icon" /> + <Component :is="subText.iconComponent" :size="16" /> <span class="sub-text">{{ subText.text }}</span> </span> </div> @@ -32,6 +32,12 @@ <script> import { mapState, mapGetters } from 'vuex' import moment from '@nextcloud/moment' +import unpublishedIcon from '../AppIcons/PublishOff.vue' +import archivedPollIcon from 'vue-material-design-icons/Archive.vue' +import closedPollIcon from 'vue-material-design-icons/Lock.vue' +import creationIcon from 'vue-material-design-icons/ClockOutline.vue' +import ProposalsIcon from 'vue-material-design-icons/Offer.vue' +import ExpirationIcon from 'vue-material-design-icons/CalendarEnd.vue' export default { name: 'PollInfoLine', @@ -62,6 +68,16 @@ export default { subTexts() { const subTexts = [] + if (this.isDeleted) { + subTexts.push({ + id: 'deleted', + text: t('polls', 'Archived'), + class: 'archived', + iconComponent: archivedPollIcon, + }) + return subTexts + } + if (this.isNoAccessSet) { subTexts.push({ id: 'no-access', @@ -69,8 +85,8 @@ export default { t('polls', 'This poll is unpublished'), t('polls', 'Invite users via the share tab in the sidebar'), ].join('. '), - icon: 'icon-mask-md-unpublished-poll', class: 'unpublished', + iconComponent: unpublishedIcon, }) return subTexts } @@ -79,34 +95,24 @@ export default { subTexts.push({ id: this.access, text: t('polls', 'A private poll from {name}', { name: this.ownerDisplayName }), - icon: '', class: '', + iconComponent: null, }) } else { subTexts.push({ id: this.access, text: t('polls', 'An openly accessible poll from {name}', { name: this.ownerDisplayName }), - icon: '', class: '', + iconComponent: null, }) } - if (this.isDeleted) { - subTexts.push({ - id: 'deleted', - text: t('polls', 'Archived'), - icon: 'icon-mask-md-archived-poll', - class: 'archived', - }) - return subTexts - } - if (this.isClosed) { subTexts.push({ id: 'closed', text: this.timeExpirationRelative, - icon: 'icon-mask-md-closed-poll', class: 'closed', + iconComponent: closedPollIcon, }) return subTexts } @@ -115,8 +121,8 @@ export default { subTexts.push({ id: 'expiring', text: t('polls', 'Closing {relativeExpirationTime}', { relativeExpirationTime: this.timeExpirationRelative }), - icon: 'icon-mask-md-expiration', class: this.closeToClosing ? 'closing' : 'open', + iconComponent: ExpirationIcon, }) return subTexts } @@ -125,8 +131,8 @@ export default { subTexts.push({ id: 'expired', text: t('polls', 'Proposal period ended {timeRelative}', { timeRelative: this.proposalsExpireRelative }), - icon: 'icon-mask-md-proposals', class: 'proposal', + iconComponent: ProposalsIcon, }) return subTexts } @@ -135,8 +141,8 @@ export default { subTexts.push({ id: 'proposal-open', text: t('polls', 'Proposal period ends {timeRelative}', { timeRelative: this.proposalsExpireRelative }), - icon: 'icon-mask-md-proposals', class: 'proposal', + iconComponent: ProposalsIcon, }) return subTexts } @@ -145,8 +151,8 @@ export default { subTexts.push({ id: 'created', text: this.dateCreatedRelative, - icon: 'icon-mask-md-creation', class: 'created', + iconComponent: creationIcon, }) } return subTexts @@ -171,11 +177,6 @@ export default { } </script> -.poll-info-line [class^="icon-"], .poll-info-line [class*=" icon-"] { - /* padding-right: 21px; */ - width: var(--icon-size); - margin: 0px 6px 0 2px; -} <style lang="scss"> .poll-info-line { display: flex; @@ -183,6 +184,10 @@ export default { opacity: 0.7; font-size: 1em; + .material-design-icon { + padding: 0 2px; + } + .sub-text { display: flex; } @@ -192,25 +197,14 @@ export default { padding: 0 2px; } - [class^="icon-"], - [class*=" icon-"] { - width: var(--icon-size); - margin: 0px 6px 0 2px; - } - - [class^="icon-md"], - [class*=" icon-md"] { - mask-size: var(--icon-size); - } - - .closed { + .closed, .archived { .sub-text{ color: var(--color-error); font-weight: 700; } } - .unpublished { + .unpublished, .open { .sub-text{ font-weight: 700; } @@ -223,19 +217,6 @@ export default { } } - .open { - .sub-text{ - font-weight: 700; - } - } - - .archived { - .sub-text{ - color: var(--color-error); - font-weight: 700; - } - } - .created { .sub-text{ color: var(--color-text-light); diff --git a/src/js/components/Poll/PollInformation.vue b/src/js/components/Poll/PollInformation.vue index 68b258f0..710effce 100644 --- a/src/js/components/Poll/PollInformation.vue +++ b/src/js/components/Poll/PollInformation.vue @@ -22,46 +22,111 @@ <template lang="html"> <div class="poll-information"> - <Badge icon="icon-mask-md-owner"> + <Badge> + <template #icon> + <OwnerIcon /> + </template> {{ t('polls', 'Poll owner:') }} <UserBubble v-if="poll.owner.userId" :user="poll.owner.userId" :display-name="poll.owner.displayName" /> </Badge> - <Badge :icon="accessClass" :title="accessCaption" /> - <Badge icon="icon-mask-md-creation" - :title="t('polls', 'Created {dateRelative}', { dateRelative: dateCreatedRelative })" /> - <Badge v-if="poll.expire" - icon="icon-mask-md-closed-poll" - :title="t('polls', 'Closing: {dateRelative}', {dateRelative: dateExpiryRelative})" /> - <Badge v-if="poll.anonymous" - icon="icon-mask-md-anonymous-poll" - :title="t('polls', 'Anonymous poll')" /> - <Badge :icon="resultsClass" :title="resultsCaption" /> - <Badge v-if="countParticipantsVoted && acl.allowSeeResults" - icon="icon-mask-md-participants" - :title="n('polls', '%n Participant', '%n Participants', countParticipantsVoted)" /> - <Badge icon="icon-mask-md-options" :title="n('polls', '%n option', '%n options', countOptions)" /> - <Badge v-if="countAllYesVotes" icon="icon-mask-md-yes-votes"> + <Badge> + <template #icon> + <PrivatePollIcon v-if="access === 'private'" /> + <OpenPollIcon v-else /> + </template> + {{ accessCaption }} + </Badge> + <Badge> + <template #icon> + <CreationIcon /> + </template> + {{ t('polls', 'Created {dateRelative}', { dateRelative: dateCreatedRelative }) }} + </Badge> + <Badge v-if="poll.expire"> + <template #icon> + <ClosedIcon /> + </template> + {{ t('polls', 'Closing: {dateRelative}', {dateRelative: dateExpiryRelative}) }} + </Badge> + <Badge v-if="poll.anonymous"> + <template #icon> + <AnoymousIcon /> + </template> + {{ t('polls', 'Anonymous poll') }} + </Badge> + <Badge> + <template #icon> + <HideResultsIcon v-if="showResults === 'never'" /> + <ShowResultsOnClosedIcon v-else-if="showResults === 'closed' && closed" /> + <ShowResultsIcon v-else /> + </template> + {{ resultsCaption }} + </Badge> + <Badge v-if="countParticipantsVoted && acl.allowSeeResults"> + <template #icon> + <ParticipantsIcon /> + </template> + {{ n('polls', '%n Participant', '%n Participants', countParticipantsVoted) }} + </Badge> + <Badge> + <template #icon> + <OptionsIcon /> + </template> + {{ n('polls', '%n option', '%n options', countOptions) }} + </Badge> + <Badge v-if="countAllYesVotes"> + <template #icon> + <CheckIcon fill-color="#49bc49" /> + </template> {{ n('polls', '%n "Yes" vote', '%n "Yes" votes', countAllYesVotes) }} </Badge> - <Badge v-if="countAllNoVotes" icon="icon-mask-md-no-votes"> + <Badge v-if="countAllNoVotes"> + <template #icon> + <CloseIcon fill-color="#f45573" /> + </template> {{ n('polls', '%n No vote', '%n "No" votes', countAllNoVotes) }} </Badge> - <Badge v-if="countAllMaybeVotes" icon="icon-mask-md-maybe-votes"> + <Badge v-if="countAllMaybeVotes"> + <template #icon> + <MaybeIcon /> + </template> {{ n('polls', '%n "Maybe" vote', '%n "Maybe" votes', countAllMaybeVotes) }} </Badge> - <Badge icon="icon-mask-md-timezone" :title="t('polls', 'Time zone: {timezoneString}', { timezoneString: currentTimeZone})" /> - <Badge v-if="proposalsAllowed" icon="icon-mask-md-proposals-allowed" :title="proposalsStatus" /> - <div v-if="poll.voteLimit" class="icon-checkmark"> + <Badge> + <template #icon> + <TimezoneIcon /> + </template> + {{ t('polls', 'Time zone: {timezoneString}', { timezoneString: currentTimeZone}) }} + </Badge> + <Badge v-if="proposalsAllowed"> + <template #icon> + <ProposalsAllowedIcon /> + </template> + {{ proposalsStatus }} + </Badge> + <Badge v-if="poll.voteLimit"> + <template #icon> + <CheckIcon /> + </template> {{ n('polls', '%n of {maximalVotes} vote left.', '%n of {maximalVotes} votes left.', poll.voteLimit - countVotes('yes'), { maximalVotes: poll.voteLimit }) }} - </div> - <div v-if="poll.optionLimit" class="icon-close"> + </Badge> + <Badge v-if="poll.optionLimit"> + <template #icon> + <CloseIcon /> + </template> {{ n('polls', 'Only %n vote per option.', 'Only %n votes per option.', poll.optionLimit) }} - </div> - <div v-if="$route.name === 'publicVote' && share.emailAddress" class="icon-mail"> + </Badge> + <Badge v-if="$route.name === 'publicVote' && share.emailAddress"> + <template #icon> + <EmailIcon /> + </template> {{ share.emailAddress }} - </div> - <Badge v-if="subscribed" - icon="icon-mask-md-subscribed" - :title="t('polls', 'You subscribed to this poll')" /> + </Badge> + <Badge v-if="subscribed"> + <template #icon> + <SubscribedIcon /> + </template> + {{ t('polls', 'You subscribed to this poll') }} + </Badge> </div> </template> @@ -70,6 +135,24 @@ import { mapState, mapGetters } from 'vuex' import moment from '@nextcloud/moment' import { UserBubble } from '@nextcloud/vue' import Badge from '../Base/Badge.vue' +import OwnerIcon from 'vue-material-design-icons/Crown.vue' +import SubscribedIcon from 'vue-material-design-icons/Bell.vue' +import ProposalsAllowedIcon from 'vue-material-design-icons/Offer.vue' +import TimezoneIcon from 'vue-material-design-icons/MapClockOutline.vue' +import OptionsIcon from 'vue-material-design-icons/FormatListCheckbox.vue' +import ParticipantsIcon from 'vue-material-design-icons/AccountGroup.vue' +import ShowResultsIcon from 'vue-material-design-icons/Monitor.vue' +import ShowResultsOnClosedIcon from 'vue-material-design-icons/MonitorLock.vue' +import HideResultsIcon from 'vue-material-design-icons/MonitorOff.vue' +import AnoymousIcon from 'vue-material-design-icons/Incognito.vue' +import ClosedIcon from 'vue-material-design-icons/Lock.vue' +import CreationIcon from 'vue-material-design-icons/ClockOutline.vue' +import PrivatePollIcon from 'vue-material-design-icons/Key.vue' +import OpenPollIcon from 'vue-material-design-icons/Earth.vue' +import CheckIcon from 'vue-material-design-icons/Check.vue' +import CloseIcon from 'vue-material-design-icons/Close.vue' +import EmailIcon from 'vue-material-design-icons/Email.vue' +import MaybeIcon from '../AppIcons/MaybeIcon.vue' export default { name: 'PollInformation', @@ -77,6 +160,24 @@ export default { components: { Badge, UserBubble, + OwnerIcon, + SubscribedIcon, + ProposalsAllowedIcon, + TimezoneIcon, + OptionsIcon, + ParticipantsIcon, + ShowResultsIcon, + ShowResultsOnClosedIcon, + HideResultsIcon, + AnoymousIcon, + ClosedIcon, + CreationIcon, + PrivatePollIcon, + OpenPollIcon, + CheckIcon, + CloseIcon, + MaybeIcon, + EmailIcon, }, computed: { @@ -131,17 +232,6 @@ export default { return t('polls', 'Results are visible') }, - resultsClass() { - if (this.showResults === 'never') { - return 'icon-mask-md-show-results-never' - } - if (this.showResults === 'closed' && !this.closed) { - return 'icon-mask-md-hide-results-until-closed' - } - return 'icon-mask-md-show-results' - - }, - accessCaption() { if (this.access === 'private') { return t('polls', 'Private poll') @@ -152,16 +242,6 @@ export default { return t('polls', 'Openly accessible poll') }, - accessClass() { - if (this.access === 'private') { - return 'icon-mask-md-private-poll' - } - if (this.important) { - return 'icon-mask-md-open-poll' - } - return 'icon-mask-md-open-poll' - }, - dateCreatedRelative() { return moment.unix(this.poll.created).fromNow() }, diff --git a/src/js/components/PollList/PollItem.vue b/src/js/components/PollList/PollItem.vue index 59b68435..1197a384 100644 --- a/src/js/components/PollList/PollItem.vue +++ b/src/js/components/PollList/PollItem.vue @@ -53,7 +53,11 @@ </div> <div v-else class="poll-item__item"> - <div v-tooltip.auto="pollTypeName" :class="['item__icon-spacer', pollTypeIcon]" /> + <div v-tooltip.auto="pollTypeName" class="item__icon-spacer"> + <TextPollIcon v-if="pollType === 'textPoll'" /> + <DatePollIcon v-else /> + </div> + <!-- <div v-tooltip.auto="pollTypeName" :class="['item__icon-spacer', pollTypeIcon]" /> --> <div v-if="noLink" class="item__title" :class="{ closed: closed }"> <div class="item__title__title"> @@ -79,8 +83,11 @@ </router-link> <slot name="actions" /> - - <div v-tooltip.auto="accessType" :class="['item__access', accessIcon]" /> + <div v-tooltip.auto="accessType" class="item__access"> + <ArchivedPollIcon v-if="poll.deleted" /> + <OpenPollIcon v-else-if="poll.access === 'open'" /> + <PrivatePollIcon v-else /> + </div> <div class="item__owner"> <UserItem v-bind="poll.owner" condensed /> @@ -88,13 +95,20 @@ <div class="wrapper"> <div class="item__created"> - <Badge :title="timeCreatedRelative" - icon="icon-mask-md-creation" /> + <Badge> + <template #icon> + <CreationIcon /> + </template> + {{ timeCreatedRelative }} + </Badge> </div> <div class="item__expiry"> - <Badge :title="timeExpirationRelative" - icon="icon-mask-md-expiration" - :class="expiryClass" /> + <Badge :class="expiryClass"> + <template #icon> + <ExpirationIcon /> + </template> + {{ timeExpirationRelative }} + </Badge> </div> </div> </div> @@ -104,11 +118,25 @@ import { mapState } from 'vuex' import moment from '@nextcloud/moment' import Badge from '../Base/Badge.vue' +import TextPollIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' +import DatePollIcon from 'vue-material-design-icons/CalendarBlank.vue' +import CreationIcon from 'vue-material-design-icons/ClockOutline.vue' +import ExpirationIcon from 'vue-material-design-icons/CalendarEnd.vue' +import PrivatePollIcon from 'vue-material-design-icons/Key.vue' +import OpenPollIcon from 'vue-material-design-icons/Earth.vue' +import ArchivedPollIcon from 'vue-material-design-icons/Archive.vue' export default { name: 'PollItem', components: { Badge, + TextPollIcon, + DatePollIcon, + CreationIcon, + ExpirationIcon, + PrivatePollIcon, + OpenPollIcon, + ArchivedPollIcon, }, props: { @@ -152,34 +180,17 @@ export default { return t('polls', 'Private poll') }, + pollType() { + return this.poll.type + }, + pollTypeName() { - if (this.poll.type === 'textPoll') { + if (this.pollType === 'textPoll') { return t('polls', 'Text poll') } - return t('polls', 'Date poll') }, - pollTypeIcon() { - if (this.poll.type === 'textPoll') { - return 'icon-mask-md-text-poll' - } - - return 'icon-mask-md-date-poll' - }, - - accessIcon() { - if (this.poll.deleted) { - return 'icon-mask-md-archived-poll' - } - - if (this.poll.access === 'open') { - return 'icon-mask-md-open-poll' - } - - return 'icon-mask-md-private-poll' - }, - timeExpirationRelative() { if (this.poll.expire) { return moment.unix(this.poll.expire).fromNow() diff --git a/src/js/components/SideBar/SideBarTabComments.vue b/src/js/components/SideBar/SideBarTabComments.vue index 73bd59d3..b797f860 100644 --- a/src/js/components/SideBar/SideBarTabComments.vue +++ b/src/js/components/SideBar/SideBarTabComments.vue @@ -24,8 +24,11 @@ <div class="comments"> <CommentAdd v-if="acl.allowComment" /> <Comments v-if="!showEmptyContent" /> - <EmptyContent v-else icon="icon-mask-md-sidebar-comments"> + <EmptyContent v-else> {{ t('polls', 'No comments') }} + <template #icon> + <CommentsIcon /> + </template> <template #desc> {{ t('polls', 'Be the first.') }} </template> @@ -38,6 +41,7 @@ import CommentAdd from '../Comments/CommentAdd.vue' import Comments from '../Comments/Comments.vue' import { EmptyContent } from '@nextcloud/vue' import { mapGetters, mapState } from 'vuex' +import CommentsIcon from 'vue-material-design-icons/CommentProcessing.vue' export default { name: 'SideBarTabComments', @@ -45,6 +49,7 @@ export default { CommentAdd, Comments, EmptyContent, + CommentsIcon, }, computed: { diff --git a/src/js/components/SideBar/SideBarTabOptions.vue b/src/js/components/SideBar/SideBarTabOptions.vue index 3b60b7a2..d5c5ce53 100644 --- a/src/js/components/SideBar/SideBarTabOptions.vue +++ b/src/js/components/SideBar/SideBarTabOptions.vue @@ -99,7 +99,6 @@ export default { ...mapGetters({ closed: 'poll/isClosed', countOptions: 'options/count', - pollTypeIcon: 'poll/typeIcon', }), ...mapState({ pollType: (state) => state.poll.type, diff --git a/src/js/components/User/UserMenu.vue b/src/js/components/User/UserMenu.vue index d02ea849..0c998e81 100644 --- a/src/js/components/User/UserMenu.vue +++ b/src/js/components/User/UserMenu.vue @@ -21,25 +21,32 @@ --> <template> - <Actions default-icon="icon-settings" primary> + <Actions primary> + <template #icon> + <SettingsIcon :size="20" decorative /> + </template> <ActionButton v-if="$route.name === 'publicVote'" icon="icon-md-link" @click="copyLink()"> {{ t('polls', 'Copy your personal link to clipboard') }} </ActionButton> <ActionSeparator /> <ActionInput v-if="$route.name === 'publicVote'" - icon="icon-mask-md-edit-email-address" :class="check.status" :value="emailAddressTemp" @click="deleteEmailAddress" @update:value="validateEmailAddress" @submit="submitEmailAddress"> + <template #icon> + <EditEmailIcon /> + </template> {{ t('polls', 'Edit Email Address') }} </ActionInput> <ActionButton v-if="$route.name === 'publicVote'" :disabled="!emailAddress" :value="emailAddress" - icon="icon-mask-md-send-link-per-email" @click="resendInvitation()"> + <template #icon> + <SendLinkPerEmailIcon /> + </template> {{ t('polls', 'Get your personal link per mail') }} </ActionButton> <ActionCheckbox :checked="subscribed" @@ -50,14 +57,22 @@ </ActionCheckbox> <ActionButton v-if="$route.name === 'publicVote' && emailAddress" :disabled="!emailAddress" - icon="icon-mask-md-delete" @click="deleteEmailAddress"> + <template #icon> + <DeleteIcon /> + </template> {{ t('polls', 'Remove Email Address') }} </ActionButton> - <ActionButton v-if="acl.allowEdit" icon="icon-mask-md-clippy" @click="getAddresses()"> + <ActionButton v-if="acl.allowEdit" @click="getAddresses()"> + <template #icon> + <ClippyIcon /> + </template> {{ t('polls', 'Copy list of email addresses to clipboard') }} </ActionButton> - <ActionButton icon="icon-mask-md-reset-votes" @click="resetVotes()"> + <ActionButton @click="resetVotes()"> + <template #icon> + <ResetVotesIcon /> + </template> {{ t('polls', 'Reset your votes') }} </ActionButton> </Actions> @@ -70,6 +85,12 @@ import { showSuccess, showError } from '@nextcloud/dialogs' import { generateUrl } from '@nextcloud/router' import { Actions, ActionButton, ActionCheckbox, ActionInput, ActionSeparator } from '@nextcloud/vue' import { mapState } from 'vuex' +import SettingsIcon from 'vue-material-design-icons/Cog.vue' +import EditEmailIcon from 'vue-material-design-icons/EmailEditOutline.vue' +import SendLinkPerEmailIcon from 'vue-material-design-icons/LinkVariant.vue' +import DeleteIcon from 'vue-material-design-icons/Delete.vue' +import ClippyIcon from 'vue-material-design-icons/ClipboardArrowLeftOutline.vue' +import ResetVotesIcon from 'vue-material-design-icons/Undo.vue' export default { name: 'UserMenu', @@ -80,6 +101,12 @@ export default { ActionCheckbox, ActionInput, ActionSeparator, + SettingsIcon, + EditEmailIcon, + SendLinkPerEmailIcon, + DeleteIcon, + ClippyIcon, + ResetVotesIcon, }, data() { diff --git a/src/js/store/modules/poll.js b/src/js/store/modules/poll.js index 3e4c8ba8..655d99de 100644 --- a/src/js/store/modules/poll.js +++ b/src/js/store/modules/poll.js @@ -109,13 +109,6 @@ const getters = { return t('polls', 'Date poll') }, - typeIcon: (state) => { - if (state.type === 'textPoll') { - return 'icon-mask-md-text-poll' - } - return 'icon-mask-md-date-poll' - }, - answerSequence: (state, getters, rootState) => { const noString = rootState.poll.useNo ? 'no' : '' if (state.allowMaybe) { diff --git a/src/js/store/modules/polls.js b/src/js/store/modules/polls.js index 6df313ff..9bc57165 100644 --- a/src/js/store/modules/polls.js +++ b/src/js/store/modules/polls.js @@ -43,7 +43,6 @@ const state = { title: t('polls', 'Relevant'), titleExt: t('polls', 'Relevant polls'), description: t('polls', 'All polls which are relevant or important to you, because you are a participant or the owner or you are invited to. Without polls closed more than five days ago.'), - icon: 'icon-mask-md-navigation-relevant', pinned: false, createDependent: false, filterCondition(poll) { @@ -61,7 +60,6 @@ const state = { title: t('polls', 'My polls'), titleExt: t('polls', 'My polls'), description: t('polls', 'Your polls (in which you are the owner).'), - icon: 'icon-mask-md-navigation-my', pinned: false, createDependent: true, filterCondition(poll) { @@ -73,7 +71,6 @@ const state = { title: t('polls', 'Private polls'), titleExt: t('polls', 'Private polls'), description: t('polls', 'All private polls, to which you have access.'), - icon: 'icon-mask-md-navigation-private', pinned: false, createDependent: true, filterCondition(poll) { @@ -85,7 +82,6 @@ const state = { title: t('polls', 'Participated'), titleExt: t('polls', 'Participated'), description: t('polls', 'All polls, where you placed a vote.'), - icon: 'icon-mask-md-navigation-participated', pinned: false, createDependent: false, filterCondition(poll) { @@ -97,7 +93,6 @@ const state = { title: t('polls', 'Openly accessible polls'), titleExt: t('polls', 'Openly accessible polls'), description: t('polls', 'A complete list with all openly accessible polls on this site, regardless who is the owner.'), - icon: 'icon-mask-md-navigation-open', pinned: false, createDependent: true, filterCondition(poll) { @@ -109,7 +104,6 @@ const state = { title: t('polls', 'All polls'), titleExt: t('polls', 'All polls'), description: t('polls', 'All polls, where you have access to.'), - icon: 'icon-mask-md-navigation-all', pinned: false, createDependent: false, filterCondition(poll) { @@ -121,7 +115,6 @@ const state = { title: t('polls', 'Closed polls'), titleExt: t('polls', 'Closed polls'), description: t('polls', 'All closed polls, where voting is disabled.'), - icon: 'icon-mask-md-navigation-closed', pinned: false, createDependent: false, filterCondition(poll) { @@ -135,7 +128,6 @@ const state = { title: t('polls', 'Archive'), titleExt: t('polls', 'My archived polls'), description: t('polls', 'Your archived polls are only accessible to you.'), - icon: 'icon-mask-md-navigation-archived', pinned: true, createDependent: true, filterCondition(poll) { diff --git a/src/js/store/modules/votes.js b/src/js/store/modules/votes.js index 9680d75e..124b10fe 100644 --- a/src/js/store/modules/votes.js +++ b/src/js/store/modules/votes.js @@ -59,7 +59,7 @@ const mutations = { } const getters = { - relevant: (state, getters, rootState) => state.list.filter((vote) => rootState.options.list.some((option) => option.pollId === vote.pollId && option.text === vote.voteOptionText)), + relevant: (state, getters, rootState) => state.list.filter((vote) => rootState.options.list.some((option) => option.pollId === vote.pollId && option.text === vote.optionText)), countVotes: (state, getters, rootState) => (answer) => getters.relevant.filter((vote) => vote.user.userId === rootState.poll.acl.userId && vote.answer === answer).length, countAllVotes: (state, getters) => (answer) => getters.relevant.filter((vote) => vote.answer === answer).length, hasVoted: (state) => (userId) => state.list.findIndex((vote) => vote.user.userId === userId) > -1, diff --git a/src/js/views/Navigation.vue b/src/js/views/Navigation.vue index 8dc116b1..be3a618a 100644 --- a/src/js/views/Navigation.vue +++ b/src/js/views/Navigation.vue @@ -27,15 +27,18 @@ :text="t('polls', 'Add new Poll')" @click="toggleCreateDlg" /> <CreateDlg v-show="createDlg" ref="createDlg" @close-create="closeCreate()" /> + <template #list> <AppNavigationItem v-for="(pollCategory) in pollCategories" :key="pollCategory.id" :title="pollCategory.title" :allow-collapse="true" :pinned="pollCategory.pinned" - :icon="pollCategory.icon" :to="{ name: 'list', params: {type: pollCategory.id}}" :open="false"> + <template #icon> + <Component :is="getIconComponent(pollCategory.id)" :size="iconSize" /> + </template> <ul> <PollNavigationItems v-for="(poll) in filteredPolls(pollCategory.id)" :key="poll.id" @@ -46,16 +49,28 @@ </ul> </AppNavigationItem> </template> + <template #footer> <AppNavigationItem v-if="isComboActivated" :title="t('polls', 'Combine polls')" - icon="icon-mask-md-navigation-combo" - :to="{ name: 'combo' }" /> + :to="{ name: 'combo' }"> + <template #icon> + <ComboIcon :size="iconSize" /> + </template> + </AppNavigationItem> <AppNavigationItem v-if="showAdminSection" :title="t('polls', 'Administration')" - icon="icon-mask-md-navigation-administration" - :to="{ name: 'administration' }" /> - <AppNavigationItem :title="t('polls', 'Personal settings')" icon="icon-mask-md-navigation-personal-settings" @click="showSettings()" /> + :to="{ name: 'administration' }"> + <template #icon> + <AdministrationIcon :size="iconSize" /> + </template> + </AppNavigationItem> + <AppNavigationItem :title="t('polls', 'Personal settings')" + @click="showSettings()"> + <template #icon> + <SettingsIcon :size="iconSize" /> + </template> + </AppNavigationItem> </template> </AppNavigation> </template> @@ -69,6 +84,17 @@ import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import CreateDlg from '../components/Create/CreateDlg.vue' import PollNavigationItems from '../components/Navigation/PollNavigationItems.vue' +import ComboIcon from 'vue-material-design-icons/VectorCombine.vue' +import AdministrationIcon from 'vue-material-design-icons/Cog.vue' +import SettingsIcon from 'vue-material-design-icons/AccountCog.vue' +import RelevantIcon from 'vue-material-design-icons/ExclamationThick.vue' +import MyPollsIcon from 'vue-material-design-icons/Crown.vue' +import PrivatePollsIcon from 'vue-material-design-icons/Key.vue' +import ParticipatedIcon from 'vue-material-design-icons/AccountCheck.vue' +import OpenPollIcon from 'vue-material-design-icons/Earth.vue' +import AllPollsIcon from 'vue-material-design-icons/Poll.vue' +import ClosedPollsIcon from 'vue-material-design-icons/Lock.vue' +import ArchivedPollsIcon from 'vue-material-design-icons/Archive.vue' export default { name: 'Navigation', @@ -78,11 +104,25 @@ export default { AppNavigationItem, CreateDlg, PollNavigationItems, + ComboIcon, + SettingsIcon, + AdministrationIcon, }, data() { return { + iconSize: 20, createDlg: false, + icons: [ + { id: 'relevant', iconComponent: RelevantIcon }, + { id: 'my', iconComponent: MyPollsIcon }, + { id: 'private', iconComponent: PrivatePollsIcon }, + { id: 'participated', iconComponent: ParticipatedIcon }, + { id: 'open', iconComponent: OpenPollIcon }, + { id: 'all', iconComponent: AllPollsIcon }, + { id: 'closed', iconComponent: ClosedPollsIcon }, + { id: 'archived', iconComponent: ArchivedPollsIcon }, + ], } }, @@ -115,6 +155,10 @@ export default { this.createDlg = false }, + getIconComponent(iconId) { + return this.icons.find((icon) => icon.id === iconId).iconComponent + }, + toggleCreateDlg() { this.createDlg = !this.createDlg if (this.createDlg) { diff --git a/src/js/views/PollList.vue b/src/js/views/PollList.vue index 2493cd30..8c0d5c83 100644 --- a/src/js/views/PollList.vue +++ b/src/js/views/PollList.vue @@ -53,31 +53,39 @@ <template #actions> <Actions force-menu> <ActionButton v-if="isPollCreationAllowed" - icon="icon-mask-md-clone-poll" :close-after-click="true" @click="clonePoll(poll.id)"> + <template #icon> + <ClonePollIcon /> + </template> {{ t('polls', 'Clone poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && !poll.deleted" - icon="icon-mask-md-archive-poll" :close-after-click="true" @click="toggleArchive(poll.id)"> + <template #icon> + <ArchivePollIcon /> + </template> {{ t('polls', 'Archive poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && poll.deleted" - icon="icon-mask-md-restore-poll" :close-after-click="true" @click="toggleArchive(poll.id)"> + <template #icon> + <RestorePollIcon /> + </template> {{ t('polls', 'Restore poll') }} </ActionButton> <ActionButton v-if="poll.allowEdit && poll.deleted" - icon="icon-mask-md-delete-poll" class="danger" :close-after-click="true" @click="deletePoll(poll.id)"> + <template #icon> + <DeletePollIcon /> + </template> {{ t('polls', 'Delete poll') }} </ActionButton> </Actions> @@ -95,6 +103,10 @@ import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import { Actions, ActionButton, AppContent, EmptyContent } from '@nextcloud/vue' import HeaderBar from '../components/Base/HeaderBar.vue' +import DeletePollIcon from 'vue-material-design-icons/Delete.vue' +import ClonePollIcon from 'vue-material-design-icons/ContentCopy.vue' +import ArchivePollIcon from 'vue-material-design-icons/Archive.vue' +import RestorePollIcon from 'vue-material-design-icons/Recycle.vue' export default { name: 'PollList', @@ -105,6 +117,10 @@ export default { ActionButton, EmptyContent, HeaderBar, + DeletePollIcon, + ClonePollIcon, + ArchivePollIcon, + RestorePollIcon, LoadingOverlay: () => import('../components/Base/LoadingOverlay.vue'), PollItem: () => import('../components/PollList/PollItem.vue'), }, diff --git a/src/js/views/SideBar.vue b/src/js/views/SideBar.vue index 1a3e20e2..40686457 100644 --- a/src/js/views/SideBar.vue +++ b/src/js/views/SideBar.vue @@ -28,24 +28,30 @@ <AppSidebarTab v-if="acl.allowEdit" :id="'configuration'" :order="1" - :name="t('polls', 'Configuration')" - icon="icon-mask-md-sidebar-configuration"> + :name="t('polls', 'Configuration')"> + <template #icon> + <SidebarConfigurationIcon /> + </template> <SideBarTabConfiguration /> </AppSidebarTab> <AppSidebarTab v-if="acl.allowEdit" :id="'options'" :order="2" - :name="t('polls', 'Options')" - icon="icon-mask-md-sidebar-options"> + :name="t('polls', 'Options')"> + <template #icon> + <SidebarOptionsIcon /> + </template> <SideBarTabOptions /> </AppSidebarTab> <AppSidebarTab v-if="acl.allowEdit" :id="'sharing'" :order="3" - :name="t('polls', 'Sharing')" - icon="icon-mask-md-sidebar-share"> + :name="t('polls', 'Sharing')"> + <template #icon> + <SidebarShareIcon /> + </template> <SideBarTabShare /> </AppSidebarTab> @@ -60,8 +66,10 @@ <AppSidebarTab v-if="acl.allowComment" :id="'comments'" :order="5" - :name="t('polls', 'Comments')" - icon="icon-mask-md-sidebar-comments"> + :name="t('polls', 'Comments')"> + <template #icon> + <SidebarCommentsIcon /> + </template> <SideBarTabComments /> </AppSidebarTab> @@ -79,6 +87,10 @@ import { AppSidebar, AppSidebarTab } from '@nextcloud/vue' import { mapState } from 'vuex' import { emit } from '@nextcloud/event-bus' +import SidebarConfigurationIcon from 'vue-material-design-icons/Wrench.vue' +import SidebarOptionsIcon from 'vue-material-design-icons/FormatListChecks.vue' +import SidebarShareIcon from 'vue-material-design-icons/ShareVariant.vue' +import SidebarCommentsIcon from 'vue-material-design-icons/CommentProcessing.vue' export default { name: 'SideBar', @@ -92,6 +104,10 @@ export default { SideBarTabActivity: () => import('../components/SideBar/SideBarTabActivity.vue'), AppSidebar, AppSidebarTab, + SidebarConfigurationIcon, + SidebarOptionsIcon, + SidebarShareIcon, + SidebarCommentsIcon, }, props: { diff --git a/src/js/views/Vote.vue b/src/js/views/Vote.vue index 52e0023b..3cb5fb54 100644 --- a/src/js/views/Vote.vue +++ b/src/js/views/Vote.vue @@ -44,7 +44,11 @@ <div class="area__main" :class="viewMode"> <VoteTable v-show="options.length" :view-mode="viewMode" /> - <EmptyContent v-if="!options.length" :icon="pollTypeIcon"> + <EmptyContent v-if="!options.length"> + <template #icon> + <TextPollIcon v-if="poll.type === 'textPoll'" /> + <DatePollIcon v-else /> + </template> {{ t('polls', 'No vote options available') }} <template #desc> <button v-if="acl.allowEdit" @click="openOptions"> @@ -84,6 +88,8 @@ import MarkUpDescription from '../components/Poll/MarkUpDescription.vue' import PollInfoLine from '../components/Poll/PollInfoLine.vue' import PollHeaderButtons from '../components/Poll/PollHeaderButtons.vue' import HeaderBar from '../components/Base/HeaderBar.vue' +import DatePollIcon from 'vue-material-design-icons/CalendarBlank.vue' +import TextPollIcon from 'vue-material-design-icons/FormatListBulletedSquare.vue' export default { name: 'Vote', @@ -94,6 +100,8 @@ export default { MarkUpDescription, PollHeaderButtons, PollInfoLine, + DatePollIcon, + TextPollIcon, LoadingOverlay: () => import('../components/Base/LoadingOverlay.vue'), OptionProposals: () => import('../components/Options/OptionProposals.vue'), PublicRegisterModal: () => import('../components/Poll/PublicRegisterModal.vue'), @@ -117,7 +125,6 @@ export default { ...mapGetters({ closed: 'poll/isClosed', options: 'options/rankedOptions', - pollTypeIcon: 'poll/typeIcon', viewMode: 'poll/viewMode', proposalsAllowed: 'poll/proposalsAllowed', proposalsOpen: 'poll/proposalsOpen', |