diff --git a/.gitignore b/.gitignore index 36526ee..27df94b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ dist-types dist .env coverage + +# Local dev +*.tgz +tmp.*.json diff --git a/package.json b/package.json index b6c36ef..00542da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@liatrio/backstage-dora-plugin", - "version": "0.0.37", + "version": "0.0.43", "main": "./dist/index.esm.js", "types": "./dist/index.d.ts", "license": "Apache-2.0", @@ -46,7 +46,7 @@ "@backstage/core-plugin-api": "^1.9.1", "@backstage/plugin-catalog-react": "^1.12.3", "@backstage/theme": "^0.5.2", - "@liatrio/react-dora-charts": "^2.0.0", + "@liatrio/react-dora-charts": "file:./liatrio-react-dora-charts-v0.0.18.tgz", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", @@ -88,7 +88,8 @@ "dist", "dist-types", "config.d.ts", - "LICENSE" + "LICENSE", + "liatrio-react-dora-charts-v*.tgz" ], "module": "./dist/index.esm.js", "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610", diff --git a/src/components/Charts.tsx b/src/components/Charts.tsx index 601450f..a10523c 100644 --- a/src/components/Charts.tsx +++ b/src/components/Charts.tsx @@ -128,10 +128,20 @@ const defaultMetrics: DoraState = { }; export const Charts = (props: ChartProps) => { - // Always call useEntity unconditionally - const entityContext = useEntity(); - // Then conditionally use the result - const entity = props.showServiceSelection ? null : entityContext; + // Use try/catch to handle the case when entity context is not available + let entity: any = null; + try { + // Only call useEntity when we're not in standalone mode + if (!props.showServiceSelection) { + const { entity: contextEntity } = useEntity(); + entity = contextEntity; + } + } catch (error) { + // Entity context not available, which is fine in standalone mode + if (!props.showServiceSelection) { + throw error; // Re-throw if we're not in service selection mode + } + } const configApi = useApi(configApiRef); const backendUrl = configApi.getString('backend.baseUrl'); const dataEndpoint = configApi.getString('dora.dataEndpoint'); @@ -240,9 +250,12 @@ export const Charts = (props: ChartProps) => { }; if (!props.showServiceSelection) { + // When not in service selection mode, use the entity name as service + fetchOptions.service = entity?.metadata?.name || ''; fetchOptions.repositories = repositories!; } else { - fetchOptions.service = service; + // In service selection mode, use the provided service name + fetchOptions.service = service || ''; } return fetchOptions; @@ -255,20 +268,27 @@ export const Charts = (props: ChartProps) => { onError: (error: any) => void, ) => { try { + console.log('Fetching services from URL:', url); const authHeader = await Promise.resolve(getAuthHeader()); + console.log('Auth header available:', !!authHeader); + const response = await fetch(url, { headers: { Authorization: authHeader || '', }, }); + console.log('Service list response status:', response.status, response.statusText); + if (!response.ok) { throw new Error(`Error fetching services: ${response.statusText}`); } const responseData = await response.json(); + console.log('Service list data received:', responseData); onSuccess(responseData); } catch (error) { + console.error('Error fetching services:', error); onError(error); } }; @@ -346,7 +366,13 @@ export const Charts = (props: ChartProps) => { const fetch = props.showServiceSelection ? async () => { + // http://localhost:7007/api/proxy/dora/api/services + console.log('Service selection mode active'); + console.log('Config servicesList:', servicesList); + console.log('Service list URL:', serviceListUrl); + if (servicesList && servicesList.length > 0) { + console.log('Using services from config:', servicesList); const serviceEntries = [ { value: '', @@ -364,26 +390,36 @@ export const Charts = (props: ChartProps) => { setMessage('Please select a Service'); setLoading(false); setServices(serviceEntries); + console.log('Services set from config:', serviceEntries); } else { + console.log('Fetching services from API'); fetchServicesData( serviceListUrl, getAuthHeaderValue, (services_data: any) => { + console.log('Services data received:', services_data); const newList: any[] = [{ label: 'Please Select', value: '' }]; - for (const entry of services_data.services) { - const newEntry = { - label: entry, - value: entry, - }; - - newList.push(newEntry); + if (services_data.services && services_data.services.length > 0) { + console.log('Processing services:', services_data.services); + for (const entry of services_data.services) { + const newEntry = { + label: entry, + value: entry, + }; + + newList.push(newEntry); + } + } else { + console.warn('No services found in response'); } + console.log('Setting services:', newList); setServices(newList); setLoading(false); }, - _ => { + error => { + console.error('Error in service list callback:', error); setLoading(false); }, ); diff --git a/src/helper.ts b/src/helper.ts index a493c96..e287312 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -5,8 +5,13 @@ export const COLOR_DARK = '#000'; export const COLOR_LIGHT = '#FFF'; export const getRepositoryName = (e: any): string => { - if ('github.com/project-slug' in e.entity.metadata.annotations) { - return e.entity.metadata.annotations['github.com/project-slug'].split( + // Handle both direct entity objects and objects containing an entity property + const entity = e.entity || e; + + // Safely access annotations with null checks + if (entity && entity.metadata && entity.metadata.annotations && + 'github.com/project-slug' in entity.metadata.annotations) { + return entity.metadata.annotations['github.com/project-slug'].split( '/', )[1]; } diff --git a/yarn.lock b/yarn.lock index 616af3f..3e920de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2299,10 +2299,9 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== -"@liatrio/react-dora-charts@^1.1.8": - version "1.1.10" - resolved "https://registry.yarnpkg.com/@liatrio/react-dora-charts/-/react-dora-charts-1.1.10.tgz#001e615b83c3abe17204e869ceadcdf2a77a60c6" - integrity sha512-CUK8JD5jGqifu3Ykx7WgXzPoR6Hulg48f5ZuizS08LG9VggRR+gAz9GNhl2co5Dg4Cyik1KGqNCHqaNVM6vBNw== +"@liatrio/react-dora-charts@file:./liatrio-react-dora-charts-v0.0.18.tgz": + version "0.0.18" + resolved "file:./liatrio-react-dora-charts-v0.0.18.tgz#74a3afc10233639a0fb27aa0be4f13755660bc15" dependencies: js-yaml "^4.1.0" react-tooltip "^5.28.0"