Skip to content

Commit

Permalink
Merge branch 'AxisCommunications:main' into improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
SaachiNayyer committed Jun 28, 2024
2 parents 0dda4d7 + e416aff commit c26a4a6
Show file tree
Hide file tree
Showing 48 changed files with 2,754 additions and 16 deletions.
7 changes: 7 additions & 0 deletions .changeset/warm-singers-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@axis-backstage/plugin-vacation-calendar': minor
'backend': minor
'app': minor
---

Added new plugin for displaying out-of-office events in a react-calendar-timeline. Also added support for microsoft autentication.
43 changes: 33 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Contributing to Axis Backstage plugins

Contributions are welcome, and they are greatly appreciated! We really want to improve our plugins ✨
Contributions are welcome and greatly appreciated! We are committed to improving our plugins ✨

These contributing guidelines explain:

- How to contribute effectively for optimal communication
- The conventions we would like you to follow

If you have any questions, please let us know!

## Code of Conduct

Expand All @@ -10,27 +17,43 @@ This project adheres to the [CNCF Code of Conduct][code-of-conduct]. By particip

## How can I contribute?

We welcome anything from bugs fixes or new, implemented features. You can create your own Pull request. Once you've submitted a Pull Request (PR), tests will be run and we will have a look at your PR as soon as we can. If we have any comments or questions, we will do so in the PR.
### 1. Create Issue

