|
4 | 4 | v-for="(clusterId, index) in selectedClusters"
|
5 | 5 | :key="clusterId"
|
6 | 6 | class="tab-item"
|
7 |
| - :class="{ 'item-selected': clusterId === modelValue }" |
| 7 | + :class="{ 'item-selected': clusterId === localClusterId }" |
8 | 8 | @click="() => handleActiveTab(clusterId)">
|
9 | 9 | <div class="active-bar"></div>
|
10 | 10 | <div class="tab-item-content">
|
|
30 | 30 | class="add-icon-main">
|
31 | 31 | <DbIcon
|
32 | 32 | class="add-icon"
|
33 |
| - type="increase" |
34 |
| - @click="handleClickAddIcon" /> |
| 33 | + type="increase" /> |
35 | 34 | </div>
|
36 | 35 | </div>
|
37 | 36 | <div style="display: none">
|
|
40 | 39 | class="webconsole-select-clusters"
|
41 | 40 | :style="{ height: clustersPanelHeight }">
|
42 | 41 | <div class="title">{{ t('连接的集群') }}</div>
|
43 |
| - <BkSelect |
44 |
| - ref="clutersRef" |
45 |
| - class="clusters-select" |
46 |
| - disable-focus-behavior |
47 |
| - filterable |
48 |
| - :model-value="selectedClusters" |
49 |
| - multiple |
50 |
| - :popover-options="{ disableTeleport: true }" |
51 |
| - @change="handleClusterSelectChange"> |
52 |
| - <template #trigger> |
53 |
| - <span></span> |
54 |
| - </template> |
55 |
| - <BkOption |
56 |
| - v-for="item in clusterList" |
57 |
| - :key="item.id" |
58 |
| - :name="item.immute_domain" |
59 |
| - :value="item.id" /> |
60 |
| - </BkSelect> |
| 42 | + <div class="clusters-select"> |
| 43 | + <BkInput |
| 44 | + v-model="searchValue" |
| 45 | + behavior="simplicity" |
| 46 | + class="cluster-select-search" |
| 47 | + :placeholder="t('请输入关键字')"> |
| 48 | + <template #prefix> |
| 49 | + <DbIcon |
| 50 | + class="input-icon" |
| 51 | + type="search" /> |
| 52 | + </template> |
| 53 | + </BkInput> |
| 54 | + <ul class="cluster-select-warpper"> |
| 55 | + <li |
| 56 | + v-for="item in renderOptions" |
| 57 | + :key="item.id" |
| 58 | + class="cluster-select-option" |
| 59 | + @click="handleClusterSelectChange([item.id])"> |
| 60 | + {{ item.immute_domain }} |
| 61 | + </li> |
| 62 | + </ul> |
| 63 | + </div> |
61 | 64 | </div>
|
62 | 65 | </div>
|
63 | 66 | </template>
|
|
96 | 99 | const { t } = useI18n();
|
97 | 100 | const route = useRoute();
|
98 | 101 |
|
99 |
| - const modelValue = defineModel({ |
100 |
| - default: 0 as number, |
101 |
| - type: Number, |
102 |
| - }); |
103 |
| -
|
104 | 102 | const routeClusterId = route.query.clusterId;
|
105 | 103 | let clustersRaw: ClusterItem[] = [];
|
106 | 104 | let tippyIns: Instance | undefined;
|
107 | 105 |
|
108 |
| - const clutersRef = ref(); |
109 | 106 | const addTabRef = ref();
|
110 | 107 | const popRef = ref();
|
| 108 | + const localClusterId = ref(0); |
111 | 109 | const clustersMap = ref<Record<number, ClusterItem>>({});
|
112 | 110 | const selectedClusters = ref<number[]>([]);
|
| 111 | + const searchValue = ref(''); |
113 | 112 |
|
114 | 113 | const clustersPanelHeight = computed(() => {
|
115 | 114 | if (!clusterList.value) {
|
|
122 | 121 | return `${height}px`;
|
123 | 122 | });
|
124 | 123 |
|
| 124 | + const renderOptions = computed(() => |
| 125 | + clusterList.value?.filter((item) => item.immute_domain.indexOf(searchValue.value) !== -1), |
| 126 | + ); |
| 127 | +
|
125 | 128 | const { data: clusterList } = useRequest(queryAllTypeCluster, {
|
126 | 129 | defaultParams: [
|
127 | 130 | {
|
|
158 | 161 | }
|
159 | 162 | const id = ids.pop()!;
|
160 | 163 | selectedClusters.value.push(id);
|
161 |
| - modelValue.value = id; |
| 164 | + localClusterId.value = id; |
162 | 165 | emits('change', clustersMap.value[id]);
|
163 | 166 | updateClusterSelect();
|
164 | 167 | tippyIns?.hide();
|
|
169 | 172 | };
|
170 | 173 |
|
171 | 174 | const handleActiveTab = (id: number) => {
|
172 |
| - modelValue.value = id; |
| 175 | + localClusterId.value = id; |
173 | 176 | emits('change', clustersMap.value[id]);
|
174 | 177 | };
|
175 | 178 |
|
|
185 | 188 | const currentClusterId = selectedClusters.value[index];
|
186 | 189 | selectedClusters.value.splice(index, 1);
|
187 | 190 | const clusterCount = selectedClusters.value.length;
|
188 |
| - if (currentClusterId === modelValue.value) { |
| 191 | + if (currentClusterId === localClusterId.value) { |
189 | 192 | emits('removeTab', currentClusterId);
|
190 | 193 | // 关闭当前打开tab
|
191 |
| - modelValue.value = clusterCount === 0 ? 0 : selectedClusters.value[clusterCount - 1]; |
192 |
| - emits('change', clustersMap.value[modelValue.value]); |
| 194 | + localClusterId.value = clusterCount === 0 ? 0 : selectedClusters.value[clusterCount - 1]; |
| 195 | + emits('change', clustersMap.value[localClusterId.value]); |
193 | 196 | }
|
194 | 197 | updateClusterSelect();
|
195 | 198 | };
|
196 | 199 |
|
197 |
| - const handleClickAddIcon = () => { |
198 |
| - setTimeout(() => { |
199 |
| - clutersRef.value.showPopover(); |
200 |
| - }); |
201 |
| - }; |
202 |
| -
|
203 | 200 | onMounted(() => {
|
204 | 201 | tippyIns = tippy(addTabRef.value as SingleTarget, {
|
205 | 202 | appendTo: () => document.body,
|
|
209 | 206 | interactive: true,
|
210 | 207 | maxWidth: 'none',
|
211 | 208 | offset: [0, 0],
|
212 |
| - onHide() { |
213 |
| - clutersRef.value.hidePopover(); |
214 |
| - }, |
215 |
| - onShow() { |
216 |
| - setTimeout(() => { |
217 |
| - clutersRef.value.showPopover(); |
218 |
| - }); |
219 |
| - }, |
220 | 209 | placement: 'bottom-start',
|
221 | 210 | theme: 'light',
|
222 | 211 | trigger: 'mouseenter click',
|
|
245 | 234 | padding: 0 !important;
|
246 | 235 |
|
247 | 236 | .clusters-select {
|
248 |
| - .bk-select-popover { |
249 |
| - border: none; |
250 |
| - transform: translate3d(0, 41px, 0); |
251 |
| - box-shadow: none; |
| 237 | + margin: 8px; |
| 238 | +
|
| 239 | + .cluster-select-search { |
| 240 | + border-bottom: 1px solid #eaebf0; |
| 241 | + } |
| 242 | +
|
| 243 | + .input-icon { |
| 244 | + display: flex; |
| 245 | + padding-left: 8px; |
| 246 | + font-size: 16px; |
| 247 | + color: #c4c6cc; |
| 248 | + align-items: center; |
| 249 | + justify-content: center; |
| 250 | + } |
| 251 | +
|
| 252 | + .cluster-select-warpper { |
| 253 | + margin-top: 4px; |
| 254 | + } |
| 255 | +
|
| 256 | + .cluster-select-option { |
| 257 | + position: relative; |
| 258 | + display: flex; |
| 259 | + height: 32px; |
| 260 | + overflow: hidden; |
| 261 | + font-size: 12px; |
| 262 | + color: #63656e; |
| 263 | + text-align: left; |
| 264 | + text-overflow: ellipsis; |
| 265 | + white-space: nowrap; |
| 266 | + cursor: pointer; |
| 267 | + user-select: none; |
| 268 | + align-items: center; |
| 269 | +
|
| 270 | + &:hover { |
| 271 | + background-color: #f5f7fa; |
| 272 | + } |
252 | 273 | }
|
253 | 274 | }
|
254 | 275 |
|
|
367 | 388 | font-size: 15px;
|
368 | 389 | color: #c4c6cc;
|
369 | 390 | }
|
370 |
| -
|
371 |
| - .clusters-select { |
372 |
| - .bk-select-popover { |
373 |
| - border: none; |
374 |
| - transform: translate3d(0, 41px, 0); |
375 |
| - box-shadow: none; |
376 |
| - } |
377 |
| - } |
378 | 391 | }
|
379 | 392 | }
|
380 | 393 | </style>
|
0 commit comments