From 8c8a5276b49833c08bca133e374e1e66273b41aa Mon Sep 17 00:00:00 2001 From: Pujit Mehrotra Date: Mon, 16 Jun 2025 11:50:37 -0400 Subject: [PATCH] fix: omit Connect actions in UPC when plugin is not installed (#1417) Removes Connect branding in dropdown when connect plugin is not installed. Preview of dropdown: image ## Summary by CodeRabbit - **New Features** - The Notifications Sidebar is now always visible in the user profile, regardless of plugin installation status. - **Refactor** - Improved detection logic for the connect plugin to enhance accuracy. - Centralized and standardized the "Settings" link in the user profile dropdown for consistent user experience. - The account status section in Connect Settings now only appears when the connect plugin is installed. - Updated the Connect page title from "Unraid Connect" to "Unraid API" for clarity. - **Chores** - Extended linting to include Vue files for better code quality enforcement. --- package.json | 2 +- .../plugins/dynamix.my.servers/Connect.page | 2 +- .../dynamix.my.servers/include/state.php | 21 +++++++++++++++---- web/__test__/components/UserProfile.test.ts | 4 ++-- .../ConnectSettings/ConnectSettings.ce.vue | 9 ++++++-- web/components/UserProfile.ce.vue | 7 ++----- .../UserProfile/DropdownContent.vue | 12 +++++------ 7 files changed, 36 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 3f2165bd0..9d3802a94 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "pre-commit": "pnpm lint-staged" }, "lint-staged": { - "*.{js,jsx,ts,tsx}": [ + "*.{js,jsx,ts,tsx,vue}": [ "pnpm lint:fix" ] }, diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page index cbb481b84..802ea0fa8 100644 --- a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page @@ -1,5 +1,5 @@ Menu="ManagementAccess:100" -Title="Unraid Connect" +Title="Unraid API" Icon="icon-u-globe" Tag="globe" --- diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php index e8a436efa..5182e912d 100644 --- a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php @@ -146,10 +146,23 @@ class ServerState private function setConnectValues() { - if (file_exists('/usr/local/bin/unraid-api')) { - $this->connectPluginInstalled = 'dynamix.unraid.net.plg'; + $apiConfigPath = '/boot/config/plugins/dynamix.my.servers/configs/api.json'; + if (!file_exists($apiConfigPath)) { + return; // plugin is not installed; exit early } - + + $apiConfig = @json_decode(file_get_contents($apiConfigPath), true); + $pluginName = 'unraid-api-plugin-connect'; // name of connect plugin's npm package + if ($apiConfig && is_array($apiConfig['plugins'])) { + foreach ($apiConfig['plugins'] as $plugin) { + // recognize npm version identifiers inside $apiConfig['plugins'] + if ($plugin === $pluginName || strpos($plugin, $pluginName . '@') === 0) { + $this->connectPluginInstalled = 'dynamix.unraid.net.plg'; + break; + } + } + } + // exit early if the plugin is not installed if (!$this->connectPluginInstalled) { return; @@ -181,7 +194,7 @@ class ServerState $this->myServersFlashCfg = file_exists($flashCfgPath) ? @parse_ini_file($flashCfgPath, true) : []; $connectJsonPath = '/boot/config/plugins/dynamix.my.servers/configs/connect.json'; $connectConfig = file_exists($connectJsonPath) ? @json_decode(file_get_contents($connectJsonPath), true) : []; - + // ensure some vars are defined here so we don't have to test them later if (empty($connectConfig['apikey'])) { $connectConfig['apikey'] = ""; diff --git a/web/__test__/components/UserProfile.test.ts b/web/__test__/components/UserProfile.test.ts index f76be17ec..e7b02aacd 100644 --- a/web/__test__/components/UserProfile.test.ts +++ b/web/__test__/components/UserProfile.test.ts @@ -294,13 +294,13 @@ describe('UserProfile.ce.vue', () => { expect(heading.html()).toContain(initialServerData.description); }); - it('conditionally renders notifications sidebar based on connectPluginInstalled', async () => { + it('always renders notifications sidebar, regardless of connectPluginInstalled', async () => { expect(wrapper.find('[data-testid="notifications-sidebar"]').exists()).toBe(true); serverStore.connectPluginInstalled = ''; await wrapper.vm.$nextTick(); - expect(wrapper.find('[data-testid="notifications-sidebar"]').exists()).toBe(false); + expect(wrapper.find('[data-testid="notifications-sidebar"]').exists()).toBe(true); }); it('conditionally renders banner based on theme store', async () => { diff --git a/web/components/ConnectSettings/ConnectSettings.ce.vue b/web/components/ConnectSettings/ConnectSettings.ce.vue index 77b004707..8c00381c7 100644 --- a/web/components/ConnectSettings/ConnectSettings.ce.vue +++ b/web/components/ConnectSettings/ConnectSettings.ce.vue @@ -8,11 +8,14 @@ import { useMutation, useQuery } from '@vue/apollo-composable'; import { BrandButton, jsonFormsRenderers, Label } from '@unraid/ui'; import { JsonForms } from '@jsonforms/vue'; +import { useServerStore } from '~/store/server'; // unified settings values are returned as JSON, so use a generic record type // import type { ConnectSettingsValues } from '~/composables/gql/graphql'; import { getConnectSettingsForm, updateConnectSettings } from './graphql/settings.query'; +const { connectPluginInstalled } = storeToRefs(useServerStore()); + /**-------------------------------------------- * Settings State & Form definition *---------------------------------------------**/ @@ -99,8 +102,10 @@ const onChange = ({ data }: { data: Record }) => {
- -
+
- +