From cbd270b9dfd23138cbcc79d6fcd716a6276f8325 Mon Sep 17 00:00:00 2001
From: NeoPlays <80448387+NeoPlays@users.noreply.github.com>
Date: Wed, 10 Jul 2024 16:10:20 +0200
Subject: [PATCH 1/5] FIX: CPU Issue
---
.../components/UI/edit-page/EditScreen.vue | 16 ++----
.../components/UI/node-page/NodeScreen.vue | 33 +-----------
.../UI/node-page/components/node/NodeBody.vue | 9 ----
.../node/clients/ConsensusClients.vue | 2 +-
.../node/clients/ExecutionClients.vue | 4 +-
.../src/components/layers/NetworkStatus.vue | 13 +----
launcher/src/composables/multiSetups.js | 37 +-------------
launcher/src/composables/pingQuality.js | 51 ++++++++-----------
launcher/src/composables/services.js | 33 ++++++++++--
launcher/src/store/theNode.js | 1 +
10 files changed, 64 insertions(+), 135 deletions(-)
diff --git a/launcher/src/components/UI/edit-page/EditScreen.vue b/launcher/src/components/UI/edit-page/EditScreen.vue
index 8b013e5740..a021838ccc 100644
--- a/launcher/src/components/UI/edit-page/EditScreen.vue
+++ b/launcher/src/components/UI/edit-page/EditScreen.vue
@@ -147,7 +147,7 @@ import { useServers } from "@/store/servers";
import { useServices } from "@/store/services";
import { useFooter } from "@/store/theFooter";
import { useStakingStore } from "@/store/theStaking";
-import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from "vue";
+import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";
import { useRouter } from "vue-router";
import { useMultiSetups } from "../../../composables/multiSetups";
import { useSetups } from "../../../store/setups";
@@ -171,6 +171,7 @@ import SetupInfos from "./components/modals/setups/SetupInfos.vue";
import ChangesSection from "./sections/ChangesSection.vue";
import ServiceSection from "./sections/ServiceSection.vue";
import SidebarSection from "./sections/SidebarSection.vue";
+import { useFrontendServices } from "@/composables/services";
const setupStore = useSetups();
const footerStore = useFooter();
@@ -200,7 +201,7 @@ const nukeModalComponent = ref();
const selectedSetupNetwork = ref("");
const changeAnime = ref("/animation/confirm-changes/modify.gif");
const setupImportAnime = ref("/animation/setup/loader.gif");
-const { loadSetups, loadServices, getAllSetups, getServerView, updateDom } = useMultiSetups();
+const { loadSetups, getAllSetups, getServerView, updateDom } = useMultiSetups();
// Computed & Watcher
@@ -226,13 +227,6 @@ const getAimationSrc = computed(() => {
// { deep: true }
// );
-watch(
- () => manageStore.newConfiguration.length,
- () => {
- updateDom();
- }
-);
-
watchEffect(() => {
if (setupStore.isImportAnimeActive) {
setTimeout(() => {
@@ -291,7 +285,6 @@ onUnmounted(() => {
// Methods
const fetchSetups = async () => {
await loadSetups();
- await loadServices();
setupStore.editSetups = getAllSetups();
};
@@ -818,6 +811,7 @@ const confirmHandler = async () => {
} catch (error) {
console.error("Error processing changes:", error);
} finally {
+ await useFrontendServices();
await resetState();
}
};
@@ -858,10 +852,10 @@ const resetState = async () => {
setupStore.selectedSetupToRemove = [];
manageStore.isLineHidden = false;
await listKeys();
+ await updateDom();
setTimeout(() => {
manageStore.disableConfirmButton = false;
}, 3000);
- await updateDom();
};
const nukeConfirmation = () => {
diff --git a/launcher/src/components/UI/node-page/NodeScreen.vue b/launcher/src/components/UI/node-page/NodeScreen.vue
index 6f9fc26bf6..a649eb9670 100755
--- a/launcher/src/components/UI/node-page/NodeScreen.vue
+++ b/launcher/src/components/UI/node-page/NodeScreen.vue
@@ -71,7 +71,6 @@ import { onMounted, onUnmounted, ref, watchEffect } from "vue";
import { useRouter } from "vue-router";
import { useRefreshNodeStats } from "../../../composables/monitoring";
import { useMultiSetups } from "../../../composables/multiSetups";
-import { usePingQuality } from "../../../composables/pingQuality";
import { useListKeys } from "../../../composables/validators";
import NetworkStatus from "../../layers/NetworkStatus.vue";
import AlertSection from "./sections/AlertSection.vue";
@@ -90,12 +89,10 @@ const router = useRouter();
const footerStore = useFooter();
const setupStore = useSetups();
const { updateDom } = useMultiSetups();
-const { checkConnectionQuality, startPolling, stopPolling } = usePingQuality();
const expertModeClient = ref(null);
const isExpertModeOpen = ref(false);
const isLogsPageActive = ref(false);
-const refreshStats = ref(false);
let polling = null;
let pollingVitals = null;
@@ -125,28 +122,11 @@ watchEffect(() => {
}
});
-watchEffect(() => {
- if (refreshStats.value) {
- updateConnectionStats();
- refreshStats.value = false;
- }
-});
-
-watchEffect(() => {
- if (serviceStore.installedServices.length) {
- updateDom();
- }
-});
-
//***************** Lifecycle Hooks *****************
onMounted(async () => {
- await fetchSetups();
- checkConnectionQuality();
+ await updateDom();
nodeSetupsPrepration();
- setTimeout(() => {
- refreshStats.value = true;
- }, 2000);
updateConnectionStats();
@@ -156,7 +136,6 @@ onMounted(async () => {
pollingVitals = setInterval(updateServerVitals, 1000); // refresh server vitals
pollingNodeStats = setInterval(updateNodeStats, 1000); // refresh server vitals
pollingListingKeys = setInterval(checkForListingKeys, 1000); // check for validators which need validator listing
- startPolling();
});
onUnmounted(() => {
@@ -166,22 +145,12 @@ onUnmounted(() => {
clearInterval(pollingListingKeys);
clearInterval(pollingPings);
setupStore.isConfigViewActive = false;
- stopPolling();
setupStore.selectedSetup = null;
});
//************* Methods *************
-const fetchSetups = async () => {
- await updateDom();
-};
-// const checkConnection = async () => {
-// let num = 1;
-// console.log("checking connection", num++);
-// let connection = await ControlService.checkConnectionQuality();
-// console.log("connected", connection);
-// };
//get all configs and services
const nodeSetupsPrepration = () => {
diff --git a/launcher/src/components/UI/node-page/components/node/NodeBody.vue b/launcher/src/components/UI/node-page/components/node/NodeBody.vue
index 64fe526516..f07945221f 100755
--- a/launcher/src/components/UI/node-page/components/node/NodeBody.vue
+++ b/launcher/src/components/UI/node-page/components/node/NodeBody.vue
@@ -226,15 +226,6 @@ const openSetup = (setup) => {
setupStore.selectedSetup = setup;
// setupStore.selectedSetup.isActive = true;
setupStore.isConfigViewActive = true;
-
- serviceStore.installedServices = serviceStore.installedServices.filter((service) => {
- const isNotServerService = !setupStore.serverServices.includes(service.name);
- const isServiceInSetup = setup.services.some(
- (svc) => svc.id === service.config?.serviceID
- );
-
- return isNotServerService && isServiceInSetup;
- });
};
const exportSetup = (setup) => {
diff --git a/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue b/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
index 1ca05f6731..83f3c8e166 100755
--- a/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
+++ b/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
@@ -63,7 +63,7 @@ const getConsensusServices = computed(() => {
return [];
}
- const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s.id);
+ const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s?.config?.serviceID);
const services = serviceStore.installedServices
.filter(
(s) =>
diff --git a/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue b/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
index bb77647059..d49ea1b78a 100755
--- a/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
+++ b/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
@@ -71,9 +71,7 @@ const getExecutionServices = computed(() => {
if (!setupStore.selectedSetup || !setupStore.selectedSetup.services) {
return [];
}
-
- const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s.id);
-
+ const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s?.config?.serviceID);
const services = serviceStore.installedServices
.filter(
(s) =>
diff --git a/launcher/src/components/layers/NetworkStatus.vue b/launcher/src/components/layers/NetworkStatus.vue
index 949a3629de..b4b7f3ee21 100644
--- a/launcher/src/components/layers/NetworkStatus.vue
+++ b/launcher/src/components/layers/NetworkStatus.vue
@@ -33,14 +33,14 @@
diff --git a/launcher/src/composables/multiSetups.js b/launcher/src/composables/multiSetups.js
index 56b7cf8725..fa7749553c 100644
--- a/launcher/src/composables/multiSetups.js
+++ b/launcher/src/composables/multiSetups.js
@@ -3,10 +3,8 @@ import { useServices } from "@/store/services";
import { useSetups } from "@/store/setups";
import { useNodeManage } from "@/store/nodeManage";
import { useDeepClone } from "@/composables/utils";
-import { ref } from "vue";
export const useMultiSetups = () => {
- const services = ref([]);
const setupStore = useSetups();
const serviceStore = useServices();
const manageStore = useNodeManage();
@@ -20,14 +18,6 @@ export const useMultiSetups = () => {
}
};
- const loadServices = async () => {
- try {
- services.value = await ControlService.getServices();
- } catch (e) {
- console.error("Couldn't read services", e);
- }
- };
-
const parseYAMLData = (data) => {
const parsedConfigs = [];
const lines = data.split("\n");
@@ -64,8 +54,8 @@ export const useMultiSetups = () => {
setupType: config.setupType,
network: config.network,
color: config.color,
- services: services.value
- .filter((service) => config.serviceIds.includes(service.id))
+ services: serviceStore.installedServices
+ .filter((service) => config.serviceIds.includes(service.config.serviceID))
.map((s) => {
return {
...s,
@@ -97,38 +87,15 @@ export const useMultiSetups = () => {
setupStore.selectedSetup = null;
};
- const updateInstalledServices = () => {
- serviceStore.installedServices = serviceStore.installedServices.map((service) => {
- if (!service.setupId) {
- for (const setup of setupStore.allSetups) {
- const matchingService = setup.services.find((s) => s.id === service?.config?.serviceID);
-
- if (matchingService) {
- return {
- ...service,
- setupId: setup.setupId,
- setupName: setup.setupName,
- };
- }
- }
- }
- return service;
- });
- };
-
const updateDom = async () => {
- await loadSetups();
- await loadServices();
setupStore.allSetups = getAllSetups();
setupStore.editSetups = getAllSetups();
- updateInstalledServices();
manageStore.newConfiguration = useDeepClone(serviceStore.installedServices);
setupStore.updateSelectedSetup();
};
return {
loadSetups,
- loadServices,
getAllSetups,
getSelectedSetup,
getServerView,
diff --git a/launcher/src/composables/pingQuality.js b/launcher/src/composables/pingQuality.js
index 8c48483965..1246fd94c5 100644
--- a/launcher/src/composables/pingQuality.js
+++ b/launcher/src/composables/pingQuality.js
@@ -1,23 +1,37 @@
import { useNodeStore } from "@/store/theNode";
import ControlService from "@/store/ControlService.js";
-import { ref, onUnmounted } from "vue";
+import { ref } from "vue";
export function usePingQuality() {
const nodeStore = useNodeStore();
let connectionStatus = ref(null);
- let intervalId = null;
// Compare real-time ping with predefined ping quality levels
const getConnectionQuality = (pingTime) => {
+ nodeStore.pingHistory.push(pingTime);
+ if (nodeStore.pingHistory.length > 3) {
+ nodeStore.pingHistory.shift();
+ }
+
+ if (nodeStore.pingHistory.every(val => val === "unknown") && nodeStore.pingHistory.length === 3) {
+ return {
+ status: "unknown",
+ description: "Unable to determine connection quality.",
+ };
+ }
+
+ if (pingTime === "unknown") {
+ pingTime = nodeStore.pingHistory.find(val => val !== "unknown")
+ }
+
for (let i = 0; i < nodeStore.pingQuality.length; i++) {
if (pingTime <= nodeStore.pingQuality[i].maxRate) {
- return nodeStore.pingQuality[i];
+ return {
+ ...nodeStore.pingQuality[i],
+ pingTime: pingTime,
+ };
}
}
- return {
- status: "unknown",
- description: "Unable to determine connection quality.",
- };
};
const checkConnectionQuality = async () => {
@@ -26,7 +40,7 @@ export function usePingQuality() {
const quality = getConnectionQuality(res.pingTime);
connectionStatus.value = {
status: quality.status,
- pingTime: res.pingTime,
+ pingTime: quality.pingTime,
description: quality.description,
};
nodeStore.connectionStatus = connectionStatus.value;
@@ -40,28 +54,7 @@ export function usePingQuality() {
}
};
- const startPolling = () => {
- if (!intervalId) {
- intervalId = setInterval(async () => {
- await checkConnectionQuality();
- }, 10000); // Polling interval
- }
- };
-
- const stopPolling = () => {
- if (intervalId) {
- clearInterval(intervalId);
- intervalId = null;
- }
- };
-
- onUnmounted(() => {
- stopPolling(); // Clean up interval on component unmount
- });
-
return {
checkConnectionQuality,
- startPolling,
- stopPolling,
};
}
diff --git a/launcher/src/composables/services.js b/launcher/src/composables/services.js
index 1a02feea1c..5536d5bc59 100644
--- a/launcher/src/composables/services.js
+++ b/launcher/src/composables/services.js
@@ -4,6 +4,9 @@ import { useNodeHeader } from "@/store/nodeHeader";
import { useNodeManage } from "@/store/nodeManage";
import { useFooter } from "@/store/theFooter";
import { useDeepClone } from "@/composables/utils";
+import { useMultiSetups } from "@/composables/multiSetups";
+import { useSetups } from "@/store/setups";
+import { usePingQuality } from "@/composables/pingQuality";
export async function useBackendServices(force = false) {
const serviceStore = useServices();
@@ -43,13 +46,21 @@ export async function useFrontendServices() {
const serviceStore = useServices();
const nodeHeaderStore = useNodeHeader();
const nodeManageStore = useNodeManage();
-
+ const setupStore = useSetups();
+ const { loadSetups, getAllSetups } = useMultiSetups();
+ const { checkConnectionQuality } = usePingQuality();
+ checkConnectionQuality();
const allServices = JSON.parse(JSON.stringify(serviceStore.allServices));
if (nodeHeaderStore.refresh) {
if (await useConnectionCheck()) {
let services;
+ let setups;
try {
services = await ControlService.refreshServiceInfos();
+ await loadSetups();
+ setups = getAllSetups();
+ setupStore.allSetups = setups;
+ setupStore.editSetups = setups;
} catch (error) {
console.log(error);
return;
@@ -111,13 +122,27 @@ export async function useFrontendServices() {
}
return oldService;
});
- serviceStore.installedServices = newServices.concat(otherServices).map((e, i) => {
- e.id = i;
- return e;
+ serviceStore.installedServices = newServices.concat(otherServices).map((service, i) => {
+ service.id = i;
+ if (!service.setupId) {
+ for (const setup of setups) {
+ const matchingService = setup.services.find((s) => s?.config?.serviceID === service?.config?.serviceID);
+
+ if (matchingService) {
+ return {
+ ...service,
+ setupId: setup.setupId,
+ setupName: setup.setupName,
+ };
+ }
+ }
+ }
+ return service;
});
let network = serviceStore.installedServices[0]?.config?.network;
nodeManageStore.currentNetwork = nodeManageStore.networkList.find((item) => item.network === network);
+ // Mange Tunnels
if (needForTunnel.length != 0 && nodeHeaderStore.refresh) {
let localPorts = await ControlService.getAvailablePort({
min: 9000,
diff --git a/launcher/src/store/theNode.js b/launcher/src/store/theNode.js
index 149f6229c4..cbc5d66bf4 100755
--- a/launcher/src/store/theNode.js
+++ b/launcher/src/store/theNode.js
@@ -35,6 +35,7 @@ export const useNodeStore = defineStore("theNode", {
description: "Very poor connection quality with high latency.Try reconnecting to the node.",
},
],
+ pingHistory: [],
connectionStatus: null,
connectionStatusIsPoor: false,
skeletonLoading: false,
From e4c939376610992ee8bc7e6f7afbce367ba3f1bb Mon Sep 17 00:00:00 2001
From: NeoPlays <80448387+NeoPlays@users.noreply.github.com>
Date: Mon, 15 Jul 2024 09:27:24 +0200
Subject: [PATCH 2/5] FIX: Tunnels and clients not loading
---
.../UI/node-page/components/node/clients/ConsensusClients.vue | 4 +---
.../UI/node-page/components/node/clients/ExecutionClients.vue | 4 +---
launcher/src/components/UI/the-control/DataApi.vue | 2 +-
launcher/src/components/UI/the-control/RpcEndpoint.vue | 2 +-
launcher/src/components/UI/the-control/WsEndpoint.vue | 2 +-
5 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue b/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
index 83f3c8e166..fd877310d1 100755
--- a/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
+++ b/launcher/src/components/UI/node-page/components/node/clients/ConsensusClients.vue
@@ -63,13 +63,11 @@ const getConsensusServices = computed(() => {
return [];
}
- const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s?.config?.serviceID);
const services = serviceStore.installedServices
.filter(
(s) =>
s.category === "consensus" &&
- selectedServiceIds.includes(s.config.serviceID) &&
- s.setupId === setupStore.selectedSetup.setupId
+ s.setupId === setupStore.selectedSetup?.setupId
)
.sort((a, b) => {
const fa = a.name.toLowerCase();
diff --git a/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue b/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
index d49ea1b78a..fbcb1eb774 100755
--- a/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
+++ b/launcher/src/components/UI/node-page/components/node/clients/ExecutionClients.vue
@@ -71,13 +71,11 @@ const getExecutionServices = computed(() => {
if (!setupStore.selectedSetup || !setupStore.selectedSetup.services) {
return [];
}
- const selectedServiceIds = setupStore.selectedSetup.services.map((s) => s?.config?.serviceID);
const services = serviceStore.installedServices
.filter(
(s) =>
s.category === "execution" &&
- selectedServiceIds.includes(s.config.serviceID) &&
- s.setupId === setupStore.selectedSetup.setupId
+ s.setupId === setupStore.selectedSetup?.setupId
)
.sort((a, b) => {
const fa = a.name.toLowerCase();
diff --git a/launcher/src/components/UI/the-control/DataApi.vue b/launcher/src/components/UI/the-control/DataApi.vue
index 136d1dcec3..6ba36e8800 100755
--- a/launcher/src/components/UI/the-control/DataApi.vue
+++ b/launcher/src/components/UI/the-control/DataApi.vue
@@ -87,7 +87,7 @@ export default {
},
filteredDataApiItems() {
if (this.selectedSetup && Array.isArray(this.selectedSetup.services)) {
- const serviceIds = this.selectedSetup.services.map((service) => service.id);
+ const serviceIds = this.selectedSetup.services.map((service) => service?.config?.serviceID);
return this.dataApiItems.filter((item) => serviceIds.includes(item.id));
}
return [];
diff --git a/launcher/src/components/UI/the-control/RpcEndpoint.vue b/launcher/src/components/UI/the-control/RpcEndpoint.vue
index 28e45a1ac2..925d1c3d08 100755
--- a/launcher/src/components/UI/the-control/RpcEndpoint.vue
+++ b/launcher/src/components/UI/the-control/RpcEndpoint.vue
@@ -87,7 +87,7 @@ export default {
}),
filteredRpcItems() {
if (this.selectedSetup && Array.isArray(this.selectedSetup.services)) {
- const serviceIds = this.selectedSetup.services.map((service) => service.id);
+ const serviceIds = this.selectedSetup.services.map((service) => service?.config?.serviceID);
return this.rpcItems.filter((item) => serviceIds.includes(item.id));
}
return [];
diff --git a/launcher/src/components/UI/the-control/WsEndpoint.vue b/launcher/src/components/UI/the-control/WsEndpoint.vue
index b3b4a2d244..3a75e89f6b 100755
--- a/launcher/src/components/UI/the-control/WsEndpoint.vue
+++ b/launcher/src/components/UI/the-control/WsEndpoint.vue
@@ -88,7 +88,7 @@ export default {
},
filteredWSItems() {
if (this.selectedSetup && Array.isArray(this.selectedSetup.services)) {
- const serviceIds = this.selectedSetup.services.map((service) => service.id);
+ const serviceIds = this.selectedSetup.services.map((service) => service?.config?.serviceID);
return this.wsItems.filter((item) => serviceIds.includes(item.id));
}
return [];
From 77af5ba77e09953b831949df5d277a5adce34162 Mon Sep 17 00:00:00 2001
From: Max Behzadi <69126271+MaxTheGeeek@users.noreply.github.com>
Date: Mon, 15 Jul 2024 10:12:02 +0200
Subject: [PATCH 3/5] FIX: setup menu on click
---
launcher/public/output.css | 17 ++++++-----------
.../components/edit/setups/SetupMenu.vue | 3 +++
.../components/edit/setups/SingleSetup.vue | 4 ++--
3 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/launcher/public/output.css b/launcher/public/output.css
index b7e7a38ca4..f0099d8a13 100755
--- a/launcher/public/output.css
+++ b/launcher/public/output.css
@@ -2571,11 +2571,6 @@ video {
appearance: none;
}
-.auto-cols-max{
- grid-auto-columns: -webkit-max-content;
- grid-auto-columns: max-content;
-}
-
.grid-flow-row{
grid-auto-flow: row;
}
@@ -2862,6 +2857,12 @@ video {
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
+.space-y-3 > :not([hidden]) ~ :not([hidden]){
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
+}
+
.space-y-4 > :not([hidden]) ~ :not([hidden]){
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
@@ -2886,12 +2887,6 @@ video {
margin-bottom: calc(1px * var(--tw-space-y-reverse));
}
-.space-y-3 > :not([hidden]) ~ :not([hidden]){
- --tw-space-y-reverse: 0;
- margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
-}
-
.divide-x > :not([hidden]) ~ :not([hidden]){
--tw-divide-x-reverse: 0;
border-right-width: calc(1px * var(--tw-divide-x-reverse));
diff --git a/launcher/src/components/UI/edit-page/components/edit/setups/SetupMenu.vue b/launcher/src/components/UI/edit-page/components/edit/setups/SetupMenu.vue
index efb09470ef..3d87827fc8 100755
--- a/launcher/src/components/UI/edit-page/components/edit/setups/SetupMenu.vue
+++ b/launcher/src/components/UI/edit-page/components/edit/setups/SetupMenu.vue
@@ -24,6 +24,7 @@
diff --git a/launcher/src/components/UI/edit-page/components/modals/setups/CreateSetup.vue b/launcher/src/components/UI/edit-page/components/modals/setups/CreateSetup.vue
index bce86374bb..d549d957b7 100644
--- a/launcher/src/components/UI/edit-page/components/modals/setups/CreateSetup.vue
+++ b/launcher/src/components/UI/edit-page/components/modals/setups/CreateSetup.vue
@@ -181,7 +181,7 @@ watch(
layoutMsg.value = "";
} else {
buttonDisabled.value = true;
- if (setupName.value.trim() === "") {
+ if (setupName.value.trim() === "" || setupName.value.trim() === "commonServices") {
nameMsg.value = "Please enter a name for your setup";
}
if (setupColor.value === "") {