@spotify/backstage-plugin-soundcheck 0.5.0 → 0.6.0
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 +30 -1
- package/README.md +97 -7
- package/config.d.ts +0 -4
- package/dist/esm/EntitySoundcheckContent-b20f0ec8.esm.js +2 -0
- package/dist/esm/OverviewPageContent-b39812fb.esm.js +2 -0
- package/dist/esm/RefetchingIndicator-026bd666.esm.js +2 -0
- package/dist/esm/index-5913b2d3.esm.js +306 -0
- package/dist/esm/index-5ffaa13b.esm.js +2 -0
- package/dist/esm/{index-b3600988.esm.js → index-95047e64.esm.js} +2 -2
- package/dist/esm/index-e398f5c6.esm.js +2 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.esm.js +1 -1
- package/package.json +15 -14
- package/dist/esm/CheckFormContext-6f85a3bf.esm.js +0 -2
- package/dist/esm/EntitySoundcheckContent-8fdad07c.esm.js +0 -2
- package/dist/esm/RefetchingIndicator-0caa936c.esm.js +0 -2
- package/dist/esm/index-0a05659f.esm.js +0 -2
- package/dist/esm/index-40aa00c1.esm.js +0 -284
- package/dist/esm/index-92271e48.esm.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @spotify/backstage-plugin-soundcheck
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added support for Soundcheck's No-Code UI.
|
|
8
|
+
- Added `GroupSoundcheckContent` react component that can be added to a group page type within Backstage `EntityPage`:
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
// packages/app/src/components/catalog/EntityPage.tsx
|
|
12
|
+
import { GroupSoundcheckContent } from '@spotify/backstage-plugin-soundcheck';
|
|
13
|
+
|
|
14
|
+
const groupPage = (
|
|
15
|
+
<EntityLayout>
|
|
16
|
+
{/* existing tabs... */}
|
|
17
|
+
|
|
18
|
+
<EntityLayout.Route path="/soundcheck" title="Soundcheck">
|
|
19
|
+
<GroupSoundcheckContent />
|
|
20
|
+
</EntityLayout.Route>
|
|
21
|
+
</EntityLayout>
|
|
22
|
+
);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Added "No certifications available" warning on Soundcheck Overview page in case a selected group doesn't own any entities that have applicable tracks configured.
|
|
28
|
+
- Upgraded Backstage to `v1.16.0`
|
|
29
|
+
- Updated dependencies
|
|
30
|
+
- @spotify/backstage-plugin-soundcheck-common@0.7.0
|
|
31
|
+
- @spotify/backstage-plugin-core@0.5.4
|
|
32
|
+
|
|
3
33
|
## 0.5.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
|
@@ -12,7 +42,6 @@
|
|
|
12
42
|
- Upgraded to Backstage `v1.15.0`
|
|
13
43
|
- Updated dependency `graphql-request` to `6.1.0`.
|
|
14
44
|
- Updated dependency `@types/node` to `^18.0.0`.
|
|
15
|
-
- Updated dependencies
|
|
16
45
|
- Updated dependencies
|
|
17
46
|
- @spotify/backstage-plugin-core@0.5.3
|
|
18
47
|
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ There are 5 fundamental elements that make up Soundcheck:
|
|
|
8
8
|
|
|
9
9
|
- **Check**: A standard or best practice a component is graded against.
|
|
10
10
|
- **Check Result**: The result of running a check against a component. Results are either pass or fail.
|
|
11
|
-
- **
|
|
11
|
+
- **Track**: A long-term tech health initiative.
|
|
12
12
|
- **Level**: A group of checks that represent a milestone within a program.
|
|
13
13
|
- **Certification**: The outcome of passing all checks within a level.
|
|
14
14
|
|
|
@@ -80,11 +80,11 @@ const serviceEntityPage = (
|
|
|
80
80
|
);
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
### 3. Install Soundcheck
|
|
83
|
+
### 3. Install Soundcheck Routing Page
|
|
84
84
|
|
|
85
|
-
Add a new Route element with the path `/soundcheck` and element of `<
|
|
85
|
+
Add a new Route element with the path `/soundcheck` and element of `<SoundcheckRoutingPage />`.
|
|
86
86
|
|
|
87
|
-
`<
|
|
87
|
+
`<SoundcheckRoutingPage />` supports the following props:
|
|
88
88
|
|
|
89
89
|
```tsx
|
|
90
90
|
{
|
|
@@ -96,7 +96,7 @@ The route should look something like this:
|
|
|
96
96
|
|
|
97
97
|
```tsx
|
|
98
98
|
// packages/app/src/App.tsx
|
|
99
|
-
import {
|
|
99
|
+
import { SoundcheckRoutingPage } from '@spotify/backstage-plugin-soundcheck';
|
|
100
100
|
|
|
101
101
|
const routes = (
|
|
102
102
|
<FlatRoutes>
|
|
@@ -104,7 +104,7 @@ const routes = (
|
|
|
104
104
|
|
|
105
105
|
<Route
|
|
106
106
|
path="/soundcheck"
|
|
107
|
-
element={<
|
|
107
|
+
element={<SoundcheckRoutingPage title="My Optional Title" />}
|
|
108
108
|
/>
|
|
109
109
|
</FlatRoutes>
|
|
110
110
|
);
|
|
@@ -134,10 +134,100 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
|
|
|
134
134
|
);
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
### 5.
|
|
137
|
+
### 5. Install Soundcheck Group Content Page
|
|
138
|
+
|
|
139
|
+
The Soundcheck Group Content Page is a Soundcheck Overview Page that can be pinned to a selected group entity.
|
|
140
|
+
It can only be added to a group page type within your Backstage `EntityPage`.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
// packages/app/src/components/catalog/EntityPage.tsx
|
|
144
|
+
import { GroupSoundcheckContent } from '@spotify/backstage-plugin-soundcheck';
|
|
145
|
+
|
|
146
|
+
const groupPage = (
|
|
147
|
+
<EntityLayout>
|
|
148
|
+
{/* existing tabs... */}
|
|
149
|
+
|
|
150
|
+
<EntityLayout.Route path="/soundcheck" title="Soundcheck">
|
|
151
|
+
<GroupSoundcheckContent />
|
|
152
|
+
</EntityLayout.Route>
|
|
153
|
+
</EntityLayout>
|
|
154
|
+
);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 6. Check everything is working
|
|
138
158
|
|
|
139
159
|
If you have followed all steps up to this point, Soundcheck is set up and
|
|
140
160
|
running. The backend successfully starts up if the program config is valid, and
|
|
141
161
|
when you navigate to a catalog page for one of the entity types you configured
|
|
142
162
|
above, you'll see the Soundcheck tab containing the applicable programs for the
|
|
143
163
|
current entity. If you visit `/soundcheck` or click the "Soundcheck" entry on the sidebar, you should see the overview page.
|
|
164
|
+
|
|
165
|
+
# Product Documentation
|
|
166
|
+
|
|
167
|
+
## No-Code UI for checks and tracks management
|
|
168
|
+
|
|
169
|
+
No-Code UI is a powerful user interface built into the Soundcheck plugin that allows users to manage checks and tracks without writing YAML code. Prior to No-Code UI, users had to write YAML code to configure a new check or track. Now, non-programmers can add checks and tracks too – thereby making it easier for everyone to work within Soundcheck.
|
|
170
|
+
|
|
171
|
+
No-Code UI has the same capabilities as its YAML configuration analog, however this capability simplifies and visualizes the process of managing checks and tracks. Checks and tracks 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.
|
|
172
|
+
|
|
173
|
+
The No-Code UI will allow non-programmers to easily manage checks and programs via the Soundcheck UI without needing to write code. However, if a user wishes to, they can still continue to create checks and tracks through Soundcheck’s YAML configuration.
|
|
174
|
+
|
|
175
|
+
## Using the No-Code UI
|
|
176
|
+
|
|
177
|
+
### Checks
|
|
178
|
+
|
|
179
|
+
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.
|
|
180
|
+
|
|
181
|
+

|
|
182
|
+
|
|
183
|
+
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.
|
|
184
|
+
|
|
185
|
+

|
|
186
|
+
|
|
187
|
+
#### Creating a new check
|
|
188
|
+
|
|
189
|
+
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.
|
|
190
|
+
|
|
191
|
+

|
|
192
|
+
|
|
193
|
+
#### Editing a check
|
|
194
|
+
|
|
195
|
+
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.
|
|
196
|
+
|
|
197
|
+

|
|
198
|
+
|
|
199
|
+
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.
|
|
200
|
+
|
|
201
|
+
### Tracks
|
|
202
|
+
|
|
203
|
+
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.
|
|
204
|
+
|
|
205
|
+

|
|
206
|
+
|
|
207
|
+
#### Creating a new track
|
|
208
|
+
|
|
209
|
+
To create a track, give your track a meaningful name and a description, and select the filters and checks that you want to use.
|
|
210
|
+
|
|
211
|
+

|
|
212
|
+
|
|
213
|
+
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.
|
|
214
|
+
|
|
215
|
+
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.
|
|
216
|
+
|
|
217
|
+
#### Editing a track
|
|
218
|
+
|
|
219
|
+
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.
|
|
220
|
+
|
|
221
|
+

|
|
222
|
+
|
|
223
|
+
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.
|
|
224
|
+
|
|
225
|
+
## RBAC Integration
|
|
226
|
+
|
|
227
|
+
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.
|
|
228
|
+
|
|
229
|
+
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.
|
|
230
|
+
|
|
231
|
+

|
|
232
|
+
|
|
233
|
+
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.
|
package/config.d.ts
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e,{useState as W,useEffect as $}from"react";import{Link as O,useParams as Q,Routes as j,Route as k,Navigate as I}from"react-router-dom";import{makeStyles as p,Typography as f,Box as U,Tab as L,Tabs as T,Paper as V,Divider as Y}from"@material-ui/core";import{SpotifyLicenseBanner as q}from"@spotify/backstage-plugin-core";import{useEntity as u}from"@backstage/plugin-catalog-react";import{R as G}from"./RefetchingIndicator-026bd666.esm.js";import{s as H,R as o,A as y,F as B,a as J,u as x,L as K,N as X,b as C,c as g,d as Z,C as _,e as ee,i as te,f as F,S as ae}from"./index-5913b2d3.esm.js";import{Skeleton as s}from"@material-ui/lab";import{MarkdownContent as P}from"@backstage/core-components";import{stringifyEntityRef as ne}from"@backstage/catalog-model";import{useApi as re,useRouteRef as b,useRouteRefParams as ie}from"@backstage/core-plugin-api";import{useQuery as le}from"@tanstack/react-query";import ce from"react-use/lib/useMeasure";import A from"react-use/lib/usePrevious";import oe from"react-confetti";import"react-use/lib/useDebounce";import"graphql-request";import"graphql-tag";import"lodash";import"@material-ui/core/styles/makeStyles";import"classnames";import"@material-ui/icons/Schedule";import"luxon";import"@material-ui/icons/Check";import"@material-ui/icons/Close";import"@material-ui/icons/RemoveCircleOutline";import"@material-ui/icons/HelpOutline";function se(t,n,a){const r=re(H),i=ne(t);return le(["soundcheck/check-details",i,n,a],async()=>r.getCheckResultDetails(i,n,a),{enabled:!!n&&!!a})}const me=p({markdownContent:{"& :last-child":{marginBottom:0}}}),de=({state:t,notes:n})=>{const a=me(),r={[o.Passed]:"success",[o.Failed]:"error",[o.NotReported]:"info",[o.NotApplicable]:"info"}[t],i={[o.Passed]:"Check passed",[o.Failed]:"Check did not pass",[o.NotReported]:"Check not reported",[o.NotApplicable]:"Check not applicable"}[t];return e.createElement(y,{severity:r,title:i},n?e.createElement(P,{className:a.markdownContent,content:n}):null)},pe=()=>{const t=D();return e.createElement(B,null,e.createElement("div",{className:t.root,"data-testid":"check-details-view"},e.createElement("div",{className:t.topBar},e.createElement(f,{variant:"h2",className:t.title},e.createElement(s,{width:300,height:32})),e.createElement(s,{width:100,height:32})),e.createElement(s,{variant:"rect",height:120}),e.createElement("div",{"data-testid":"soundcheck-check-details-description"},e.createElement(f,{variant:"h3"},e.createElement(s,null)),e.createElement(s,null),e.createElement(s,null),e.createElement(s,null))))},D=p(t=>({root:{padding:`${t.spacing(3)}px ${t.spacing(5)}px`},title:{fontWeight:"normal",fontSize:t.typography.h5.fontSize},description:{padding:`${t.spacing(3)}px 0`},subtitle:{fontWeight:"normal",fontSize:t.typography.h6.fontSize},topBar:{display:"flex",justifyContent:"space-between",marginBottom:t.spacing(2)}})),ue=({programId:t,checkId:n})=>{const a=D(),{entity:r}=u(),{data:i,isLoading:l,isError:c}=se(r,t,n);if(c)return e.createElement(U,{padding:2},e.createElement(y,{severity:"error",title:"Error loading check details"}));if(l||!t||!n)return e.createElement(pe,null);if(!i)return null;const{name:h,description:d,result:v,timestamp:m,notes:E}=i;return e.createElement("div",{className:a.root,"data-testid":"check-details-view"},e.createElement("div",{className:a.topBar},e.createElement(f,{variant:"h2",className:a.title},h),m?e.createElement(J,{timestamp:m,description:"Last updated"}):null),e.createElement(de,{state:v,notes:E}),e.createElement("div",{className:a.description,"data-testid":"soundcheck-check-details-description"},e.createElement(f,{variant:"h3",className:a.subtitle},"Description"),e.createElement(P,{content:d})))},he=p(()=>({root:{position:"absolute",width:"100%",height:"100%"}})),Ee=({programId:t})=>{var n,a;const r=he(),{entity:i}=u(),{data:l,isLoading:c}=x(i,t),[h,{width:d,height:v}]=ce(),m=c?void 0:(a=(n=l==null?void 0:l.highestLevel)==null?void 0:n.ordinal)!=null?a:-1,E=A(m),R=A(t),[M,S]=W(!1);return $(()=>{typeof E!="undefined"&&typeof m!="undefined"&&t===R&&m>E&&S(!0)},[m,E,t,R]),M?e.createElement("div",{ref:h,className:r.root},e.createElement(oe,{width:d,height:v,numberOfPieces:1e3,gravity:1,initialVelocityY:20,recycle:!1,onConfettiComplete:()=>S(!1)})):null},z=p(t=>({root:{maxWidth:"80ch",textTransform:"uppercase",paddingTop:t.spacing(2),paddingBottom:t.spacing(2)},wrapper:{display:"inline-block",textOverflow:"ellipsis",whiteSpace:"nowrap",overflow:"hidden"},badge:{marginRight:t.spacing(1)}})),fe=({id:t,name:n,badge:a,href:r,selected:i=!1})=>{const l=z();return e.createElement(L,{className:l.root,classes:{wrapper:l.wrapper},value:t,label:e.createElement(e.Fragment,null,a?e.createElement(K,{badge:a,className:l.badge}):e.createElement(X,{className:l.badge}),n),component:O,to:r,selected:i})},w=()=>{const t=z();return e.createElement(L,{className:t.root,classes:{wrapper:t.wrapper},label:e.createElement(s,{width:180})})},ge=()=>e.createElement(B,null,e.createElement(T,{value:!1,indicatorColor:"primary"},e.createElement(w,null),e.createElement(w,null),e.createElement(w,null)));function ve(t=[],n){const a=t.findIndex(r=>r.program.id===n);return a<0?!1:a}const ke=({trackId:t})=>{const{entity:n}=u(),{isLoading:a,data:r}=C(n),i=b(g);if(a||!t)return e.createElement(ge,null);const l=ve(r,t);return e.createElement(T,{value:l,indicatorColor:"primary","aria-label":"Certifications",variant:"scrollable"},r&&r.map(({program:{id:c,name:h},highestLevel:d})=>e.createElement(fe,{key:c,id:c,name:h,badge:d==null?void 0:d.badge,selected:c===t,href:i({trackId:c})})))},ye=p({paper:{overflow:"hidden",position:"relative"},view:{display:"grid",gridTemplateColumns:"1fr 2fr"}}),Ce=()=>{const{trackId:t,checkId:n}=Q(),a=ye(),{entity:r}=u(),{isError:i,isFetched:l,data:c}=C(r);return i?e.createElement(y,{severity:"error",title:"Error loading certifications"}):l&&!(c!=null&&c.length)?e.createElement(Z,null):e.createElement(V,{className:a.paper},e.createElement(G,null),e.createElement(ke,{trackId:t}),e.createElement(Y,null),e.createElement("div",{"data-testid":"soundcheck-certification-view",className:a.view},e.createElement(_,{trackId:t,checkId:n}),e.createElement(ue,{programId:t,checkId:n}),e.createElement(Ee,{programId:t})))},be=p(t=>({root:{"&:not(:first-child)":{marginTop:t.spacing(2)}}})),N=()=>{const t=be();return e.createElement(e.Fragment,null,e.createElement(q,{backend:ee,invalidLicenseMessage:te,inline:!0}),e.createElement("div",{className:t.root},e.createElement(Ce,null)))},we=()=>{var t;const{entity:n}=u(),a=b(g),{data:r}=C(n),i=(t=r==null?void 0:r[0])==null?void 0:t.program.id;return i?e.createElement(I,{to:a({trackId:i}),replace:!0}):null},Ne=()=>{var t,n;const{entity:a}=u(),{trackId:r}=ie(g),i=b(F),{data:l}=x(a,r),c=(n=(t=l==null?void 0:l.levels[0])==null?void 0:t.checks[0])==null?void 0:n.id;return c?e.createElement(I,{to:i({trackId:r,checkId:c}),replace:!0}):null},Re=()=>e.createElement(j,null,e.createElement(k,{path:"/",element:e.createElement(e.Fragment,null,e.createElement(N,null),e.createElement(we,null))}),e.createElement(k,{path:g.path,element:e.createElement(e.Fragment,null,e.createElement(N,null),e.createElement(Ne,null))}),e.createElement(k,{path:F.path,element:e.createElement(N,null)})),Se=()=>e.createElement(ae,null,e.createElement(Re,null));export{Se as EntitySoundcheckContent};
|
|
2
|
+
//# sourceMappingURL=EntitySoundcheckContent-b20f0ec8.esm.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import t,{useState as I,useEffect as k,useMemo as P,useCallback as j,createContext as pe,useContext as me,memo as b,Fragment as ue}from"react";import{useSearchParams as ge}from"react-router-dom";import{makeStyles as f,alpha as M,TextField as he,CircularProgress as fe,Tooltip as K,LinearProgress as ye,withStyles as ve,Grid as C,Typography as v}from"@material-ui/core";import ke from"@material-ui/lab/Autocomplete";import{stringifyEntityRef as H,parseEntityRef as w}from"@backstage/catalog-model";import{useApi as E,identityApiRef as U,useRouteRef as O,configApiRef as Ee}from"@backstage/core-plugin-api";import{useQuery as A}from"@tanstack/react-query";import{s as D,R as N,h as be,B as Ce,L as _,N as Q,A as we,d as Ne,j as Re}from"./index-5913b2d3.esm.js";import{catalogApiRef as W,humanizeEntityRef as x,entityRouteRef as B}from"@backstage/plugin-catalog-react";import $e from"react-use/lib/useAsync";import{HeaderTabs as q,Link as S,EmptyState as xe}from"@backstage/core-components";import{R as Te}from"./RefetchingIndicator-026bd666.esm.js";import{countBy as J}from"lodash";import{Skeleton as F}from"@material-ui/lab";import{VariableSizeGrid as Le}from"react-window";function Ie(){const e=E(W);return A(["soundcheck/all-groups"],async()=>{const{items:r}=await e.getEntities({filter:{kind:"Group"}});return r.filter(a=>(a==null?void 0:a.kind)==="Group").map(a=>{var n,l,o,i;return{name:(i=(o=(l=(n=a.spec)==null?void 0:n.profile)==null?void 0:l.displayName)!=null?o:a.metadata.title)!=null?i:a.metadata.name,ref:H(a)}})})}function Pe(e){const r=E(D);return A(["soundcheck/facets-for-owner",e],async()=>r.getFacetsForOwner(e),{enabled:!!e})}function X(e,r){const a=E(D);return A(["soundcheck/track-overview-for-owner",e,r],async()=>a.getProgramOverviewForOwner(e,r),{enabled:!!e&&!!(r!=null&&r.kind)})}function Oe(){const e=E(U),r=E(W);return A(["soundcheck/user-groups-claims"],async()=>{const{ownershipEntityRefs:a}=await e.getBackstageIdentity();return(await r.getEntitiesByRefs({entityRefs:a})).items.filter(n=>(n==null?void 0:n.kind)==="Group").map(n=>{var l,o,i,s;return{name:(s=(i=(o=(l=n.spec)==null?void 0:l.profile)==null?void 0:o.displayName)!=null?i:n.metadata.title)!=null?s:n.metadata.name,ref:H(n)}})})}const Ae=()=>{const[e,r]=ge(),a=Object.fromEntries(e.entries()),[n,l]=I(a);return k(()=>{r(n,{replace:!0})},[n]),[n,l]},Y=()=>{const{data:e,isLoading:r,isError:a}=Oe(),{data:n,isLoading:l,isError:o}=Ie();return{options:P(()=>{const i=[];return e&&i.push(...e.map(({name:s,ref:c})=>({name:s,ref:c,key:"My Groups"}))),n&&i.push(...n.map(({name:s,ref:c})=>({name:s,ref:c,key:"All Groups"}))),i},[e,n]),isLoading:r||l,isError:a||o}},Be=f(e=>({root:{width:"100%",minWidth:250},textField:{"& $notchedOutline":{borderColor:M(e.page.fontColor,.25)},"&:hover $notchedOutline":{borderColor:e.page.fontColor}},input:{backgroundColor:"transparent",color:e.page.fontColor},clearIndicator:{color:e.page.fontColor},popupIndicator:{color:e.page.fontColor},notchedOutline:{}})),Se=e=>{const{onChange:r,initialValue:a,setError:n}=e,{options:l,isLoading:o,isError:i}=Y(),s=Be(),[c,d]=I(null);k(()=>{if(!o&&l!=null&&l.length&&!c){const p=a?l.find(m=>m.ref===a):l[0];p&&(d(p),r==null||r(p.ref))}},[o,l,c,r,a]);const u=j((p,m)=>{d(m),r==null||r(m==null?void 0:m.ref)},[r,d]);return k(()=>{n==null||n(i?new Error("Error loading groups"):void 0)},[i,n]),i?null:t.createElement(ke,{"aria-label":"Current group",className:s.root,classes:{clearIndicator:s.clearIndicator,popupIndicator:s.popupIndicator},disableClearable:!0,options:l!=null?l:[],loading:o,groupBy:p=>p.key,value:c,freeSolo:!1,onChange:u,getOptionLabel:p=>p.name,renderInput:p=>t.createElement(he,{...p,variant:"outlined",placeholder:o?"Loading":"Select a group",className:s.textField,InputProps:{...p.InputProps,className:s.input,classes:{notchedOutline:s.notchedOutline},endAdornment:t.createElement(t.Fragment,null,o?t.createElement(fe,{color:"inherit",size:20}):null,p.InputProps.endAdornment)}})})},Z={loading:!1},ee=pe(Z),Fe=()=>me(ee),ze=({children:e})=>{const[r,a]=I(Z),n=E(W),l=E(U),{value:o,loading:i,error:s}=$e(async()=>{const[{token:c},d]=await Promise.all([l.getCredentials(),l.getBackstageIdentity()]);return c?await n.getEntityByRef(d.userEntityRef):null},[n,l]);return k(()=>{if(o){const c=H(o);a({user:o,userEntityRef:c,loading:i,error:s})}else a({loading:i,error:s})},[o,i,s]),t.createElement(ee.Provider,{value:r},e)},He=e=>({key:`skeleton${e}`,label:"",id:`skeleton${e}`}),We=()=>{const e=Array.from({length:4},(r,a)=>He(a));return t.createElement(q,{tabs:e})},Ge=f(e=>({root:{borderTop:`1px solid ${e.palette.divider}`,borderBottom:`1px solid ${e.palette.divider}`},tab:{textTransform:"uppercase",paddingTop:e.spacing(2),paddingBottom:e.spacing(2)}})),Ve=({unfilteredFacets:e,onChange:r,kind:a,type:n})=>{var l,o,i;const s=Ge(),c={types:(l=e==null?void 0:e.types.filter(({count:m})=>m>0))!=null?l:[]},d=j(m=>{var g;r((g=c==null?void 0:c.types[m].kind)!=null?g:"",c==null?void 0:c.types[m].type)},[c==null?void 0:c.types,r]);k(()=>{var m,g,y;const h=(c==null?void 0:c.types)&&c.types.length>=0,T=!a&&h,$=a&&h&&!(c!=null&&c.types.find(({kind:L,type:V})=>a===L&&(!n&&!V||n===V)));(T||$)&&r((g=(m=c==null?void 0:c.types[0])==null?void 0:m.kind)!=null?g:"",(y=c==null?void 0:c.types[0])==null?void 0:y.type)},[a,n,c==null?void 0:c.types,r]);const u=(o=c==null?void 0:c.types.map(({kind:m,type:g,count:y})=>{const h=`${m}|${g!=null?g:""}`;return{key:h,label:`${g!=null?g:m} (${y>50?"50+":y})`,id:h,tabProps:{className:s.tab}}}))!=null?o:[];if(!u.length)return null;const p=(i=c==null?void 0:c.types.findIndex(m=>m.kind===a&&(!m.type&&!n||m.type===n)))!=null?i:-1;return t.createElement(t.Fragment,null,t.createElement(Te,null),t.createElement(q,{onChange:d,tabs:u,selectedIndex:p>-1?p:void 0}))},je=f(e=>({root:{height:"8px",minWidth:"64px",marginLeft:e.spacing(2),borderRadius:"100vh",backgroundColor:e.palette.background.default},bar:{backgroundColor:e.palette.success.main,transition:"none"}})),te=e=>{var r,a;const n=je(e),l=P(()=>Object.entries(e.progress).reduce((i,[,s])=>i+s,0),[e.progress]);if(l===0)return null;const o=(r=e.progress[N.Passed])!=null?r:0;return t.createElement(K,{arrow:!0,title:`Check passing for ${o} of ${l} ${l===1?"entity":"entities"}`,enterDelay:0,placement:"top"},t.createElement(ye,{variant:"determinate",value:((a=e.progress[N.Passed])!=null?a:0)/l*100,classes:{root:n.root,bar:n.bar}}))},Me=f(e=>({headerWrapper:{marginTop:e.spacing(.5)},entityRefName:{fontWeight:"bold"},iconWrapper:{padding:e.spacing(1.5,.5),display:"flex",alignItems:"center",justifyContent:"center"}})),Ke=({check:{name:e,description:r},icon:a,entityRef:n})=>{const l=Me(),o=w(n);return t.createElement(C,{spacing:1},t.createElement(C,{container:!0,direction:"row",spacing:1,wrap:"nowrap"},t.createElement("div",{className:l.iconWrapper},a),t.createElement(v,{variant:"h6",className:l.headerWrapper,noWrap:!0},e)),t.createElement(C,{item:!0,wrap:"nowrap"},t.createElement(v,{variant:"subtitle2",className:l.entityRefName},x(o,{defaultKind:o.kind}))),t.createElement(v,{variant:"caption"},r))},Ue=ve(e=>{const r=e.palette.type==="dark"?e.palette.common.black:e.palette.grey[300];return{tooltip:{backgroundColor:r,color:e.palette.type==="dark"?e.palette.common.white:e.palette.grey[700]},arrow:{color:r}}})(K),De=({children:e,check:r,icon:a,entityRef:n})=>t.createElement(Ue,{arrow:!0,title:t.createElement(Ke,{check:r,icon:a,entityRef:n}),enterDelay:150,placement:"top"},e),_e=f(e=>({root:{padding:0},iconWrapper:{padding:e.spacing(1.5),display:"flex",alignItems:"center",justifyContent:"center"},link:{"&:hover $iconWrapper, &:active $iconWrapper, &:focus $iconWrapper":{backgroundColor:e.palette.infoBackground}},icon:{width:"17px",height:"17px"},virtualized:{borderBottom:`1px solid ${e.palette.divider}`,borderRight:`1px solid ${e.palette.divider}`}})),re=b(({programId:e,check:r,entityRef:a,result:n,entityRoute:l,isVirtualized:o})=>{const i=_e();if(typeof a!="string"){const u=t.createElement("div",{className:i.iconWrapper},t.createElement("div",{className:i.icon}));return o?t.createElement("div",{className:`${i.root} ${i.virtualized}`,"aria-hidden":!0},u):t.createElement("td",{className:i.root,"aria-hidden":!0},u)}const s=t.createElement(be,{className:i.icon,result:n!=null?n:N.NotReported}),c=t.createElement("div",{className:i.iconWrapper},s),d=n&&n===N.NotApplicable?c:t.createElement(S,{className:i.link,to:`${l(w(a))}/soundcheck/${e}/${r.id}`},c);return o?t.createElement("div",{className:`${i.root} ${i.virtualized}`},t.createElement(De,{check:r,icon:s,entityRef:a},d)):t.createElement("td",{className:`${i.root}`},d)}),ae=8,Qe=16,R={programTitle:70,levelTitle:30,check:42,entityRefFooter:100},z={programTitle:350+Qe*2,checkResult:42},qe=e=>e.reduce((r,a)=>r+a.height,0),Je=e=>e*z.checkResult+z.programTitle,Xe=e=>e.filter(r=>r!==void 0).map(r=>{const a=w(r);return x(a,{defaultKind:a.kind})}).reduce((r,a)=>r.length>a.length?r:a,""),Ye=e=>ae*e+ae,ne="NoLevel",Ze=e=>({name:ne,badge:{options:{level:0,color:""},variant:Ce.Medal},entityRef:e,ordinal:0}),le=f(e=>({checkNameCell:{padding:0,backgroundColor:e.palette.background.paper},checkNameContent:{padding:`0 ${e.spacing(2)}px`,display:"flex",justifyContent:"space-between",alignItems:"center"},checkNameTypography:{overflow:"hidden",textOverflow:"ellipsis"},checkIndicator:{flexBasis:e.spacing(8)},checkNameCellVirtualized:{height:`${R.check}px`,lineHeight:`${R.check}px`,borderBottom:`1px solid ${e.palette.divider}`,borderRight:`1px solid ${e.palette.divider}`}})),et=b(({programId:e,programName:r,check:a,entityRefs:n,results:l,entityRoute:o})=>{const i=le(),s=P(()=>J(l.filter(({result:d})=>d!==N.NotApplicable),"result"),[l]),c=new Map(l.map(d=>[d.entityRef,d.result]));return t.createElement("tr",{"data-testid":"track-check-row"},t.createElement("th",{scope:"row",className:i.checkNameCell,"aria-label":`${a.name} check for ${r} track`},t.createElement("div",{className:i.checkNameContent},t.createElement(v,{className:i.checkNameTypography,variant:"subtitle2",component:"p"},a.name),t.createElement(te,{className:i.checkIndicator,progress:s}))),n.map((d,u)=>t.createElement(re,{key:u,programId:e,check:a,entityRef:d,result:typeof d=="string"?c.get(d):void 0,entityRoute:o})))}),tt=({name:e,progress:r})=>{const a=le();return t.createElement("div",{className:a.checkNameCell,"aria-label":`${e} check`},t.createElement("div",{className:`${a.checkNameContent} ${a.checkNameCellVirtualized}`},t.createElement(v,{variant:"subtitle2",component:"p",className:a.checkNameTypography},e),t.createElement(te,{className:a.checkIndicator,progress:r})))},rt=f(e=>({virtualized:{borderRight:`1px solid ${e.palette.divider}`,height:`${R.programTitle}px`,display:"flex",justifyContent:"center",alignItems:"center"}})),at=b(({entityRef:e,highestLevels:r})=>{const a=r.find(n=>n.entityRef===e);return t.createElement(t.Fragment,null,a!=null&&a.badge?t.createElement(_,{badge:a.badge}):t.createElement(Q,null))}),nt=({highestLevel:e})=>{const r=rt();if(!(e!=null&&e.badge))return t.createElement("div",{className:r.virtualized},"\xA0");const a=e.name!==ne;return t.createElement("div",{className:r.virtualized},a?t.createElement(_,{badge:e.badge}):t.createElement(Q,null))},oe=f(e=>({programNameCell:{padding:0,position:"sticky",backgroundColor:e.palette.background.paper},programNameContent:{padding:e.spacing(2)},programNameTypography:{overflow:"hidden",textOverflow:"ellipsis"},badgeCellContent:{display:"flex",justifyContent:"center",alignItems:"center"},programNameCellVirtualized:{borderRight:`1px solid ${e.palette.divider}`}})),lt=b(({program:e,entityRefs:r,highestLevels:a})=>{const n=oe();return t.createElement("tr",{"data-testid":"track-title-row"},t.createElement("th",{scope:"row",className:n.programNameCell},t.createElement("div",{className:n.programNameContent},t.createElement(v,{className:n.programNameTypography,variant:"h5",component:"p"},e.name))),r.map((l,o)=>typeof l!="string"?t.createElement("td",{key:o,"aria-hidden":!0}):t.createElement("td",{key:o,"data-testid":"track-certification-cell"},t.createElement("div",{className:n.badgeCellContent},t.createElement(at,{entityRef:l,highestLevels:a})))))}),ot=b(({name:e})=>{const r=oe();return t.createElement("div",{className:`${r.programNameCell} ${r.programNameCellVirtualized}`},t.createElement("div",{className:r.programNameContent},t.createElement(v,{className:r.programNameTypography,variant:"h5",component:"p"},e)))}),G=f(e=>{const r=e.palette.type==="dark"?e.palette.grey[700]:e.palette.grey[100];return{root:{color:M(e.palette.getContrastText(r),.8),backgroundColor:r},levelContent:{padding:`${e.spacing(.5)}px ${e.spacing(2)}px`,backgroundColor:r},levelTypography:{overflow:"hidden",textOverflow:"ellipsis"},levelHeaderCell:{padding:`${e.spacing(.5)}px ${e.spacing(2)}px`,borderRight:`1px solid ${e.palette.divider}`,height:`${R.levelTitle}px`}}}),it=b(({level:e,entityRefs:r,programName:a})=>{const n=G();return t.createElement("tr",{className:n.root,"data-testid":"track-level-row"},t.createElement("th",{scope:"row",className:n.root},t.createElement("div",{className:n.levelContent},t.createElement(v,{className:n.levelTypography,variant:"subtitle2",component:"p","aria-label":`${e.name} for ${a} track`},e.name))),r.map((l,o)=>t.createElement("td",{key:o,className:n.root,"aria-hidden":!0})))}),st=({name:e})=>{const r=G();return t.createElement("div",{className:`${r.levelHeaderCell} ${r.root}`,"aria-label":`${e}`},t.createElement(v,{variant:"subtitle2",component:"p",className:r.levelTypography},e))},ct=()=>{const e=G();return t.createElement("div",{className:`${e.levelHeaderCell} ${e.root}`},"\xA0")},dt=({program:e,highestLevels:r,levels:a,entityRefs:n,entityRoute:l})=>t.createElement("tbody",null,t.createElement(lt,{program:e,entityRefs:n,highestLevels:r}),a.map((o,i)=>t.createElement(ue,{key:i},t.createElement(it,{entityRefs:n,level:o,programName:e.name}),o.checks.map(({check:s,results:c},d)=>t.createElement(et,{key:d,check:s,programId:e.id,programName:e.name,entityRefs:n,results:c,entityRoute:l}))))),ie=f(e=>({root:{position:"sticky",bottom:"-1px",backgroundColor:e.palette.background.default,boxShadow:`0 -1px ${e.palette.divider}`,"& td$cell, & th$cell":{border:0,padding:e.spacing(1)},"& td$cell":{backgroundColor:e.palette.background.default}},row:{boxShadow:`1px 0 ${e.palette.background.default}, -1px 0 ${e.palette.background.default}`},cell:{verticalAlign:"top"},cellInner:{textOrientation:"mixed",writingMode:"vertical-lr",transform:"rotate(-20deg)",transformOrigin:`100% ${e.spacing(1)}px`,wordBreak:"keep-all",fontWeight:"bold",overflow:"hidden",textOverflow:"ellipsis",maxHeight:"max(15vh, 175px)"}})),pt=({entityRefs:e})=>{const r=O(B),a=ie();return t.createElement("tfoot",{className:a.root,"data-testid":"results-table-footer"},t.createElement("tr",{className:a.row},t.createElement("td",{className:a.cell}),e.map((n,l)=>{if(typeof n!="string")return t.createElement("th",{key:l,className:a.cell,"aria-hidden":!0});const o=w(n);return t.createElement("th",{scope:"col",key:l,className:a.cell},t.createElement("div",{className:a.cellInner},t.createElement(S,{to:r(o)},x(o,{defaultKind:o.kind}))))})))},mt=({entityRef:e})=>{const r=O(B),a=ie(),n=e?w(e):void 0,l=n?t.createElement(S,{to:r(n)},x(n,{defaultKind:n.kind})):t.createElement(t.Fragment,null);return t.createElement("div",{className:a.cell},t.createElement("div",{className:a.cellInner},l))},ut=f(e=>({table:{backgroundColor:e.palette.background.paper,borderCollapse:"collapse",whiteSpace:"nowrap","& th, & td":{border:`1px solid ${e.palette.divider}`,borderCollapse:"collapse"},paddingBottom:e.spacing(2)},programTitle:{padding:e.spacing(2)},checkResult:{padding:e.spacing(1.5)},title:{padding:`${e.spacing(1)}px ${e.spacing(2)}px`},header:{backgroundColor:e.palette.type==="dark"?e.palette.grey[700]:e.palette.grey[100]}})),se=()=>{const e=ut(),r=new Array(25).fill(void 0),a=new Array(5).fill(void 0),n=new Array(3).fill(void 0);return t.createElement("table",{className:e.table},t.createElement("tbody",null,t.createElement("tr",null,t.createElement("td",{className:e.programTitle},t.createElement(F,{width:180,height:40})),r.map((l,o)=>t.createElement("td",{key:o}))),n.map((l,o)=>t.createElement(t.Fragment,{key:o},t.createElement("tr",{className:e.header},t.createElement("td",{className:e.title},t.createElement(F,{width:180})),r.map((i,s)=>t.createElement("td",{key:s}))),a.map((i,s)=>t.createElement("tr",{key:s},t.createElement("td",{className:e.title},t.createElement(F,{width:240})),r.map((c,d)=>t.createElement("td",{key:d,className:e.checkResult},t.createElement(F,{width:18,height:18,variant:"rect"})))))))))},gt=f(e=>({root:{width:"100%"},table:{overflow:"auto",backgroundColor:e.palette.background.paper,borderCollapse:"collapse",whiteSpace:"nowrap",textAlign:"left","& th, & td":{border:`1px solid ${e.palette.divider}`,borderCollapse:"collapse"},"& th:first-of-type":{position:"sticky",left:0,zIndex:1,maxWidth:"60ch"},"& tfoot":{bottom:0,zIndex:1e3},"& tbody td:first-of-type":{border:`1px solid ${e.palette.divider}`,boxShadow:`1px 0 ${e.palette.background.default}, -1px 0 ${e.palette.background.default}`}}})),ht=b(e=>{const{setError:r,kind:a,type:n,ownerEntityRef:l}=e,o=gt(),i=O(B),{data:s,isLoading:c,isError:d}=X(l,{kind:a,type:n});if(k(()=>{r==null||r(d?new Error("Error loading track overview"):void 0)},[d,r]),c)return t.createElement(se,null);if(!s||!l)return null;const{programs:u,entityRefs:p}=s;if(!c&&!u.length)return t.createElement(xe,{missing:"data",title:"Missing tracks",description:t.createElement(t.Fragment,null,"Looks like the group"," ",x(w(l),{defaultKind:"Group"})," ","doesn't own any ",n!=null?n:a," components that have Soundcheck tracks set up.",t.createElement("br",null),t.createElement("br",null),"If you're an administrator, you can learn more about configuring and filtering tracks in the"," ",t.createElement(S,{to:"https://www.npmjs.com/package/@spotify/backstage-plugin-soundcheck-backend#entity-filter"},"docs"),".")});if(d)return null;const m=p.length>=25?p:[...p,...Array.from({length:25-p.length},()=>{})];return t.createElement("div",{className:o.root},t.createElement("table",{className:o.table,"aria-label":"Check results"},u.map(({program:g,levels:y,highestLevels:h},T)=>t.createElement(dt,{key:T,program:g,entityRefs:m,levels:y,highestLevels:h,entityRoute:i})),t.createElement(pt,{entityRefs:m})))}),ft=e=>t.createElement(ot,{name:e}),yt=e=>({type:"ProgramHeader",render:()=>ft(e)}),vt=e=>e?t.createElement(st,{name:e}):t.createElement(ct,null),ce=e=>({type:"LevelHeader",render:()=>vt(e)}),kt=(e,r)=>t.createElement(tt,{name:e,progress:r}),Et=(e,r)=>({type:"CheckTitle",render:()=>kt(e,r)}),bt=(e,r,a,n,l)=>t.createElement(re,{check:r,entityRef:a,entityRoute:l,programId:e,result:n,isVirtualized:!0}),Ct=(e,r,a,n,l)=>({type:"CheckResult",render:()=>bt(e,r,a,n,l)}),wt=e=>t.createElement(mt,{entityRef:e}),de=e=>({type:"EntityHeader",render:()=>wt(e)}),Nt=e=>t.createElement(nt,{highestLevel:e}),Rt=e=>({type:"LevelBadge",render:()=>Nt(e)}),$t=e=>r=>{const a=e[r.rowIndex].cells[r.columnIndex];return a?t.createElement("div",{style:r.style},a.render()):t.createElement("div",{style:r.style})},xt=(e,r,a)=>{var n;const l=[];for(const{program:i,levels:s,highestLevels:c}of e){l.push({height:R.programTitle,cells:[yt(i.name),...r.map(d=>{const u=d?c.find(p=>p.entityRef===d)||Ze(d):void 0;return Rt(u)})]});for(const d of s){l.push({height:R.levelTitle,cells:[ce(d.name),...r.map(u=>ce(""))]});for(const{check:u,results:p}of d.checks)l.push({height:R.check,cells:[Et(u.name,J(p.filter(({result:m})=>m!==N.NotApplicable),"result")),...r.map(m=>{var g,y;return Ct(i.id,u,m,(y=(g=p.find(h=>h.entityRef===m))==null?void 0:g.result)!=null?y:N.NotApplicable,a)})]})}}const o=Xe(r!=null?r:[]);return l.push({height:Ye((n=o.length)!=null?n:1),cells:[de(""),...r.map(i=>de(i||""))]}),l},Tt=f(e=>({table:{backgroundColor:e.palette.background.paper,borderCollapse:"collapse",whiteSpace:"nowrap",textAlign:"left",overflow:"auto"}})),Lt=e=>{const{setError:r,kind:a,type:n,ownerEntityRef:l}=e,o=Tt(),i=O(B),{data:s,isLoading:c,isError:d}=X(l,{kind:a,type:n});if(k(()=>{r==null||r(d?new Error("Error loading program overview"):void 0)},[d,r]),c)return t.createElement(se,null);if(!s||!l)return null;const{programs:u,entityRefs:p}=s,m=p.length>=25?p:[...p,...Array.from({length:25-p.length},()=>{})],g=xt(u,m,i),y=$t(g);return t.createElement(C,{"aria-label":`Check results for ${n!=null?n:a}`,key:`${a}|${n!=null?n:""}`,item:!0,xs:12},t.createElement(Le,{className:o.table,columnCount:m.length+1,columnWidth:h=>h===0?z.programTitle:z.checkResult,rowCount:g.length,rowHeight:h=>g[h].height,height:qe(g),width:Je(m.length)},y))},It=({facets:e,ownerEntityRef:r,kind:a,type:n,setError:l})=>{const o=P(()=>{const i=new Map;return e.types.forEach(({kind:s,type:c})=>{const d=`${s}|${c!=null?c:""}`;i.set(d,t.createElement(Lt,{key:d,ownerEntityRef:r,kind:s,type:c,setError:l}))}),i},[e,r,l]);return t.createElement("div",null,o.get(`${a}|${n!=null?n:""}`))},Pt=f(()=>({scrollContainer:{overflow:"auto"}})),Ot=({facets:e,ownerEntityRef:r,hasError:a,kind:n,type:l,setError:o,useVirtualizedResultsTable:i})=>{var s,c,d;const u=Pt();return a?t.createElement(we,{severity:"error",title:a.message}):e&&((c=(s=e.types)==null?void 0:s.length)!=null?c:0)>0?(d=e.types)!=null&&d.find(p=>p.count>0)?t.createElement("div",{className:u.scrollContainer},i?t.createElement(It,{facets:e,kind:n,type:l,setError:o,ownerEntityRef:r,hasError:a}):t.createElement(ht,{ownerEntityRef:r,kind:n,type:l,setError:o})):t.createElement(Ne,{description:t.createElement(t.Fragment,null,"Looks like the group"," ",x(w(r),{defaultKind:"Group"})," ","doesn't own any entities that have any applicable tracks configured.",t.createElement("br",null),t.createElement("br",null),"Please select another group from the dropdown in the corner of the header.")}):t.createElement(Re,{ownerEntityRef:r})},At=f(()=>({tableContainer:{padding:0,backgroundColor:"transparent"}})),Bt=({groupSelectorError:e,searchParams:r,setSearchParams:a})=>{var n;const{group:l,kind:o,type:i}=r,[s,c]=I(void 0),[d,u]=I(void 0);k(()=>{((s==null?void 0:s.kind)!==o||(s==null?void 0:s.type)!==i)&&c({kind:o,type:i})},[o,i,s]);const{data:p,isLoading:m}=Pe(l),g=(n=E(Ee).getOptionalBoolean("soundcheck.virtualizeOverviewPage"))!=null?n:!1,y=d||e,h=($,L)=>{$&&(c({kind:$,type:L}),L?a({...r,kind:$,type:L}):(r!=null&&r.hasOwnProperty("type")&&delete r.type,a({...r,kind:$})))},T=At();return t.createElement(C,{container:!0,spacing:0},t.createElement(C,{item:!0,xs:12},m?t.createElement(We,null):t.createElement(Ve,{unfilteredFacets:p,kind:s==null?void 0:s.kind,type:s==null?void 0:s.type,onChange:h})),t.createElement(C,{item:!0,xs:12,className:T.tableContainer},!m&&t.createElement(Ot,{facets:p,kind:s==null?void 0:s.kind,type:s==null?void 0:s.type,setError:u,hasError:y,ownerEntityRef:l,useVirtualizedResultsTable:g})))};export{Se as G,Bt as O,ze as U,Y as a,Fe as b,Ae as u};
|
|
2
|
+
//# sourceMappingURL=OverviewPageContent-b39812fb.esm.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import t,{useState as n}from"react";import{makeStyles as a,LinearProgress as m}from"@material-ui/core";import s from"react-use/lib/useDebounce";import"@backstage/catalog-model";import"@backstage/core-plugin-api";import{useIsFetching as c}from"@tanstack/react-query";import{F as d}from"./index-5913b2d3.esm.js";import"@backstage/plugin-catalog-react";import"react-router-dom";const p=a(e=>({indicator:{position:"absolute",width:"100%",zIndex:e.zIndex.speedDial}})),l=()=>{const e=c(),i=p(),[r,o]=n(!!e);return s(()=>{o(!!e)},250,[e]),r?t.createElement(d,null,t.createElement("div",{className:i.indicator},t.createElement(m,{variant:"indeterminate","data-testid":"refetching-indicator"}))):null};export{l as R};
|
|
2
|
+
//# sourceMappingURL=RefetchingIndicator-026bd666.esm.js.map
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import{createApiRef as Fe,createRouteRef as S,createSubRouteRef as C,createPlugin as Le,createApiFactory as Ae,discoveryApiRef as xe,fetchApiRef as Oe,createRoutableExtension as $,createComponentExtension as qe,useApi as B,errorApiRef as Te,useRouteRef as j}from"@backstage/core-plugin-api";import{GraphQLClient as Be}from"graphql-request";import s from"graphql-tag";import a,{createContext as V,useState as P,useCallback as E,useContext as K,useRef as Me,useEffect as ze,Fragment as Ge}from"react";import{QueryClient as Ue,QueryClientProvider as We,useQuery as _}from"@tanstack/react-query";import{memoize as He}from"lodash";import Qe from"@material-ui/core/styles/makeStyles";import{makeStyles as p,Typography as u,Modal as je,Box as J,Button as X,Fade as Ve,alpha as w,Tooltip as Ke,withStyles as N,Divider as _e}from"@material-ui/core";import{MarkdownContent as Y,Link as Z,EmptyState as ee,InfoCard as Je}from"@backstage/core-components";import{useEntity as te,humanizeEntityRef as Xe}from"@backstage/plugin-catalog-react";import{useAutoUpdatingRelativeTime as Ye,SpotifyLicenseBanner as Ze}from"@spotify/backstage-plugin-core";import{stringifyEntityRef as re,parseEntityRef as et}from"@backstage/catalog-model";import{Alert as tt,Skeleton as f}from"@material-ui/lab";import{Link as rt}from"react-router-dom";import I from"classnames";import at from"@material-ui/icons/Schedule";import{DateTime as ae}from"luxon";import nt from"@material-ui/icons/Check";import it from"@material-ui/icons/Close";import ot from"@material-ui/icons/RemoveCircleOutline";import ct from"@material-ui/icons/HelpOutline";var ne=(e=>(e.Medal="MEDAL",e))(ne||{}),g=(e=>(e.Failed="FAILED",e.NotApplicable="NOT_APPLICABLE",e.NotReported="NOT_REPORTED",e.Passed="PASSED",e))(g||{});const st=s`
|
|
2
|
+
fragment CertificationSummary on Certification {
|
|
3
|
+
entityRef
|
|
4
|
+
program {
|
|
5
|
+
id
|
|
6
|
+
name
|
|
7
|
+
}
|
|
8
|
+
highestLevel {
|
|
9
|
+
ordinal
|
|
10
|
+
name
|
|
11
|
+
description
|
|
12
|
+
badge {
|
|
13
|
+
... on BadgeVariantMedal {
|
|
14
|
+
variant
|
|
15
|
+
options {
|
|
16
|
+
level
|
|
17
|
+
color
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
`,lt=s`
|
|
24
|
+
fragment check on Check {
|
|
25
|
+
id
|
|
26
|
+
name
|
|
27
|
+
description
|
|
28
|
+
}
|
|
29
|
+
`,mt=s`
|
|
30
|
+
fragment level on Level {
|
|
31
|
+
ordinal
|
|
32
|
+
name
|
|
33
|
+
description
|
|
34
|
+
checks {
|
|
35
|
+
...check
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
${lt}`,dt=s`
|
|
39
|
+
fragment CheckResultSummary on CheckResult {
|
|
40
|
+
id
|
|
41
|
+
name
|
|
42
|
+
result
|
|
43
|
+
timestamp
|
|
44
|
+
}
|
|
45
|
+
`,ut=s`
|
|
46
|
+
fragment LevelResultDetails on LevelResult {
|
|
47
|
+
ordinal
|
|
48
|
+
name
|
|
49
|
+
description
|
|
50
|
+
badge {
|
|
51
|
+
... on BadgeVariantMedal {
|
|
52
|
+
variant
|
|
53
|
+
options {
|
|
54
|
+
level
|
|
55
|
+
color
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
certified
|
|
60
|
+
checks {
|
|
61
|
+
...CheckResultSummary
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
${dt}`,pt=s`
|
|
65
|
+
fragment CheckResultDetails on CheckResult {
|
|
66
|
+
id
|
|
67
|
+
name
|
|
68
|
+
description
|
|
69
|
+
result
|
|
70
|
+
timestamp
|
|
71
|
+
notes
|
|
72
|
+
}
|
|
73
|
+
`,ht=s`
|
|
74
|
+
fragment OverviewLevelResult on OverviewLevelResult {
|
|
75
|
+
ordinal
|
|
76
|
+
name
|
|
77
|
+
checks {
|
|
78
|
+
check {
|
|
79
|
+
id
|
|
80
|
+
name
|
|
81
|
+
description
|
|
82
|
+
}
|
|
83
|
+
results {
|
|
84
|
+
id
|
|
85
|
+
entityRef
|
|
86
|
+
result
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
`,ie=s`
|
|
91
|
+
fragment HighestLevel on LevelResult {
|
|
92
|
+
entityRef
|
|
93
|
+
ordinal
|
|
94
|
+
name
|
|
95
|
+
badge {
|
|
96
|
+
... on BadgeVariantMedal {
|
|
97
|
+
variant
|
|
98
|
+
options {
|
|
99
|
+
color
|
|
100
|
+
level
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`,gt=s`
|
|
106
|
+
mutation createCheck($input: CheckerInput!) {
|
|
107
|
+
check: createChecker(input: $input) {
|
|
108
|
+
id
|
|
109
|
+
filter
|
|
110
|
+
name
|
|
111
|
+
description
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`,ft=s`
|
|
115
|
+
mutation createProgram($input: ProgramInput!) {
|
|
116
|
+
program: createProgram(input: $input) {
|
|
117
|
+
id
|
|
118
|
+
ownerEntityRef
|
|
119
|
+
name
|
|
120
|
+
description
|
|
121
|
+
documentationURL
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
`,kt=s`
|
|
125
|
+
mutation deleteChecker($checkerId: String!) {
|
|
126
|
+
deleteChecker(checkerId: $checkerId)
|
|
127
|
+
}
|
|
128
|
+
`,yt=s`
|
|
129
|
+
mutation deleteProgram($programId: String!) {
|
|
130
|
+
programDeleted: deleteProgram(programId: $programId)
|
|
131
|
+
}
|
|
132
|
+
`,vt=s`
|
|
133
|
+
mutation updateCheck($input: CheckerInput!) {
|
|
134
|
+
check: updateChecker(input: $input) {
|
|
135
|
+
id
|
|
136
|
+
filter
|
|
137
|
+
name
|
|
138
|
+
description
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
`,Ct=s`
|
|
142
|
+
mutation updateProgram($input: ProgramInput!) {
|
|
143
|
+
program: updateProgram(input: $input) {
|
|
144
|
+
id
|
|
145
|
+
ownerEntityRef
|
|
146
|
+
name
|
|
147
|
+
description
|
|
148
|
+
documentationURL
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
`,Et=s`
|
|
152
|
+
query getAllCertifications($entityRef: String!) {
|
|
153
|
+
certifications(entityRef: $entityRef, includeFilteredChecks: false) {
|
|
154
|
+
...CertificationSummary
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
${st}`,wt=s`
|
|
158
|
+
query getAllPrograms($programIds: [String!], $first: Int, $after: String) {
|
|
159
|
+
programs(programIds: $programIds, first: $first, after: $after) {
|
|
160
|
+
totalCount
|
|
161
|
+
endCursor
|
|
162
|
+
hasNextPage
|
|
163
|
+
edges {
|
|
164
|
+
cursor
|
|
165
|
+
program {
|
|
166
|
+
id
|
|
167
|
+
ownerEntityRef
|
|
168
|
+
name
|
|
169
|
+
description
|
|
170
|
+
documentationURL
|
|
171
|
+
filter
|
|
172
|
+
levels {
|
|
173
|
+
...level
|
|
174
|
+
}
|
|
175
|
+
isEditable
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
${mt}`,Rt=s`
|
|
181
|
+
query getCertificationDetails($entityRef: String!, $programId: String!) {
|
|
182
|
+
programCertification(
|
|
183
|
+
entityRef: $entityRef
|
|
184
|
+
programId: $programId
|
|
185
|
+
includeFilteredChecks: false
|
|
186
|
+
) {
|
|
187
|
+
program {
|
|
188
|
+
id
|
|
189
|
+
name
|
|
190
|
+
description
|
|
191
|
+
documentationURL
|
|
192
|
+
}
|
|
193
|
+
highestLevel {
|
|
194
|
+
...HighestLevel
|
|
195
|
+
}
|
|
196
|
+
levels {
|
|
197
|
+
...LevelResultDetails
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
${ie}
|
|
202
|
+
${ut}`,bt=s`
|
|
203
|
+
query getCheckResultDetails($entityRef: String!, $programId: String!, $checkId: String!) {
|
|
204
|
+
checkResult(entityRef: $entityRef, programId: $programId, checkId: $checkId) {
|
|
205
|
+
...CheckResultDetails
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
${pt}`,St=s`
|
|
209
|
+
query getCheckers($ids: [String!], $first: Int, $after: String, $orderAlphabetical: String, $searchByOwner: String, $searchByName: String) {
|
|
210
|
+
checkers(
|
|
211
|
+
ids: $ids
|
|
212
|
+
first: $first
|
|
213
|
+
after: $after
|
|
214
|
+
orderAlphabetical: $orderAlphabetical
|
|
215
|
+
searchByOwner: $searchByOwner
|
|
216
|
+
searchByName: $searchByName
|
|
217
|
+
) {
|
|
218
|
+
totalCount
|
|
219
|
+
endCursor
|
|
220
|
+
hasNextPage
|
|
221
|
+
edges {
|
|
222
|
+
cursor
|
|
223
|
+
checker {
|
|
224
|
+
id
|
|
225
|
+
ownerEntityRef
|
|
226
|
+
supportChannel
|
|
227
|
+
name
|
|
228
|
+
description
|
|
229
|
+
rule
|
|
230
|
+
passedMessage
|
|
231
|
+
failedMessage
|
|
232
|
+
filter
|
|
233
|
+
isEditable
|
|
234
|
+
schedule
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
`,$t=s`
|
|
240
|
+
query getFacetsForOwner($ownerEntityRef: String!) {
|
|
241
|
+
facetsForOwner(ownerEntityRef: $ownerEntityRef) {
|
|
242
|
+
types {
|
|
243
|
+
kind
|
|
244
|
+
type
|
|
245
|
+
count
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
`,Pt=s`
|
|
250
|
+
query getCollectors($ids: [String!]) {
|
|
251
|
+
collectors(ids: $ids) {
|
|
252
|
+
id
|
|
253
|
+
factNames
|
|
254
|
+
collectionConfigs {
|
|
255
|
+
factRefs
|
|
256
|
+
filter
|
|
257
|
+
frequency
|
|
258
|
+
cache {
|
|
259
|
+
... on HumanDuration {
|
|
260
|
+
years
|
|
261
|
+
months
|
|
262
|
+
weeks
|
|
263
|
+
days
|
|
264
|
+
hours
|
|
265
|
+
minutes
|
|
266
|
+
seconds
|
|
267
|
+
milliseconds
|
|
268
|
+
}
|
|
269
|
+
... on CacheBoolean {
|
|
270
|
+
cache
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
`,Nt=s`
|
|
277
|
+
query getFactSchemas($collectorId: String!, $factName: String!) {
|
|
278
|
+
factSchema(collectorId: $collectorId, factName: $factName) {
|
|
279
|
+
schema
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
`,It=s`
|
|
283
|
+
query getProgramOverviewForOwner($ownerEntityRef: String!, $facet: FacetInput) {
|
|
284
|
+
programOverviewForOwner(
|
|
285
|
+
ownerEntityRef: $ownerEntityRef
|
|
286
|
+
facet: $facet
|
|
287
|
+
includeFilteredChecks: false
|
|
288
|
+
) {
|
|
289
|
+
programs {
|
|
290
|
+
program {
|
|
291
|
+
id
|
|
292
|
+
name
|
|
293
|
+
}
|
|
294
|
+
highestLevels {
|
|
295
|
+
...HighestLevel
|
|
296
|
+
}
|
|
297
|
+
levels {
|
|
298
|
+
...OverviewLevelResult
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
entityRefs
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
${ie}
|
|
305
|
+
${ht}`,Dt=(e,t,r)=>e();function Ft(e,t=Dt){return{createCheck(r,n){return t(i=>e.request(gt,r,{...n,...i}),"createCheck","mutation")},createProgram(r,n){return t(i=>e.request(ft,r,{...n,...i}),"createProgram","mutation")},deleteChecker(r,n){return t(i=>e.request(kt,r,{...n,...i}),"deleteChecker","mutation")},deleteProgram(r,n){return t(i=>e.request(yt,r,{...n,...i}),"deleteProgram","mutation")},updateCheck(r,n){return t(i=>e.request(vt,r,{...n,...i}),"updateCheck","mutation")},updateProgram(r,n){return t(i=>e.request(Ct,r,{...n,...i}),"updateProgram","mutation")},getAllCertifications(r,n){return t(i=>e.request(Et,r,{...n,...i}),"getAllCertifications","query")},getAllPrograms(r,n){return t(i=>e.request(wt,r,{...n,...i}),"getAllPrograms","query")},getCertificationDetails(r,n){return t(i=>e.request(Rt,r,{...n,...i}),"getCertificationDetails","query")},getCheckResultDetails(r,n){return t(i=>e.request(bt,r,{...n,...i}),"getCheckResultDetails","query")},getCheckers(r,n){return t(i=>e.request(St,r,{...n,...i}),"getCheckers","query")},getFacetsForOwner(r,n){return t(i=>e.request($t,r,{...n,...i}),"getFacetsForOwner","query")},getCollectors(r,n){return t(i=>e.request(Pt,r,{...n,...i}),"getCollectors","query")},getFactSchemas(r,n){return t(i=>e.request(Nt,r,{...n,...i}),"getFactSchemas","query")},getProgramOverviewForOwner(r,n){return t(i=>e.request(It,r,{...n,...i}),"getProgramOverviewForOwner","query")}}}var oe=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},o=(e,t,r)=>(oe(e,t,"read from private field"),r?r.call(e):t.get(e)),R=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},M=(e,t,r,n)=>(oe(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),D,F,m,z,d;const L=Fe({id:"plugin.soundcheck"}),Lt=e=>"response"in e&&"errors"in e.response,At=e=>"response"in e&&"message"in e.response;class xt{constructor(t){R(this,D,void 0),R(this,F,void 0),R(this,m,void 0),R(this,z,n=>{var i,c,l;return Lt(n)?(l=(c=(i=n.response)==null?void 0:i.errors)==null?void 0:c[0].message)!=null?l:`${n}`:At(n)?n.response.message:`${n}`}),R(this,d,async n=>{try{return await n()}catch(i){throw new Error(`Error from Soundcheck backend: ${o(this,z).call(this,i)}`)}}),M(this,D,t.fetchApi),M(this,F,t.discoveryApi);const r=new Be("/graphql",{fetch:async(n,i)=>{const c=`${await o(this,F).getBaseUrl("soundcheck")}${n}`;return o(this,D).fetch(c,i)}});M(this,m,Ft(r))}async getAllCertifications(t){return o(this,d).call(this,async()=>{const{certifications:r}=await o(this,m).getAllCertifications({entityRef:t});return r})}async getCertificationDetails(t,r){return o(this,d).call(this,async()=>{const{programCertification:n}=await o(this,m).getCertificationDetails({entityRef:t,programId:r});return n})}async getCheckResultDetails(t,r,n){return o(this,d).call(this,async()=>{const{checkResult:i}=await o(this,m).getCheckResultDetails({entityRef:t,programId:r,checkId:n});return i})}async getFacetsForOwner(t){return o(this,d).call(this,async()=>{const{facetsForOwner:r}=await o(this,m).getFacetsForOwner({ownerEntityRef:t});return r})}async getProgramOverviewForOwner(t,r){return o(this,d).call(this,async()=>{const{programOverviewForOwner:n}=await o(this,m).getProgramOverviewForOwner({ownerEntityRef:t,facet:r});return n})}async getAllPrograms(t,r,n){return o(this,d).call(this,async()=>{const{programs:i}=await o(this,m).getAllPrograms({programIds:t,first:r,after:n});return i})}async createProgram(t){return o(this,d).call(this,async()=>{const{program:r}=await o(this,m).createProgram({input:t});return r})}async updateProgram(t){return o(this,d).call(this,async()=>{const{program:r}=await o(this,m).updateProgram({input:t});return r})}async deleteProgram(t){return o(this,d).call(this,async()=>{const{programDeleted:r}=await o(this,m).deleteProgram({programId:t});return r})}async getChecks(t,r,n){return o(this,d).call(this,async()=>{const{checkers:i}=await o(this,m).getCheckers({ids:t,first:r,after:n});return i})}async createCheck(t){return o(this,d).call(this,async()=>{const{check:r}=await o(this,m).createCheck({input:t});return r})}async updateCheck(t){return o(this,d).call(this,async()=>{const{check:r}=await o(this,m).updateCheck({input:t});return r})}async deleteCheck(t){return o(this,d).call(this,async()=>await o(this,m).deleteChecker({checkerId:t}))}async getCollectors(t){return o(this,d).call(this,async()=>{const{collectors:r}=await o(this,m).getCollectors({ids:t});return r})}async getFactSchema(t,r){if(!(!t||!r))return o(this,d).call(this,async()=>{const{factSchema:n}=await o(this,m).getFactSchemas({collectorId:t,factName:r});return n})}}D=new WeakMap,F=new WeakMap,m=new WeakMap,z=new WeakMap,d=new WeakMap;const A=S({id:"soundcheck-entity"}),Ot=S({id:"soundcheck-group"}),ce=C({id:"soundcheck-entity-certification-track-redirect",parent:A,path:"/:trackId"}),se=C({id:"soundcheck-entity-certification",parent:A,path:"/:trackId/:checkId"}),qt=S({id:"soundcheck-overview"}),x=S({id:"soundcheck"});C({id:"soundcheck-checks",parent:x,path:"/checks"}),C({id:"soundcheck-tracks",parent:x,path:"/tracks"}),C({id:"soundcheck-track-details",parent:x,path:"/tracks/:trackId"});const y=Le({id:"soundcheck",apis:[Ae({api:L,deps:{discoveryApi:xe,fetchApi:Oe},factory:e=>new xt(e)})],routes:{entityContent:A}}),Tt=y.provide($({name:"EntitySoundcheckContent",component:()=>import("./EntitySoundcheckContent-b20f0ec8.esm.js").then(e=>e.EntitySoundcheckContent),mountPoint:A})),Bt=y.provide(qe({name:"EntitySoundcheckCard",component:{lazy:()=>import("./index-95047e64.esm.js").then(e=>e.EntitySoundcheckCard)}})),Mt=y.provide($({name:"GroupSoundcheckContent",component:()=>import("./index-5ffaa13b.esm.js").then(e=>e.FixedGroupOverviewPage),mountPoint:Ot})),zt=y.provide($({name:"SoundcheckOverviewPage",component:()=>import("./index-5ffaa13b.esm.js").then(e=>e.OverviewPage),mountPoint:qt})),Gt=y.provide($({name:"SoundcheckRoutingPage",component:()=>import("./index-e398f5c6.esm.js").then(e=>e.RoutingPage),mountPoint:x})),Ut=He(e=>new Ue({defaultOptions:{queries:{refetchInterval:6e4,refetchIntervalInBackground:!1,refetchOnWindowFocus:"always",retry:2,retryDelay:t=>{const r=450+Math.ceil(Math.random()*100);return Math.min(r*2**t,3e4)},onError:t=>e.post(t)}}})),Wt=e=>{const t=B(Te),r=Ut(t);return a.createElement(We,{client:r},e.children)};function le(e){const t=B(L),r=re(e);return _(["soundcheck/certifications",r],async()=>t.getAllCertifications(r))}function me(e,t){const r=B(L),n=re(e);return _(["soundcheck/certifications",n,t],async()=>r.getCertificationDetails(n,t),{enabled:!!t})}var de=(e=>(e.GetAllPrograms="soundcheck/programs",e.GetChecks="soundcheck/checks",e.GetCollectors="soundcheck/collectors",e.GetFactSchema="soundcheck/collectors/schema",e.GetEntityFacets="soundcheck/catalog/facets",e))(de||{}),ue=(e=>(e.DeleteCheck="soundcheck/deleteCheck",e.CreateCheck="soundcheck/createCheck",e.UpdateCheck="soundcheck/updateCheck",e.DeleteProgram="soundcheck/deleteProgram",e.CreateProgram="soundcheck/createProgram",e.UpdateProgram="soundcheck/updateProgram",e))(ue||{});const Ht=p(e=>({root:{padding:e.spacing(3)},icon:{display:"none"},message:{padding:0},type:{fontWeight:700,lineHeight:1.75}})),O=e=>{const{type:t,...r}=Ht();return a.createElement(tt,{severity:e.severity,elevation:1,classes:r,onClose:e.onClose},a.createElement(u,{classes:{root:t}},e.title),e.children)},pe=V({}),Qt=e=>{const[t,r]=P(),n=E(c=>{r(c)},[]),i=E(()=>{r(null)},[]);return a.createElement(pe.Provider,{value:{showAlert:n,clearAlert:i}},t&&a.createElement(O,{severity:t.severity,title:t.title,onClose:i},t.message),e.children)},jt=()=>K(pe),Vt=p(e=>({modalContent:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",padding:"25px",backgroundColor:e.palette.type==="dark"?e.palette.grey[800]:e.palette.grey[200]},modalButtons:{display:"flex",justifyContent:"space-evenly","& button":{width:"40%",maxWidth:"185px"}},modalMessage:{margin:"15px 0 35px"}})),he=V({}),Kt=e=>{const t=Vt(),[r,n]=P(!1),[i,c]=P(),l=Me(),h=E(({title:b,message:Ne,error:Ie})=>(c({title:b,message:Ne,error:Ie}),n(!0),new Promise(De=>{l.current=De})),[]),v=E(()=>{l.current&&l.current(!0),n(!1)},[]),k=E(()=>{l.current&&l.current(!1),n(!1)},[]);return a.createElement(he.Provider,{value:{showModal:h}},e.children,i&&a.createElement(je,{open:r,onClose:k,"aria-labelledby":"confirmation-modal-title","aria-describedby":"confirmation-modal-description"},a.createElement(J,{className:t.modalContent},a.createElement(u,{id:"confirmation-modal-title",variant:"h6"},i.title),a.createElement(u,{className:t.modalMessage,id:"confirmation-modal-description",variant:"body1"},i.message),a.createElement("div",{className:t.modalButtons},!i.error&&a.createElement(X,{onClick:k,variant:"contained","aria-label":"cancel"},"Cancel"),a.createElement(X,{color:"primary",onClick:v,variant:"contained","aria-label":"confirm"},i.error?"Ok":"Confirm")))))},_t=()=>K(he),ge=24,Jt=11,G=e=>e==="small"?1:2,Xt=p({root:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",borderRadius:"50%",borderWidth:"2px",fontWeight:700,width:({size:e})=>`${ge*G(e)}px`,height:({size:e})=>`${ge*G(e)}px`,fontSize:({size:e})=>`${Jt*G(e)}px`}}),fe=({className:e,label:t,size:r="small"})=>{const n=Xt({size:r});return a.createElement("span",{className:I(e,n.root),role:"img","aria-label":`${t} badge`},t)},Yt=p(e=>({root:{background:({color:t})=>t,color:e.palette.common.black,borderColor:e.palette.common.black,borderStyle:"solid","&::after":{position:"absolute",display:"block",content:'""',top:0,left:0,width:"100%",height:"100%",borderRadius:"50%",boxShadow:["inset 0 -0.18em 0 0 rgba(0, 0, 0, 0.25)","inset 0px 0.18em 0px 0px rgba(255, 255, 255, 0.5)","inset 0px 1.3em 0px -0.5em rgba(255, 255, 255, 0.2)"].join(",")}}})),U=({className:e,badge:t,size:r="small"})=>{const n=Yt({color:t.options.color,size:r});return a.createElement(fe,{className:I(e,n.root),size:r,label:`L${t.options.level}`})},Zt=p({root:{borderColor:"currentColor",borderStyle:"dashed"}}),ke=({className:e,size:t="small"})=>{const r=Zt();return a.createElement(fe,{className:I(e,r.root),size:t,label:"NL"})},W=p(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 er({description:e,documentationUrl:t}){const r=W();return t?a.createElement("div",{className:r.description},a.createElement(Y,{content:e}),a.createElement(Z,{to:t},"Learn more")):a.createElement("div",{className:r.description},a.createElement(Y,{content:e}))}const ye=({name:e,level:t,badge:r,description:n,documentationUrl:i})=>{const c=W();return a.createElement("div",{className:c.root},r?a.createElement(U,{size:"large",badge:r}):a.createElement(ke,{size:"large"}),a.createElement("div",null,a.createElement(u,{variant:"caption",className:c.level},t!=null?t:"No Level"),a.createElement(u,{className:c.title},e),n&&a.createElement(er,{description:n,documentationUrl:i})))},q=({children:e})=>{const[t,r]=P(!1);return ze(()=>{const n=setTimeout(()=>{r(!0)},250);return()=>clearTimeout(n)},[]),a.createElement(Ve,{in:t,timeout:250},e)},H=({hideDescription:e=!1})=>{const t=W();return a.createElement(q,null,a.createElement("div",{className:t.root},a.createElement(f,{width:44,height:44}),a.createElement("div",null,a.createElement(u,{variant:"caption",className:t.level},a.createElement(f,{width:100})),a.createElement(u,{variant:"h4",className:t.title},a.createElement(f,{width:300})),!e&&a.createElement(u,{variant:"body2"},a.createElement(f,null)))))},ve=p(e=>{const t=e.palette.type==="dark"?e.palette.grey[700]:e.palette.grey[100];return{wrapper:{backgroundColor:t,color:w(e.palette.getContrastText(t),.8),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:r})=>[`"${r?"badge":"title"} title"`,`"${r?".":"description"} description"`].join(" "),gridTemplateColumns:"auto 1fr"},title:{gridArea:"title",textTransform:"uppercase",fontWeight:"bold",color:w(e.palette.getContrastText(t),.8),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:w(e.palette.getContrastText(t),.8),fontSize:e.typography.subtitle2.fontSize,marginTop:e.spacing(1)}}}),tr=e=>{const t=ve({badge:e.badge});return a.createElement("div",{className:t.wrapper},e.badge?a.createElement(U,{className:t.badge,badge:e.badge}):null,a.createElement(u,{className:t.title},e.title),e.description?a.createElement(u,{className:t.description},e.description):null)},rr=()=>{const e=ve({});return a.createElement(q,null,a.createElement("div",{className:e.wrapper},a.createElement(f,{className:e.title}),a.createElement(u,{className:e.description},a.createElement(f,null))))},ar=p(e=>({root:{display:"inline-flex",alignItems:"center",gap:e.spacing(1)}})),Ce=({timestamp:e,description:t})=>{const r=ar(),n=ae.fromISO(e).toLocaleString(ae.DATETIME_FULL),i=Ye(e),c=t?`${t}: ${i}`:void 0;return a.createElement("div",{className:r.root},a.createElement(Ke,{title:n},a.createElement(u,{variant:"caption","aria-label":c},i)),a.createElement(at,null))},nr=e=>({[g.Passed]:"Check passed",[g.NotReported]:"Check not reported",[g.Failed]:"Check failed",[g.NotApplicable]:"Check not applicable"})[e],ir=N(e=>({root:{color:e.palette.success.main}}))(nt),or=N(e=>({root:{color:e.palette.error.main}}))(it),cr=N(e=>({root:{color:e.palette.info.main}}))(ct),sr=N(e=>({root:{color:e.palette.text.disabled}}))(ot),Ee=({result:e,className:t})=>{const r={className:t,"aria-label":nr(e),"aria-hidden":!1};return e===g.Passed?a.createElement(ir,{...r}):e===g.NotReported?a.createElement(cr,{...r}):e===g.Failed?a.createElement(or,{...r}):e===g.NotApplicable?a.createElement(sr,{...r}):null},we=p(e=>({root:{display:"grid",width:"100%",gridTemplateColumns:"auto 1fr auto",gridColumnGap:e.spacing(1),padding:e.spacing(1),alignItems:"center","&.selected":{backgroundColor:w(e.palette.primary[e.palette.type],.2)},"&:hover, &:active, &:focus":{backgroundColor:w(e.palette.primary[e.palette.type],.3)}}})),lr=({className:e,href:t,children:r})=>t?a.createElement(rt,{to:t,className:e},r):a.createElement("div",{className:e},r),mr=({result:e,name:t,timestamp:r,selected:n=!1,href:i})=>{const c=we(),l=I(c.root,{selected:n});return a.createElement(lr,{href:i,className:l},a.createElement(Ee,{result:e}),a.createElement(u,{variant:"body2"},t),r?a.createElement(Ce,{timestamp:r}):null)},Q=()=>{const e=we();return a.createElement(q,null,a.createElement("div",{className:e.root},a.createElement(f,{width:24,height:24}),a.createElement(u,{variant:"body2"},a.createElement(f,null)),a.createElement(f,{width:100,height:24})))},dr=()=>{const e=Re();return a.createElement("div",{className:e.root},a.createElement(H,null),new Array(3).fill(null).map((t,r)=>a.createElement(a.Fragment,{key:`skeleton-level-${r}`},a.createElement(rr,null),a.createElement("ul",{className:e.checks},a.createElement(Q,null),a.createElement(Q,null),a.createElement(Q,null)))))},ur=p(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"}}})),pr=({checks:e,trackId:t,checkId:r})=>{const n=ur(),i=j(se);return e.length?a.createElement("ul",{className:n.checks},e.map(c=>a.createElement("li",{key:c.id,className:n.checkItem},a.createElement(mr,{...c,selected:c.id===r,href:i({trackId:t,checkId:c.id})})))):a.createElement(u,{variant:"body2",className:n.noChecks},"No applicable checks at this level.")},hr=({level:e,checkId:t,trackId:r})=>{var n;return a.createElement(a.Fragment,null,a.createElement(tr,{badge:e.badge,title:e.name,description:e.description}),a.createElement(pr,{checks:(n=e.checks)!=null?n:[],trackId:r,checkId:t}))},Re=p(e=>({root:{borderRight:`1px solid ${e.palette.divider}`},checks:{padding:0,margin:0,flex:1,listStyle:"none"}})),gr=({trackId:e,checkId:t})=>{var r,n;const i=Re(),{entity:c}=te(),{data:l,isLoading:h,isError:v}=me(c,e);return v?a.createElement("div",{className:i.root},a.createElement(J,{padding:2},a.createElement(O,{severity:"error",title:"Error loading certification"}))):h||!e?a.createElement(dr,null):l?a.createElement("div",{className:i.root},a.createElement(ye,{name:l.program.name,level:(r=l.highestLevel)==null?void 0:r.name,badge:(n=l.highestLevel)==null?void 0:n.badge,description:l.program.description,documentationUrl:l.program.documentationURL}),l==null?void 0:l.levels.map(k=>a.createElement(hr,{key:k.ordinal,level:k,checkId:t,trackId:e}))):null},fr=()=>a.createElement(a.Fragment,null,a.createElement(H,{hideDescription:!0}),a.createElement(H,{hideDescription:!0})),be=({className:e,description:t="There are no tracks configured that apply to this entity."})=>a.createElement("div",{className:e},a.createElement(ee,{title:"No certifications available",missing:"data",description:t})),kr=({ownerEntityRef:e})=>e?a.createElement(ee,{missing:"data",title:"Missing entities",description:a.createElement(a.Fragment,null,"Looks like the group"," ",Xe(et(e),{defaultKind:"Group"})," ","doesn't own any entities.",a.createElement("br",null),a.createElement("br",null),"Please select another group from the dropdown in the corner of the header.")}):null,Se="soundcheck",$e="Submitted check results will still be stored, but it will not be possible to view certifications or individual results until a valid license is present.",Pe=Qe(e=>({certificationWrapper:{display:"flex",justifyContent:"space-between",alignItems:"center"},infoCard:{display:"grid",gridRowGap:e.spacing(2)},emptyState:{"& > div":{backgroundColor:e.palette.background.paper}}})),T=({children:e,title:t})=>{const r=Pe();return a.createElement(Je,{title:t},a.createElement("div",{className:r.infoCard},a.createElement(Ze,{inline:!0,backend:Se,invalidLicenseMessage:$e}),e))},yr=({title:e="Soundcheck"})=>{const{entity:t}=te(),r=Pe(),{data:n,isError:i,isLoading:c}=le(t),l=j(ce);return i?a.createElement(T,{title:e},a.createElement(O,{severity:"error",title:"Error loading certifications"})):c||!n?a.createElement(T,{title:e},a.createElement(fr,null)):n.length===0?a.createElement(T,{title:e},a.createElement(be,{className:r.emptyState})):a.createElement(T,{title:e},n.map((h,v)=>{var k,b;return a.createElement(Ge,{key:h.program.name},a.createElement("div",{className:r.certificationWrapper,"data-testid":"soundcheck-track-row"},a.createElement(ye,{key:h.program.id,name:h.program.name,badge:(k=h.highestLevel)==null?void 0:k.badge,level:(b=h.highestLevel)==null?void 0:b.name}),a.createElement(Z,{to:l({trackId:h.program.id})},"View Details")),v<n.length-1?a.createElement(_e,null):null)}))};export{O as A,ne as B,gr as C,Tt as E,q as F,Mt as G,U as L,ue as M,ke as N,de as Q,g as R,Wt as S,Ce as a,le as b,ce as c,be as d,Se as e,se as f,yr as g,Ee as h,$e as i,kr as j,jt as k,_t as l,Qt as m,y as n,Bt as o,zt as p,Gt as q,L as s,me as u,Kt as w};
|
|
306
|
+
//# sourceMappingURL=index-5913b2d3.esm.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e,{useState as n}from"react";import{Page as E,Header as d}from"@backstage/core-components";import{SpotifyLicenseBanner as a}from"@spotify/backstage-plugin-core";import{u as g,U as v,G as f,O as h}from"./OverviewPageContent-b39812fb.esm.js";import{S as l,w as P,e as p,i as s}from"./index-5913b2d3.esm.js";import{stringifyEntityRef as S}from"@backstage/catalog-model";import"@backstage/core-plugin-api";import"@tanstack/react-query";import{useEntity as k}from"@backstage/plugin-catalog-react";import{Routes as y,Route as w}from"react-router-dom";import"@material-ui/core";import"@material-ui/lab/Autocomplete";import"react-use/lib/useAsync";import"./RefetchingIndicator-026bd666.esm.js";import"react-use/lib/useDebounce";import"lodash";import"@material-ui/lab";import"react-window";import"graphql-request";import"graphql-tag";import"@material-ui/core/styles/makeStyles";import"classnames";import"@material-ui/icons/Schedule";import"luxon";import"@material-ui/icons/Check";import"@material-ui/icons/Close";import"@material-ui/icons/RemoveCircleOutline";import"@material-ui/icons/HelpOutline";const L=r=>{const{title:i="Soundcheck"}=r,[t,o]=g(),{group:c}=t,u=n(void 0)[1];return e.createElement(l,null,e.createElement(v,null,e.createElement(P,null,e.createElement(E,{themeId:"website"},e.createElement(a,{backend:p,invalidLicenseMessage:s}),e.createElement(d,{title:i},e.createElement(f,{onChange:m=>{m&&o({...t,group:m})},initialValue:c,setError:u}))))))},O=()=>{const{entity:r}=k(),i={group:S(r)},[t,o]=n(i);return e.createElement(l,null,e.createElement(y,null,e.createElement(w,{path:"/*",element:e.createElement(e.Fragment,null,e.createElement(a,{backend:p,invalidLicenseMessage:s,inline:!0}),e.createElement(h,{searchParams:t,setSearchParams:o}))})))};export{O as FixedGroupOverviewPage,L as OverviewPage};
|
|
2
|
+
//# sourceMappingURL=index-5ffaa13b.esm.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import t from"react";import{S as o,
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import t from"react";import{S as o,g as i}from"./index-5913b2d3.esm.js";import"@backstage/core-plugin-api";import"graphql-request";import"graphql-tag";import"@tanstack/react-query";import"lodash";import"@material-ui/core/styles/makeStyles";import"@material-ui/core";import"@backstage/core-components";import"@backstage/plugin-catalog-react";import"@spotify/backstage-plugin-core";import"@backstage/catalog-model";import"@material-ui/lab";import"react-router-dom";import"classnames";import"@material-ui/icons/Schedule";import"luxon";import"@material-ui/icons/Check";import"@material-ui/icons/Close";import"@material-ui/icons/RemoveCircleOutline";import"@material-ui/icons/HelpOutline";const m=({title:r})=>t.createElement(o,null,t.createElement(i,{title:r}));export{m as EntitySoundcheckCard};
|
|
2
|
+
//# sourceMappingURL=index-95047e64.esm.js.map
|