Skip to content

Commit

Permalink
feat: hasHumanitecAnnotations function
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswuerbach committed Jun 17, 2024
1 parent c32bdb9 commit 22a6c79
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/slimy-crews-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@humanitec/backstage-plugin': minor
---

Add hasHumanitecAnnotations function for conditional rendering
12 changes: 12 additions & 0 deletions examples/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ spec:
system: examples
providesApis: [example-grpc-api]
---
# https://backstage.io/docs/features/software-catalog/descriptor-format#kind-component
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: example-service-without
spec:
type: service
lifecycle: experimental
owner: guests
system: examples
providesApis: [example-grpc-api]
---
# https://backstage.io/docs/features/software-catalog/descriptor-format#kind-api
apiVersion: backstage.io/v1alpha1
kind: API
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@
},
"dependencies": {
"@changesets/cli": "^2.27.1"
}
},
"packageManager": "[email protected]+sha512.ca75da26c00327d26267ce33536e5790f18ebd53266796fbb664d2a4a5116308042dd8ee7003b276a20eace7d3c5561c3577bdd71bcb67071187af124779620a"
}
15 changes: 11 additions & 4 deletions packages/app/src/components/catalog/EntityPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ import {

import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { HumanitecCardComponent } from '@humanitec/backstage-plugin';
import {
HumanitecCardComponent,
hasHumanitecAnnotations,
} from '@humanitec/backstage-plugin';

const techdocsContent = (
<EntityTechdocsContent>
Expand Down Expand Up @@ -138,9 +141,13 @@ const overviewContent = (
<Grid item md={8} xs={12}>
<EntityHasSubcomponentsCard variant="gridItem" />
</Grid>
<Grid item md={6}>
<HumanitecCardComponent />
</Grid>
<EntitySwitch>
<EntitySwitch.Case if={hasHumanitecAnnotations}>
<Grid item md={6}>
<HumanitecCardComponent />
</Grid>
</EntitySwitch.Case>
</EntitySwitch>
</Grid>
);

Expand Down
20 changes: 20 additions & 0 deletions plugins/humanitec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ const overviewContent = (
)
```

In case the Humanitec component should only be display when the entity has Humanitec annotations configured,
the code could look like the following:

```diff
+ import { HumanitecCardComponent, hasHumanitecAnnotations } from '@humanitec/backstage-plugin';
...
const overviewContent = (
<Grid container>
...
+ <EntitySwitch>
+ <EntitySwitch.Case if={hasHumanitecAnnotations}>
+ <Grid item md={6}>
+ <HumanitecCardComponent />
+ </Grid>
+ </EntitySwitch.Case>
+ </EntitySwitch>
</Grid>
)
```

Add annotations to types that have Humanitec apps display:

```yaml
Expand Down
36 changes: 36 additions & 0 deletions plugins/humanitec/src/components/HumanitecCardComponent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Entity } from '@backstage/catalog-model';
import { hasHumanitecAnnotations } from './HumanitecCardComponent';

describe('<HumanitecCardComponent />', () => {
it('returns hasHumanitecAnnotations truthy if the entity has humanitec annotations', async () => {
const entity: Entity = {
apiVersion: 'v1',
kind: 'Component',
metadata: {
name: 'software',
annotations: {
'humanitec.com/orgId': 'orgId',
'humanitec.com/appId': 'appId',
},
},
};

const hasAnnotations = await hasHumanitecAnnotations(entity);

expect(hasAnnotations).toBeTruthy();
});

it('returns hasHumanitecAnnotations falsy if the entity has no humanitec annotations', async () => {
const entity: Entity = {
apiVersion: 'v1',
kind: 'Component',
metadata: {
name: 'software',
},
};

const hasAnnotations = await hasHumanitecAnnotations(entity);

expect(hasAnnotations).toBeFalsy();
});
});
37 changes: 26 additions & 11 deletions plugins/humanitec/src/components/HumanitecCardComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { useEntity } from '@backstage/plugin-catalog-react';
import { Button, Card, CardContent, Divider } from '@material-ui/core';
import CardHeader from '@material-ui/core/CardHeader';
import React, { ReactNode } from 'react';
import { HUMANITEC_APP_ID_ANNOTATION, HUMANITEC_MISSING_ANNOTATION_ERROR, HUMANITEC_ORG_ID_ANNOTATION } from '../annotations';
import { Entity } from '@backstage/catalog-model';
import {
HUMANITEC_APP_ID_ANNOTATION,
HUMANITEC_MISSING_ANNOTATION_ERROR,
HUMANITEC_ORG_ID_ANNOTATION,
} from '../annotations';
import { useAppInfo } from '../hooks/useAppInfo';
import { useHumanitecParams } from '../hooks/useHumanitecParams';
import { useStyles } from '../hooks/useStyles';
Expand All @@ -12,10 +17,9 @@ import { HumanitecCardContent } from './HumanitecCardContent';
import { HumanitecErrorState } from './HumanitecErrorState';
import { HumanitecLogoIcon } from './HumanitecLogoIcon';

interface HumanitecCardComponentProps {
}
interface HumanitecCardComponentProps {}

export function HumanitecCardComponent({ }: HumanitecCardComponentProps) {
export function HumanitecCardComponent({}: HumanitecCardComponentProps) {
const { entity } = useEntity<HumanitecAnnotationedEntity>();

const orgId = entity.metadata.annotations[HUMANITEC_ORG_ID_ANNOTATION];
Expand All @@ -41,11 +45,14 @@ export function HumanitecCardComponent({ }: HumanitecCardComponentProps) {
selectedWorkload={params?.workloadId}
actions={actions}
/>
)
} else if (data instanceof Error && data.message === HUMANITEC_MISSING_ANNOTATION_ERROR) {
content = (<HumanitecAnnotationsEmptyState />)
);
} else if (
data instanceof Error &&
data.message === HUMANITEC_MISSING_ANNOTATION_ERROR
) {
content = <HumanitecAnnotationsEmptyState />;
} else {
content = (<HumanitecErrorState error={data} />)
content = <HumanitecErrorState error={data} />;
}

let action: ReactNode = null;
Expand All @@ -54,11 +61,11 @@ export function HumanitecCardComponent({ }: HumanitecCardComponentProps) {
<Button component="a" startIcon={<HumanitecLogoIcon />} href={appUrl}>
Humanitec App
</Button>
)
);
}

return (
<Card className={`${classes.cardClass}`} >
<Card className={`${classes.cardClass}`}>
<CardHeader
action={action}
className={classes.cardHeader}
Expand All @@ -70,5 +77,13 @@ export function HumanitecCardComponent({ }: HumanitecCardComponentProps) {
{content}
</CardContent>
</Card>
)
);
}

export async function hasHumanitecAnnotations(entity: Entity) {
return !!(
entity.metadata.annotations &&
entity.metadata.annotations[HUMANITEC_ORG_ID_ANNOTATION] &&
entity.metadata.annotations[HUMANITEC_APP_ID_ANNOTATION]
);
}
2 changes: 1 addition & 1 deletion plugins/humanitec/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { humanitecPlugin } from './plugin';
export { HumanitecCardComponent } from './components/HumanitecCardComponent';
export { HumanitecCardComponent, hasHumanitecAnnotations } from './components/HumanitecCardComponent';
export { ValidateHumanitecAppIDFieldExtension } from './scaffolder/ValidateHumanitecAppID';

0 comments on commit 22a6c79

Please sign in to comment.