You need approval from one of the core maintainers (in this case, the Backstage team at Axis). Once you have one approval it's ready to be merged, this task is also done by one of us.
We welcome anything from bug fixes to new features. **Please start by creating an [issue in our repository](https://github.com/backstage/backstage/issues/new/choose)**. The Axis Backstage team will respond as soon as possible regarding:

As a contributor, here are the guidelines we would like you to follow:
- Whether this is an implementation we want in our main repository
- If there are any points to discuss before implementing the feature
- Who should implement the feature

### 2. Create Pull Request

#### Pull Request Best Practises

Once the discussion in the issue is complete, you are welcome to create a Pull Request (PR). We follow [GitHub's best practices for creating pull Requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/best-practices-for-pull-requests). Please review these guidelines if you are not familiar with them.

- [Api-reports](#api-reports)
- [Changesets](#changesets)
- [Styling conventions](#styling-conventions)
In addition, provide a clear title for your PR that explains the change.

#### Pull Request Approval

After submitting a PR, tests will run and the team will review it as soon as possible. If there are any comments or questions, we will communicate through the PR.

You need approval from one of the core maintainers (the Axis Backstage team). Once you have approval, the PR is ready to be merged. **This task will also be done by one of us**.

## Other contributing guidelines

As a contributor, here are the guidelines we would like you to follow:

## Api reports
### Api reports

Similar to Backstage upstream, we use api reports generated by [API Extractor](https://api-extractor.com/) to help us build better TypeScript library packages. To learn more about api-reports and how to generate them, we refer to the [upstream documentation](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#api-reports).

## Changesets
### Changesets

Just like Backstage upstream, we use [changesets](https://github.com/changesets/changesets) to help us prepare releases. By using changsets we can make sure that the process generating releases is easy, and that every change gets a proper version number.

If you wish to know more about the use of **changesets** in Backstage, please read the [official Backstage documentation about changesets](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#creating-changesets).

### How to create a changeset
#### How to create a changeset

1. Run `yarn changeset` from the root of the repo
2. Select which packages you want to include a changeset for
Expand Down
10 changes: 9 additions & 1 deletion app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,15 @@ techdocs:

auth:
# see https://backstage.io/docs/auth/ to learn about auth providers
providers: {}
providers:
microsoft:
development:
clientId: ${AUTH_MICROSOFT_CLIENT_ID}
clientSecret: ${AUTH_MICROSOFT_CLIENT_SECRET}
tenantId: ${AUTH_MICROSOFT_TENANT_ID}
signIn:
resolvers:
- resolver: emailMatchingUserEntityProfileEmail

scaffolder:
# see https://backstage.io/docs/features/software-templates/configuration for software template options
Expand Down
12 changes: 12 additions & 0 deletions examples/org.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ metadata:
spec:
memberOf: [guests]
---
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
name: Sophie
description: Software Developer
spec:
profile:
displayName: Sophie
email: [email protected]
picture: https://api.dicebear.com/7.x/avataaars/svg?seed=Sophie
memberOf: [guests]
---
# https://backstage.io/docs/features/software-catalog/descriptor-format#kind-group
apiVersion: backstage.io/v1alpha1
kind: Group
Expand Down
1 change: 1 addition & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@axis-backstage/plugin-jira-dashboard-common": "workspace:^",
"@axis-backstage/plugin-readme": "workspace:^",
"@axis-backstage/plugin-statuspage": "workspace:^",
"@axis-backstage/plugin-vacation-calendar": "^0.1.0",
"@backstage-community/plugin-github-actions": "^0.6.16",
"@backstage/app-defaults": "^1.5.5",
"@backstage/catalog-model": "^1.5.0",
Expand Down
25 changes: 24 additions & 1 deletion packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,37 @@ import { entityPage } from './components/catalog/EntityPage';
import { searchPage } from './components/search/SearchPage';
import { Root } from './components/Root';

import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';
import {
AlertDisplay,
OAuthRequestDialog,
SignInPage,
} from '@backstage/core-components';
import { createApp } from '@backstage/app-defaults';
import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import { RequirePermission } from '@backstage/plugin-permission-react';
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
import { StatuspagePage } from '@axis-backstage/plugin-statuspage';
import { VacationCalendarPage } from '@axis-backstage/plugin-vacation-calendar';
import { microsoftAuthApiRef } from '@backstage/core-plugin-api';

const app = createApp({
components: {
SignInPage: props => (
<SignInPage
{...props}
providers={[
'guest',
{
id: 'microsoft-auth-provider',
title: 'Microsoft',
message: 'Sign in using Microsoft',
apiRef: microsoftAuthApiRef,
},
]}
/>
),
},
apis,
bindRoutes({ bind }) {
bind(catalogPlugin.externalRoutes, {
Expand Down Expand Up @@ -90,6 +112,7 @@ const routes = (
<Route path="/settings" element={<UserSettingsPage />} />
<Route path="/catalog-graph" element={<CatalogGraphPage />} />
<Route path="/statuspage" element={<StatuspagePage name="myid" />} />
<Route path="/vacation-calendar" element={<VacationCalendarPage />} />
</FlatRoutes>
);

Expand Down
14 changes: 14 additions & 0 deletions packages/app/src/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import {
createApiFactory,
discoveryApiRef,
fetchApiRef,
microsoftAuthApiRef,
} from '@backstage/core-plugin-api';
import { UmamiAnalytics } from '@axis-backstage/plugin-analytics-module-umami';
import {
StatuspageClient,
statuspageApiRef,
} from '@axis-backstage/plugin-statuspage';
import {
vacationCalendarApiRef,
VacationCalendarApiClient,
} from '@axis-backstage/plugin-vacation-calendar';

export const apis: AnyApiFactory[] = [
createApiFactory({
Expand All @@ -41,5 +46,14 @@ export const apis: AnyApiFactory[] = [
factory: ({ discoveryApi, fetchApi }) =>
new StatuspageClient({ discoveryApi, fetchApi }),
}),
createApiFactory({
api: vacationCalendarApiRef,
deps: {
authApi: microsoftAuthApiRef,
fetchApi: fetchApiRef,
},
factory: ({ authApi, fetchApi }) =>
new VacationCalendarApiClient({ authApi, fetchApi }),
}),
ScmAuth.createDefaultApiFactory(),
];
11 changes: 11 additions & 0 deletions packages/app/src/components/catalog/EntityPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
isStatuspageAvailable,
StatuspageEntityCard,
} from '@axis-backstage/plugin-statuspage';
import { VacationCalendarPage } from '@axis-backstage/plugin-vacation-calendar';

const techdocsContent = (
<EntityTechdocsContent>
Expand Down Expand Up @@ -280,6 +281,11 @@ const userPage = (
</Grid>
</Grid>
</EntityLayout.Route>
<EntityLayout.Route path="/vacation-calendar" title="Out Of Office">
<Grid md={6}>
<VacationCalendarPage />
</Grid>
</EntityLayout.Route>
</EntityLayout>
);

Expand All @@ -299,6 +305,11 @@ const groupPage = (
</Grid>
</Grid>
</EntityLayout.Route>
<EntityLayout.Route path="/vacation-calendar" title="Out Of Office">
<Grid md={6}>
<VacationCalendarPage />
</Grid>
</EntityLayout.Route>
</EntityLayout>
);

Expand Down
1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@backstage/config": "^1.2.0",
"@backstage/plugin-app-backend": "^0.3.67",
"@backstage/plugin-auth-backend": "^0.22.5",
"@backstage/plugin-auth-backend-module-microsoft-provider": "^0.1.13",
"@backstage/plugin-auth-node": "^0.4.13",
"@backstage/plugin-catalog-backend": "^1.22.0",
"@backstage/plugin-permission-common": "^0.7.13",
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const backend = createBackend();
backend.add(import('@backstage/plugin-catalog-backend/alpha'));
backend.add(import('@backstage/plugin-scaffolder-backend/alpha'));
backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider'));
backend.add(import('@backstage/plugin-proxy-backend/alpha'));
backend.add(import('@backstage/plugin-techdocs-backend/alpha'));
backend.add(import('@backstage/plugin-search-backend/alpha'));
Expand Down
13 changes: 13 additions & 0 deletions packages/backend/src/plugins/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ export default async function createPlugin(
// resolver: providers.github.resolvers.usernameMatchingUserEntityName(),
},
}),
microsoft: providers.microsoft.create({
signIn: {
resolver(_, ctx) {
const userRef = 'user:default/guest'; // Must be a full entity reference
return ctx.issueToken({
claims: {
sub: userRef, // The user's own identity
ent: [userRef], // A list of identities that the user claims ownership through
},
});
},
},
}),
},
});
}
1 change: 1 addition & 0 deletions plugins/vacation-calendar/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
110 changes: 110 additions & 0 deletions plugins/vacation-calendar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Vacation Calendar plugin

Welcome to the Vacation Calendar plugin!

![calendar-year-light-example](https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/vacation-calendar/media/year-light.png)
![calendar-year-dark-example](https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/vacation-calendar/media/year-dark.png)

## Introduction

The Vacation Calendar plugin allows you to get a comprehensive overview of your colleagues' vacations and out-of-office events. Clearly see when your vacations overlap or which team members will be present on specific occasions, making your life and teamwork easier and more efficient.

Our plugin is based on [Microsoft-Calendar Plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/microsoft-calendar/plugins/microsoft-calendar) with modifications for focusing on multiple users' calendars. Full credit to them for their great plugin!

## How it works

The plugin interacts with the Microsoft Graph API to fetch users' calendars and schedule items. Mark your events as Out of Office in either the Outlook client or the Teams client. By marking your events as "Out of Office," they will be correctly reflected in the Vacation Calendar plugin, providing an accurate overview of your availability.

## Autentication

The Vacation Calendar plugin requires Microsoft authentication. If you have not set this up, please follow the upstream guide on Microsoft authentication: [Backstage.io Microsoft Authentication Guide](https://backstage.io/docs/auth/microsoft/provider/).

At present, the plugin supports only Microsoft authentication and does not integrate with other Backstage authentication methods. If you need the plugin to support a different authentication method, please create an issue so we can discuss your requirements.

## Getting started

1. First, install the plugin into your app:

```bash
# From your Backstage root directory
yarn --cwd packages/app add @axis-backstage/plugin-vacation-calendar
```

2. Setup the API-factory.

```ts
// packages/app/src/apis.ts:

createApiFactory({
api: vacationCalendarApiRef,
deps: {
authApi: microsoftAuthApiRef,
fetchApi: fetchApiRef,
},
factory: ({ authApi, fetchApi }) =>
new VacationCalendarApiClient({ authApi, fetchApi }),
}),

```

3. Modify your entity page to include the `VacationCalendarPage` component:

```tsx
// In packages/app/src/components/catalog/EntityPage.tsx
import { VacationCalendarPage } from '@axis-backstage/plugin-vacation-calendar';

const groupPage = (
<EntityLayout>
<EntityLayout.Route path="/vacation-calendar" title="Out Of Office">
<Grid md={6}>
<VacationCalendarPage />
</Grid>
</EntityLayout.Route>
</EntityLayout>
);
```

By doing this, all Backstage users who are part of that group will be displayed in the `Out of Office` tab on the group's entity page.

## Integration with the Catalog

To fetch all colleagues with the same manager for a user entity, add the manager annotation to the entity's **catalog-info.yaml** file:

```yaml
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
# ...
annotations:
manager: value # The Backstage username of the mananger
```
If the manager annotation is set, you can display all users with the same manager for a user entity. To do this, add the `VacationCalendarPage` component to the entity page for users:

```tsx
// In packages/app/src/components/catalog/EntityPage.tsx
import { VacationCalendarPage } from '@axis-backstage/plugin-vacation-calendar';
const userPage = (
<EntityLayout>
<EntityLayout.Route path="/vacation-calendar" title="Out Of Office">
<Grid md={6}>
<VacationCalendarPage />
</Grid>
</EntityLayout.Route>
</EntityLayout>
);
```

## Development

The plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/vacation-calendar](http://localhost:3000/vacation-calendar).

You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.

## Screenshots

![calendar-month-light-example](https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/vacation-calendar/media/month-light.png)
![calendar-month-dark-example](https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/vacation-calendar/media/month-dark.png)
Loading

0 comments on commit c26a4a6

Please sign in to comment.