From 427b3bb7741bc424c6014c12b888881a2ba53bdc Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Sun, 13 Apr 2025 22:32:34 +0800
Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E2=80=9C=E8=AE=BE?=
=?UTF-8?q?=E5=A4=87=E7=AE=A1=E7=90=86=E2=80=9D=E8=83=8C=E6=99=AF=E9=A2=9C?=
=?UTF-8?q?=E8=89=B2=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=90=9C=E7=B4=A2=E6=A1=86?=
=?UTF-8?q?=EF=BC=8C=E5=AE=8C=E6=88=90=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86?=
=?UTF-8?q?=E7=9A=84=E5=89=8D=E7=AB=AF=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/views/DeviceManagement.vue | 86 +++++++++++++++----
1 file changed, 69 insertions(+), 17 deletions(-)
diff --git a/main/manager-web/src/views/DeviceManagement.vue b/main/manager-web/src/views/DeviceManagement.vue
index bffefb07..ade5e7d8 100644
--- a/main/manager-web/src/views/DeviceManagement.vue
+++ b/main/manager-web/src/views/DeviceManagement.vue
@@ -1,9 +1,18 @@
+
+
+
-
设备列表
@@ -82,8 +91,9 @@ export default {
data() {
return {
addDeviceDialogVisible: false,
- selectedDevices: [],
+ selectedDevices: [],
isAllSelected: false,
+ searchKeyword: "",
currentAgentId: this.$route.query.agentId || '',
currentPage: 1,
pageSize: 5,
@@ -93,13 +103,22 @@ export default {
};
},
computed: {
+ filteredDeviceList() {
+ const keyword = this.searchKeyword.toLowerCase();
+ if (!keyword) return this.deviceList;
+ return this.deviceList.filter(device =>
+ (device.model && device.model.toLowerCase().includes(keyword)) ||
+ (device.macAddress && device.macAddress.toLowerCase().includes(keyword))
+ );
+ },
+
paginatedDeviceList() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
- return this.deviceList.slice(start, end);
+ return this.filteredDeviceList.slice(start, end);
},
pageCount() {
- return Math.ceil(this.deviceList.length / this.pageSize);
+ return Math.ceil(this.filteredDeviceList.length / this.pageSize);
},
visiblePages() {
const pages = [];
@@ -115,7 +134,7 @@ export default {
pages.push(i);
}
return pages;
- },
+ }
},
mounted() {
const agentId = this.$route.query.agentId;
@@ -124,6 +143,10 @@ export default {
}
},
methods: {
+ handleSearch() {
+ this.currentPage = 1;
+ this.fetchBindDevices(this.currentAgentId);
+ },
handleSelectionChange(val) {
this.selectedDevices = val;
@@ -183,9 +206,7 @@ export default {
Api.device.getAgentBindDevices(agentId, ({ data }) => {
this.loading = false;
if (data.code === 0) {
- // 格式化日期并按照绑定时间降序排列
this.deviceList = data.data.map(device => {
- // 格式化绑定时间
const bindDate = new Date(device.createDate);
const formattedBindTime = `${bindDate.getFullYear()}-${(bindDate.getMonth() + 1).toString().padStart(2, '0')}-${bindDate.getDate().toString().padStart(2, '0')} ${bindDate.getHours().toString().padStart(2, '0')}:${bindDate.getMinutes().toString().padStart(2, '0')}:${bindDate.getSeconds().toString().padStart(2, '0')}`;
return {
@@ -221,9 +242,8 @@ export default {
height: 100vh;
display: flex;
flex-direction: column;
- background: linear-gradient(145deg, #e6eeff, #eff0ff);
+ background: linear-gradient(to bottom right, #dce8ff, #e4eeff, #e6cbfd);
background-size: cover;
- background-position: center;
-webkit-background-size: cover;
-o-background-size: cover;
}
@@ -252,14 +272,6 @@ export default {
}
}
-.device-list-title {
- float: left;
- font-size: 18px;
- font-weight: 700;
- margin: 5px;
- color: #2c3e50;
-}
-
.el-icon-edit {
color: #409eff;
cursor: pointer;
@@ -348,4 +360,44 @@ export default {
}
+.operation-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px 24px;
+ margin-top: 15px;
+}
+
+.page-title {
+ font-size: 24px;
+ margin: 0;
+ color: #2c3e50;
+}
+
+.right-operations {
+ display: flex;
+ gap: 10px;
+ margin-left: auto;
+}
+
+.search-input {
+ width: 280px;
+ border-radius: 4px;
+ transition: all 0.3s;
+}
+
+.btn-search {
+ background: linear-gradient(135deg, #6b8cff, #a966ff);
+ border: none;
+ color: white;
+ transition: all 0.3s;
+
+ &:hover {
+ opacity: 0.9;
+ transform: translateY(-1px);
+ box-shadow: 0 2px 6px rgba(107, 140, 255, 0.4);
+ }
+}
+
+
From 5a4d65986d3ecacf602ec33959873e4cf09fafc8 Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Mon, 14 Apr 2025 07:52:00 +0800
Subject: [PATCH 2/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86=E7=95=8C?=
=?UTF-8?q?=E9=9D=A2=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/views/DeviceManagement.vue | 390 +++++++++++-------
1 file changed, 240 insertions(+), 150 deletions(-)
diff --git a/main/manager-web/src/views/DeviceManagement.vue b/main/manager-web/src/views/DeviceManagement.vue
index ade5e7d8..eb42d565 100644
--- a/main/manager-web/src/views/DeviceManagement.vue
+++ b/main/manager-web/src/views/DeviceManagement.vue
@@ -11,73 +11,86 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ scope.row.remark }}
-
-
-
-
-
-
-
-
-
-
-
-
- 解绑
-
-
-
-
-
-
-
- {{ isAllSelected ? '取消全选' : '全选' }}
-
-
- 新增
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.remark }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 解绑
+
+
+
+
+
+
+
+
+ {{ isAllSelected ? '取消全选' : '全选' }}
+
+
+ 新增
+
+ 删除
+
+
+
+
-
- ©2025 xiaozhi-esp32-server
-
-
-
+
+
+
©2025 xiaozhi-esp32-server
+
@@ -156,6 +169,28 @@ export default {
this.$refs.deviceTable.toggleAllSelection();
},
+ deleteSelected() {
+ if (this.selectedDevices.length === 0) {
+ this.$message.warning("请先选择需要删除的设备");
+ return;
+ }
+
+ this.$confirm(`确定要删除选中的${this.selectedDevices.length}个设备吗?`, '警告', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ const ids = this.selectedDevices.map(device => device.device_id);
+ Api.device.batchDeleteDevices(ids, ({ data }) => {
+ if (data.code === 0) {
+ this.$message.success(`成功删除${this.selectedDevices.length}个设备`);
+ this.fetchBindDevices(this.currentAgentId);
+ } else {
+ this.$message.error(data.msg || '删除失败');
+ }
+ });
+ });
+ },
handleAddDevice() {
this.addDeviceDialogVisible = true;
@@ -214,25 +249,28 @@ export default {
model: device.board,
firmwareVersion: device.appVersion,
macAddress: device.macAddress,
- bindTime: formattedBindTime, // 使用格式化后的时间
+ bindTime: formattedBindTime,
lastConversation: device.lastConnectedAt,
remark: device.alias,
isEdit: false,
otaSwitch: device.autoUpdate === 1,
- // 添加原始时间用于排序
rawBindTime: new Date(device.createDate).getTime()
};
})
- // 按照绑定时间降序排序
.sort((a, b) => a.rawBindTime - b.rawBindTime);
} else {
this.$message.error(data.msg || '获取设备列表失败');
}
});
},
+ headerCellClassName({ columnIndex }) {
+ if (columnIndex === 0) {
+ return "custom-selection-header";
+ }
+ return "";
+ }
}
};
-
From 57ed552f43530fb68f66feb4872e0bcaf2fdc339 Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Mon, 14 Apr 2025 09:34:51 +0800
Subject: [PATCH 3/9] =?UTF-8?q?=E5=AE=8C=E6=88=90=E2=80=9C=E8=AE=BE?=
=?UTF-8?q?=E5=A4=87=E7=AE=A1=E7=90=86=E2=80=9D=E6=A0=B7=E5=BC=8F=E7=9A=84?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/views/DeviceManagement.vue | 59 ++++++++-----------
1 file changed, 24 insertions(+), 35 deletions(-)
diff --git a/main/manager-web/src/views/DeviceManagement.vue b/main/manager-web/src/views/DeviceManagement.vue
index eb42d565..4244f0bf 100644
--- a/main/manager-web/src/views/DeviceManagement.vue
+++ b/main/manager-web/src/views/DeviceManagement.vue
@@ -21,15 +21,14 @@
@selection-change="handleSelectionChange"
class="transparent-table"
:header-cell-class-name="headerCellClassName"
- border
stripe>
-
+
-
-
-
+
+
+
@@ -65,7 +64,7 @@
新增
删除
+ @click="deleteSelected">解绑
-
diff --git a/main/manager-web/src/views/home.vue b/main/manager-web/src/views/home.vue
index 0e9fd32a..2c091a08 100644
--- a/main/manager-web/src/views/home.vue
+++ b/main/manager-web/src/views/home.vue
@@ -19,8 +19,8 @@
Hello, Let's have a wonderful day!
-
-
+
+
添加智能体
From 66fd551d6874875ded4f75d7f88c51f3050e0a3f Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Mon, 14 Apr 2025 14:20:33 +0800
Subject: [PATCH 5/9] =?UTF-8?q?=E5=AE=8C=E6=88=90=E2=80=9C=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E7=AE=A1=E7=90=86=E2=80=9D=E7=9A=84=E8=AE=BE=E7=BD=AE?=
=?UTF-8?q?=E6=AF=8F=E9=A1=B5=E5=A4=A7=E5=B0=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/views/ParamsManagement.vue | 53 +++++++++++++++++--
1 file changed, 50 insertions(+), 3 deletions(-)
diff --git a/main/manager-web/src/views/ParamsManagement.vue b/main/manager-web/src/views/ParamsManagement.vue
index e9baa1e8..883cb809 100644
--- a/main/manager-web/src/views/ParamsManagement.vue
+++ b/main/manager-web/src/views/ParamsManagement.vue
@@ -16,7 +16,7 @@
+ :header-cell-class-name="headerCellClassName" :max-height="tableMaxHeight">
删除
-
©2025 xiaozhi-esp32-server
+
@@ -423,20 +423,6 @@ export default {
margin-left: 10px;
}
-.copyright {
- text-align: center;
- color: #979db1;
- font-size: 12px;
- font-weight: 400;
- margin-top: auto;
- padding: 30px 0 20px;
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
-}
-
:deep(.transparent-table) {
background: white;
border: none;
diff --git a/main/manager-web/src/views/ModelConfig.vue b/main/manager-web/src/views/ModelConfig.vue
index 343cb06f..002a3e5a 100644
--- a/main/manager-web/src/views/ModelConfig.vue
+++ b/main/manager-web/src/views/ModelConfig.vue
@@ -126,9 +126,9 @@
-
- ©2025 xiaozhi-esp32-server
-
+
+
+
@@ -639,19 +639,6 @@ export default {
gap: 8px;
}
-.copyright {
- text-align: center;
- color: #979db1;
- font-size: 12px;
- font-weight: 400;
- margin-top: auto;
- padding: 30px 0 20px;
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
-}
.title-wrapper {
display: flex;
diff --git a/main/manager-web/src/views/ParamsManagement.vue b/main/manager-web/src/views/ParamsManagement.vue
index 883cb809..47c4edf9 100644
--- a/main/manager-web/src/views/ParamsManagement.vue
+++ b/main/manager-web/src/views/ParamsManagement.vue
@@ -73,7 +73,7 @@
-
©2025 xiaozhi-esp32-server
+
@@ -399,20 +399,6 @@ export default {
}
}
-.copyright {
- text-align: center;
- color: #979db1;
- font-size: 12px;
- font-weight: 400;
- margin-top: auto;
- padding: 30px 0 20px;
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
-}
-
.custom-pagination {
display: flex;
align-items: center;
diff --git a/main/manager-web/src/views/UserManagement.vue b/main/manager-web/src/views/UserManagement.vue
index 45015d97..79593591 100644
--- a/main/manager-web/src/views/UserManagement.vue
+++ b/main/manager-web/src/views/UserManagement.vue
@@ -70,7 +70,7 @@
- ©2025 xiaozhi-esp32-server
+
@@ -465,20 +465,6 @@ export default {
color: black;
}
-.copyright {
- text-align: center;
- color: #979db1;
- font-size: 12px;
- font-weight: 400;
- margin-top: auto;
- padding: 30px 0 20px;
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
-}
-
.custom-pagination {
display: flex;
align-items: center;
diff --git a/main/manager-web/src/views/home.vue b/main/manager-web/src/views/home.vue
index 2c091a08..eeeb499e 100644
--- a/main/manager-web/src/views/home.vue
+++ b/main/manager-web/src/views/home.vue
@@ -260,4 +260,7 @@ export default {
text-align: center;
/* 居中显示 */
}
+
+
+
\ No newline at end of file
diff --git a/main/manager-web/src/views/roleConfig.vue b/main/manager-web/src/views/roleConfig.vue
index 75ec04e4..1b6d861a 100644
--- a/main/manager-web/src/views/roleConfig.vue
+++ b/main/manager-web/src/views/roleConfig.vue
@@ -81,9 +81,9 @@
-
- ©2025 xiaozhi-esp32-server
-
+
+
+
From 98a4ce701cac233cb7938e741c57274ffee5afc8 Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Mon, 14 Apr 2025 16:10:46 +0800
Subject: [PATCH 7/9] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D"=E8=AE=BE=E5=A4=87?=
=?UTF-8?q?=E7=AE=A1=E7=90=86"=E9=A1=B5=E9=9D=A2=E8=A7=A3=E7=BB=91?=
=?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=97=B6=E5=87=BA=E7=8E=B0=E7=9A=84=E5=BC=82?=
=?UTF-8?q?=E5=B8=B8=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=89=B9=E9=87=8F=E8=A7=A3?=
=?UTF-8?q?=E7=BB=91=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=AE=8C=E5=96=84=E6=90=9C?=
=?UTF-8?q?=E7=B4=A2=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/views/DeviceManagement.vue | 78 ++++++++++++++++---
.../src/views/ParamsManagement.vue | 1 -
2 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/main/manager-web/src/views/DeviceManagement.vue b/main/manager-web/src/views/DeviceManagement.vue
index 913ee0cc..9e362edb 100644
--- a/main/manager-web/src/views/DeviceManagement.vue
+++ b/main/manager-web/src/views/DeviceManagement.vue
@@ -26,9 +26,9 @@
-
-
-
+
+
+
@@ -40,15 +40,15 @@
-
+
-
+
-
+
解绑
@@ -86,7 +86,6 @@
-
@@ -105,17 +104,19 @@ export default {
selectedDevices: [],
isAllSelected: false,
searchKeyword: "",
+ activeSearchKeyword: "",
currentAgentId: this.$route.query.agentId || '',
currentPage: 1,
pageSize: 5,
deviceList: [],
loading: false,
userApi: null,
+
};
},
computed: {
filteredDeviceList() {
- const keyword = this.searchKeyword.toLowerCase();
+ const keyword = this.activeSearchKeyword.toLowerCase();
if (!keyword) return this.deviceList;
return this.deviceList.filter(device =>
(device.model && device.model.toLowerCase().includes(keyword)) ||
@@ -155,8 +156,8 @@ export default {
},
methods: {
handleSearch() {
+ this.activeSearchKeyword = this.searchKeyword;
this.currentPage = 1;
- this.fetchBindDevices(this.currentAgentId);
},
handleSelectionChange(val) {
@@ -168,7 +169,53 @@ export default {
},
deleteSelected() {
- console.log("批量解绑")
+ if (this.selectedDevices.length === 0) {
+ this.$message.warning({
+ message: '请至少选择一条记录',
+ showClose: true
+ });
+ return;
+ }
+
+ this.$confirm(`确认要解绑选中的 ${this.selectedDevices.length} 台设备吗?`, '警告', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ const deviceIds = this.selectedDevices.map(device => device.device_id);
+ this.batchUnbindDevices(deviceIds);
+ });
+ },
+
+ batchUnbindDevices(deviceIds) {
+ const promises = deviceIds.map(id => {
+ return new Promise((resolve, reject) => {
+ Api.device.unbindDevice(id, ({ data }) => {
+ if (data.code === 0) {
+ resolve();
+ } else {
+ reject(data.msg || '解绑失败');
+ }
+ });
+ });
+ });
+
+ Promise.all(promises)
+ .then(() => {
+ this.$message.success({
+ message: `成功解绑 ${deviceIds.length} 台设备`,
+ showClose: true
+ });
+ this.fetchBindDevices(this.currentAgentId);
+ this.selectedDevices = [];
+ this.isAllSelected = false;
+ })
+ .catch(error => {
+ this.$message.error({
+ message: error || '批量解绑过程中出现错误',
+ showClose: true
+ });
+ });
},
handleAddDevice() {
@@ -237,6 +284,8 @@ export default {
};
})
.sort((a, b) => a.rawBindTime - b.rawBindTime);
+ this.activeSearchKeyword = "";
+ this.searchKeyword = "";
} else {
this.$message.error(data.msg || '获取设备列表失败');
}
@@ -465,4 +514,13 @@ export default {
font-weight: bold;
padding-bottom: 18px;
}
+
+:deep(.el-table .el-button--text) {
+ color: #7079aa;
+}
+
+:deep(.el-table .el-button--text:hover) {
+ color: #5a64b5;
+}
+
diff --git a/main/manager-web/src/views/ParamsManagement.vue b/main/manager-web/src/views/ParamsManagement.vue
index 47c4edf9..55fdf2d2 100644
--- a/main/manager-web/src/views/ParamsManagement.vue
+++ b/main/manager-web/src/views/ParamsManagement.vue
@@ -73,7 +73,6 @@
-
From b15c59aa48392205ad51a2b7f752b632d6fac5ed Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Mon, 14 Apr 2025 17:23:07 +0800
Subject: [PATCH 8/9] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=88=86?=
=?UTF-8?q?=E9=A1=B5=E5=99=A8=E9=A2=9C=E8=89=B2=E4=B8=8D=E4=B8=80=E8=87=B4?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/manager-web/src/views/ParamsManagement.vue | 5 +++--
main/manager-web/src/views/home.vue | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/main/manager-web/src/views/ParamsManagement.vue b/main/manager-web/src/views/ParamsManagement.vue
index 55fdf2d2..d6e0d956 100644
--- a/main/manager-web/src/views/ParamsManagement.vue
+++ b/main/manager-web/src/views/ParamsManagement.vue
@@ -410,7 +410,8 @@ export default {
.pagination-btn:first-child,
.pagination-btn:nth-child(2),
- .pagination-btn:nth-last-child(2) {
+ .pagination-btn:nth-last-child(2),
+ .pagination-btn:nth-child(3) {
min-width: 60px;
height: 32px;
padding: 0 12px;
@@ -432,7 +433,7 @@ export default {
}
}
- .pagination-btn:not(:first-child):not(:nth-child(2)):not(:nth-last-child(2)) {
+ .pagination-btn:not(:first-child):not(:nth-child(3)):not(:nth-child(2)):not(:nth-last-child(2)) {
min-width: 28px;
height: 32px;
padding: 0;
diff --git a/main/manager-web/src/views/home.vue b/main/manager-web/src/views/home.vue
index eeeb499e..c33d2049 100644
--- a/main/manager-web/src/views/home.vue
+++ b/main/manager-web/src/views/home.vue
@@ -25,7 +25,7 @@
-
+
From e528510f5ca9823cf6252f7405f78ab8c92e9a25 Mon Sep 17 00:00:00 2001
From: CGD <3030332422@qq.com>
Date: Tue, 15 Apr 2025 08:24:06 +0800
Subject: [PATCH 9/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E7=AE=A1=E7=90=86=E7=9A=84=E9=A1=B5=E9=9D=A2=E9=AB=98?=
=?UTF-8?q?=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/manager-web/src/views/ParamsManagement.vue | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/main/manager-web/src/views/ParamsManagement.vue b/main/manager-web/src/views/ParamsManagement.vue
index d6e0d956..c815a77b 100644
--- a/main/manager-web/src/views/ParamsManagement.vue
+++ b/main/manager-web/src/views/ParamsManagement.vue
@@ -296,12 +296,16 @@ export default {
}
.main-wrapper {
- margin: 5px 22px;
- border-radius: 15px;
- min-height: 600px;
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
- position: relative;
- background: rgba(237, 242, 255, 0.5);
+ margin: 5px 22px;
+ border-radius: 15px;
+ min-height: calc(100vh - 350px);
+ height: auto;
+ max-height: 80vh;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+ position: relative;
+ background: rgba(237, 242, 255, 0.5);
+ display: flex;
+ flex-direction: column;
}
.operation-bar {