Skip to content

Commit 818adeb

Browse files
authored
Support bulk edit members attribute (#1177)
1 parent 4f21a85 commit 818adeb

File tree

4 files changed

+597
-0
lines changed

4 files changed

+597
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<template>
2+
<el-popover v-model:visible="open" placement="bottom-start" size="large" width="39rem" popper-class="!p-0" trigger="click">
3+
<template #reference>
4+
<el-select
5+
ref="focus"
6+
v-model="currentSelection"
7+
class="w-full"
8+
popper-class="attribute-dropdown-popper"
9+
clearable
10+
placeholder="Select option"
11+
/>
12+
</template>
13+
14+
<div class="border-b border-gray-100 p-2">
15+
<el-input
16+
ref="queryInput"
17+
v-model="search"
18+
placeholder="Search..."
19+
class="filter-dropdown-search"
20+
data-qa="filter-list-search"
21+
>
22+
<template #prefix>
23+
<i class="ri-search-line" />
24+
</template>
25+
</el-input>
26+
</div>
27+
<div class="max-h-80 overflow-auto px-2 py-3">
28+
<!-- DEFAULT ATTRIBUTES -->
29+
<template v-if="filteredDefaultOptions.length > 0">
30+
<div class="el-dropdown-title !my-3 !-ml-1">
31+
Default Attributes
32+
</div>
33+
<article
34+
v-for="attribute in filteredDefaultOptions"
35+
:key="attribute.name"
36+
class="mb-1 p-3 rounded flex justify-between items-center transition whitespace-nowrap h-10 hover:bg-gray-50 text-xs !cursor-pointer"
37+
data-qa="filter-list-item-custom"
38+
@click="selectItem(attribute, 'default')"
39+
>
40+
<span class="!text-gray-900">{{ attribute.label }}</span>
41+
</article>
42+
</template>
43+
44+
<!-- CUSTOM ATTRIBUTES -->
45+
<template v-if="filteredCustomOptions.length > 0">
46+
<div
47+
class="el-dropdown-title !my-3 !-ml-1"
48+
>
49+
Custom Attributes
50+
</div>
51+
<article
52+
v-for="attribute in filteredCustomOptions"
53+
:key="attribute.name"
54+
class="mb-1 p-3 rounded flex justify-between items-center transition whitespace-nowrap h-10 hover:bg-gray-50 text-xs !cursor-pointer"
55+
data-qa="filter-list-item-custom"
56+
@click="selectItem(attribute, 'custom')"
57+
>
58+
<span class="!text-gray-900">{{ attribute.label }}</span>
59+
</article>
60+
</template>
61+
<div
62+
v-if="filteredDefaultOptions.length === 0 && filteredCustomOptions.length === 0"
63+
class="el-dropdown-title !mt-2"
64+
>
65+
No results
66+
</div>
67+
</div>
68+
</el-popover>
69+
</template>
70+
71+
<script setup lang="ts">
72+
import {
73+
computed,
74+
defineProps, ref,
75+
watch,
76+
} from 'vue';
77+
78+
type Attribute = {
79+
label: string,
80+
name: string,
81+
};
82+
83+
const props = defineProps<{
84+
modelValue: {
85+
default: Attribute[],
86+
custom: Attribute[],
87+
}}>();
88+
89+
const emit = defineEmits(['update:modelValue', 'change', 'clear']);
90+
91+
const currentSelection = ref<string>('');
92+
const open = ref<boolean>(false);
93+
const search = ref<string>('');
94+
95+
const matchesSearch = (label: string, query: string): boolean => label.toLowerCase().includes(query.toLowerCase());
96+
97+
const filteredDefaultOptions = computed(() => props.modelValue.default.filter((filter) => matchesSearch(filter.label, search.value)));
98+
99+
const filteredCustomOptions = computed(() => props.modelValue.custom.filter((filter) => matchesSearch(filter.label, search.value)));
100+
101+
watch(currentSelection, (value) => {
102+
if (value === '') {
103+
emit('clear');
104+
}
105+
});
106+
107+
const selectItem = (item: Attribute, source: string) => {
108+
currentSelection.value = item.label;
109+
search.value = '';
110+
open.value = false;
111+
emit('change', { [source]: item });
112+
};
113+
114+
</script>
115+
116+
<script lang="ts">
117+
export default {
118+
name: 'AppBulkEditAttributeDropdown',
119+
};
120+
</script>
121+
122+
<style>
123+
.attribute-dropdown-popper {
124+
display: none !important;
125+
}
126+
</style>

0 commit comments

Comments
 (0)