web-map/src/components/robot-groups.vue

155 lines
5.6 KiB
Vue
Raw Normal View History

2025-05-05 01:06:09 +08:00
<script setup lang="ts">
import { type RobotGroup, type RobotInfo } from '@api/robot';
import type { RobotAddModalRef } from '@common/modal/robot-add-modal.vue';
import type { RobotGroupRenameModalRef } from '@common/modal/robot-group-rename-modal.vue';
import type { RobotRegisterModalRef } from '@common/modal/robot-register-modal.vue';
import type { EditorService } from '@core/editor.service';
import { Modal } from 'ant-design-vue';
import { map } from 'lodash-es';
import { computed, inject, type InjectionKey, ref, type ShallowRef, shallowRef } from 'vue';
import { useI18n } from 'vue-i18n';
type Props = {
token: InjectionKey<ShallowRef<EditorService>>;
editable?: boolean;
current?: string;
};
const props = defineProps<Props>();
const editor = inject(props.token)!;
type Events = {
(e: 'change', id: string): void;
};
const emit = defineEmits<Events>();
const { t } = useI18n();
//#region 接口
//#endregion
const keyword = ref<string>('');
//#region 机器人列表
const groups = computed<RobotGroup[]>(() => editor.value.robotGroups.value ?? []);
const robots = computed<RobotInfo[]>(() => editor.value.robots.filter(({ label }) => label.includes(keyword.value)));
const getGroupRobots = (ids: RobotGroup['robots']) =>
ids?.map((id) => editor.value.getRobotById(id)).filter((robot) => robot?.label.includes(keyword.value));
const selected = ref<RobotInfo['id'][]>([]);
const isAllSelected = computed<boolean>(() => robots.value.every(({ id }) => selected.value.includes(id)));
const selectAll = (checked: boolean) => {
selected.value = checked ? map(robots.value, 'id') : [];
};
//#endregion
//#region 机器人组操作
const refAddRobot = shallowRef<RobotAddModalRef>();
const refRegisterRobot = shallowRef<RobotRegisterModalRef>();
const refRenameGroup = shallowRef<RobotGroupRenameModalRef>();
const toDeleteGroup = (id: RobotGroup['id']) =>
Modal.confirm({
class: 'confirm',
title: t('您确定要删除该机器人组吗?'),
centered: true,
cancelText: t('返回'),
okText: t('删除'),
onOk: () => editor.value.deleteRobotGroup(id),
});
//#endregion
</script>
<template>
<RobotAddModal ref="refAddRobot" :token="token" />
<RobotRegisterModal ref="refRegisterRobot" :token="token" />
<RobotGroupRenameModal ref="refRenameGroup" :token="token" />
<a-flex class="full" vertical>
<a-input class="search mb-16" :placeholder="$t('请输入搜索关键字')" v-model:value="keyword">
<template #suffix><SearchOutlined /></template>
</a-input>
<a-flex v-if="editable" class="mb-8" style="height: 32px" justify="space-between" align="center">
<a-checkbox :checked="isAllSelected" @change="selectAll($event.target.checked)">{{ $t('全选') }}</a-checkbox>
<a-space align="center">
<a-button class="icon-btn panel-btn" size="small" :disabled="!selected.length">
<i class="mask control" />
</a-button>
<a-button class="icon-btn panel-btn" size="small" :disabled="!selected.length">
<i class="mask trash_fill" />
</a-button>
</a-space>
</a-flex>
<a-collapse style="flex: auto; overflow-y: auto" expand-icon-position="end" ghost>
<template #expandIcon="v">
<i class="icon dropdown" :class="{ active: v?.isActive }" />
</template>
<a-collapse-panel v-for="{ id, label, robots } in groups" :key="id" :header="label">
<template v-if="editable" #extra>
<a-dropdown placement="bottomRight">
<a-button class="icon-btn" size="small">
<i class="icon dot" />
</a-button>
<template #overlay>
<a-menu>
<a-menu-item>
<a-space align="center" :size="4" @click="refAddRobot?.open(id)">
<i class="icon plus size-20" />
<span>{{ $t('添加机器人') }}</span>
</a-space>
</a-menu-item>
<a-menu-item>
<a-space align="center" :size="4" @click="refRegisterRobot?.open(id)">
<i class="icon register size-20" />
<span>{{ $t('注册机器人') }}</span>
</a-space>
</a-menu-item>
<a-menu-item @click="refRenameGroup?.open(id, label)">
<a-space align="center" :size="4">
<i class="icon pen size-20" />
<span>{{ $t('修改组名称') }}</span>
</a-space>
</a-menu-item>
<a-menu-item @click="toDeleteGroup(id)">
<a-space align="center" :size="4">
<i class="icon trash size-20" />
<span>{{ $t('删除组') }}</span>
</a-space>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
<a-list :data-source="getGroupRobots(robots)">
<template #renderItem="{ item }">
<a-list-item
class="ph-16"
:class="{ selected: item.id === current }"
style="height: 36px"
@click="emit('change', item.id)"
>
<template #actions> </template>
<a-typography-text>{{ item.label }}</a-typography-text>
</a-list-item>
</template>
</a-list>
</a-collapse-panel>
</a-collapse>
<a-button class="mt-8" v-if="editable" type="dashed" size="large" block @click="editor.createRobotGroup()">
<i class="mask plus size-20 primary" />
<span>{{ $t('添加机器人组') }}</span>
</a-button>
</a-flex>
</template>
<style scoped lang="scss">
.btn {
justify-self: flex-end;
}
</style>