@@ -11,10 +11,15 @@ import Button from "@/components/ui/Button.vue"
1111import Tooltip from " @/components/ui/Tooltip.vue"
1212import Popover from " @/components/ui/Popover.vue"
1313import Radio from " @/components/ui/Radio.vue"
14+ import Checkbox from " @/components/ui/Checkbox.vue"
1415
1516/** Shared Components */
1617import TablePlaceholderView from " @/components/shared/TablePlaceholderView.vue"
1718
19+ /** Store */
20+ import { useEnumStore } from " @/store/enums"
21+ const enumStore = useEnumStore ()
22+
1823const emit = defineEmits ([" onPrevPage" , " onNextPage" , " updatePage" , " updateFilters" , " onFiltersReset" ])
1924const props = defineProps ({
2025 proposal: {
@@ -44,33 +49,52 @@ const props = defineProps({
4449
4550const router = useRouter ()
4651
52+ const options = enumStore .enums .voteOption
53+
4754/** Filter by vote option */
48- const optionFilter = ref ()
55+ const setDefaultOptionFilter = () => {
56+ options .forEach ((opt ) => {
57+ optionFilter[opt] = false
58+ })
59+ }
60+ const optionFilter = reactive ({})
61+ setDefaultOptionFilter ()
62+
4963const cachedOptionFilter = ref ()
5064
51- const hasActiveFilters = computed (() => !! optionFilter .value )
65+ const hasActiveOptionFilters = computed (() => {
66+ let hasActiveFilter = false
67+ Object .keys (optionFilter).forEach ((opt ) => {
68+ if (optionFilter[opt]) {
69+ hasActiveFilter = true
70+ }
71+ })
72+ return hasActiveFilter
73+ })
5274
5375const isOptionPopoverOpen = ref (false )
5476const handleOpenOptionPopover = () => {
5577 isOptionPopoverOpen .value = true
5678
57- cachedOptionFilter .value = optionFilter . value
79+ cachedOptionFilter .value = { ... optionFilter }
5880}
5981const onOptionPopoverClose = () => {
6082 isOptionPopoverOpen .value = false
6183
62- optionFilter .value = cachedOptionFilter .value
84+ options .forEach ((opt ) => {
85+ optionFilter[opt] = cachedOptionFilter .value [opt]
86+ })
6387}
6488const handleApplyOptionFilters = () => {
6589 isOptionPopoverOpen .value = false
6690
67- emit (" updateFilters" , " option" , optionFilter . value , true )
91+ emit (" updateFilters" , " option" , optionFilter, true )
6892}
6993const handleResetOptionFilter = () => {
7094 isOptionPopoverOpen .value = false
7195
7296 emit (" onFiltersReset" , " option" , true )
73- optionFilter . value = null
97+ setDefaultOptionFilter ()
7498}
7599
76100/** Pagination */
@@ -90,7 +114,7 @@ const handleNextPage = () => {
90114watch (
91115 () => props .filters .option ,
92116 () => {
93- if (! props .filters .option ) optionFilter . value = null
117+ if (! props .filters .option ) setDefaultOptionFilter ()
94118 },
95119)
96120 </script >
@@ -99,13 +123,18 @@ watch(
99123 <Flex direction =" column" :class =" [$style.wrapper, isLoadingVotes && $style.disabled]" >
100124 <Flex wrap =" wrap" align =" center" gap =" 8" :class =" $style.filters" >
101125 <Popover :open =" isOptionPopoverOpen" @on-close =" onOptionPopoverClose" width =" 200" >
102- <Button @click =" handleOpenOptionPopover" type =" secondary" size =" mini" :disabled =" !votes.length && !hasActiveFilters " >
103- <Icon name =" plus-circle" size =" 12" :color =" optionFilter ? 'brand' : 'tertiary'" />
104- <Text color =" secondary" >Option<template v-if =" optionFilter " >:</template ></Text >
126+ <Button @click =" handleOpenOptionPopover" type =" secondary" size =" mini" :disabled =" !votes.length && !hasActiveOptionFilters " >
127+ <Icon name =" plus-circle" size =" 12" :color =" hasActiveOptionFilters ? 'brand' : 'tertiary'" />
128+ <Text color =" secondary" >Option<template v-if =" hasActiveOptionFilters " >:</template ></Text >
105129
106- <template v-if =" optionFilter " >
130+ <template v-if =" hasActiveOptionFilters " >
107131 <Text size =" 12" weight =" 600" color =" primary" style =" text-transform : capitalize " >
108- {{ optionFilter.replaceAll("_", " ") }}
132+ {{
133+ options
134+ .map((opt) => optionFilter[opt] && opt.replaceAll("_", " "))
135+ .filter(Boolean)
136+ .join(", ")
137+ }}
109138 </Text >
110139
111140 <Icon @click.stop =" handleResetOptionFilter" name =" close-circle" size =" 12" color =" secondary" />
@@ -117,25 +146,20 @@ watch(
117146 <Text size =" 12" weight =" 600" color =" secondary" >Filter by Vote Option</Text >
118147
119148 <Flex direction =" column" gap =" 8" >
120- <Radio v-model =" optionFilter" value =" yes" >
121- <Text size =" 12" weight =" 600" color =" primary" >Yes</Text >
122- </Radio >
123- <Radio v-model =" optionFilter" value =" no" >
124- <Text size =" 12" weight =" 600" color =" primary" >No</Text >
125- </Radio >
126- <Radio v-model =" optionFilter" value =" no_with_veto" >
127- <Text size =" 12" weight =" 600" color =" primary" >No with veto</Text >
128- </Radio >
129- <Radio v-model =" optionFilter" value =" abstain" >
130- <Text size =" 12" weight =" 600" color =" primary" >Abstain</Text >
131- </Radio >
149+ <Checkbox v-for =" opt in options" v-model =" optionFilter[opt]" >
150+ <Text size =" 12" weight =" 600" color =" primary" style =" text-transform : capitalize " >
151+ {{ opt.replaceAll("_", " ") }}
152+ </Text >
153+ </Checkbox >
132154 </Flex >
133155
134156 <Flex gap =" 8" >
135- <Button @click =" handleApplyOptionFilters" type =" secondary" size =" mini" wide :disabled =" !optionFilter " >
157+ <Button @click =" handleApplyOptionFilters" type =" secondary" size =" mini" wide :disabled =" !hasActiveOptionFilters " >
136158 Apply
137159 </Button >
138- <Button v-if =" optionFilter" @click =" handleResetOptionFilter" type =" tertiary" size =" mini" wide >Reset</Button >
160+ <Button v-if =" hasActiveOptionFilters" @click =" handleResetOptionFilter" type =" tertiary" size =" mini" wide >
161+ Reset
162+ </Button >
139163 </Flex >
140164 </Flex >
141165 </template >
@@ -217,7 +241,7 @@ watch(
217241 icon =" governance"
218242 subIcon =" search"
219243 :descriptionWidth =" 260"
220- :callback =" optionFilter ? () => handleResetOptionFilter() : null"
244+ :callback =" hasActiveOptionFilters ? () => handleResetOptionFilter() : null"
221245 callbackText =" Reset Filters"
222246 style =" height : 100% "
223247 />
0 commit comments