From cf3f2c75723f3237f36d94713abe32ab04df598f Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Wed, 1 May 2024 15:37:34 -0400 Subject: [PATCH] feat(admin): identify external plugins (#1202) Signed-off-by: Yi Cai --- .sonarcloud.properties | 2 +- .../dynamic-plugins-info.spec.ts | 9 +- plugins/dynamic-plugins-info/package.json | 1 + .../__fixtures__/listLoadedPluginsResult.ts | 24 +++- plugins/dynamic-plugins-info/src/api/types.ts | 2 + .../DynamicPluginsInfoContent.tsx | 11 +- .../DynamicPluginsTable.test.tsx | 92 ++++++++----- .../DynamicPluginsTable.tsx | 87 +++++++++--- .../src/components/InternalPluginsMap.tsx | 126 ++++++++++++++++++ 9 files changed, 287 insertions(+), 67 deletions(-) create mode 100644 plugins/dynamic-plugins-info/src/components/InternalPluginsMap.tsx diff --git a/.sonarcloud.properties b/.sonarcloud.properties index e0a956610..5bc44f69b 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -1,2 +1,2 @@ # comma delimited path of files to exclude from copy/paste duplicate checking -sonar.cpd.exclusions=packages/app/src/components/DynamicRoot/DynamicRoot.test.tsx,packages/app/src/components/admin/AdminTabs.test.tsx,packages/app/src/components/catalog/EntityPage/defaultTabs.tsx +sonar.cpd.exclusions=packages/app/src/components/DynamicRoot/DynamicRoot.test.tsx,packages/app/src/components/admin/AdminTabs.test.tsx,packages/app/src/components/catalog/EntityPage/defaultTabs.tsx,plugins/dynamic-plugins-info/src/components/InternalPluginsMap.tsx diff --git a/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts b/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts index c7fa6d1fb..8978c7991 100644 --- a/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts @@ -16,20 +16,19 @@ test.describe('dynamic-plugins-info UI tests', () => { await uiHelper.clickTab('Plugins'); }); - test('it should show a table and have a support button, the table should contain techdocs plugins', async ({ + test('it should show a table, and the table should contain techdocs plugins', async ({ page, }) => { // what shows up in the list depends on how the instance is configured so // let's check for the main basic elements of the component to verify the // mount point is working as expected - await uiHelper.verifyText('Installed Plugins', false); + await uiHelper.verifyText('Plugins', false); await uiHelper.verifyText('5 rows'); await uiHelper.verifyText('Name'); await uiHelper.verifyText('Version'); + await uiHelper.verifyText('Enabled'); + await uiHelper.verifyText('Preinstalled'); await uiHelper.verifyText('Role'); - await uiHelper.clickButton('Support'); - await uiHelper.verifyText('All of the installed plugins'); - await uiHelper.clickButton('Close'); // Check the filter and use that to verify that the table contains the // dynamic-plugins-info plugin, which is required for this test to run diff --git a/plugins/dynamic-plugins-info/package.json b/plugins/dynamic-plugins-info/package.json index 793249508..0b2e2951e 100644 --- a/plugins/dynamic-plugins-info/package.json +++ b/plugins/dynamic-plugins-info/package.json @@ -29,6 +29,7 @@ "@backstage/core-plugin-api": "1.9.1", "@backstage/theme": "0.5.2", "@material-table/core": "3.1.0", + "@mui/material": "5.15.6", "react-use": "17.4.0" }, "peerDependencies": { diff --git a/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts b/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts index d8d93f27e..363a1b794 100644 --- a/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts +++ b/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts @@ -1,38 +1,50 @@ export const listLoadedPluginsResult = [ { - name: 'some-plugin-one', + name: 'api-returned-some-plugin-one', version: '0.1.0', role: 'frontend-plugin', platform: 'web', + internal: true, + enabled: true, }, { - name: 'some-plugin-two', + name: 'api-returned-some-plugin-two', version: '1.1.0', role: 'backend-plugin-module', platform: 'node', + internal: false, + enabled: true, }, { - name: 'some-plugin-three', + name: 'api-returned-some-plugin-three', version: '0.1.2', role: 'backend-plugin', platform: 'node', + internal: false, + enabled: true, }, { - name: 'some-plugin-four', + name: 'api-returned-some-plugin-four', version: '1.1.0', role: 'frontend-plugin', platform: 'web', + internal: true, + enabled: true, }, { - name: 'some-plugin-five', + name: 'api-returned-some-plugin-five', version: '1.2.0', role: 'frontend-plugin', platform: 'web', + internal: true, + enabled: true, }, { - name: 'some-plugin-six', + name: 'api-returned-some-plugin-six', version: '0.6.3', role: 'backend-plugin', platform: 'node', + internal: true, + enabled: true, }, ]; diff --git a/plugins/dynamic-plugins-info/src/api/types.ts b/plugins/dynamic-plugins-info/src/api/types.ts index af6b4d908..d8dd3af37 100644 --- a/plugins/dynamic-plugins-info/src/api/types.ts +++ b/plugins/dynamic-plugins-info/src/api/types.ts @@ -5,6 +5,8 @@ export type DynamicPluginInfo = { version: string; role: string; platform: string; + enabled: boolean; + internal: boolean; }; export interface DynamicPluginsInfoApi { diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx index 6b56251a8..1fff94d42 100644 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx +++ b/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx @@ -1,14 +1,9 @@ import React from 'react'; - -import { ContentHeader, SupportButton } from '@backstage/core-components'; - +import Box from '@mui/material/Box'; import { DynamicPluginsTable } from '../DynamicPluginsTable/DynamicPluginsTable'; export const DynamicPluginsInfoContent = () => ( - <> - - All of the installed plugins - + - + ); diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx index e2a33a4bc..463b0c052 100644 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx +++ b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx @@ -27,19 +27,38 @@ describe('DynamicPluginsTable', () => { const { findByText, container } = await renderWithEffects( , ); - expect(await findByText('Installed Plugins (6)')).toBeInTheDocument(); - expect(await findByText('some-plugin-five')).toBeInTheDocument(); + // 6 mockapi returned external(enabled) + 52 internal(not enabled) + // mockapi returns enabled plugins + // keys from InternalPluginsMap are internal plugins + expect(await findByText('Plugins (58)')).toBeInTheDocument(); + expect( + await findByText('@janus-idp/backstage-plugin-3scale-backend-dynamic'), + ).toBeInTheDocument(); const nameCells = Array.from( container.querySelectorAll('tbody tr > td:first-child'), ); const versionCells = Array.from( container.querySelectorAll('tbody tr > td:nth-child(2)'), ); + const enabledCells = Array.from( + container.querySelectorAll('tbody tr > td:nth-child(3)'), + ); + const internalCells = Array.from( + container.querySelectorAll('tbody tr > td:nth-child(4)'), + ); expect(nameCells.length).toBe(5); - expect(nameCells[0].textContent).toBe('some-plugin-five'); - expect(nameCells[4].textContent).toBe('some-plugin-three'); - expect(versionCells[0].textContent).toBe('1.2.0'); - expect(versionCells[4].textContent).toBe('0.1.2'); + expect(nameCells[0].textContent).toBe( + '@janus-idp/backstage-plugin-3scale-backend-dynamic', + ); + expect(nameCells[4].textContent).toBe( + '@janus-idp/backstage-plugin-jfrog-artifactory', + ); + expect(versionCells[0].textContent).toBe(''); + expect(versionCells[4].textContent).toBe(''); + expect(enabledCells[0].textContent).toBe('No'); + expect(enabledCells[4].textContent).toBe('No'); + expect(internalCells[0].textContent).toBe('Yes'); + expect(internalCells[4].textContent).toBe('Yes'); }); it('supports filtering by a simple text search', async () => { @@ -52,11 +71,11 @@ describe('DynamicPluginsTable', () => { container.querySelectorAll('tbody tr > td:first-child'), ); expect(nameCells.length).toBe(2); - expect(nameCells[0].textContent).toBe('some-plugin-five'); - expect(nameCells[1].textContent).toBe('some-plugin-four'); + expect(nameCells[0].textContent).toBe('api-returned-some-plugin-five'); + expect(nameCells[1].textContent).toBe('api-returned-some-plugin-four'); }); - it('supports sorting by name and version columns', async () => { + it('supports sorting by name, version and rhdh embedded columns', async () => { const { findByText, container } = await renderWithEffects( , ); @@ -64,40 +83,53 @@ describe('DynamicPluginsTable', () => { let nameCells = Array.from( container.querySelectorAll('tbody tr > td:first-child'), ); - let versionCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(2)'), - ); expect(nameCells.length).toBe(5); - expect(nameCells[0].textContent).toBe('some-plugin-five'); - expect(nameCells[4].textContent).toBe('some-plugin-three'); - expect(versionCells[0].textContent).toBe('1.2.0'); - expect(versionCells[4].textContent).toBe('0.1.2'); + expect(nameCells[0].textContent).toBe( + '@janus-idp/backstage-plugin-3scale-backend-dynamic', + ); + expect(nameCells[4].textContent).toBe( + '@janus-idp/backstage-plugin-jfrog-artifactory', + ); await act(() => findByText('Name').then(el => el.click())); // ascending by name nameCells = Array.from( container.querySelectorAll('tbody tr > td:first-child'), ); - versionCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(2)'), - ); expect(nameCells.length).toBe(5); - expect(nameCells[0].textContent).toBe('some-plugin-two'); - expect(nameCells[4].textContent).toBe('some-plugin-four'); - expect(versionCells[0].textContent).toBe('1.1.0'); - expect(versionCells[4].textContent).toBe('1.1.0'); + expect(nameCells[0].textContent).toBe( + 'roadiehq-scaffolder-backend-module-utils-dynamic', + ); + expect(nameCells[4].textContent).toBe('roadiehq-backstage-plugin-jira'); // ascending by version await act(() => findByText('Version').then(el => el.click())); nameCells = Array.from( container.querySelectorAll('tbody tr > td:first-child'), ); - versionCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(2)'), + expect(nameCells.length).toBe(5); + expect(nameCells[0].textContent).toBe('api-returned-some-plugin-five'); + expect(nameCells[4].textContent).toBe('api-returned-some-plugin-three'); + + // ascending by enabled + await act(() => findByText('Enabled').then(el => el.click())); + nameCells = Array.from( + container.querySelectorAll('tbody tr > td:first-child'), ); expect(nameCells.length).toBe(5); - expect(nameCells[0].textContent).toBe('some-plugin-five'); - expect(nameCells[4].textContent).toBe('some-plugin-three'); - expect(versionCells[0].textContent).toBe('1.2.0'); - expect(versionCells[4].textContent).toBe('0.1.2'); + expect(nameCells[0].textContent).toBe('api-returned-some-plugin-six'); + expect(nameCells[4].textContent).toBe('api-returned-some-plugin-two'); + + // ascending by Preinstalled + await act(() => findByText('Preinstalled').then(el => el.click())); + nameCells = Array.from( + container.querySelectorAll('tbody tr > td:first-child'), + ); + expect(nameCells.length).toBe(5); + expect(nameCells[0].textContent).toBe( + '@janus-idp/backstage-plugin-analytics-provider-segment', + ); + expect(nameCells[4].textContent).toBe( + '@janus-idp/backstage-plugin-jfrog-artifactory', + ); }); it('supports changing the number of items per page', async () => { @@ -116,6 +148,6 @@ describe('DynamicPluginsTable', () => { nameCells = Array.from( container.querySelectorAll('tbody tr > td:first-child'), ); - expect(nameCells.length).toBe(6); + expect(nameCells.length).toBe(10); }); }); diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx index f79b7855c..3cada79b0 100644 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx +++ b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx @@ -10,11 +10,16 @@ import { useApi } from '@backstage/core-plugin-api'; import { Query, QueryResult } from '@material-table/core'; import { DynamicPluginInfo, dynamicPluginsInfoApiRef } from '../../api/types'; +import { + InternalPluginsMap, + getNotEnabledInternalPlugins, +} from '../InternalPluginsMap'; export const DynamicPluginsTable = () => { const [error, setError] = useState(undefined); const [count, setCount] = useState(0); const dynamicPluginInfo = useApi(dynamicPluginsInfoApiRef); + let data: DynamicPluginInfo[] = []; const columns: TableColumn[] = [ { title: 'Name', @@ -24,11 +29,25 @@ export const DynamicPluginsTable = () => { { title: 'Version', field: 'version', - width: '30%', + width: '15%', + }, + { + title: 'Enabled', + field: 'enabled', + render: ({ enabled }) => <>{enabled ? 'Yes' : 'No'}, + width: '10%', + }, + { + title: 'Preinstalled', + field: 'internal', + render: ({ internal }) => <>{internal ? 'Yes' : 'No'}, + width: '10%', }, { title: 'Role', - render: ({ platform, role }) => <>{`${role} (${platform})`}, + render: ({ platform, role }) => ( + <>{(role && `${role} (${platform})`) || null} + ), sorting: false, }, ]; @@ -44,21 +63,55 @@ export const DynamicPluginsTable = () => { } = query || {}; try { // for now sorting/searching/pagination is handled client-side - const data = (await dynamicPluginInfo.listLoadedPlugins()) - .sort((a: Record, b: Record) => { - const field = orderBy.field!; - if (!a[field] || !b[field]) { - return 0; + const enabledPlugins = (await dynamicPluginInfo.listLoadedPlugins()).map( + plugin => { + if (plugin.name in InternalPluginsMap) { + return { + ...plugin, + internal: true, + enabled: true, + }; } - return ( - a[field].localeCompare(b[field]) * - (orderDirection === 'desc' ? -1 : 1) - ); - }) - .filter( - value => - search.trim() === '' || - JSON.stringify(value).indexOf(search.trim()) > 0, + return { ...plugin, internal: false, enabled: true }; + }, + ); + const notEnabledInternalPlugins = getNotEnabledInternalPlugins( + enabledPlugins.map(plugin => plugin.name), + ); + data = [...enabledPlugins] + // add other internal plugins that are not enabled + .concat(notEnabledInternalPlugins) + .sort( + ( + a: Record, + b: Record, + ) => { + const field = orderBy.field!; + const orderMultiplier = orderDirection === 'desc' ? -1 : 1; + + if (a[field] === null || b[field] === null) { + return 0; + } + + // Handle boolean values separately + if ( + typeof a[field] === 'boolean' && + typeof b[field] === 'boolean' + ) { + return (a[field] ? 1 : -1) * orderMultiplier; + } + + return ( + (a[field] as string).localeCompare(b[field] as string) * + orderMultiplier + ); + }, + ) + .filter(plugin => + plugin.name + .toLowerCase() + .trim() + .includes(search.toLowerCase().trim()), ); const totalCount = data.length; let start = 0; @@ -79,7 +132,7 @@ export const DynamicPluginsTable = () => { } return ( = { + 'backstage-plugin-scaffolder-backend-module-github-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-github-dynamic', + 'backstage-plugin-catalog-backend-module-github-dynamic': + './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic', + 'backstage-plugin-catalog-backend-module-github-org-dynamic': + './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic', + 'backstage-plugin-github-actions': + './dynamic-plugins/dist/backstage-plugin-github-actions', + 'backstage-plugin-github-issues': + './dynamic-plugins/dist/backstage-plugin-github-issues', + 'roadiehq-backstage-plugin-github-insights': + './dynamic-plugins/dist/roadiehq-backstage-plugin-github-insights', + 'roadiehq-backstage-plugin-github-pull-requests': + './dynamic-plugins/dist/roadiehq-backstage-plugin-github-pull-requests', + 'roadiehq-backstage-plugin-security-insights': + './dynamic-plugins/dist/roadiehq-backstage-plugin-security-insights', + 'backstage-plugin-scaffolder-backend-module-gitlab-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gitlab-dynamic', + 'backstage-plugin-kubernetes-backend-dynamic': + './dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic', + 'backstage-plugin-kubernetes': + './dynamic-plugins/dist/backstage-plugin-kubernetes', + '@janus-idp/backstage-plugin-topology': + './dynamic-plugins/dist/janus-idp-backstage-plugin-topology', + 'roadiehq-scaffolder-backend-argocd-dynamic': + './dynamic-plugins/dist/roadiehq-scaffolder-backend-argocd-dynamic', + 'roadiehq-backstage-plugin-argo-cd': + './dynamic-plugins/dist/roadiehq-backstage-plugin-argo-cd', + 'backstage-plugin-scaffolder-backend-module-azure-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-azure-dynamic', + 'backstage-plugin-azure-devops-backend-dynamic': + './dynamic-plugins/dist/backstage-plugin-azure-devops-backend-dynamic', + 'backstage-plugin-azure-devops': + './dynamic-plugins/dist/backstage-plugin-azure-devops', + 'backstage-plugin-jenkins-backend-dynamic': + './dynamic-plugins/dist/backstage-plugin-jenkins-backend-dynamic', + 'backstage-plugin-jenkins': './dynamic-plugins/dist/backstage-plugin-jenkins', + 'backstage-plugin-sonarqube-backend-dynamic': + './dynamic-plugins/dist/backstage-plugin-sonarqube-backend-dynamic', + 'backstage-plugin-sonarqube': + './dynamic-plugins/dist/backstage-plugin-sonarqube', + '@janus-idp/backstage-plugin-ocm-backend-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-plugin-ocm-backend-dynamic', + '@janus-idp/backstage-plugin-ocm': + './dynamic-plugins/dist/janus-idp-backstage-plugin-ocm', + 'backstage-plugin-techdocs-backend-dynamic': + './dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic', + 'backstage-plugin-techdocs': + './dynamic-plugins/dist/backstage-plugin-techdocs', + 'backstage-plugin-scaffolder-backend-module-gerrit-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gerrit-dynamic', + 'roadiehq-scaffolder-backend-module-utils-dynamic': + './dynamic-plugins/dist/roadiehq-scaffolder-backend-module-utils-dynamic', + 'roadiehq-scaffolder-backend-module-http-request-dynamic': + './dynamic-plugins/dist/roadiehq-scaffolder-backend-module-http-request-dynamic', + '@janus-idp/backstage-scaffolder-backend-module-quay-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-scaffolder-backend-module-quay-dynamic', + '@janus-idp/backstage-scaffolder-backend-module-regex-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-scaffolder-backend-module-regex-dynamic', + '@janus-idp/backstage-plugin-rbac': + './dynamic-plugins/dist/janus-idp-backstage-plugin-rbac', + '@janus-idp/backstage-scaffolder-backend-module-servicenow-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-scaffolder-backend-module-servicenow-dynamic', + '@janus-idp/backstage-scaffolder-backend-module-sonarqube-dynamic': + '/dynamic-plugins/dist/janus-idp-backstage-scaffolder-backend-module-sonarqube-dynamic', + '@janus-idp/backstage-plugin-aap-backend-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-plugin-aap-backend-dynamic', + '@janus-idp/backstage-plugin-3scale-backend-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-plugin-3scale-backend-dynamic', + '@janus-idp/backstage-plugin-keycloak-backend-dynamic': + './dynamic-plugins/dist/janus-idp-backstage-plugin-keycloak-backend-dynamic', + 'backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic', + 'backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic': + './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic', + 'backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic': + './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic', + 'backstage-plugin-catalog-backend-module-bitbucket-server-dynamic': + './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic', + 'backstage-plugin-dynatrace': + '/dynamic-plugins/dist/backstage-plugin-dynatrace', + 'roadiehq-backstage-plugin-jira': + './dynamic-plugins/dist/roadiehq-backstage-plugin-jira', + 'roadiehq-backstage-plugin-datadog': + './dynamic-plugins/dist/roadiehq-backstage-plugin-datadog', + '@janus-idp/backstage-plugin-tekton': + './dynamic-plugins/dist/janus-idp-backstage-plugin-tekton', + '@janus-idp/backstage-plugin-quay': + './dynamic-plugins/dist/janus-idp-backstage-plugin-quay', + '@janus-idp/backstage-plugin-nexus-repository-manager': + './dynamic-plugins/dist/janus-idp-backstage-plugin-nexus-repository-manager', + '@janus-idp/backstage-plugin-acr': + './dynamic-plugins/dist/janus-idp-backstage-plugin-acr', + '@janus-idp/backstage-plugin-jfrog-artifactory': + './dynamic-plugins/dist/janus-idp-backstage-plugin-jfrog-artifactory', + 'pagerduty-backstage-plugin': + './dynamic-plugins/dist/pagerduty-backstage-plugin', + 'backstage-plugin-lighthouse': + './dynamic-plugins/dist/backstage-plugin-lighthouse', + 'backstage-plugin-tech-radar': + './dynamic-plugins/dist/backstage-plugin-tech-radar', + '@janus-idp/backstage-plugin-analytics-provider-segment': + './dynamic-plugins/dist/janus-idp-backstage-plugin-analytics-provider-segment', +}; + +export const getNotEnabledInternalPlugins = (enabledPlugins: string[]) => { + const plugins: DynamicPluginInfo[] = []; + if (!enabledPlugins || enabledPlugins?.length === 0) return []; + Object.keys(InternalPluginsMap).forEach(internalPlugin => { + if (!enabledPlugins.includes(internalPlugin)) { + plugins.push({ + name: internalPlugin, + version: '', + internal: true, + enabled: false, + role: '', + platform: '', + }); + } + }); + return plugins; +};