temp
This commit is contained in:
parent
0c3b2b405b
commit
07f7a378c0
@ -3,46 +3,44 @@
|
|||||||
"success": true,
|
"success": true,
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-1",
|
"id": "mock-robot-1",
|
||||||
"label": "模拟机器人A",
|
"label": "模拟机器人A",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 1,
|
"type": 1
|
||||||
"ip": "127.0.1.1"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-2",
|
"id": "mock-robot-2",
|
||||||
"label": "模拟机器人B",
|
"label": "模拟机器人B",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 2,
|
"type": 2
|
||||||
"ip": "127.0.1.2"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-3",
|
"id": "mock-robot-3",
|
||||||
"label": "模拟机器人C",
|
"label": "模拟机器人C",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 3,
|
"type": 3
|
||||||
"ip": "127.0.1.3"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-2",
|
||||||
"id": "mock-robot-4",
|
"id": "mock-robot-4",
|
||||||
"label": "模拟机器人D",
|
"label": "模拟机器人D",
|
||||||
"brand": "模拟品牌B",
|
"brand": "模拟品牌B",
|
||||||
"type": 1,
|
"type": 1
|
||||||
"ip": "127.0.2.1"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "mock-robot-5",
|
"id": "mock-robot-5",
|
||||||
"label": "模拟机器人E",
|
"label": "模拟机器人E",
|
||||||
"brand": "模拟品牌B",
|
"brand": "模拟品牌B",
|
||||||
"type": 2,
|
"type": 2
|
||||||
"ip": "127.0.2.2"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "mock-robot-6",
|
"id": "mock-robot-6",
|
||||||
"label": "模拟机器人F",
|
"label": "模拟机器人F",
|
||||||
"brand": "模拟品牌B",
|
"brand": "模拟品牌B",
|
||||||
"type": 3,
|
"type": 3
|
||||||
"ip": "127.0.2.3"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"message": "模拟提示"
|
"message": "模拟提示"
|
||||||
|
@ -10,25 +10,25 @@
|
|||||||
"label": "模拟机器人组A",
|
"label": "模拟机器人组A",
|
||||||
"robots": [
|
"robots": [
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-1",
|
"id": "mock-robot-1",
|
||||||
"label": "模拟机器人A",
|
"label": "模拟机器人A",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 1,
|
"type": 1
|
||||||
"ip": "127.0.1.1"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-2",
|
"id": "mock-robot-2",
|
||||||
"label": "模拟机器人B",
|
"label": "模拟机器人B",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 2,
|
"type": 2
|
||||||
"ip": "127.0.1.2"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-1",
|
||||||
"id": "mock-robot-3",
|
"id": "mock-robot-3",
|
||||||
"label": "模拟机器人C",
|
"label": "模拟机器人C",
|
||||||
"brand": "模拟品牌A",
|
"brand": "模拟品牌A",
|
||||||
"type": 3,
|
"type": 3
|
||||||
"ip": "127.0.1.3"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -37,25 +37,11 @@
|
|||||||
"label": "模拟机器人组B",
|
"label": "模拟机器人组B",
|
||||||
"robots": [
|
"robots": [
|
||||||
{
|
{
|
||||||
|
"gid": "mock-robot-group-2",
|
||||||
"id": "mock-robot-4",
|
"id": "mock-robot-4",
|
||||||
"label": "模拟机器人D",
|
"label": "模拟机器人D",
|
||||||
"brand": "模拟品牌B",
|
"brand": "模拟品牌B",
|
||||||
"type": 1,
|
"type": 1
|
||||||
"ip": "127.0.2.1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "mock-robot-5",
|
|
||||||
"label": "模拟机器人E",
|
|
||||||
"brand": "模拟品牌B",
|
|
||||||
"type": 2,
|
|
||||||
"ip": "127.0.2.2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "mock-robot-6",
|
|
||||||
"label": "模拟机器人F",
|
|
||||||
"brand": "模拟品牌B",
|
|
||||||
"type": 3,
|
|
||||||
"ip": "127.0.2.3"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,43 @@
|
|||||||
border-color: get-color(warning);
|
border-color: get-color(warning);
|
||||||
box-shadow: 0 2px 0 0 get-color(0000000a);
|
box-shadow: 0 2px 0 0 get-color(0000000a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.icon-btn {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
&.ant-btn-sm {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-checkbox {
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .ant-checkbox-inner {
|
||||||
|
background-color: get-color(141414);
|
||||||
|
border-color: get-color(434343);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ant-checkbox-checked:not(.ant-checkbox-disabled) > .ant-checkbox-inner {
|
||||||
|
background-color: get-color(primary);
|
||||||
|
border-color: get-color(primary);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: get-color(141414);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-checkbox-wrapper {
|
||||||
|
align-items: center;
|
||||||
|
font: 400 14px/22px Roboto;
|
||||||
|
color: get-color(ffffffa6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-collapse.ant-collapse-ghost {
|
.ant-collapse.ant-collapse-ghost {
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
@use 'asset/icons/icon' as *;
|
@use 'asset/icons/icon' as *;
|
||||||
|
|
||||||
@include themed {
|
@include themed {
|
||||||
|
i {
|
||||||
|
&.bg-1 {
|
||||||
|
background-color: get-color(ffffffd9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
display: inline-block;
|
@extend %icon;
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1;
|
|
||||||
vertical-align: top;
|
|
||||||
|
|
||||||
@each $icon in $icons {
|
@each $icon in $icons {
|
||||||
&.#{$icon} {
|
&.#{$icon} {
|
||||||
@ -16,4 +17,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
@extend %icon;
|
||||||
|
|
||||||
|
@each $icon in $icons {
|
||||||
|
&.#{$icon} {
|
||||||
|
mask: get-icon($icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,15 @@ export interface RobotGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RobotInfo {
|
export interface RobotInfo {
|
||||||
|
gid?: string; // 机器人组id
|
||||||
id: string; // 机器人id
|
id: string; // 机器人id
|
||||||
label: string; // 机器人名称
|
label: string; // 机器人名称
|
||||||
brand: RobotBrand; // 机器人品牌
|
brand: RobotBrand; // 机器人品牌
|
||||||
type: RobotType; // 机器人类型
|
type: RobotType; // 机器人类型
|
||||||
ip: string; // 机器人ip
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RobotDetail extends RobotInfo {
|
export interface RobotDetail extends RobotInfo {
|
||||||
group?: string; // 机器人组id
|
ip: string; // 机器人ip
|
||||||
isSimulative?: boolean; // 是否仿真机器人
|
isSimulative?: boolean; // 是否仿真机器人
|
||||||
battery?: number; // 机器人电量
|
battery?: number; // 机器人电量
|
||||||
minBattery?: number; // 最小电量
|
minBattery?: number; // 最小电量
|
||||||
|
@ -1 +1 @@
|
|||||||
$icons: (dropdown, edit, exit);
|
$icons: (control, dropdown, edit, exit, trash_fill);
|
||||||
|
BIN
src/assets/icons/dark/control.png
Normal file
BIN
src/assets/icons/dark/control.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 971 B |
BIN
src/assets/icons/dark/trash_fill.png
Normal file
BIN
src/assets/icons/dark/trash_fill.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 767 B |
@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { RobotGroup, RobotInfo } from '@api/robot';
|
import type { RobotGroup, RobotInfo } from '@api/robot';
|
||||||
import type { EditorService } from '@core/editor.service';
|
import type { EditorService } from '@core/editor.service';
|
||||||
import { chain } from 'lodash-es';
|
import { chain, groupBy, map } from 'lodash-es';
|
||||||
import { computed, inject, type InjectionKey, ref, type ShallowRef } from 'vue';
|
import { computed, inject, type InjectionKey, ref, type ShallowRef } from 'vue';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -15,11 +15,21 @@ const editor = inject(props.editor)!;
|
|||||||
const keyword = ref<string>('');
|
const keyword = ref<string>('');
|
||||||
|
|
||||||
//#region 机器人列表
|
//#region 机器人列表
|
||||||
// const groups = computed<RobotGroup[]>(() => chain(props.groups).filter().value())
|
const robotList = computed<RobotInfo[]>(() =>
|
||||||
const robots = computed<RobotInfo[]>(() => chain(props.groups).map('robots').flatten().value());
|
chain(props.groups)
|
||||||
|
.map('robots')
|
||||||
|
.flatten()
|
||||||
|
.filter(({ label }) => label.includes(keyword.value))
|
||||||
|
.value(),
|
||||||
|
);
|
||||||
|
const robotGroupMap = computed<Record<RobotGroup['id'], RobotInfo[]>>(() => groupBy(robotList.value, 'gid'));
|
||||||
|
|
||||||
const selected = ref<RobotInfo['id'][]>([]);
|
const selected = ref<RobotInfo['id'][]>([]);
|
||||||
const isAllSelected = computed<boolean>(() => robots.value.every(({ id }) => selected.value.includes(id)));
|
const isAllSelected = computed<boolean>(() => robotList.value.every(({ id }) => selected.value.includes(id)));
|
||||||
|
|
||||||
|
const selectAll = (checked: boolean) => {
|
||||||
|
selected.value = checked ? map(robotList.value, 'id') : [];
|
||||||
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -30,15 +40,20 @@ const isAllSelected = computed<boolean>(() => robots.value.every(({ id }) => sel
|
|||||||
</a-input>
|
</a-input>
|
||||||
|
|
||||||
<a-flex v-if="editable" class="mb-8" style="height: 32px" flex="none" justify="space-between" align="center">
|
<a-flex v-if="editable" class="mb-8" style="height: 32px" flex="none" justify="space-between" align="center">
|
||||||
<a-checkbox :checked="isAllSelected">{{ $t('全选') }}</a-checkbox>
|
<a-checkbox :checked="isAllSelected" @change="selectAll($event.target.checked)">{{ $t('全选') }}</a-checkbox>
|
||||||
|
<a-space>
|
||||||
|
<a-button class="icon-btn" size="small" :disabled="!selected.length">
|
||||||
|
<i class="mask control bg-1" />
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
</a-flex>
|
</a-flex>
|
||||||
|
|
||||||
<a-collapse class="scroll" expand-icon-position="end" ghost>
|
<a-collapse class="scroll" expand-icon-position="end" ghost>
|
||||||
<template #expandIcon="v">
|
<template #expandIcon="v">
|
||||||
<i class="icon dropdown" :class="{ active: v?.isActive }" />
|
<i class="icon dropdown" :class="{ active: v?.isActive }" />
|
||||||
</template>
|
</template>
|
||||||
<a-collapse-panel v-for="{ id, label, robots } in groups" :key="id" :header="label">
|
<a-collapse-panel v-for="{ id, label } in groups" :key="id" :header="label">
|
||||||
<a-list :data-source="robots">
|
<a-list :data-source="robotGroupMap[id]">
|
||||||
<template #renderItem="{ item }">
|
<template #renderItem="{ item }">
|
||||||
<a-list-item class="ph-16" style="height: 36px">
|
<a-list-item class="ph-16" style="height: 36px">
|
||||||
<template #actions> </template>
|
<template #actions> </template>
|
||||||
|
@ -47,11 +47,11 @@ watch(editable, (v) => {
|
|||||||
<a-typography-text strong>{{ title }}</a-typography-text>
|
<a-typography-text strong>{{ title }}</a-typography-text>
|
||||||
<a-space align="center">
|
<a-space align="center">
|
||||||
<a-button v-if="editable" class="warning" @click="editable = false">
|
<a-button v-if="editable" class="warning" @click="editable = false">
|
||||||
<i class="icon exit mr-8" />
|
<i class="icon exit size-18 mr-8" />
|
||||||
<span>{{ $t('退出编辑器') }}</span>
|
<span>{{ $t('退出编辑器') }}</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button v-else type="primary" @click="editable = true">
|
<a-button v-else type="primary" @click="editable = true">
|
||||||
<i class="icon edit mr-8" />
|
<i class="icon edit size-18 mr-8" />
|
||||||
<span>{{ $t('启用编辑器') }}</span>
|
<span>{{ $t('启用编辑器') }}</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button>{{ $t('推送') }}</a-button>
|
<a-button>{{ $t('推送') }}</a-button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user