@backstage-community/plugin-lighthouse 0.4.20 → 0.4.21
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 +8 -0
- package/dist/Router.esm.js +26 -0
- package/dist/Router.esm.js.map +1 -0
- package/dist/api.esm.js +8 -0
- package/dist/api.esm.js.map +1 -0
- package/dist/components/AuditList/AuditListForEntity.esm.js +43 -0
- package/dist/components/AuditList/AuditListForEntity.esm.js.map +1 -0
- package/dist/components/AuditList/AuditListTable.esm.js +92 -0
- package/dist/components/AuditList/AuditListTable.esm.js.map +1 -0
- package/dist/components/AuditList/index.esm.js +83 -0
- package/dist/components/AuditList/index.esm.js.map +1 -0
- package/dist/components/AuditStatusIcon/index.esm.js +11 -0
- package/dist/components/AuditStatusIcon/index.esm.js.map +1 -0
- package/dist/components/AuditView/index.esm.js +135 -0
- package/dist/components/AuditView/index.esm.js.map +1 -0
- package/dist/components/Cards/LastLighthouseAuditCard.esm.js +57 -0
- package/dist/components/Cards/LastLighthouseAuditCard.esm.js.map +1 -0
- package/dist/components/Cards/index.esm.js +2 -0
- package/dist/components/Cards/index.esm.js.map +1 -0
- package/dist/components/CreateAudit/index.esm.js +152 -0
- package/dist/components/CreateAudit/index.esm.js.map +1 -0
- package/dist/components/Intro/index.esm.js +130 -0
- package/dist/components/Intro/index.esm.js.map +1 -0
- package/dist/components/SupportButton/index.esm.js +9 -0
- package/dist/components/SupportButton/index.esm.js.map +1 -0
- package/dist/constants.esm.js +4 -0
- package/dist/constants.esm.js.map +1 -0
- package/dist/hooks/useWebsiteForEntity.esm.js +23 -0
- package/dist/hooks/useWebsiteForEntity.esm.js.map +1 -0
- package/dist/index.esm.js +4 -770
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +55 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/utils.esm.js +44 -0
- package/dist/utils.esm.js.map +1 -0
- package/package.json +17 -11
- package/dist/esm/index-DTZMI_cR.esm.js +0 -26
- package/dist/esm/index-DTZMI_cR.esm.js.map +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,771 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
|
|
6
|
-
import Button from '@material-ui/core/Button';
|
|
7
|
-
import Grid from '@material-ui/core/Grid';
|
|
8
|
-
import Pagination from '@material-ui/lab/Pagination';
|
|
9
|
-
import useAsync from 'react-use/esm/useAsync';
|
|
10
|
-
import useLocalStorage from 'react-use/esm/useLocalStorage';
|
|
11
|
-
import Tab from '@material-ui/core/Tab';
|
|
12
|
-
import Tabs from '@material-ui/core/Tabs';
|
|
13
|
-
import { makeStyles } from '@material-ui/core/styles';
|
|
14
|
-
import CloseIcon from '@material-ui/icons/Close';
|
|
15
|
-
import { SupportButton, ContentHeader, InfoCard, Link, MarkdownContent, StatusError, StatusOK, StatusPending, TrendLine, Table, WarningPanel, Page, Header, HeaderLabel, Content, Progress, EmptyState, StructuredMetadataTable, StatusWarning } from '@backstage/core-components';
|
|
16
|
-
import Typography from '@material-ui/core/Typography';
|
|
17
|
-
import useInterval from 'react-use/esm/useInterval';
|
|
18
|
-
import List from '@material-ui/core/List';
|
|
19
|
-
import ListItem from '@material-ui/core/ListItem';
|
|
20
|
-
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
|
21
|
-
import ListItemText from '@material-ui/core/ListItemText';
|
|
22
|
-
import Alert from '@material-ui/lab/Alert';
|
|
23
|
-
import MenuItem from '@material-ui/core/MenuItem';
|
|
24
|
-
import TextField from '@material-ui/core/TextField';
|
|
25
|
-
|
|
26
|
-
const lighthouseApiRef = createApiRef({
|
|
27
|
-
id: "plugin.lighthouse.service"
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const rootRouteRef = createRouteRef({
|
|
31
|
-
id: "lighthouse"
|
|
32
|
-
});
|
|
33
|
-
createRouteRef({
|
|
34
|
-
id: "lighthouse:audit"
|
|
35
|
-
});
|
|
36
|
-
const createAuditRouteRef = createRouteRef({
|
|
37
|
-
id: "lighthouse:create-audit"
|
|
38
|
-
});
|
|
39
|
-
const entityContentRouteRef = createRouteRef({
|
|
40
|
-
id: "lighthouse:entity-content"
|
|
41
|
-
});
|
|
42
|
-
const lighthousePlugin = createPlugin({
|
|
43
|
-
id: "lighthouse",
|
|
44
|
-
apis: [
|
|
45
|
-
createApiFactory({
|
|
46
|
-
api: lighthouseApiRef,
|
|
47
|
-
deps: { configApi: configApiRef },
|
|
48
|
-
factory: ({ configApi }) => LighthouseRestApi.fromConfig(configApi)
|
|
49
|
-
})
|
|
50
|
-
],
|
|
51
|
-
routes: {
|
|
52
|
-
root: createAuditRouteRef,
|
|
53
|
-
entityContent: entityContentRouteRef
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const LighthousePage = lighthousePlugin.provide(
|
|
57
|
-
createRoutableExtension({
|
|
58
|
-
name: "LighthousePage",
|
|
59
|
-
component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
|
|
60
|
-
mountPoint: rootRouteRef
|
|
61
|
-
})
|
|
62
|
-
);
|
|
63
|
-
const EntityLighthouseContent = lighthousePlugin.provide(
|
|
64
|
-
createRoutableExtension({
|
|
65
|
-
name: "EntityLighthouseContent",
|
|
66
|
-
component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.EmbeddedRouter),
|
|
67
|
-
mountPoint: entityContentRouteRef
|
|
68
|
-
})
|
|
69
|
-
);
|
|
70
|
-
const EntityLastLighthouseAuditCard = lighthousePlugin.provide(
|
|
71
|
-
createComponentExtension({
|
|
72
|
-
name: "EntityLastLighthouseAuditCard",
|
|
73
|
-
component: {
|
|
74
|
-
lazy: () => import('./esm/index-DTZMI_cR.esm.js').then((m) => m.LastLighthouseAuditCard)
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
function useQuery() {
|
|
80
|
-
return new URLSearchParams(useLocation().search);
|
|
81
|
-
}
|
|
82
|
-
function formatTime(timestamp) {
|
|
83
|
-
let date;
|
|
84
|
-
if (timestamp instanceof Date) {
|
|
85
|
-
date = timestamp;
|
|
86
|
-
} else {
|
|
87
|
-
date = new Date(timestamp);
|
|
88
|
-
}
|
|
89
|
-
return date.toUTCString();
|
|
90
|
-
}
|
|
91
|
-
const CATEGORIES = [
|
|
92
|
-
"accessibility",
|
|
93
|
-
"performance",
|
|
94
|
-
"seo",
|
|
95
|
-
"best-practices"
|
|
96
|
-
];
|
|
97
|
-
const CATEGORY_LABELS = {
|
|
98
|
-
accessibility: "Accessibility",
|
|
99
|
-
performance: "Performance",
|
|
100
|
-
seo: "SEO",
|
|
101
|
-
"best-practices": "Best Practices",
|
|
102
|
-
pwa: "Progressive Web App"
|
|
103
|
-
};
|
|
104
|
-
function buildSparklinesDataForItem(item) {
|
|
105
|
-
return item.audits.filter(
|
|
106
|
-
(audit) => audit.status === "COMPLETED"
|
|
107
|
-
).reduce((scores, audit) => {
|
|
108
|
-
Object.values(audit.categories).forEach((category) => {
|
|
109
|
-
scores[category.id] = scores[category.id] || [];
|
|
110
|
-
scores[category.id].unshift(category.score);
|
|
111
|
-
});
|
|
112
|
-
Object.values(scores).forEach((arr) => {
|
|
113
|
-
if (arr.length === 1)
|
|
114
|
-
arr.push(arr[0]);
|
|
115
|
-
});
|
|
116
|
-
return scores;
|
|
117
|
-
}, {});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function LighthouseSupportButton() {
|
|
121
|
-
return /* @__PURE__ */ React.createElement(SupportButton, null, "Lighthouse audits run for any web domain, stored over time.");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const LIGHTHOUSE_INTRO_LOCAL_STORAGE = "@backstage/lighthouse-plugin/intro-dismissed";
|
|
125
|
-
const USE_CASES = `
|
|
126
|
-
Google's [Lighthouse](https://developers.google.com/web/tools/lighthouse) auditing tool for websites
|
|
127
|
-
is a great open-source resource for benchmarking and improving the accessibility, performance, SEO, and best practices of your site.
|
|
128
|
-
At Spotify, we keep track of Lighthouse audit scores over time to look at trends and overall areas for investment.
|
|
129
|
-
|
|
130
|
-
This plugin allows you to generate on-demand Lighthouse audits for websites, and to track the trends for the
|
|
131
|
-
top-level categories of Lighthouse at a glance.
|
|
132
|
-
|
|
133
|
-
In the future, we hope to add support for scheduling audits (which we do internally), as well as allowing
|
|
134
|
-
custom runs of Lighthouse to be ingested (for auditing sites that require authentication or some session state).
|
|
135
|
-
`;
|
|
136
|
-
const SETUP = `
|
|
137
|
-
To get started, you will need a running instance of [lighthouse-audit-service](https://github.com/spotify/lighthouse-audit-service).
|
|
138
|
-
_It's likely you will need to enable CORS when running lighthouse-audit-service. Initialize the app
|
|
139
|
-
with the environment variable \`LAS_CORS\` set to \`true\`._
|
|
140
|
-
|
|
141
|
-
When you have an instance running that Backstage can hook into, first install the plugin into your app:
|
|
142
|
-
|
|
143
|
-
\`\`\`sh
|
|
144
|
-
# From your Backstage root directory
|
|
145
|
-
yarn --cwd packages/app add @backstage-community/plugin-lighthouse
|
|
146
|
-
\`\`\`
|
|
147
|
-
|
|
148
|
-
Modify your app routes in \`App.tsx\` to include the \`LighthousePage\` component exported from the plugin, for example:
|
|
149
|
-
|
|
150
|
-
\`\`\`tsx
|
|
151
|
-
// At the top imports
|
|
152
|
-
import { LighthousePage } from '@backstage-community/plugin-lighthouse';
|
|
153
|
-
|
|
154
|
-
<FlatRoutes>
|
|
155
|
-
// ...
|
|
156
|
-
<Route path="/lighthouse" element={<LighthousePage />} />
|
|
157
|
-
// ...
|
|
158
|
-
</FlatRoutes>;
|
|
159
|
-
\`\`\`
|
|
160
|
-
|
|
161
|
-
Then configure the \`lighthouse-audit-service\` URL in your [\`app-config.yaml\`](https://github.com/backstage/backstage/blob/master/app-config.yaml).
|
|
162
|
-
|
|
163
|
-
\`\`\`yaml
|
|
164
|
-
lighthouse:
|
|
165
|
-
baseUrl: http://your-service-url
|
|
166
|
-
\`\`\`
|
|
167
|
-
`;
|
|
168
|
-
const useStyles$2 = makeStyles((theme) => ({
|
|
169
|
-
tabs: { marginBottom: -18 },
|
|
170
|
-
tab: { minWidth: 72, paddingLeft: 1, paddingRight: 1 },
|
|
171
|
-
content: { marginBottom: theme.spacing(2) },
|
|
172
|
-
closeButtonContainer: { height: "100%" },
|
|
173
|
-
closeButtonItem: { paddingBottom: 0 }
|
|
174
|
-
}));
|
|
175
|
-
function GettingStartedCard() {
|
|
176
|
-
const classes = useStyles$2();
|
|
177
|
-
const [value, setValue] = useState(0);
|
|
178
|
-
return /* @__PURE__ */ React.createElement(
|
|
179
|
-
InfoCard,
|
|
180
|
-
{
|
|
181
|
-
title: "Get started",
|
|
182
|
-
subheader: /* @__PURE__ */ React.createElement(
|
|
183
|
-
Tabs,
|
|
184
|
-
{
|
|
185
|
-
value,
|
|
186
|
-
indicatorColor: "primary",
|
|
187
|
-
textColor: "primary",
|
|
188
|
-
onChange: (_ev, newValue) => setValue(newValue),
|
|
189
|
-
"aria-label": "get started tabs",
|
|
190
|
-
className: classes.tabs
|
|
191
|
-
},
|
|
192
|
-
/* @__PURE__ */ React.createElement(Tab, { className: classes.tab, label: "Use cases" }),
|
|
193
|
-
/* @__PURE__ */ React.createElement(Tab, { className: classes.tab, label: "Setup" })
|
|
194
|
-
),
|
|
195
|
-
divider: true,
|
|
196
|
-
actions: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row", justifyContent: "flex-end" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(
|
|
197
|
-
Button,
|
|
198
|
-
{
|
|
199
|
-
component: Link,
|
|
200
|
-
to: "https://github.com/spotify/lighthouse-audit-service",
|
|
201
|
-
size: "small"
|
|
202
|
-
},
|
|
203
|
-
"Check out the README"
|
|
204
|
-
))))
|
|
205
|
-
},
|
|
206
|
-
value === 0 && /* @__PURE__ */ React.createElement(MarkdownContent, { content: USE_CASES }),
|
|
207
|
-
value === 1 && /* @__PURE__ */ React.createElement(MarkdownContent, { content: SETUP })
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
function LighthouseIntro({ onDismiss = () => {
|
|
211
|
-
} }) {
|
|
212
|
-
const classes = useStyles$2();
|
|
213
|
-
const [dismissed, setDismissed] = useLocalStorage(
|
|
214
|
-
LIGHTHOUSE_INTRO_LOCAL_STORAGE,
|
|
215
|
-
false
|
|
216
|
-
);
|
|
217
|
-
if (dismissed)
|
|
218
|
-
return null;
|
|
219
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ContentHeader, { title: "Welcome to Lighthouse in Backstage!" }, /* @__PURE__ */ React.createElement(LighthouseSupportButton, null)), /* @__PURE__ */ React.createElement(Grid, { className: classes.content, container: true, spacing: 3, direction: "row" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, sm: 6, md: 4 }, /* @__PURE__ */ React.createElement(GettingStartedCard, null)), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, sm: 6, md: 8 }, /* @__PURE__ */ React.createElement(
|
|
220
|
-
Grid,
|
|
221
|
-
{
|
|
222
|
-
container: true,
|
|
223
|
-
justifyContent: "flex-end",
|
|
224
|
-
alignItems: "flex-end",
|
|
225
|
-
className: classes.closeButtonContainer
|
|
226
|
-
},
|
|
227
|
-
/* @__PURE__ */ React.createElement(Grid, { item: true, className: classes.closeButtonItem }, /* @__PURE__ */ React.createElement(
|
|
228
|
-
Button,
|
|
229
|
-
{
|
|
230
|
-
variant: "text",
|
|
231
|
-
onClick: () => {
|
|
232
|
-
onDismiss();
|
|
233
|
-
setDismissed(true);
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
/* @__PURE__ */ React.createElement(CloseIcon, null),
|
|
237
|
-
" Hide intro"
|
|
238
|
-
))
|
|
239
|
-
))));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const AuditStatusIcon = ({ audit }) => {
|
|
243
|
-
if (audit.status === "FAILED")
|
|
244
|
-
return /* @__PURE__ */ React.createElement(StatusError, null);
|
|
245
|
-
if (audit.status === "COMPLETED")
|
|
246
|
-
return /* @__PURE__ */ React.createElement(StatusOK, null);
|
|
247
|
-
return /* @__PURE__ */ React.createElement(StatusPending, null);
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const columns = [
|
|
251
|
-
{
|
|
252
|
-
title: "Website URL",
|
|
253
|
-
field: "websiteUrl"
|
|
254
|
-
},
|
|
255
|
-
...CATEGORIES.map((category) => ({
|
|
256
|
-
title: CATEGORY_LABELS[category],
|
|
257
|
-
field: category
|
|
258
|
-
})),
|
|
259
|
-
{
|
|
260
|
-
title: "Last Report",
|
|
261
|
-
field: "lastReport",
|
|
262
|
-
cellStyle: {
|
|
263
|
-
whiteSpace: "nowrap"
|
|
264
|
-
}
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
title: "Last Audit Triggered",
|
|
268
|
-
field: "lastAuditTriggered",
|
|
269
|
-
cellStyle: {
|
|
270
|
-
minWidth: 120
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
];
|
|
274
|
-
const AuditListTable = ({ items }) => {
|
|
275
|
-
const [websiteState, setWebsiteState] = useState(items);
|
|
276
|
-
const lighthouseApi = useApi(lighthouseApiRef);
|
|
277
|
-
useEffect(() => {
|
|
278
|
-
setWebsiteState(items);
|
|
279
|
-
}, [items]);
|
|
280
|
-
const runRefresh = (websites) => {
|
|
281
|
-
websites.forEach(async (website) => {
|
|
282
|
-
const response = await lighthouseApi.getWebsiteForAuditId(
|
|
283
|
-
website.lastAudit.id
|
|
284
|
-
);
|
|
285
|
-
const auditStatus = response.lastAudit.status;
|
|
286
|
-
if (auditStatus === "COMPLETED" || auditStatus === "FAILED") {
|
|
287
|
-
const newWebsiteData = websiteState.slice(0);
|
|
288
|
-
newWebsiteData[newWebsiteData.findIndex((w) => w.url === response.url)] = response;
|
|
289
|
-
setWebsiteState(newWebsiteData);
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
};
|
|
293
|
-
const runningWebsiteAudits = websiteState ? websiteState.filter((website) => website.lastAudit.status === "RUNNING") : [];
|
|
294
|
-
useInterval(
|
|
295
|
-
() => runRefresh(runningWebsiteAudits),
|
|
296
|
-
runningWebsiteAudits.length > 0 ? 5e3 : null
|
|
297
|
-
);
|
|
298
|
-
const data = websiteState.map((website) => {
|
|
299
|
-
const trendlineData = buildSparklinesDataForItem(website);
|
|
300
|
-
const trendlines = {};
|
|
301
|
-
CATEGORIES.forEach((category) => {
|
|
302
|
-
trendlines[category] = /* @__PURE__ */ React.createElement(
|
|
303
|
-
TrendLine,
|
|
304
|
-
{
|
|
305
|
-
title: `trendline for ${CATEGORY_LABELS[category]} category of ${website.url}`,
|
|
306
|
-
data: trendlineData[category] || []
|
|
307
|
-
}
|
|
308
|
-
);
|
|
309
|
-
});
|
|
310
|
-
return {
|
|
311
|
-
websiteUrl: /* @__PURE__ */ React.createElement(Link, { to: generatePath("audit/:id", { id: website.lastAudit.id }) }, website.url),
|
|
312
|
-
...trendlines,
|
|
313
|
-
lastReport: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(AuditStatusIcon, { audit: website.lastAudit }), " ", /* @__PURE__ */ React.createElement(Typography, { component: "span" }, website.lastAudit.status.toLocaleUpperCase("en-US"))),
|
|
314
|
-
lastAuditTriggered: formatTime(website.lastAudit.timeCreated)
|
|
315
|
-
};
|
|
316
|
-
});
|
|
317
|
-
return /* @__PURE__ */ React.createElement(
|
|
318
|
-
Table,
|
|
319
|
-
{
|
|
320
|
-
options: {
|
|
321
|
-
paging: false,
|
|
322
|
-
toolbar: false
|
|
323
|
-
},
|
|
324
|
-
columns,
|
|
325
|
-
data
|
|
326
|
-
}
|
|
327
|
-
);
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
const LIMIT = 10;
|
|
331
|
-
const AuditList = () => {
|
|
332
|
-
const [dismissedStored] = useLocalStorage(
|
|
333
|
-
LIGHTHOUSE_INTRO_LOCAL_STORAGE
|
|
334
|
-
);
|
|
335
|
-
const [dismissed, setDismissed] = useState(dismissedStored);
|
|
336
|
-
const query = useQuery();
|
|
337
|
-
const page = query.get("page") ? parseInt(query.get("page"), 10) || 1 : 1;
|
|
338
|
-
const lighthouseApi = useApi(lighthouseApiRef);
|
|
339
|
-
const { value, loading, error } = useAsync(
|
|
340
|
-
async () => await lighthouseApi.getWebsiteList({
|
|
341
|
-
limit: LIMIT,
|
|
342
|
-
offset: (page - 1) * LIMIT
|
|
343
|
-
}),
|
|
344
|
-
[page]
|
|
345
|
-
);
|
|
346
|
-
const pageCount = useMemo(() => {
|
|
347
|
-
if ((value == null ? void 0 : value.total) && (value == null ? void 0 : value.limit))
|
|
348
|
-
return Math.ceil((value == null ? void 0 : value.total) / (value == null ? void 0 : value.limit));
|
|
349
|
-
return 0;
|
|
350
|
-
}, [value == null ? void 0 : value.total, value == null ? void 0 : value.limit]);
|
|
351
|
-
const navigate = useNavigate();
|
|
352
|
-
let content = null;
|
|
353
|
-
if (value) {
|
|
354
|
-
content = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(AuditListTable, { items: (value == null ? void 0 : value.items) || [] }), pageCount > 1 && /* @__PURE__ */ React.createElement(
|
|
355
|
-
Pagination,
|
|
356
|
-
{
|
|
357
|
-
page,
|
|
358
|
-
count: pageCount,
|
|
359
|
-
onChange: (_event, newPage) => {
|
|
360
|
-
navigate(`?page=${newPage}`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
));
|
|
364
|
-
} else if (loading) {
|
|
365
|
-
content = /* @__PURE__ */ React.createElement(Progress, null);
|
|
366
|
-
} else if (error) {
|
|
367
|
-
content = /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not load audit list." }, error.message);
|
|
368
|
-
}
|
|
369
|
-
return /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(
|
|
370
|
-
Header,
|
|
371
|
-
{
|
|
372
|
-
title: "Lighthouse",
|
|
373
|
-
subtitle: "Website audits powered by Lighthouse"
|
|
374
|
-
},
|
|
375
|
-
/* @__PURE__ */ React.createElement(HeaderLabel, { label: "Owner", value: "Spotify" }),
|
|
376
|
-
/* @__PURE__ */ React.createElement(HeaderLabel, { label: "Lifecycle", value: "Alpha" })
|
|
377
|
-
), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(LighthouseIntro, { onDismiss: () => setDismissed(true) }), /* @__PURE__ */ React.createElement(
|
|
378
|
-
ContentHeader,
|
|
379
|
-
{
|
|
380
|
-
title: "Audits",
|
|
381
|
-
description: "View all audits run for your website through Backstage here. Track the trend of your most recent audits."
|
|
382
|
-
},
|
|
383
|
-
/* @__PURE__ */ React.createElement(
|
|
384
|
-
Button,
|
|
385
|
-
{
|
|
386
|
-
variant: "contained",
|
|
387
|
-
color: "primary",
|
|
388
|
-
onClick: () => navigate("create-audit")
|
|
389
|
-
},
|
|
390
|
-
"Create Audit"
|
|
391
|
-
),
|
|
392
|
-
dismissed && /* @__PURE__ */ React.createElement(LighthouseSupportButton, null)
|
|
393
|
-
), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 3, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(InfoCard, { noPadding: true }, content)))));
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
const useStyles$1 = makeStyles({
|
|
397
|
-
contentGrid: {
|
|
398
|
-
height: "100%"
|
|
399
|
-
},
|
|
400
|
-
iframe: {
|
|
401
|
-
border: "0",
|
|
402
|
-
width: "100%",
|
|
403
|
-
height: "100%"
|
|
404
|
-
},
|
|
405
|
-
errorOutput: { whiteSpace: "pre" }
|
|
406
|
-
});
|
|
407
|
-
const AuditLinkList = ({ audits = [], selectedId }) => {
|
|
408
|
-
var _a, _b;
|
|
409
|
-
const fromPath = (_b = (_a = useRouteRef(rootRouteRef)) == null ? void 0 : _a()) != null ? _b : "../";
|
|
410
|
-
return /* @__PURE__ */ React.createElement(
|
|
411
|
-
List,
|
|
412
|
-
{
|
|
413
|
-
"data-testid": "audit-sidebar",
|
|
414
|
-
component: "nav",
|
|
415
|
-
"aria-label": "lighthouse audit history"
|
|
416
|
-
},
|
|
417
|
-
audits.map((audit) => /* @__PURE__ */ React.createElement(
|
|
418
|
-
ListItem,
|
|
419
|
-
{
|
|
420
|
-
key: audit.id,
|
|
421
|
-
selected: audit.id === selectedId,
|
|
422
|
-
button: true,
|
|
423
|
-
component: Link$1,
|
|
424
|
-
replace: true,
|
|
425
|
-
to: resolvePath(
|
|
426
|
-
generatePath("audit/:id", { id: audit.id }),
|
|
427
|
-
fromPath
|
|
428
|
-
)
|
|
429
|
-
},
|
|
430
|
-
/* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(AuditStatusIcon, { audit })),
|
|
431
|
-
/* @__PURE__ */ React.createElement(ListItemText, { primary: formatTime(audit.timeCreated) })
|
|
432
|
-
))
|
|
433
|
-
);
|
|
434
|
-
};
|
|
435
|
-
const AuditView = ({ audit }) => {
|
|
436
|
-
const classes = useStyles$1();
|
|
437
|
-
const params = useParams();
|
|
438
|
-
const { url: lighthouseUrl } = useApi(lighthouseApiRef);
|
|
439
|
-
if ((audit == null ? void 0 : audit.status) === "RUNNING")
|
|
440
|
-
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
441
|
-
if ((audit == null ? void 0 : audit.status) === "FAILED")
|
|
442
|
-
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, "This audit failed when attempting to run after several retries. Check that your instance of lighthouse-audit-service can successfully connect to your website and try again.");
|
|
443
|
-
return /* @__PURE__ */ React.createElement(InfoCard, { variant: "fullHeight" }, /* @__PURE__ */ React.createElement(
|
|
444
|
-
"iframe",
|
|
445
|
-
{
|
|
446
|
-
className: classes.iframe,
|
|
447
|
-
title: `Lighthouse audit${(audit == null ? void 0 : audit.url) ? ` for ${audit.url}` : ""}`,
|
|
448
|
-
src: `${lighthouseUrl}/v1/audits/${encodeURIComponent(params.id)}`
|
|
449
|
-
}
|
|
450
|
-
));
|
|
451
|
-
};
|
|
452
|
-
const AuditViewContent = () => {
|
|
453
|
-
var _a, _b;
|
|
454
|
-
const lighthouseApi = useApi(lighthouseApiRef);
|
|
455
|
-
const fromPath = (_b = (_a = useRouteRef(rootRouteRef)) == null ? void 0 : _a()) != null ? _b : "../";
|
|
456
|
-
const params = useParams();
|
|
457
|
-
const classes = useStyles$1();
|
|
458
|
-
const navigate = useNavigate();
|
|
459
|
-
const {
|
|
460
|
-
loading,
|
|
461
|
-
error,
|
|
462
|
-
value: nextValue
|
|
463
|
-
} = useAsync(
|
|
464
|
-
async () => await lighthouseApi.getWebsiteForAuditId(params.id),
|
|
465
|
-
[params.id]
|
|
466
|
-
);
|
|
467
|
-
const [value, setValue] = useState();
|
|
468
|
-
useEffect(() => {
|
|
469
|
-
if (!!nextValue && nextValue.url !== (value == null ? void 0 : value.url)) {
|
|
470
|
-
setValue(nextValue);
|
|
471
|
-
}
|
|
472
|
-
}, [value, nextValue, setValue]);
|
|
473
|
-
let content = null;
|
|
474
|
-
if (value) {
|
|
475
|
-
content = /* @__PURE__ */ React.createElement(Grid, { container: true, alignItems: "stretch", className: classes.contentGrid }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React.createElement(AuditLinkList, { audits: value == null ? void 0 : value.audits, selectedId: params.id })), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 9 }, /* @__PURE__ */ React.createElement(AuditView, { audit: value == null ? void 0 : value.audits.find((a) => a.id === params.id) })));
|
|
476
|
-
} else if (loading) {
|
|
477
|
-
content = /* @__PURE__ */ React.createElement(Progress, null);
|
|
478
|
-
} else if (error) {
|
|
479
|
-
content = /* @__PURE__ */ React.createElement(
|
|
480
|
-
Alert,
|
|
481
|
-
{
|
|
482
|
-
"data-testid": "error-message",
|
|
483
|
-
severity: "error",
|
|
484
|
-
className: classes.errorOutput
|
|
485
|
-
},
|
|
486
|
-
error.message
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
let createAuditButtonUrl = "create-audit";
|
|
490
|
-
if (value == null ? void 0 : value.url) {
|
|
491
|
-
createAuditButtonUrl += `?url=${encodeURIComponent(value.url)}`;
|
|
492
|
-
}
|
|
493
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
494
|
-
ContentHeader,
|
|
495
|
-
{
|
|
496
|
-
title: (value == null ? void 0 : value.url) || "Audit",
|
|
497
|
-
description: "See a history of all Lighthouse audits for your website run through Backstage."
|
|
498
|
-
},
|
|
499
|
-
/* @__PURE__ */ React.createElement(
|
|
500
|
-
Button,
|
|
501
|
-
{
|
|
502
|
-
variant: "contained",
|
|
503
|
-
color: "primary",
|
|
504
|
-
onClick: () => navigate(resolvePath(createAuditButtonUrl, fromPath))
|
|
505
|
-
},
|
|
506
|
-
"Create New Audit"
|
|
507
|
-
),
|
|
508
|
-
/* @__PURE__ */ React.createElement(LighthouseSupportButton, null)
|
|
509
|
-
), content);
|
|
510
|
-
};
|
|
511
|
-
const ConnectedAuditView = () => /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Lighthouse", subtitle: "Website audits powered by Lighthouse" }, /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Owner", value: "Spotify" }), /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Lifecycle", value: "Alpha" })), /* @__PURE__ */ React.createElement(Content, { stretch: true }, /* @__PURE__ */ React.createElement(AuditViewContent, null)));
|
|
512
|
-
|
|
513
|
-
const useStyles = makeStyles((theme) => ({
|
|
514
|
-
input: {
|
|
515
|
-
minWidth: 300,
|
|
516
|
-
[theme.breakpoints.down("xs")]: {
|
|
517
|
-
minWidth: "100%"
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
buttonList: {
|
|
521
|
-
marginLeft: theme.spacing(-1),
|
|
522
|
-
marginRight: theme.spacing(-1),
|
|
523
|
-
"& > *": {
|
|
524
|
-
margin: theme.spacing(1)
|
|
525
|
-
},
|
|
526
|
-
[theme.breakpoints.down("xs")]: {
|
|
527
|
-
marginLeft: 0,
|
|
528
|
-
marginRight: 0,
|
|
529
|
-
flexDirection: "column",
|
|
530
|
-
"& > *": {
|
|
531
|
-
width: "100%"
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
}));
|
|
536
|
-
const formFactorToScreenEmulationMap = {
|
|
537
|
-
// the default is mobile, so no need to override
|
|
538
|
-
mobile: void 0,
|
|
539
|
-
// Values from lighthouse's cli "desktop" preset
|
|
540
|
-
// https://github.com/GoogleChrome/lighthouse/blob/a6738e0033e7e5ca308b97c1c36f298b7d399402/lighthouse-core/config/constants.js#L71-L77
|
|
541
|
-
desktop: {
|
|
542
|
-
mobile: false,
|
|
543
|
-
width: 1350,
|
|
544
|
-
height: 940,
|
|
545
|
-
deviceScaleFactor: 1,
|
|
546
|
-
disabled: false
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
const CreateAuditContent = () => {
|
|
550
|
-
const errorApi = useApi(errorApiRef);
|
|
551
|
-
const lighthouseApi = useApi(lighthouseApiRef);
|
|
552
|
-
const classes = useStyles();
|
|
553
|
-
const query = useQuery();
|
|
554
|
-
const navigate = useNavigate();
|
|
555
|
-
const [submitting, setSubmitting] = useState(false);
|
|
556
|
-
const [url, setUrl] = useState(query.get("url") || "");
|
|
557
|
-
const [formFactor, setFormFactor] = useState("mobile");
|
|
558
|
-
const triggerAudit = useCallback(async () => {
|
|
559
|
-
setSubmitting(true);
|
|
560
|
-
try {
|
|
561
|
-
await lighthouseApi.triggerAudit({
|
|
562
|
-
url: url.replace(/\/$/, ""),
|
|
563
|
-
options: {
|
|
564
|
-
lighthouseConfig: {
|
|
565
|
-
settings: {
|
|
566
|
-
formFactor,
|
|
567
|
-
emulatedFormFactor: formFactor,
|
|
568
|
-
screenEmulation: formFactorToScreenEmulationMap[formFactor]
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
navigate("..");
|
|
574
|
-
} catch (err) {
|
|
575
|
-
errorApi.post(err);
|
|
576
|
-
} finally {
|
|
577
|
-
setSubmitting(false);
|
|
578
|
-
}
|
|
579
|
-
}, [url, formFactor, lighthouseApi, setSubmitting, errorApi, navigate]);
|
|
580
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
581
|
-
ContentHeader,
|
|
582
|
-
{
|
|
583
|
-
title: "Trigger a new audit",
|
|
584
|
-
description: "Submitting this form will immediately trigger and store a new Lighthouse audit. Trigger audits to track your website's accessibility, performance, SEO, and best practices over time."
|
|
585
|
-
},
|
|
586
|
-
/* @__PURE__ */ React.createElement(LighthouseSupportButton, null)
|
|
587
|
-
), /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "column" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, sm: 6 }, /* @__PURE__ */ React.createElement(InfoCard, null, /* @__PURE__ */ React.createElement(
|
|
588
|
-
"form",
|
|
589
|
-
{
|
|
590
|
-
onSubmit: (ev) => {
|
|
591
|
-
ev.preventDefault();
|
|
592
|
-
triggerAudit();
|
|
593
|
-
}
|
|
594
|
-
},
|
|
595
|
-
/* @__PURE__ */ React.createElement(List, null, /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(
|
|
596
|
-
TextField,
|
|
597
|
-
{
|
|
598
|
-
name: "lighthouse-create-audit-url-tf",
|
|
599
|
-
className: classes.input,
|
|
600
|
-
label: "URL",
|
|
601
|
-
placeholder: "https://spotify.com",
|
|
602
|
-
helperText: "The target URL for Lighthouse to use.",
|
|
603
|
-
required: true,
|
|
604
|
-
disabled: submitting,
|
|
605
|
-
onChange: (ev) => setUrl(ev.target.value),
|
|
606
|
-
value: url,
|
|
607
|
-
inputProps: { "aria-label": "URL" }
|
|
608
|
-
}
|
|
609
|
-
)), /* @__PURE__ */ React.createElement(ListItem, null, /* @__PURE__ */ React.createElement(
|
|
610
|
-
TextField,
|
|
611
|
-
{
|
|
612
|
-
name: "lighthouse-create-audit-emulated-form-factor-tf",
|
|
613
|
-
className: classes.input,
|
|
614
|
-
label: "Emulated Form Factor",
|
|
615
|
-
helperText: "Device to simulate when auditing",
|
|
616
|
-
select: true,
|
|
617
|
-
required: true,
|
|
618
|
-
disabled: submitting,
|
|
619
|
-
onChange: (ev) => setFormFactor(ev.target.value),
|
|
620
|
-
value: formFactor,
|
|
621
|
-
inputProps: { "aria-label": "Emulated form factor" }
|
|
622
|
-
},
|
|
623
|
-
/* @__PURE__ */ React.createElement(MenuItem, { value: "mobile" }, "Mobile"),
|
|
624
|
-
/* @__PURE__ */ React.createElement(MenuItem, { value: "desktop" }, "Desktop")
|
|
625
|
-
)), /* @__PURE__ */ React.createElement(ListItem, { className: classes.buttonList }, /* @__PURE__ */ React.createElement(
|
|
626
|
-
Button,
|
|
627
|
-
{
|
|
628
|
-
variant: "outlined",
|
|
629
|
-
color: "primary",
|
|
630
|
-
onClick: () => navigate(".."),
|
|
631
|
-
disabled: submitting
|
|
632
|
-
},
|
|
633
|
-
"Cancel"
|
|
634
|
-
), /* @__PURE__ */ React.createElement(
|
|
635
|
-
Button,
|
|
636
|
-
{
|
|
637
|
-
variant: "contained",
|
|
638
|
-
color: "primary",
|
|
639
|
-
type: "submit",
|
|
640
|
-
disabled: submitting
|
|
641
|
-
},
|
|
642
|
-
"Create Audit"
|
|
643
|
-
)))
|
|
644
|
-
)))));
|
|
645
|
-
};
|
|
646
|
-
const CreateAudit = () => /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Lighthouse", subtitle: "Website audits powered by Lighthouse" }, /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Owner", value: "Spotify" }), /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Lifecycle", value: "Alpha" })), /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(CreateAuditContent, null)));
|
|
647
|
-
|
|
648
|
-
const LIGHTHOUSE_WEBSITE_URL_ANNOTATION = "lighthouse.com/website-url";
|
|
649
|
-
|
|
650
|
-
const useWebsiteForEntity = () => {
|
|
651
|
-
var _a, _b;
|
|
652
|
-
const { entity } = useEntity();
|
|
653
|
-
const websiteUrl = (_b = (_a = entity.metadata.annotations) == null ? void 0 : _a[LIGHTHOUSE_WEBSITE_URL_ANNOTATION]) != null ? _b : "";
|
|
654
|
-
const lighthouseApi = useApi(lighthouseApiRef);
|
|
655
|
-
const errorApi = useApi(errorApiRef);
|
|
656
|
-
const response = useAsync(
|
|
657
|
-
() => lighthouseApi.getWebsiteByUrl(websiteUrl),
|
|
658
|
-
[websiteUrl]
|
|
659
|
-
);
|
|
660
|
-
if (response.error && !response.error.message.includes("no audited website found for url")) {
|
|
661
|
-
errorApi.post(response.error);
|
|
662
|
-
}
|
|
663
|
-
return response;
|
|
664
|
-
};
|
|
665
|
-
|
|
666
|
-
const AuditListForEntity = () => {
|
|
667
|
-
var _a, _b, _c, _d;
|
|
668
|
-
const { value, loading, error } = useWebsiteForEntity();
|
|
669
|
-
const { entity } = useEntity();
|
|
670
|
-
const navigate = useNavigate();
|
|
671
|
-
const fromPath = (_b = (_a = useRouteRef(rootRouteRef)) == null ? void 0 : _a()) != null ? _b : "../";
|
|
672
|
-
let createAuditButtonUrl = "create-audit";
|
|
673
|
-
const websiteUrl = (_d = (_c = entity.metadata.annotations) == null ? void 0 : _c[LIGHTHOUSE_WEBSITE_URL_ANNOTATION]) != null ? _d : "";
|
|
674
|
-
if (websiteUrl) {
|
|
675
|
-
createAuditButtonUrl += `?url=${encodeURIComponent(websiteUrl)}`;
|
|
676
|
-
}
|
|
677
|
-
let content = null;
|
|
678
|
-
content = /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, { title: "Latest Audit" }, /* @__PURE__ */ React.createElement(
|
|
679
|
-
Button,
|
|
680
|
-
{
|
|
681
|
-
variant: "contained",
|
|
682
|
-
color: "primary",
|
|
683
|
-
onClick: () => navigate(resolvePath(createAuditButtonUrl, fromPath))
|
|
684
|
-
},
|
|
685
|
-
"Create New Audit"
|
|
686
|
-
), /* @__PURE__ */ React.createElement(LighthouseSupportButton, null)), /* @__PURE__ */ React.createElement(AuditListTable, { items: value ? [value] : [] }));
|
|
687
|
-
if (loading) {
|
|
688
|
-
content = /* @__PURE__ */ React.createElement(Progress, null);
|
|
689
|
-
}
|
|
690
|
-
if (error && !error.message.includes("no audited website found for url")) {
|
|
691
|
-
content = /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not load audit list." }, error.message);
|
|
692
|
-
}
|
|
693
|
-
return /* @__PURE__ */ React.createElement(InfoCard, { noPadding: true }, content);
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
const isLighthouseAvailable = (entity) => {
|
|
697
|
-
var _a;
|
|
698
|
-
return Boolean((_a = entity.metadata.annotations) == null ? void 0 : _a[LIGHTHOUSE_WEBSITE_URL_ANNOTATION]);
|
|
699
|
-
};
|
|
700
|
-
const Router = () => /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, { path: "/", element: /* @__PURE__ */ React.createElement(AuditList, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/audit/:id", element: /* @__PURE__ */ React.createElement(ConnectedAuditView, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/create-audit", element: /* @__PURE__ */ React.createElement(CreateAudit, null) }));
|
|
701
|
-
const EmbeddedRouter = () => {
|
|
702
|
-
const { entity } = useEntity();
|
|
703
|
-
if (!isLighthouseAvailable(entity)) {
|
|
704
|
-
return /* @__PURE__ */ React.createElement(
|
|
705
|
-
MissingAnnotationEmptyState,
|
|
706
|
-
{
|
|
707
|
-
annotation: LIGHTHOUSE_WEBSITE_URL_ANNOTATION
|
|
708
|
-
}
|
|
709
|
-
);
|
|
710
|
-
}
|
|
711
|
-
return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, { path: "/", element: /* @__PURE__ */ React.createElement(AuditListForEntity, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/audit/:id", element: /* @__PURE__ */ React.createElement(AuditViewContent, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/create-audit", element: /* @__PURE__ */ React.createElement(CreateAuditContent, null) }));
|
|
712
|
-
};
|
|
713
|
-
|
|
714
|
-
var Router$1 = /*#__PURE__*/Object.freeze({
|
|
715
|
-
__proto__: null,
|
|
716
|
-
EmbeddedRouter: EmbeddedRouter,
|
|
717
|
-
Router: Router,
|
|
718
|
-
isLighthouseAvailable: isLighthouseAvailable
|
|
719
|
-
});
|
|
720
|
-
|
|
721
|
-
const LighthouseCategoryScoreStatus = (props) => {
|
|
722
|
-
const scoreAsPercentage = Math.round(props.score * 100);
|
|
723
|
-
switch (true) {
|
|
724
|
-
case scoreAsPercentage >= 90:
|
|
725
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(StatusOK, null), scoreAsPercentage, "%");
|
|
726
|
-
case (scoreAsPercentage >= 50 && scoreAsPercentage < 90):
|
|
727
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(StatusWarning, null), scoreAsPercentage, "%");
|
|
728
|
-
case scoreAsPercentage < 50:
|
|
729
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(StatusError, null), scoreAsPercentage, "%");
|
|
730
|
-
default:
|
|
731
|
-
return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, "N/A");
|
|
732
|
-
}
|
|
733
|
-
};
|
|
734
|
-
const LighthouseAuditStatus = (props) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(AuditStatusIcon, { audit: props.audit }), props.audit.status.toLocaleUpperCase("en-US"));
|
|
735
|
-
const LighthouseAuditSummary = (props) => {
|
|
736
|
-
const { audit, dense = false } = props;
|
|
737
|
-
const { url } = audit;
|
|
738
|
-
const flattenedCategoryData = {};
|
|
739
|
-
if (audit.status === "COMPLETED") {
|
|
740
|
-
const categories = audit.categories;
|
|
741
|
-
const categoryIds = Object.keys(categories);
|
|
742
|
-
categoryIds.forEach((id) => {
|
|
743
|
-
const { title, score } = categories[id];
|
|
744
|
-
flattenedCategoryData[title] = /* @__PURE__ */ React.createElement(LighthouseCategoryScoreStatus, { score });
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
const tableData = {
|
|
748
|
-
url,
|
|
749
|
-
status: /* @__PURE__ */ React.createElement(LighthouseAuditStatus, { audit }),
|
|
750
|
-
...flattenedCategoryData
|
|
751
|
-
};
|
|
752
|
-
return /* @__PURE__ */ React.createElement(StructuredMetadataTable, { metadata: tableData, dense });
|
|
753
|
-
};
|
|
754
|
-
const LastLighthouseAuditCard = (props) => {
|
|
755
|
-
const { dense = false, variant } = props;
|
|
756
|
-
const { value: website, loading, error } = useWebsiteForEntity();
|
|
757
|
-
let content;
|
|
758
|
-
if (loading) {
|
|
759
|
-
content = /* @__PURE__ */ React.createElement(Progress, null);
|
|
760
|
-
}
|
|
761
|
-
if (error) {
|
|
762
|
-
content = error.message.includes("no audited website found for url") ? /* @__PURE__ */ React.createElement(EmptyState, { title: "No Audits Found", missing: "data" }) : /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not load audit list." }, error.message);
|
|
763
|
-
}
|
|
764
|
-
if (website) {
|
|
765
|
-
content = /* @__PURE__ */ React.createElement(LighthouseAuditSummary, { audit: website.lastAudit, dense });
|
|
766
|
-
}
|
|
767
|
-
return /* @__PURE__ */ React.createElement(InfoCard, { title: "Lighthouse Audit", variant }, content);
|
|
768
|
-
};
|
|
769
|
-
|
|
770
|
-
export { EmbeddedRouter, EntityLastLighthouseAuditCard, EntityLighthouseContent, LastLighthouseAuditCard, LighthousePage, Router, isLighthouseAvailable, isLighthouseAvailable as isPluginApplicableToEntity, lighthouseApiRef, lighthousePlugin, lighthousePlugin as plugin };
|
|
1
|
+
export { EntityLastLighthouseAuditCard, EntityLighthouseContent, LighthousePage, lighthousePlugin, lighthousePlugin as plugin } from './plugin.esm.js';
|
|
2
|
+
export { EmbeddedRouter, Router, isLighthouseAvailable, isLighthouseAvailable as isPluginApplicableToEntity } from './Router.esm.js';
|
|
3
|
+
export { lighthouseApiRef } from './api.esm.js';
|
|
4
|
+
export { LastLighthouseAuditCard } from './components/Cards/LastLighthouseAuditCard.esm.js';
|
|
771
5
|
//# sourceMappingURL=index.esm.js.map
|