Files
Situation-Awareness-Platfor…/src/components/BranchSelect/index.vue
2025-03-12 18:41:20 +08:00

119 lines
2.7 KiB
Vue

<template>
<div class="fordeep relative" :class="{ forended: isEnded }">
<Icon class="absolute z-10 top-2 left-4" :name="branchIcon" :size="branchIconSize" />
<d-editable-select
:max-height="maxHeight"
placeholder=""
v-model="value"
:options="branchList"
:enable-lazy-load="true"
@load-more="loadMore"
:loading="loading"
:width="width"
@input-change="inputChange"
>
<template #item="{ option, index }">
<div class="flex gap-2 items-center overflow-hidden">
<Icon :name="branchIcon" :size="branchIconSize" />
<div class="flex-1 ellipsis">{{ option.label }}</div>
</div>
</template>
</d-editable-select>
</div>
</template>
<script setup>
import { ref, watch, reactive, computed } from 'vue';
import { getBranches } from '@/api/branch';
import repo from '@/router/config/repo';
import { escapeResData } from '@/utils';
import { useVModel } from '@vueuse/core';
import debounce from 'lodash/debounce';
const branchIcon = 'gt-branches';
const branchIconSize = '16px';
const props = defineProps(['repo', 'value', 'sort', 'width', 'maxHeight']);
const emit = defineEmits(['update:value']);
const value = useVModel(props, 'value', emit);
const page = reactive({
per_page: 20,
page: 1
});
const total = ref(0);
const search = ref('');
const branchList = ref([]);
const loading = ref(false);
const isEnded = computed(() => total.value && (page.page - 1) * page.per_page > total.value);
const getList = debounce(
(isInputChange) => {
if (isEnded.value) return;
loading.value = true;
getBranches({
repoId: props.repo,
sort: props.sort,
search: search.value,
...page
})
.then((res) => {
const data = escapeResData(res);
total.value = data.total;
const list = data.content.map((x) => ({ label: x.name, value: x.name }));
if (isInputChange) branchList.value = list;
else branchList.value = [...branchList.value, ...list];
})
.finally(() => (loading.value = false));
},
500,
{
leading: true
}
);
const loadMore = () => {
page.page += 1;
getList();
};
const inputChange = (e) => {
search.value = e;
reset();
getList(true);
};
const reset = () => {
page.page = 1;
branchList.value = [];
};
watch(
repo,
() => {
reset();
getList();
},
{ immediate: true }
);
</script>
<style scoped lang="scss">
.fordeep {
:deep(.devui-editable-select-input__inner) {
padding-left: 32px;
}
}
.forended {
:deep(.devui-editable-select__inner:after) {
content: '--- 到底啦 ---';
display: flex;
justify-content: center;
color: #888;
padding-top: 10px;
}
}
</style>