@spotify/backstage-plugin-soundcheck 0.12.2 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +2 -510
- package/alpha/package.json +1 -1
- package/config.d.ts +0 -4
- package/dist/alpha.esm.js +1 -1
- package/dist/esm/Card-Dj5kNp2Q.esm.js +2 -0
- package/dist/esm/CertificationSidebar-CVyVchB8.esm.js +2 -0
- package/dist/esm/EmptyState-CFyDYjmm.esm.js +2 -0
- package/dist/esm/EntitySoundcheckContent-Dm1OGOA5.esm.js +2 -0
- package/dist/esm/OverviewPageContent-DW92KphH.esm.js +2 -0
- package/dist/esm/{RefetchingIndicator-b4961e02.esm.js → RefetchingIndicator-CdGa4YBG.esm.js} +2 -2
- package/dist/esm/chartUtils-CDPSRCm-.esm.js +2 -0
- package/dist/esm/{index-f4bdaf5c.esm.js → index-ChMeGQBh.esm.js} +2 -2
- package/dist/esm/index-DNAl7tKw.esm.js +2 -0
- package/dist/esm/index-e9SWucyI.esm.js +2 -0
- package/dist/esm/{license-e9e73904.esm.js → license-CQErZDIh.esm.js} +1 -1
- package/dist/esm/routes-DcGwdXHX.esm.js +699 -0
- package/dist/images/git-dark.svg +1 -0
- package/dist/images/github-dark.svg +1 -0
- package/dist/images/github-light.svg +1 -0
- package/dist/images/pagerduty-dark.png +0 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +1 -1
- package/package.json +20 -19
- package/dist/esm/Card-2862fdca.esm.js +0 -2
- package/dist/esm/CertificationSidebar-5e4230a7.esm.js +0 -2
- package/dist/esm/EmptyState-6a402254.esm.js +0 -2
- package/dist/esm/EntitySoundcheckContent-bc7bdbe2.esm.js +0 -2
- package/dist/esm/OverviewPageContent-d5467d2c.esm.js +0 -2
- package/dist/esm/chartUtils-080232d7.esm.js +0 -2
- package/dist/esm/index-5610fc82.esm.js +0 -2
- package/dist/esm/index-99d39b7d.esm.js +0 -2
- package/dist/esm/routes-93cd1496.esm.js +0 -599
- package/dist/images/octocat.svg +0 -17
- package/dist/images/settings.svg +0 -90
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# @spotify/backstage-plugin-soundcheck
|
|
2
2
|
|
|
3
|
+
## 0.12.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependency `@uiw/react-md-editor` to `3.20.10`.
|
|
8
|
+
- Added tooltips to show the reason why collector is not configurable via No-Code UI.
|
|
9
|
+
- Track Insights now takes a tracks' filter, custom track applicability filters, and the total number of applicable entities into account when calculating certification rates.
|
|
10
|
+
- Fixed an issue in the filter dropdown where owner names could be displayed incorrectly.
|
|
11
|
+
- Updated text colors and logos on Track, Check, Campaign and Collector list pages for improved readability.
|
|
12
|
+
- Removing configuration option to enable non-virtualized Soundcheck Overview table.
|
|
13
|
+
- Tech Health Entities and Teams tabs can now display unlimited number of entities.
|
|
14
|
+
- Added a possibility to export full dataset as CSV in Tech Health.
|
|
15
|
+
- Updated backstage dependencies to `v1.26.0`
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
- Updated dependencies
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- Updated dependencies
|
|
28
|
+
- @spotify/backstage-plugin-core@0.7.1
|
|
29
|
+
- @spotify/backstage-plugin-soundcheck-common@0.13.1
|
|
30
|
+
|
|
31
|
+
## 0.12.3
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Minor tweaks to margins/padding to make things more visually distinct.
|
|
36
|
+
- Improved the performance of the Track Insights page.
|
|
37
|
+
- Fixes the campaign link on the card view of the Tech Health Campaigns page.
|
|
38
|
+
- Add support for different track types in the overview card.
|
|
39
|
+
- Added a "Systems" filter to the Track Insights page.
|
|
40
|
+
- Fixed overview page route history. Browser controls (such as the forward and back buttons) now navigate the overview page correctly.
|
|
41
|
+
- Fixed an issue with level progress bars on the Track page that caused them to only ever show 0 or 100%
|
|
42
|
+
- Exported the RouteRef for the '/tracks/:trackId/checks/:checkId' route
|
|
43
|
+
- Added a preview of the entities that will be affected by filter selections when creating checks, tracks, and campaigns.
|
|
44
|
+
- Resolved an issue related to the caching of certain frontend queries.
|
|
45
|
+
- Adjusted the "Filter by owner" options of the checks, tracks, and campaigns pages to show display names rather than identifiers.
|
|
46
|
+
- Added a type filter for track insights page
|
|
47
|
+
- Resolved an issue with the display of badges on the overview card.
|
|
48
|
+
- Modified the track insights page so that the owner filter options display names instead of identifiers.
|
|
49
|
+
- Minor update to the tracks GraphQL API allowing filtering tracks by type.
|
|
50
|
+
- Fixed the results table width on the Soundcheck Overview page.
|
|
51
|
+
- Adjusted the filters for track insights to only show the relevant options in the filter dropdowns.
|
|
52
|
+
- Adjusted "Filter by owner" options to show all owners at all times for the checks, tracks, and campaigns pages.
|
|
53
|
+
- Added logic to hide the lifecycle filter on track insights page if there are less than 2 options.
|
|
54
|
+
- Added support for filtering Track Insights by owner and lifecycle.
|
|
55
|
+
- Updated backstage dependencies to `v1.24.0`
|
|
56
|
+
- Updated dependencies
|
|
57
|
+
- `@spotify/backstage-plugin-core` to `^0.7.0`
|
|
58
|
+
- `@spotify/backstage-plugin-soundcheck-common` to `^0.13.0`
|
|
59
|
+
|
|
3
60
|
## 0.12.2
|
|
4
61
|
|
|
5
62
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,513 +1,5 @@
|
|
|
1
1
|
# Spotify Plugins for Backstage: Soundcheck
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This plugin is part of [Spotify Plugins for Backstage](https://backstage.spotify.com/marketplace/spotify/bundle/spotify-plugins-bundle/).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
There are 5 fundamental elements that make up Soundcheck:
|
|
8
|
-
|
|
9
|
-
- **Check**: A standard or best practice a component is graded against.
|
|
10
|
-
- **Check Result**: The result of running a check against a component. Possible results are passed, failed, warning or not applicable.
|
|
11
|
-
- **Track**: A long-term tech health initiative.
|
|
12
|
-
- **Level**: A group of checks that represent a milestone within a track.
|
|
13
|
-
- **Certification**: The outcome of passing all applicable checks within a level.
|
|
14
|
-
|
|
15
|
-
Together, they show you how any given software component is performing against your organization's long-term tech health initiatives.
|
|
16
|
-
|
|
17
|
-
<!-- TOC -->
|
|
18
|
-
|
|
19
|
-
- [Spotify Plugins for Backstage: Soundcheck](#spotify-plugins-for-backstage-soundcheck)
|
|
20
|
-
- [Prerequisites](#prerequisites)
|
|
21
|
-
- [1. Install the Soundcheck backend plugin](#1-install-the-soundcheck-backend-plugin)
|
|
22
|
-
- [Installation](#installation)
|
|
23
|
-
- [1. Install the plugin](#1-install-the-plugin)
|
|
24
|
-
- [2. Install Soundcheck Entity Content Page & Card](#2-install-soundcheck-entity-content-page--card)
|
|
25
|
-
- [3. Install Soundcheck Routing Page](#3-install-soundcheck-routing-page)
|
|
26
|
-
- [4. Setup sidebar item](#4-setup-sidebar-item)
|
|
27
|
-
- [5. Install Soundcheck Group Content Page](#5-install-soundcheck-group-content-page)
|
|
28
|
-
- [6. Check everything is working](#6-check-everything-is-working)
|
|
29
|
-
- [Product Documentation](#product-documentation)
|
|
30
|
-
- [No-Code UI for checks, tracks and facts management](#no-code-ui-for-checks-tracks-and-facts-management)
|
|
31
|
-
- [Using the No-Code UI](#using-the-no-code-ui)
|
|
32
|
-
- [Checks](#checks)
|
|
33
|
-
- [Creating a new check](#creating-a-new-check)
|
|
34
|
-
- [Editing a check](#editing-a-check)
|
|
35
|
-
- [Tracks](#tracks)
|
|
36
|
-
- [Creating a new track](#creating-a-new-track)
|
|
37
|
-
- [Editing a track](#editing-a-track)
|
|
38
|
-
- [Fact Collectors](#fact-collectors)
|
|
39
|
-
- [Configuring a fact collector](#configuring-a-fact-collector)
|
|
40
|
-
- [Frequency](#frequency)
|
|
41
|
-
- [Filters](#filters)
|
|
42
|
-
- [Caching](#caching)
|
|
43
|
-
- [RBAC Integration](#rbac-integration)
|
|
44
|
-
- [Soundcheck Tech Health Page](#soundcheck-tech-health-page)
|
|
45
|
-
- [Aggregations](#aggregations)
|
|
46
|
-
- [Filters](#filters-1)
|
|
47
|
-
- [Trends](#trends)
|
|
48
|
-
- [Data Export](#data-export)
|
|
49
|
-
- [Data Caching](#data-caching)
|
|
50
|
-
- [Campaigns in Soundcheck](#campaigns-in-soundcheck)
|
|
51
|
-
- [Key features include:](#key-features-include)
|
|
52
|
-
- [Campaigns Library](#campaigns-library)
|
|
53
|
-
- [Campaign Creation](#campaign-creation)
|
|
54
|
-
- [Step 1: Campaign Details](#step-1-campaign-details)
|
|
55
|
-
- [Step 2: Selecting Checks](#step-2-selecting-checks)
|
|
56
|
-
- [Step 3: Applying Filters](#step-3-applying-filters)
|
|
57
|
-
- [Step 4: Defining Milestones](#step-4-defining-milestones)
|
|
58
|
-
- [Campaign Archival](#campaign-archival)
|
|
59
|
-
- [Campaign Progress and Milestones](#campaign-progress-and-milestones)
|
|
60
|
-
- [Campaign Notifications](#campaign-notifications)
|
|
61
|
-
- [Scenarios for Receiving Notifications](#scenarios-for-receiving-notifications)
|
|
62
|
-
<!-- TOC -->
|
|
63
|
-
|
|
64
|
-
## Prerequisites
|
|
65
|
-
|
|
66
|
-
### 1. Install the Soundcheck backend plugin
|
|
67
|
-
|
|
68
|
-
You must install the [Soundcheck backend plugin](https://npmjs.com/package/@spotify/backstage-plugin-soundcheck-backend) and all of its prerequisites before installing the Soundcheck frontend plugin.
|
|
69
|
-
|
|
70
|
-
## Installation
|
|
71
|
-
|
|
72
|
-
The next steps describe how to install the Soundcheck frontend plugin.
|
|
73
|
-
|
|
74
|
-
### 1. Install the plugin
|
|
75
|
-
|
|
76
|
-
1. Add the Soundcheck packages as dependencies to your Backstage instance
|
|
77
|
-
|
|
78
|
-
```sh
|
|
79
|
-
yarn workspace app add @spotify/backstage-plugin-soundcheck
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 2. Install Soundcheck Entity Content Page & Card
|
|
83
|
-
|
|
84
|
-
The Soundcheck Entity Page consists of a view on the [Catalog Entity page](https://github.com/backstage/backstage/blob/master/packages/app/src/components/catalog/EntityPage.tsx), and lists
|
|
85
|
-
all the related certifications, levels, checks and check results for a
|
|
86
|
-
particular entity.
|
|
87
|
-
|
|
88
|
-
The code below adds the Soundcheck card to the overview tab for all component types.
|
|
89
|
-
The Soundcheck entity content component needs to be added to each relevant
|
|
90
|
-
page type within your Backstage `EntityPage`. The snippets below insert the
|
|
91
|
-
card/tabs at the end of their respective containers, but it's fine to reorder
|
|
92
|
-
them as you wish. When reordering the card in particular, consider whether the
|
|
93
|
-
[fluid layout](https://v4.mui.com/components/grid/#fluid-grids) of the grid
|
|
94
|
-
should be adjusted to ensure the cards fill each row.
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
// packages/app/src/components/catalog/EntityPage.tsx
|
|
98
|
-
|
|
99
|
-
import {
|
|
100
|
-
EntitySoundcheckContent,
|
|
101
|
-
EntitySoundcheckCard,
|
|
102
|
-
} from '@spotify/backstage-plugin-soundcheck';
|
|
103
|
-
|
|
104
|
-
// ...
|
|
105
|
-
|
|
106
|
-
const overviewContent = (
|
|
107
|
-
<Grid container spacing={3} alignItems="stretch">
|
|
108
|
-
{/* existing cards... */}
|
|
109
|
-
|
|
110
|
-
<Grid item md={6} xs={12}>
|
|
111
|
-
<EntitySoundcheckCard />
|
|
112
|
-
</Grid>
|
|
113
|
-
</Grid>
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// ...
|
|
117
|
-
|
|
118
|
-
// Repeat this for all component entity pages which use the `overviewContent`
|
|
119
|
-
const serviceEntityPage = (
|
|
120
|
-
<EntityLayout>
|
|
121
|
-
{/* existing tabs... */}
|
|
122
|
-
|
|
123
|
-
<EntityLayout.Route path="/soundcheck" title="Soundcheck">
|
|
124
|
-
<EntitySoundcheckContent />
|
|
125
|
-
</EntityLayout.Route>
|
|
126
|
-
</EntityLayout>
|
|
127
|
-
);
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### 3. Install Soundcheck Routing Page
|
|
131
|
-
|
|
132
|
-
Add a new Route element with the path `/soundcheck` and element of `<SoundcheckRoutingPage />`.
|
|
133
|
-
|
|
134
|
-
`<SoundcheckRoutingPage />` supports the following props:
|
|
135
|
-
|
|
136
|
-
```tsx
|
|
137
|
-
{
|
|
138
|
-
title: string; // OPTIONAL - Defaults to 'Soundcheck' when excluded
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
The route should look something like this:
|
|
143
|
-
|
|
144
|
-
```tsx
|
|
145
|
-
// packages/app/src/App.tsx
|
|
146
|
-
import { SoundcheckRoutingPage } from '@spotify/backstage-plugin-soundcheck';
|
|
147
|
-
|
|
148
|
-
const routes = (
|
|
149
|
-
<FlatRoutes>
|
|
150
|
-
{/* existing routes... */}
|
|
151
|
-
|
|
152
|
-
<Route
|
|
153
|
-
path="/soundcheck"
|
|
154
|
-
element={<SoundcheckRoutingPage title="My Optional Title" />}
|
|
155
|
-
/>
|
|
156
|
-
</FlatRoutes>
|
|
157
|
-
);
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### 4. Setup sidebar item
|
|
161
|
-
|
|
162
|
-
Add a sidebar menu item that routes to the path setup in the previous step
|
|
163
|
-
|
|
164
|
-
```tsx
|
|
165
|
-
// packages/app/src/components/Root.tsx
|
|
166
|
-
import DoneAllIcon from '@material-ui/icons/DoneAll';
|
|
167
|
-
|
|
168
|
-
export const Root = ({ children }: PropsWithChildren<{}>) => (
|
|
169
|
-
<SidebarPage>
|
|
170
|
-
<Sidebar>
|
|
171
|
-
<SidebarLogo />
|
|
172
|
-
{/* existing sidebar items... */}
|
|
173
|
-
|
|
174
|
-
<SidebarScrollWrapper>
|
|
175
|
-
{/* existing sidebar items... */}
|
|
176
|
-
|
|
177
|
-
<SidebarItem icon={DoneAllIcon} to="soundcheck" text="Soundcheck" />
|
|
178
|
-
</SidebarScrollWrapper>
|
|
179
|
-
</Sidebar>
|
|
180
|
-
</SidebarPage>
|
|
181
|
-
);
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### 5. Install Soundcheck Group Content Page
|
|
185
|
-
|
|
186
|
-
The Soundcheck Group Content Page is a Soundcheck Overview Page that can be pinned to a selected group entity.
|
|
187
|
-
It can only be added to a group page type within your Backstage `EntityPage`.
|
|
188
|
-
|
|
189
|
-
```tsx
|
|
190
|
-
// packages/app/src/components/catalog/EntityPage.tsx
|
|
191
|
-
import { GroupSoundcheckContent } from '@spotify/backstage-plugin-soundcheck';
|
|
192
|
-
|
|
193
|
-
const groupPage = (
|
|
194
|
-
<EntityLayout>
|
|
195
|
-
{/* existing tabs... */}
|
|
196
|
-
|
|
197
|
-
<EntityLayout.Route path="/soundcheck" title="Soundcheck">
|
|
198
|
-
<GroupSoundcheckContent />
|
|
199
|
-
</EntityLayout.Route>
|
|
200
|
-
</EntityLayout>
|
|
201
|
-
);
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 6. Check everything is working
|
|
205
|
-
|
|
206
|
-
If you have followed all steps up to this point, Soundcheck is set up and
|
|
207
|
-
running. The backend successfully starts up if the track config is valid, and
|
|
208
|
-
when you navigate to a catalog page for one of the entity types you configured
|
|
209
|
-
above, you'll see the Soundcheck tab containing the applicable tracks for the
|
|
210
|
-
current entity. If you visit `/soundcheck` or click the "Soundcheck" entry on the sidebar, you should see the overview page.
|
|
211
|
-
|
|
212
|
-
# Product Documentation
|
|
213
|
-
|
|
214
|
-
## No-Code UI for checks, tracks and facts management
|
|
215
|
-
|
|
216
|
-
No-Code UI is a powerful user interface built into the Soundcheck plugin that allows users to manage checks, tracks and facts without writing YAML code. Prior to No-Code UI, users had to write YAML code to configure a new check, track or fact. Now, non-programmers can add checks, tracks and facts too – thereby making it easier for everyone to work within Soundcheck.
|
|
217
|
-
|
|
218
|
-
No-Code UI has the same capabilities as its YAML configuration analog, however this capability simplifies and visualizes the process of managing checks, tracks and facts. Checks, tracks and facts created via No-Code UI are stored in the central Backstage database, or a [plugin-specific database](https://backstage.io/docs/tutorials/configuring-plugin-databases?__hstc=71158991.ce8f00825b31a2e008e99e7bf8c61d36.1687962480385.1687962480385.1687962480385.1&__hssc=71158991.1.1687962480385&__hsfp=2924083047#connection-configuration-per-plugin) if configured.
|
|
219
|
-
|
|
220
|
-
The No-Code UI will allow non-programmers to easily manage checks, tracks and facts via the Soundcheck UI without needing to write code. However, if a user wishes to, they can still continue to create checks, tracks and facts through Soundcheck’s YAML configuration.
|
|
221
|
-
|
|
222
|
-
## Using the No-Code UI
|
|
223
|
-
|
|
224
|
-
### Checks
|
|
225
|
-
|
|
226
|
-
A check is a comparison between a defined acceptable outcome and the actual outcome of a given process. Checks indicate where the software aligns to or deviates from organizational standards and best practices.
|
|
227
|
-
|
|
228
|
-

|
|
229
|
-
|
|
230
|
-
Checks consist of four components: facts, paths, operators, and values. These components are then organized via a Boolean calculator in the UI. You can see an example of the rule layout a user will see when creating a check in the image below.
|
|
231
|
-
|
|
232
|
-

|
|
233
|
-
|
|
234
|
-
#### Creating a new check
|
|
235
|
-
|
|
236
|
-
To create a check, select the facts that you want to use, organize them into rules and give your check a meaningful name and a description. The rules are what defines a check and what a track will use in determining if an entity passes or fails. Simple expressions can be combined using Any Of / All Of to create more complex rules. You also have the option of adding Pass/Fail messages for additional details of why something passed/failed.
|
|
237
|
-
|
|
238
|
-

|
|
239
|
-
|
|
240
|
-
#### Editing a check
|
|
241
|
-
|
|
242
|
-
Once a check is created, you will be able to manage and edit your check on its detail page. You’ll find no differences in how the pages look when creating/editing a check. From the checks listing page, you will see an option to edit you check, which will bring you to the details page shown below.
|
|
243
|
-
|
|
244
|
-

|
|
245
|
-
|
|
246
|
-
You can make as many changes as desired, but just keep in mind that changes are reflected in tracks that may already have said check assigned. Checks can also be a part of multiple tracks, which could have the unintentional effect of causing some tracks to start failing. While the track you want the check updated in may pass, a track setup somewhere else may fail.
|
|
247
|
-
|
|
248
|
-
### Tracks
|
|
249
|
-
|
|
250
|
-
Tracks are composed of levels and checks. Tracks encourage alignment to architectural best practices and standards and are analogous to an organization’s long-term tech health initiatives. Tracks are composed of one or more levels, and each level is composed of one or more checks. Each level of checks sets the standard for an organization and how they want to determine what passes and what fails in the individual track.
|
|
251
|
-
|
|
252
|
-

|
|
253
|
-
|
|
254
|
-
#### Creating a new track
|
|
255
|
-
|
|
256
|
-
To create a track, give your track a meaningful name and a description, and select the filters and checks that you want to use.
|
|
257
|
-
|
|
258
|
-

|
|
259
|
-
|
|
260
|
-
Filters allow a user further customization for their tracks to only be applicable to specific entities in the Software Catalog. This allows users to tie their tracks to specific tags such as “Java”, “service” or “production” to name a few. You can have as many or as few selections per type as you want to include in each track. Each type of filter will display a dropdown menu with your choice for selection. You can select any number of filters per section as desired.
|
|
261
|
-
|
|
262
|
-
Checks are searchable, and can be dragged-and-dropped from the list of checks into the level(s) of the track. Levels can be added to a track with the “+ Add Level” button shown above. Organizing checks into levels allows for a more nuanced read of what checks cleared and which ones didn’t. Most use levels by order of difficulty to clear, where level one means hardest to pass, level two is medium hard to pass, and level three is relatively easy to pass.
|
|
263
|
-
|
|
264
|
-
#### Editing a track
|
|
265
|
-
|
|
266
|
-
Once a track is created, you will be able to manage and edit your track on its detail page. From the tracks listing page, you will see an option to edit your track, which will bring you to the details page shown below.
|
|
267
|
-
|
|
268
|
-

|
|
269
|
-
|
|
270
|
-
As with checks, you can make as many changes as desired when editing tracks. Just make sure to save your track in order for changes to take effect. Also, similar to checks,, editing a track and saving will immediately reflect onto anything that has been assigned to said track.
|
|
271
|
-
|
|
272
|
-
### Fact Collectors
|
|
273
|
-
|
|
274
|
-
While Soundcheck comes with two built-in fact collectors: catalog and soundcheck, soundcheck can be extended with additional fact collectors. A fact collector can collect one or more facts on a given entity. At the moment, only Github fact collectors are supported for No Code UI, with support for others coming in future releases.
|
|
275
|
-
|
|
276
|
-

|
|
277
|
-
|
|
278
|
-
#### Configuring a fact collector
|
|
279
|
-
|
|
280
|
-
To configure a fact collector, make sure you are on the Collectors tab. Click on a Fact's “Configure” link to open a modal that displays the Fact Collector's configuration form.
|
|
281
|
-
|
|
282
|
-
- WARNING: If you already have a config YAML file setup, you will be unable to use No-Code UI to configure your collector. In order to use the No-Code UI, simply remove the YAML file/reference and you will have access to configure from No-Code UI.
|
|
283
|
-
|
|
284
|
-

|
|
285
|
-
|
|
286
|
-
Once you choose to configure a collector, you will see the following page with 3 configuration options. You can see what each configuration collects in its description. All 3 configs have the following options:
|
|
287
|
-
|
|
288
|
-
#### Frequency
|
|
289
|
-
|
|
290
|
-

|
|
291
|
-
|
|
292
|
-
You can set the frequency of how often to collect details from each collector option. The frequency of runs can be set using regular intervals or defined as custom cron expressions.
|
|
293
|
-
|
|
294
|
-
#### Filters
|
|
295
|
-
|
|
296
|
-

|
|
297
|
-
|
|
298
|
-
You can set filters for each option as well. These filters contain the same options as Tracks. You can learn by going to the [Creating a new track](#creating-a-new-track) section.
|
|
299
|
-
|
|
300
|
-
#### Caching
|
|
301
|
-
|
|
302
|
-

|
|
303
|
-
|
|
304
|
-
Lastly, you can enable Caching and set up an optional duration for said cache.
|
|
305
|
-
|
|
306
|
-
Once you have finished making your desired changes, make sure to click on the save button in order to properly save you configuration. Optionally, you can click on the cancel button at anytime to discard your changes..
|
|
307
|
-
|
|
308
|
-
## RBAC Integration
|
|
309
|
-
|
|
310
|
-
Along with the No Code UI release, we have recently integrated Soundcheck with the [RBAC plugin](https://backstage.spotify.com/plugins/rbac/). Admins can now use the RBAC plugin to manage (allow and restrict) what individual users or groups can do within Soundcheck.
|
|
311
|
-
|
|
312
|
-
Soundcheck’s No-Code UI integrates with Backstage’s permission framework on the RBAC plugin. This integration enables restricting which users/groups can Create, Read, Update, or Delete (CRUD) Soundcheck checks and tracks.
|
|
313
|
-
|
|
314
|
-

|
|
315
|
-
|
|
316
|
-
> Note: For the Soundcheck permissions to display as you see above sure you have added `soundcheck` to the list of `permissionedPlugins` in your `app-config.yaml`. For more details, [click here](https://www.npmjs.com/package/@spotify/backstage-plugin-rbac-backend#3-configure-permissioned-plugins).
|
|
317
|
-
|
|
318
|
-
Take a look at the [RBAC Integration](https://backstage.spotify.com/plugins/rbac/) for details and [RBAC Readme](https://www.npmjs.com/package/@spotify/backstage-plugin-rbac) for steps.
|
|
319
|
-
|
|
320
|
-
## Soundcheck Tech Health Page
|
|
321
|
-
|
|
322
|
-
Soundcheck has the capability to aggregate, filter, and display check result and certification data.
|
|
323
|
-
The `pass rate` is the aggregation metric representing the percentage of check results or
|
|
324
|
-
certifications marked as 'passed' within a filterable group of current check results or certifications
|
|
325
|
-
for the date the metric is calculated.
|
|
326
|
-
|
|
327
|
-
The tech health page is available at the following link:
|
|
328
|
-
http://[hostname]:[port]/soundcheck/tech-health
|
|
329
|
-
|
|
330
|
-

|
|
331
|
-
|
|
332
|
-
### Aggregations
|
|
333
|
-
|
|
334
|
-
The check result and certification data can be aggregated by:
|
|
335
|
-
|
|
336
|
-
- `Checks`: Pass rates for checks, either organization-wide or filtered by specific checks,
|
|
337
|
-
tracks/levels, and entities based on the selections.
|
|
338
|
-
- `Tracks`: Pass rates for track levels, either organization-wide or filtered by specific checks,
|
|
339
|
-
tracks/levels, and entities based on the selections.
|
|
340
|
-
- `Entities`: Pass rates for entities, either organization-wide or filtered by specific checks,
|
|
341
|
-
tracks/levels, and entities based on the selections.
|
|
342
|
-
- `Teams`: Pass rates for teams, either organization-wide or filtered by specific checks,
|
|
343
|
-
tracks/levels, and entities based on the selections.
|
|
344
|
-
- `Campaigns`: Pass rates for campaigns, either organization-wide or filtered by specific checks,
|
|
345
|
-
tracks/levels, teams, and entities based on the selections.
|
|
346
|
-
|
|
347
|
-
### Filters
|
|
348
|
-
|
|
349
|
-
The data can be filtered by the following categories:
|
|
350
|
-
|
|
351
|
-
- `Entities`: check and certification pass rates will be calculated only for selected entities.
|
|
352
|
-
- `Entity Kind`: check and certification pass rates will be calculated only for the entities
|
|
353
|
-
with selected kinds.
|
|
354
|
-
- `Entity Type`: check and certification pass rates will be calculated only for the entities
|
|
355
|
-
with selected types.
|
|
356
|
-
- `Entity Owner`: check and certification pass rates will be calculated only for the entities
|
|
357
|
-
owned by selected teams and their child teams recursively.
|
|
358
|
-
- `Entity Lifecycle`: check and certification pass rates will be calculated only for the entities
|
|
359
|
-
with selected lifecycles.
|
|
360
|
-
- `Tracks`: check and certification pass rates will be calculated only for selected tracks and
|
|
361
|
-
checks included in these tracks.
|
|
362
|
-
- `Track Level`: check and certification pass rates will be calculated only for selected track
|
|
363
|
-
levels and checks included in these track levels.
|
|
364
|
-
- `Checks`: check pass rates will be calculated only for selected checks. Certification pass rates
|
|
365
|
-
will be calculated only for track levels that include these checks.
|
|
366
|
-
- `Check Owner`: check pass rates will be calculated only for the checks owned by selected teams.
|
|
367
|
-
Certification pass rates will be calculated only for track levels that include checks owned by
|
|
368
|
-
selected teams.
|
|
369
|
-
|
|
370
|
-
Filter rules:
|
|
371
|
-
|
|
372
|
-
- If no filter values are selected the pass rates will be calculated across the entire organization.
|
|
373
|
-
- Filter values within the same category are treated as ANY (OR).
|
|
374
|
-
- Filter values within different categories are treated as ALL (AND).
|
|
375
|
-
|
|
376
|
-
### Trends
|
|
377
|
-
|
|
378
|
-
The pass rate metric can be calculated for up to the last 90 days so that the pass rates can be monitored over time.
|
|
379
|
-
Check result history and certification history must be enabled in order to be able to see the trend data:
|
|
380
|
-
|
|
381
|
-
- [Enabling check result history](https://www.npmjs.com/package/@spotify/backstage-plugin-soundcheck-backend#enabling-check-result-history)
|
|
382
|
-
- [Enabling certification history](https://www.npmjs.com/package/@spotify/backstage-plugin-soundcheck-backend#enabling-certification-history)
|
|
383
|
-
|
|
384
|
-
### Data Export
|
|
385
|
-
|
|
386
|
-
The aggregated data from each Tech Health Page tab can be exported into a Comma-Separated Values (CSV)
|
|
387
|
-
file format. The CSV format is widely supported and can be easily imported into various data analysis
|
|
388
|
-
tools, spreadsheets, and databases.
|
|
389
|
-
|
|
390
|
-
### Data Caching
|
|
391
|
-
|
|
392
|
-
In order to improve Soundcheck Tech Health page performance you can enable data caching.
|
|
393
|
-
Caching can be specified for trends and snapshots separately.
|
|
394
|
-
Omitting a cache specification will disable caching for that data type.
|
|
395
|
-
|
|
396
|
-
The configuration should be added to the soundcheck portion of `app-config.yaml`:
|
|
397
|
-
|
|
398
|
-
```yaml
|
|
399
|
-
# app-config.yaml
|
|
400
|
-
soundcheck:
|
|
401
|
-
techHealth:
|
|
402
|
-
caching:
|
|
403
|
-
trends:
|
|
404
|
-
enabled: true
|
|
405
|
-
cacheTtl: 86400
|
|
406
|
-
snapshots:
|
|
407
|
-
enabled: true
|
|
408
|
-
cacheTtl: 600
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
- `caching`: A section in which caching per data type can be enabled/disabled. Default value is 'true' for both types.
|
|
412
|
-
- `trends`: A section in which trend data caching can be configured.
|
|
413
|
-
- `snapshots`: A section in which snapshot data caching can be configured.
|
|
414
|
-
- `enabled`: A boolean value indicating whether caching is enabled for the data type. Default value is 'true'.
|
|
415
|
-
- `cacheTtl`: The number of seconds for which the data will be cached, if enabled. Default value is 900 (15 minutes) for snapshots and 86400 (24 hours) for trends.
|
|
416
|
-
|
|
417
|
-
## Campaigns in Soundcheck
|
|
418
|
-
|
|
419
|
-
Soundcheck Campaigns provide a structured approach for organizations to drive focused initiatives, such as software updates or system transitions. They offer a way to create, manage, and monitor these initiatives within the Soundcheck framework.
|
|
420
|
-
|
|
421
|
-
### Key features include:
|
|
422
|
-
|
|
423
|
-
- **Initiation of Campaigns**: Users can create campaigns with specific goals, ownership, and timelines.
|
|
424
|
-
- **Focused Initiatives**: Campaigns enable targeting specific organizational objectives, like updating a software library.
|
|
425
|
-
- **Notification System**: Alerts are optionally sent out via Slack when there are changes in check statuses or certification levels, aiding prompt action.
|
|
426
|
-
- **Dashboard Tracking**: Progress of campaigns across different teams or the entire organization is visually trackable.
|
|
427
|
-
- **Archiving Feature**: Completed campaigns can be archived for historical reference.
|
|
428
|
-
|
|
429
|
-
Campaigns are designed to enhance awareness and actionability in focused initiatives, providing an additional capability within Soundcheck to manage initiatives that run for shorter periods. Some example use cases include:
|
|
430
|
-
|
|
431
|
-
**Examples include:**
|
|
432
|
-
|
|
433
|
-
- There is a need to Upgrade Spring Libraries to use a specific version of Spring Boot.
|
|
434
|
-
- When your organization wants to remove unneeded data endpoints to save cost.
|
|
435
|
-
|
|
436
|
-
### Campaigns Library
|
|
437
|
-
|
|
438
|
-
The Campaigns Library in Soundcheck serves as the central dashboard for all campaign-related activities. It is designed to provide users with a comprehensive overview of campaigns as well as control over various campaigns within the organization. Here, users can engage in several key activities:
|
|
439
|
-
|
|
440
|
-
- **Navigate to Individual Campaign Details**: Users can view detailed information about each campaign, including its objectives, current status, assigned teams or individuals, and progress metrics. This detailed view helps in monitoring and managing specific campaigns more effectively.
|
|
441
|
-
- **Create New Campaigns**: This function allows users to initiate new campaigns. Users can define the campaign's objectives, set timelines, assign owners, and specify other relevant parameters. The creation process is designed to be intuitive, guiding users through each step to ensure all necessary information is captured.
|
|
442
|
-
- **Edit Campaigns**: Campaign creators have the flexibility to modify the details of existing campaigns. This includes changing objectives, timelines, ownership, and other critical campaign parameters. This feature is crucial for adapting to changing conditions or requirements within a project or organization.
|
|
443
|
-
- **Delete Campaigns**: In cases where a campaign is no longer relevant or has been created by mistake, users can remove it from the system. This helps in maintaining a clean and up-to-date campaign dashboard.
|
|
444
|
-
- **Archive Completed Campaigns**: Once a campaign has reached its conclusion or its goals have been met, users can archive the campaign. This feature keeps the main dashboard focused on active campaigns, while still preserving the data of completed initiatives for future reference or analysis.
|
|
445
|
-
|
|
446
|
-

|
|
447
|
-
|
|
448
|
-
### Campaign Creation
|
|
449
|
-
|
|
450
|
-
Creating campaigns in Soundcheck is a feature accessible to all users,
|
|
451
|
-
allowing them to initiate new campaigns. This process is divided into four structured steps.
|
|
452
|
-
|
|
453
|
-
#### Step 1: Campaign Details
|
|
454
|
-
|
|
455
|
-
In this initial step, users establish the foundational elements of the campaign:
|
|
456
|
-
|
|
457
|
-
- **Campaign Name**: Assign a unique and descriptive name for easy identification.
|
|
458
|
-
- **Campaign Description**: Provide a detailed description of the campaign’s objectives and scope.
|
|
459
|
-
- **Campaign Owner**: Designate the individual or team responsible for overseeing the campaign.
|
|
460
|
-
- **Support Channel**: Optionally specify the Slack channel for campaign-related notifications.
|
|
461
|
-
- **Start and End Dates**: Set definitive start and end dates to establish a clear timeline for the campaign.
|
|
462
|
-
|
|
463
|
-
#### Step 2: Selecting Checks
|
|
464
|
-
|
|
465
|
-
This step involves choosing specific checks that the campaign will use to track progress against.
|
|
466
|
-
|
|
467
|
-
#### Step 3: Applying Filters
|
|
468
|
-
|
|
469
|
-
Filters are used to determine which entities the campaign targets.
|
|
470
|
-
|
|
471
|
-
#### Step 4: Defining Milestones
|
|
472
|
-
|
|
473
|
-
Milestones are set to track progress and achieve specific targets within the campaign.
|
|
474
|
-
Each milestone includes a name, description, and a defined pass rate, providing clear targets for
|
|
475
|
-
campaign progression.
|
|
476
|
-
|
|
477
|
-

|
|
478
|
-
|
|
479
|
-
### Campaign Archival
|
|
480
|
-
|
|
481
|
-
The Soundcheck Campaigns page lists all active campaigns offers users tools for finalizing and
|
|
482
|
-
archiving campaigns, ensuring the completion of objectives is clearly documented.
|
|
483
|
-
Admins and authorized users can view archived campaigns, providing a historical perspective on past initiatives.
|
|
484
|
-
|
|
485
|
-
### Campaign Progress and Milestones
|
|
486
|
-
|
|
487
|
-
Milestones are an important part of campaigns, serving as tangible markers of progress and success.
|
|
488
|
-
Each milestone’s progress is monitored, with updates provided on completion rates and remaining tasks.
|
|
489
|
-
|
|
490
|
-
Campaign progress is monitored and displayed in various sections within Soundcheck:
|
|
491
|
-
|
|
492
|
-
- **Overview Tab**: A dedicated section in the Overview tab provides a snapshot of all ongoing campaigns.
|
|
493
|
-
- **Tech Health Page**: The Tech Health Page includes a tab for campaigns, showcasing detailed analytics and progress for each campaign. This helps in understanding the broader impact of campaigns on organizational tech health.
|
|
494
|
-
- **Entity-Specific Progress**: For each entity page in Soundcheck, there's a section that displays the campaign progress related to that particular entity.
|
|
495
|
-
- **Group-Specific Progress**: Similar to entity pages, each group page in Soundcheck includes a section that shows the campaign progress for the group.
|
|
496
|
-
|
|
497
|
-

|
|
498
|
-

|
|
499
|
-
|
|
500
|
-
### Campaign Notifications
|
|
501
|
-
|
|
502
|
-
The optional notification feature for campaigns is designed to keep users informed and responsive to changes and developments within their software environment. They act as a proactive communication tool, enhancing awareness and efficiency in managing software health and compliance.
|
|
503
|
-
|
|
504
|
-
For detailed documentation on getting notifications set up, refer to the [Slack Notifications section](../../plugins/soundcheck-backend/README.md#5-slack-notifications) of the Soundcheck Backend README.
|
|
505
|
-
|
|
506
|
-
#### Scenarios for Receiving Notifications
|
|
507
|
-
|
|
508
|
-
During campaign creation, the creator has the option to set up a Slack channel to be used for campaign notifications. If specified, campaign notifications will be sent to the provided channel.
|
|
509
|
-
|
|
510
|
-
- **Assigned Campaigns**: When a new campaign is created, the campaign specific channel will receive a notification to acknowledge and start addressing the goals of the campaign.
|
|
511
|
-
- **Campaign Updates**: Alerts are issued for any changes to a campaigns, including the checks associated with the campaign, the milestones of the campaign, or any related metadata.
|
|
512
|
-
|
|
513
|
-

|
|
5
|
+
If you are already a customer, you can find detailed documentation about the Soundcheck Plugins [here](https://backstage.spotify.com/docs/soundcheck).
|
package/alpha/package.json
CHANGED
package/config.d.ts
CHANGED
package/dist/alpha.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createApiExtension as
|
|
1
|
+
import{createApiExtension as i,createApiFactory as u,discoveryApiRef as d,fetchApiRef as p,createPageExtension as c,createNavItemExtension as s,createPlugin as m}from"@backstage/frontend-plugin-api";import{s as h,S as l,e as f,g as R,r as a,o as k}from"./esm/routes-DcGwdXHX.esm.js";import{convertLegacyRouteRef as t,compatWrapper as o}from"@backstage/core-compat-api";import{createEntityContentExtension as r,createEntityCardExtension as g}from"@backstage/plugin-catalog-react/alpha";import n from"react";import v from"@material-ui/icons/DoneAll";import"@backstage/core-plugin-api";import"graphql-request";import"graphql-tag";const y=i({factory:u({api:h,deps:{discoveryApi:d,fetchApi:p},factory:e=>new l(e)})}),E=r({defaultPath:"soundcheck",defaultTitle:"Soundcheck",name:"entity",routeRef:t(f),loader:()=>import("./esm/EntitySoundcheckContent-Dm1OGOA5.esm.js").then(e=>o(n.createElement(e.EntitySoundcheckContent,null)))}),P=g({name:"card",loader:()=>import("./esm/index-ChMeGQBh.esm.js").then(e=>o(n.createElement(e.EntitySoundcheckCard,null)))}),S=r({defaultPath:"soundcheck",defaultTitle:"Soundcheck",name:"group",routeRef:t(R),attachTo:{id:"page:catalog/group-details",input:"contents"},loader:()=>import("./esm/index-e9SWucyI.esm.js").then(e=>o(n.createElement(e.FixedGroupOverviewPage,null)))}),A=c({name:"SoundcheckRoutingPage",namespace:"soundcheck",routeRef:t(a),defaultPath:"/soundcheck",loader:()=>import("./esm/index-DNAl7tKw.esm.js").then(e=>o(n.createElement(e.RoutingPage,null)))}),x=c({name:"overview",namespace:"soundcheck",routeRef:t(k),defaultPath:"/soundcheck",loader:()=>import("./esm/index-e9SWucyI.esm.js").then(e=>o(n.createElement(e.OverviewPage,null)))}),C=s({title:"Soundcheck",icon:v,routeRef:t(a)});var w=m({id:"soundcheck",extensions:[A,x,y,E,P,S,C]});export{w as default};
|
|
2
2
|
//# sourceMappingURL=alpha.esm.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Link as h,InfoCard as C}from"@backstage/core-components";import{useRouteRef as p}from"@backstage/core-plugin-api";import{useEntity as S}from"@backstage/plugin-catalog-react";import{Divider as I}from"@material-ui/core";import L from"@material-ui/core/styles/makeStyles";import{SpotifyLicenseBanner as R}from"@spotify/backstage-plugin-core";import e,{Fragment as b}from"react";import{g as f,a as w,b as D,d as N}from"./CertificationSidebar-CVyVchB8.esm.js";import"@tanstack/react-query";import{b as A,a as P}from"./routes-DcGwdXHX.esm.js";import{A as x,a as B}from"./EmptyState-CFyDYjmm.esm.js";import"@backstage/catalog-model";import"react-router-dom";import{s as F,i as M}from"./license-CQErZDIh.esm.js";import"@material-ui/lab";const T=()=>e.createElement(e.Fragment,null,e.createElement(f,{hideDescription:!0}),e.createElement(f,{hideDescription:!0})),u=L(t=>({certificationWrapper:{display:"flex",justifyContent:"space-between",alignItems:"center"},infoCard:{display:"grid",gridRowGap:t.spacing(2)},emptyState:{overflow:"hidden"}})),o=({children:t,title:n})=>{const a=u();return e.createElement(C,{title:n},e.createElement("div",{className:a.infoCard},e.createElement(R,{inline:!0,backend:F,invalidLicenseMessage:M}),t))},W=(t,n)=>{var a,i;return(i=(a=t.find(l=>l.trackIds.some(m=>m===n)))==null?void 0:a.id)!=null?i:""},$=({title:t="Soundcheck"})=>{const{entity:n}=S(),a=u(),{data:i,isError:l,isLoading:m}=w(n),{data:c,isError:g,isLoading:E}=D(n),y=p(A),k=p(P);return l||g?e.createElement(o,{title:t},e.createElement(x,{severity:"error",title:"Error loading certifications"})):m||E||!i||!c?e.createElement(o,{title:t},e.createElement(T,null)):i.length?e.createElement(o,{title:t},i.map((r,v)=>{var s,d;return e.createElement(b,{key:r.program.name},e.createElement("div",{className:a.certificationWrapper,"data-testid":"soundcheck-track-row"},e.createElement(N,{key:r.program.id,name:r.program.name,badge:(s=r.highestLevel)==null?void 0:s.badge,trackType:(d=r.program)==null?void 0:d.type}),e.createElement(h,{to:r.program.type==="playlist"?k({playlistId:W(c,r.program.id),trackId:r.program.id}):y({trackId:r.program.id})},"View Details")),v<i.length-1?e.createElement(I,null):null)})):e.createElement(o,{title:t},e.createElement("div",{className:a.emptyState},e.createElement(B,null)))};export{$ as C};
|
|
2
|
+
//# sourceMappingURL=Card-Dj5kNp2Q.esm.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{stringifyEntityRef as p}from"@backstage/catalog-model";import{useApi as g,useRouteRef as b}from"@backstage/core-plugin-api";import{useQuery as u}from"@tanstack/react-query";import{s as E,c as F,d as U}from"./routes-DcGwdXHX.esm.js";import{Q as C,C as P,L as N,N as H,b as Q,F as y,A as W}from"./EmptyState-CFyDYjmm.esm.js";import{useEntity as G}from"@backstage/plugin-catalog-react";import{makeStyles as m,Tooltip as M,Typography as c,Box as $}from"@material-ui/core";import t from"react";import{Link as j}from"react-router-dom";import K from"classnames";import O from"@material-ui/icons/Schedule";import{useAutoUpdatingRelativeTime as _}from"@spotify/backstage-plugin-core";import{DateTime as S}from"luxon";import{MarkdownContent as f,Link as q}from"@backstage/core-components";import{Skeleton as o}from"@material-ui/lab";function J(e){const a=g(E),r=p(e);return u([C.Certifications,r],async()=>a.getAllCertifications(r))}function I(e,a){const r=g(E),l=p(e);return u([C.CertificationDetails,l,a],async()=>r.getCertificationDetailsForTrack(l,a),{enabled:!!a})}function V(e){const a=g(E),r=p(e);return u(["soundcheck/playlists",r],async()=>a.getPlaylists(r))}const X=m(e=>({root:{display:"inline-flex",alignItems:"center",gap:e.spacing(1)}})),T=({timestamp:e,description:a})=>{const r=X(),l=S.fromISO(e).toLocaleString(S.DATETIME_FULL),i=_(e),n=a?`${a}: ${i}`:void 0;return t.createElement("div",{className:r.root},t.createElement(M,{title:l},t.createElement(c,{variant:"caption","aria-label":n},i)),t.createElement(O,null))},x=m(e=>({root:{display:"grid",width:"100%",gridTemplateColumns:"auto 1fr auto",gridColumnGap:e.spacing(1),padding:e.spacing(1),alignItems:"center","&.selected":{backgroundColor:e.palette.action.hover},"&:hover, &:active, &:focus":{backgroundColor:e.palette.action.hover}}})),Y=({className:e,href:a,children:r})=>a?t.createElement(j,{to:a,className:e},r):t.createElement("div",{className:e},r),Z=({result:e,name:a,timestamp:r,selected:l=!1,href:i})=>{const n=x(),d=K(n.root,{selected:l});return t.createElement(Y,{href:i,className:d},t.createElement(P,{result:e}),t.createElement(c,{variant:"body2"},a),r?t.createElement(T,{timestamp:r}):null)},ee=m(e=>({noChecks:{padding:e.spacing(1)},checks:{padding:0,margin:0,flex:1,listStyle:"none"},checkItem:{borderBottom:`1px solid ${e.palette.divider}`,"&:last-of-type":{borderBottom:"0"},color:e.palette.text.primary,"& a":{color:e.palette.text.primary,textDecoration:"none"}}})),te=({checks:e,playlistId:a,trackId:r,checkId:l})=>{const i=ee(),n=b(F),d=b(U);return e.length?t.createElement("ul",{className:i.checks},e.map(s=>t.createElement("li",{key:s.id,className:i.checkItem},t.createElement(Z,{...s,selected:s.id===l,href:a?d({playlistId:a,trackId:r,checkId:s.id}):n({trackId:r,checkId:s.id})})))):t.createElement(c,{variant:"body2",className:i.noChecks},"No applicable checks at this level.")},L=m(e=>({wrapper:{backgroundColor:e.palette.type==="dark"?e.palette.grey[700]:e.palette.grey[100],color:e.palette.text.primary,fontSize:e.typography.caption.fontSize,minHeight:"auto",borderTop:`1px solid ${e.palette.divider}`,borderBottom:`1px solid ${e.palette.divider}`,padding:e.spacing(1),display:"grid",gridTemplateAreas:({badge:a})=>[`"${a?"badge":"title"} title"`,`"${a?".":"description"} description"`].join(" "),gridTemplateColumns:"auto 1fr"},title:{gridArea:"title",textTransform:"uppercase",fontWeight:"bold",color:e.palette.text.primary,fontSize:e.typography.body2.fontSize,paddingTop:e.spacing(.5),paddingBottom:e.spacing(.5),lineHeight:1},badge:{gridArea:"badge",marginRight:e.spacing(1)},description:{gridArea:"description",color:e.palette.text.primary,fontSize:e.typography.subtitle2.fontSize,"& p":{marginBlockStart:0,marginBlockEnd:0}}})),ae=e=>{const a=L({badge:e.badge});return t.createElement("div",{className:a.wrapper},e.badge?t.createElement(N,{className:a.badge,badge:e.badge}):null,t.createElement(c,{className:a.title},e.title),e.description?t.createElement(f,{className:a.description,content:e.description}):null)},R=({level:e,checkId:a,trackId:r,playlistId:l,isCampaign:i})=>{var n;return t.createElement(t.Fragment,null,!i&&t.createElement(ae,{badge:e.badge,title:e.name,description:e.description}),t.createElement(te,{checks:(n=e.checks)!=null?n:[],playlistId:l,trackId:r,checkId:a}))},A=({badge:e,className:a,size:r="small",trackType:l})=>{const i=a||"";let n=t.createElement(H,{className:i,size:r});return l==="campaign"?n=t.createElement(Q,{className:i,size:r}):e&&(n=t.createElement(N,{className:i,size:r,badge:e})),n},h=m(e=>({description:{padding:0,margin:0,display:"block","& p":{margin:0}},root:{padding:e.spacing(2),margin:0,display:"grid",gridTemplateColumns:"min-content auto",gridGap:e.spacing(2)},title:{fontSize:e.typography.pxToRem(18),fontWeight:700,lineHeight:1.235,marginBottom:"6px"},level:{textTransform:"uppercase",color:e.palette.text.secondary,fontWeight:700,letterSpacing:"1px"}}));function re({description:e,documentationUrl:a}){const r=h();return a?t.createElement("div",{className:r.description},t.createElement(f,{content:e}),t.createElement(q,{to:a},"Learn more")):t.createElement("div",{className:r.description},t.createElement(f,{content:e}))}const z=({name:e,badge:a,description:r,documentationUrl:l,trackType:i="standard"})=>{const n=h();return t.createElement("div",{className:n.root},t.createElement(A,{badge:a,trackType:i,size:"large"}),t.createElement("div",null,t.createElement(c,{className:n.title},e),r&&t.createElement(re,{description:r,documentationUrl:l})))},B=({hideDescription:e=!1})=>{const a=h();return t.createElement(y,null,t.createElement("div",{className:a.root},t.createElement(o,{width:44,height:44}),t.createElement("div",null,t.createElement(c,{variant:"caption",className:a.level},t.createElement(o,{width:100})),t.createElement(c,{variant:"h4",className:a.title},t.createElement(o,{width:300})),!e&&t.createElement(c,{variant:"body2"},t.createElement(o,null)))))},k=()=>{const e=x();return t.createElement(y,null,t.createElement("div",{className:e.root},t.createElement(o,{width:24,height:24}),t.createElement(c,{variant:"body2"},t.createElement(o,null)),t.createElement(o,{width:100,height:24})))},ne=()=>{const e=L({});return t.createElement(y,null,t.createElement("div",{className:e.wrapper},t.createElement(o,{className:e.title}),t.createElement(c,{className:e.description},t.createElement(o,null))))},w=()=>{const e=ie();return t.createElement("div",null,t.createElement(B,null),new Array(3).fill(null).map((a,r)=>t.createElement(t.Fragment,{key:`skeleton-level-${r}`},t.createElement(ne,null),t.createElement("ul",{className:e.checks},t.createElement(k,null),t.createElement(k,null),t.createElement(k,null)))))},ie=m(()=>({checks:{padding:0,margin:0,flex:1,listStyle:"none"}})),le=({playlistId:e,trackId:a,checkId:r})=>{var l;const{entity:i}=G(),{data:n,isLoading:d,isError:s}=I(i,a);if(s)return t.createElement("div",null,t.createElement($,{padding:2},t.createElement(W,{severity:"error",title:"Error loading certification"})));if(d||!a)return t.createElement(w,null);if(!n)return null;const D=n.program.type==="campaign";return t.createElement("div",null,t.createElement(z,{name:n.program.name,badge:(l=n.highestLevel)==null?void 0:l.badge,description:n.program.description,documentationUrl:n.program.documentationURL,trackType:n.program.type}),n==null?void 0:n.levels.map(v=>t.createElement(R,{key:v.ordinal,level:v,checkId:r,trackId:a,playlistId:e,isCampaign:D})))};export{A as C,T as R,J as a,V as b,w as c,z as d,R as e,le as f,B as g,I as u};
|
|
2
|
+
//# sourceMappingURL=CertificationSidebar-CVyVchB8.esm.js.map
|