Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cypress/integration/example.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// https://docs.cypress.io/api/introduction/api.html

describe("My First Test", () => {
it("visits the app root url", () => {
cy.visit("/");
cy.contains("h1", "You did it!");
describe('My First Test', () => {
it('visits the app root url', () => {
cy.visit('/');
cy.contains('h1', 'You did it!');
});
});
2 changes: 1 addition & 1 deletion cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// ***********************************************************

// Import commands.js using ES2015 syntax:
import "./commands";
import './commands';

// Alternatively you can use CommonJS syntax:
// require('./commands')
7 changes: 5 additions & 2 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { globalIgnores } from 'eslint/config'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
import * as pluginVue from 'eslint-plugin-vue'
import * as pluginVitest from '@vitest/eslint-plugin'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'

// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
// import { configureVueProject } from '@vue/eslint-config-typescript'
Expand All @@ -24,5 +23,9 @@ export default defineConfigWithVueTs(
...pluginVitest.default.configs.recommended,
files: ['src/**/__tests__/*'],
},
skipFormatting,
{
rules: {
'quotes': ['error', 'single', { 'allowTemplateLiterals': true }],
},
},
)
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"build": "vue-tsc --noEmit -p tsconfig.app.json --composite false && vite build",
"test:unit": "vitest --environment jsdom",
"test:e2e": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress open'",
"lint": "eslint . --fix",
"lint": "eslint .",
"dev": "vite",
"preview": "vite preview --port 5050",
"test:e2e:ci": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress run'"
Expand Down Expand Up @@ -46,7 +46,6 @@
"@vitejs/plugin-vue-jsx": "^5.0.0",
"@vitest/eslint-plugin": "^1.2.7",
"@vue/compiler-sfc": "^3.5.17",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.5.1",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.7.0",
Expand All @@ -57,7 +56,6 @@
"jiti": "^2.4.2",
"jsdom": "^26.1.0",
"npm-run-all2": "^8.0.4",
"prettier": "^3.5.3",
"sass": "^1.89.2",
"start-server-and-test": "^2.0.12",
"typescript": "^5.8.3",
Expand Down
39 changes: 21 additions & 18 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script setup lang="ts">
import { useDevicesStore } from "./stores/devices.js";
import { useSocketIO } from "./plugins/vueSocketIOClient.js";
import type { Socket } from "socket.io-client";
import type Device from "./model/devices/Device";
import { useSettingsStore } from "./stores/settings.js";
import { useAutomationStore } from "./stores/automation.js";
import { storeToRefs } from "pinia";
import { useAppStore } from "./stores/app";
import { useHealthStore } from "./stores/health";
import { useBackendStore } from "@/stores/backend";
import ServerStatusOverlay from "@/components/ServerStatusOverlay.vue";
import { useDevicesStore } from './stores/devices.js';
import { useSocketIO } from './plugins/vueSocketIOClient.js';
import type { Socket } from 'socket.io-client';
import type Device from './model/devices/Device';
import { useSettingsStore } from './stores/settings.js';
import { useAutomationStore } from './stores/automation.js';
import { storeToRefs } from 'pinia';
import { useAppStore } from './stores/app';
import { useHealthStore } from './stores/health';
import { useBackendStore } from '@/stores/backend';
import ServerStatusOverlay from '@/components/ServerStatusOverlay.vue';

const settingsStore = useSettingsStore();
const healthStore = useHealthStore();
Expand All @@ -23,7 +23,7 @@ const { theme } = storeToRefs(settingsStore);
if (backendStore.backendUrl) {
const io = useSocketIO() as Socket;

io.on("connect", () => {
io.on('connect', () => {
backendStore.setServerOnline(true);

// Init/update stores with initial data from server
Expand All @@ -32,9 +32,12 @@ if (backendStore.backendUrl) {
devicesStore.init();
healthStore.init();
});
io.on("disconnect", () => backendStore.setServerOnline(false));
io.on('disconnect', () => {
backendStore.setServerOnline(false);
devicesStore.clear();
});

io.on("deviceDisconnected", (device) => {
io.on('deviceDisconnected', (device) => {
devicesStore.removeDevice(device);

appStore.displaySnackbar(
Expand All @@ -43,7 +46,7 @@ if (backendStore.backendUrl) {
}) disconnected`
);
});
io.on("deviceConnected", (device) => {
io.on('deviceConnected', (device) => {
devicesStore.addDevice(device);

appStore.displaySnackbar(
Expand All @@ -52,17 +55,17 @@ if (backendStore.backendUrl) {
}) connected`
);
});
io.on("deviceRefreshed", (device) => {
io.on('deviceRefreshed', (device) => {
devicesStore.updateDevice(device);
});
io.on("automationConsoleLog", (data: string) => {
io.on('automationConsoleLog', (data: string) => {
automationStore.logMessages.push(data);

if (automationStore.logMessages.length > 500) {
automationStore.logMessages.shift();
}
});
io.on("settingsChanged", async () => {
io.on('settingsChanged', async () => {
await settingsStore.getServerSettings()
});
}
Expand Down
14 changes: 7 additions & 7 deletions src/components/DeviceInfo.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import type Device from "@/model/devices/Device";
import DeviceIcon from "./icons/DeviceIcon.vue";
import { computed, reactive } from "vue";
import {hasProperty} from "@/utils/utils";
import type Device from '@/model/devices/Device';
import DeviceIcon from './icons/DeviceIcon.vue';
import { computed, reactive } from 'vue';
import {hasProperty} from '@/utils/utils';

interface Props {
device: Device;
Expand All @@ -14,12 +14,12 @@ const device = reactive<Device>(props.device);
const lastRefreshed = computed<string>((): string => {
return device.lastRefresh
? new Date(device.lastRefresh).toISOString()
: "n/a";
: 'n/a';
});

const deviceTypeModel = computed<string>((): string => {
return `${device.type} ${
device.type === "slvCtrlPlus" ? ` (model: ${device.deviceModel})` : ""
device.type === 'slvCtrlPlus' ? ` (model: ${device.deviceModel})` : ''
}`;
});

Expand All @@ -38,7 +38,7 @@ function formatFwVersion(fwVersion: string|number): string {
}

function isStringOrNumber(val: unknown): val is string | number {
return typeof val === "string" || typeof val === "number";
return typeof val === 'string' || typeof val === 'number';
}
</script>

Expand Down
8 changes: 4 additions & 4 deletions src/components/ServerStatusOverlay.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import {useBackendStore} from "@/stores/backend";
import {storeToRefs} from "pinia";
import {computed, ref, watch} from "vue";
import {format} from "date-fns";
import {useBackendStore} from '@/stores/backend';
import {storeToRefs} from 'pinia';
import {computed, ref, watch} from 'vue';
import {format} from 'date-fns';

const backendStore = useBackendStore();
const { backendUrl, isServerOnline, wasServerEverOnline } = storeToRefs(backendStore);
Expand Down
14 changes: 7 additions & 7 deletions src/components/__tests__/HelloWorld.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, it, expect } from "vitest";
import { describe, it, expect } from 'vitest';

import { mount } from "@vue/test-utils";
import HelloWorld from "../HelloWorld.vue";
import { mount } from '@vue/test-utils';
import HelloWorld from '../HelloWorld.vue';

describe("HelloWorld", () => {
it("renders properly", () => {
const wrapper = mount(HelloWorld, { props: { msg: "Hello Vitest" } });
expect(wrapper.text()).toContain("Hello Vitest");
describe('HelloWorld', () => {
it('renders properly', () => {
const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } });
expect(wrapper.text()).toContain('Hello Vitest');
});
});
24 changes: 12 additions & 12 deletions src/components/automation/CreateForm.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
<script setup lang="ts">
import { ref } from "vue";
import { useAutomationStore } from "@/stores/automation.js";
import { useAppStore } from "@/stores/app.js";
import { ref } from 'vue';
import { useAutomationStore } from '@/stores/automation.js';
import { useAppStore } from '@/stores/app.js';

const emit = defineEmits(["save", "cancel"]);
const emit = defineEmits(['save', 'cancel']);

const appStore = useAppStore();
const automationStore = useAutomationStore();

const newScriptName = ref("");
const newScriptName = ref('');
const isValid = ref(true);

const scriptNameRules = [
(value: string) => {
if (value) return true;
return "You must enter a script name.";
return 'You must enter a script name.';
},
(value: string) => {
if (value.length >= 3) return true;
return "The script name needs to be at least 3 characters long.";
return 'The script name needs to be at least 3 characters long.';
},
(value: string) => {
if (value.length < 64) return true;
return "The script name needs to no more than 64 characters long.";
return 'The script name needs to no more than 64 characters long.';
Comment on lines 24 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the max-length validation copy.

Line 25 says "needs to no more than 64 characters long." That should read "needs to be no more than 64 characters long."

Suggested fix
-    return 'The script name needs to no more than 64 characters long.';
+    return 'The script name needs to be no more than 64 characters long.';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (value.length < 64) return true;
return "The script name needs to no more than 64 characters long.";
return 'The script name needs to no more than 64 characters long.';
if (value.length < 64) return true;
return 'The script name needs to be no more than 64 characters long.';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/automation/CreateForm.vue` around lines 24 - 25, The
validation message returned by the script name max-length check (the branch
where value.length >= 64 in CreateForm.vue) has a typo; update the string
returned from "The script name needs to no more than 64 characters long." to
"The script name needs to be no more than 64 characters long." so the message
reads correctly when the validation fails.

},
(value: string) => {
if (value.match(/^[a-z\d-_.]+$/)) return true;
return "Only lower case letters, numbers, hyphens, underscores and dots are allowed.";
return 'Only lower case letters, numbers, hyphens, underscores and dots are allowed.';
},
];

Expand All @@ -45,10 +45,10 @@ function createScript(): void {
automationStore.fetchScript(scriptNameWithExt);
})
.then(() => {
emit("save");
newScriptName.value = "";
emit('save');
newScriptName.value = '';
})
.catch((e: Error) => appStore.displaySnackbar(`${e.message}`, "red"));
.catch((e: Error) => appStore.displaySnackbar(`${e.message}`, 'red'));
}
</script>

Expand Down
6 changes: 3 additions & 3 deletions src/components/automation/LogViewer.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from "vue";
import moment from "moment";
import { computed, nextTick, ref, watch } from 'vue';
import moment from 'moment';

interface Props {
logData: string[];
Expand All @@ -11,7 +11,7 @@ const emit = defineEmits(['close']);

const props = defineProps<Props>();

const logData = computed(() => `${props.logData.join("\n")}\n\n`);
const logData = computed(() => `${props.logData.join('\n')}\n\n`);
const runningSinceFormatted = computed(() => {
if (null === props.runningSince) {
return null;
Expand Down
20 changes: 10 additions & 10 deletions src/components/automation/MonacoEditor.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useSettingsStore } from "@/stores/settings.js";
import { storeToRefs } from "pinia";
import {defineAsyncComponent, watch} from "vue";
import type * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
import { useSettingsStore } from '@/stores/settings.js';
import { storeToRefs } from 'pinia';
import {defineAsyncComponent, watch} from 'vue';
import type * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';

// Load Monaco Editor asynchronously for performance reasons
const MonacoEditor = defineAsyncComponent(() => import('monaco-editor-vue3'));
Expand All @@ -28,7 +28,7 @@ const options: monaco.editor.IEditorOptions = {
minimap: { enabled: false },
};

window.addEventListener("resize", () => {
window.addEventListener('resize', () => {
if (editorInstance === null) {
return;
}
Expand All @@ -37,7 +37,7 @@ window.addEventListener("resize", () => {

// wait for next frame to ensure last layout finished
window.requestAnimationFrame(() => {
const monacoElement = document.getElementById("monaco-wrapper");
const monacoElement = document.getElementById('monaco-wrapper');

if (null === editorInstance || null === monacoElement) {
return;
Expand Down Expand Up @@ -85,11 +85,11 @@ declare const console: {
trace: (...args: any[]) => void;
};
`;
const libUri = "ts:filename/facts.d.ts";
const libUri = 'ts:filename/facts.d.ts';

const compilerOptions = {
target: monacoInstance.languages.typescript.ScriptTarget.ES2020,
lib: ["es2020"],
lib: ['es2020'],
allowNonTsExtensions: true,
};

Expand Down Expand Up @@ -124,9 +124,9 @@ watch(
}
);

const emit = defineEmits(["update:code"]);
const emit = defineEmits(['update:code']);

const updateValue = (event: string) => emit("update:code", event);
const updateValue = (event: string) => emit('update:code', event);
</script>

<template>
Expand Down
14 changes: 7 additions & 7 deletions src/components/chart/StreamLineChart.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Line } from "vue-chartjs";
import { Line } from 'vue-chartjs';
import {
Chart as ChartJS,
Title,
Expand All @@ -10,14 +10,14 @@ import {
PointElement,
CategoryScale,
Filler,
} from "chart.js";
import type { ChartOptions, ChartData, Plugin } from "chart.js";
import "chartjs-adapter-luxon";
import ChartStreaming from "chartjs-plugin-streaming";
} from 'chart.js';
import type { ChartOptions, ChartData, Plugin } from 'chart.js';
import 'chartjs-adapter-luxon';
import ChartStreaming from 'chartjs-plugin-streaming';

interface Props {
chartData: ChartData<"line">;
chartOptions: ChartOptions<"line">;
chartData: ChartData<'line'>;
chartOptions: ChartOptions<'line'>;
}

const props = defineProps<Props>();
Expand Down
2 changes: 1 addition & 1 deletion src/components/device/DebouncedSlider.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import type {IntRangeDeviceAttribute} from "@/model/devices/Device";
import type {IntRangeDeviceAttribute} from '@/model/devices/Device';

interface Props {
modelValue: number|undefined;
Expand Down
Loading
Loading