@backstage/core-components 0.17.4-next.1 → 0.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @backstage/core-components
2
2
 
3
+ ## 0.17.4
4
+
5
+ ### Patch Changes
6
+
7
+ - f6ffea6: Add optional message field for auth providers. This is intended to be a user friendly message that displays in the OAuth request dialog. A default message will be displayed if one is not provided.
8
+ - aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out.
9
+ - Updated dependencies
10
+ - @backstage/config@1.3.3
11
+ - @backstage/core-plugin-api@1.10.9
12
+ - @backstage/theme@0.6.7
13
+
14
+ ## 0.17.4-next.2
15
+
16
+ ### Patch Changes
17
+
18
+ - aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out.
19
+ - Updated dependencies
20
+ - @backstage/theme@0.6.7-next.1
21
+ - @backstage/core-plugin-api@1.10.9-next.0
22
+
3
23
  ## 0.17.4-next.1
4
24
 
5
25
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -43,6 +43,7 @@ declare const coreComponentsTranslationRef: _backstage_core_plugin_api_alpha.Tra
43
43
  readonly "supportConfig.default.title": "Support Not Configured";
44
44
  readonly "supportConfig.default.linkTitle": "Add `app.support` config key";
45
45
  readonly "errorBoundary.title": "Please contact {{slackChannel}} for help.";
46
+ readonly "oauthRequestDialog.message": "Sign-in to allow {{appTitle}} access to {{provider}} APIs and identities.";
46
47
  readonly "oauthRequestDialog.title": "Login Required";
47
48
  readonly "oauthRequestDialog.authRedirectTitle": "This will trigger a http redirect to OAuth Login.";
48
49
  readonly "oauthRequestDialog.login": "Log in";
@@ -1,4 +1,4 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { makeStyles } from '@material-ui/core/styles';
3
3
  import ListItem from '@material-ui/core/ListItem';
4
4
  import ListItemAvatar from '@material-ui/core/ListItemAvatar';
@@ -7,13 +7,18 @@ import Typography from '@material-ui/core/Typography';
7
7
  import Button from '@material-ui/core/Button';
8
8
  import { useState } from 'react';
9
9
  import { isError } from '@backstage/errors';
10
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
10
11
  import { coreComponentsTranslationRef } from '../../translation.esm.js';
11
12
  import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
13
+ import Box from '@material-ui/core/Box';
12
14
 
13
15
  const useItemStyles = makeStyles(
14
16
  (theme) => ({
15
17
  root: {
16
- paddingLeft: theme.spacing(3)
18
+ paddingLeft: theme.spacing(2)
19
+ },
20
+ button: {
21
+ marginLeft: theme.spacing(2)
17
22
  }
18
23
  }),
19
24
  { name: "BackstageLoginRequestListItem" }
@@ -22,6 +27,7 @@ const LoginRequestListItem = ({ request, busy, setBusy }) => {
22
27
  const classes = useItemStyles();
23
28
  const [error, setError] = useState();
24
29
  const { t } = useTranslationRef(coreComponentsTranslationRef);
30
+ const configApi = useApi(configApiRef);
25
31
  const handleContinue = async () => {
26
32
  setBusy(true);
27
33
  try {
@@ -33,16 +39,34 @@ const LoginRequestListItem = ({ request, busy, setBusy }) => {
33
39
  }
34
40
  };
35
41
  const IconComponent = request.provider.icon;
42
+ const message = request.provider.message ?? t("oauthRequestDialog.message", {
43
+ appTitle: configApi.getString("app.title"),
44
+ provider: request.provider.title
45
+ });
36
46
  return /* @__PURE__ */ jsxs(ListItem, { disabled: busy, classes: { root: classes.root }, children: [
37
47
  /* @__PURE__ */ jsx(ListItemAvatar, { children: /* @__PURE__ */ jsx(IconComponent, { fontSize: "large" }) }),
38
- /* @__PURE__ */ jsx(
39
- ListItemText,
40
- {
41
- primary: request.provider.title,
42
- secondary: error && /* @__PURE__ */ jsx(Typography, { color: "error", children: error })
43
- }
44
- ),
45
- /* @__PURE__ */ jsx(Button, { color: "primary", variant: "contained", onClick: handleContinue, children: t("oauthRequestDialog.login") })
48
+ /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flex: 1, children: [
49
+ /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsx(
50
+ ListItemText,
51
+ {
52
+ primary: request.provider.title,
53
+ secondary: /* @__PURE__ */ jsxs(Fragment, { children: [
54
+ message && /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", color: "textSecondary", children: message }),
55
+ error && /* @__PURE__ */ jsx(Typography, { color: "error", children: error })
56
+ ] })
57
+ }
58
+ ) }),
59
+ /* @__PURE__ */ jsx(
60
+ Button,
61
+ {
62
+ color: "primary",
63
+ variant: "contained",
64
+ onClick: handleContinue,
65
+ className: classes.button,
66
+ children: t("oauthRequestDialog.login")
67
+ }
68
+ )
69
+ ] })
46
70
  ] });
47
71
  };
48
72
 
@@ -1 +1 @@
1
- {"version":3,"file":"LoginRequestListItem.esm.js","sources":["../../../src/components/OAuthRequestDialog/LoginRequestListItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport Typography from '@material-ui/core/Typography';\nimport Button from '@material-ui/core/Button';\nimport { useState } from 'react';\nimport { isError } from '@backstage/errors';\nimport { PendingOAuthRequest } from '@backstage/core-plugin-api';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport type LoginRequestListItemClassKey = 'root';\n\nconst useItemStyles = makeStyles(\n theme => ({\n root: {\n paddingLeft: theme.spacing(3),\n },\n }),\n { name: 'BackstageLoginRequestListItem' },\n);\n\ntype RowProps = {\n request: PendingOAuthRequest;\n busy: boolean;\n setBusy: (busy: boolean) => void;\n};\n\nconst LoginRequestListItem = ({ request, busy, setBusy }: RowProps) => {\n const classes = useItemStyles();\n const [error, setError] = useState<string>();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const handleContinue = async () => {\n setBusy(true);\n try {\n await request.trigger();\n } catch (e) {\n setError(isError(e) ? e.message : 'An unspecified error occurred');\n } finally {\n setBusy(false);\n }\n };\n\n const IconComponent = request.provider.icon;\n\n return (\n <ListItem disabled={busy} classes={{ root: classes.root }}>\n <ListItemAvatar>\n <IconComponent fontSize=\"large\" />\n </ListItemAvatar>\n <ListItemText\n primary={request.provider.title}\n secondary={error && <Typography color=\"error\">{error}</Typography>}\n />\n <Button color=\"primary\" variant=\"contained\" onClick={handleContinue}>\n {t('oauthRequestDialog.login')}\n </Button>\n </ListItem>\n );\n};\n\nexport default LoginRequestListItem;\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BA,MAAM,aAAgB,GAAA,UAAA;AAAA,EACpB,CAAU,KAAA,MAAA;AAAA,IACR,IAAM,EAAA;AAAA,MACJ,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA;AAC9B,GACF,CAAA;AAAA,EACA,EAAE,MAAM,+BAAgC;AAC1C,CAAA;AAQA,MAAM,uBAAuB,CAAC,EAAE,OAAS,EAAA,IAAA,EAAM,SAAwB,KAAA;AACrE,EAAA,MAAM,UAAU,aAAc,EAAA;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAiB,EAAA;AAC3C,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,4BAA4B,CAAA;AAE5D,EAAA,MAAM,iBAAiB,YAAY;AACjC,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAI,IAAA;AACF,MAAA,MAAM,QAAQ,OAAQ,EAAA;AAAA,aACf,CAAG,EAAA;AACV,MAAA,QAAA,CAAS,OAAQ,CAAA,CAAC,CAAI,GAAA,CAAA,CAAE,UAAU,+BAA+B,CAAA;AAAA,KACjE,SAAA;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA;AACf,GACF;AAEA,EAAM,MAAA,aAAA,GAAgB,QAAQ,QAAS,CAAA,IAAA;AAEvC,EACE,uBAAA,IAAA,CAAC,YAAS,QAAU,EAAA,IAAA,EAAM,SAAS,EAAE,IAAA,EAAM,OAAQ,CAAA,IAAA,EACjD,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,aAAc,EAAA,EAAA,QAAA,EAAS,SAAQ,CAClC,EAAA,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,QAAQ,QAAS,CAAA,KAAA;AAAA,QAC1B,WAAW,KAAS,oBAAA,GAAA,CAAC,UAAW,EAAA,EAAA,KAAA,EAAM,SAAS,QAAM,EAAA,KAAA,EAAA;AAAA;AAAA,KACvD;AAAA,oBACA,GAAA,CAAC,MAAO,EAAA,EAAA,KAAA,EAAM,SAAU,EAAA,OAAA,EAAQ,aAAY,OAAS,EAAA,cAAA,EAClD,QAAE,EAAA,CAAA,CAAA,0BAA0B,CAC/B,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"LoginRequestListItem.esm.js","sources":["../../../src/components/OAuthRequestDialog/LoginRequestListItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport Typography from '@material-ui/core/Typography';\nimport Button from '@material-ui/core/Button';\nimport { useState } from 'react';\nimport { isError } from '@backstage/errors';\nimport {\n configApiRef,\n PendingOAuthRequest,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport Box from '@material-ui/core/Box';\n\nexport type LoginRequestListItemClassKey = 'root';\n\nconst useItemStyles = makeStyles(\n theme => ({\n root: {\n paddingLeft: theme.spacing(2),\n },\n button: {\n marginLeft: theme.spacing(2),\n },\n }),\n { name: 'BackstageLoginRequestListItem' },\n);\n\ntype RowProps = {\n request: PendingOAuthRequest;\n busy: boolean;\n setBusy: (busy: boolean) => void;\n};\n\nconst LoginRequestListItem = ({ request, busy, setBusy }: RowProps) => {\n const classes = useItemStyles();\n const [error, setError] = useState<string>();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const configApi = useApi(configApiRef);\n\n const handleContinue = async () => {\n setBusy(true);\n try {\n await request.trigger();\n } catch (e) {\n setError(isError(e) ? e.message : 'An unspecified error occurred');\n } finally {\n setBusy(false);\n }\n };\n\n const IconComponent = request.provider.icon;\n const message =\n request.provider.message ??\n t('oauthRequestDialog.message', {\n appTitle: configApi.getString('app.title'),\n provider: request.provider.title,\n });\n\n return (\n <ListItem disabled={busy} classes={{ root: classes.root }}>\n <ListItemAvatar>\n <IconComponent fontSize=\"large\" />\n </ListItemAvatar>\n <Box display=\"flex\" alignItems=\"center\" flex={1}>\n <Box flex={1}>\n <ListItemText\n primary={request.provider.title}\n secondary={\n <>\n {message && (\n <Typography variant=\"subtitle2\" color=\"textSecondary\">\n {message}\n </Typography>\n )}\n {error && <Typography color=\"error\">{error}</Typography>}\n </>\n }\n />\n </Box>\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={handleContinue}\n className={classes.button}\n >\n {t('oauthRequestDialog.login')}\n </Button>\n </Box>\n </ListItem>\n );\n};\n\nexport default LoginRequestListItem;\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAmCA,MAAM,aAAgB,GAAA,UAAA;AAAA,EACpB,CAAU,KAAA,MAAA;AAAA,IACR,IAAM,EAAA;AAAA,MACJ,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA,KAC9B;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,UAAA,EAAY,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA;AAC7B,GACF,CAAA;AAAA,EACA,EAAE,MAAM,+BAAgC;AAC1C,CAAA;AAQA,MAAM,uBAAuB,CAAC,EAAE,OAAS,EAAA,IAAA,EAAM,SAAwB,KAAA;AACrE,EAAA,MAAM,UAAU,aAAc,EAAA;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAiB,EAAA;AAC3C,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,4BAA4B,CAAA;AAC5D,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAErC,EAAA,MAAM,iBAAiB,YAAY;AACjC,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAI,IAAA;AACF,MAAA,MAAM,QAAQ,OAAQ,EAAA;AAAA,aACf,CAAG,EAAA;AACV,MAAA,QAAA,CAAS,OAAQ,CAAA,CAAC,CAAI,GAAA,CAAA,CAAE,UAAU,+BAA+B,CAAA;AAAA,KACjE,SAAA;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA;AACf,GACF;AAEA,EAAM,MAAA,aAAA,GAAgB,QAAQ,QAAS,CAAA,IAAA;AACvC,EAAA,MAAM,OACJ,GAAA,OAAA,CAAQ,QAAS,CAAA,OAAA,IACjB,EAAE,4BAA8B,EAAA;AAAA,IAC9B,QAAA,EAAU,SAAU,CAAA,SAAA,CAAU,WAAW,CAAA;AAAA,IACzC,QAAA,EAAU,QAAQ,QAAS,CAAA;AAAA,GAC5B,CAAA;AAEH,EACE,uBAAA,IAAA,CAAC,YAAS,QAAU,EAAA,IAAA,EAAM,SAAS,EAAE,IAAA,EAAM,OAAQ,CAAA,IAAA,EACjD,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,aAAc,EAAA,EAAA,QAAA,EAAS,SAAQ,CAClC,EAAA,CAAA;AAAA,yBACC,GAAI,EAAA,EAAA,OAAA,EAAQ,QAAO,UAAW,EAAA,QAAA,EAAS,MAAM,CAC5C,EAAA,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,GAAA,EAAA,EAAI,MAAM,CACT,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,OAAA,EAAS,QAAQ,QAAS,CAAA,KAAA;AAAA,UAC1B,2BAEK,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,YAAA,OAAA,wBACE,UAAW,EAAA,EAAA,OAAA,EAAQ,WAAY,EAAA,KAAA,EAAM,iBACnC,QACH,EAAA,OAAA,EAAA,CAAA;AAAA,YAED,KAAS,oBAAA,GAAA,CAAC,UAAW,EAAA,EAAA,KAAA,EAAM,SAAS,QAAM,EAAA,KAAA,EAAA;AAAA,WAC7C,EAAA;AAAA;AAAA,OAGN,EAAA,CAAA;AAAA,sBACA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,KAAM,EAAA,SAAA;AAAA,UACN,OAAQ,EAAA,WAAA;AAAA,UACR,OAAS,EAAA,cAAA;AAAA,UACT,WAAW,OAAQ,CAAA,MAAA;AAAA,UAElB,YAAE,0BAA0B;AAAA;AAAA;AAC/B,KACF,EAAA;AAAA,GACF,EAAA,CAAA;AAEJ;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useApi, configApiRef } from '@backstage/core-plugin-api';
2
+ import { useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';
3
3
  import { UserIdentity } from './UserIdentity.esm.js';
4
4
  import Button from '@material-ui/core/Button';
5
5
  import Grid from '@material-ui/core/Grid';
@@ -70,6 +70,7 @@ const SingleSignInPage = ({
70
70
  const authApi = useApi(provider.apiRef);
71
71
  const configApi = useApi(configApiRef);
72
72
  const { t } = useTranslationRef(coreComponentsTranslationRef);
73
+ const analytics = useAnalytics();
73
74
  const [error, setError] = useState();
74
75
  const [showLoginPage, setShowLoginPage] = useState(false);
75
76
  const [searchParams, _setSearchParams] = useSearchParams();
@@ -105,6 +106,7 @@ const SingleSignInPage = ({
105
106
  profile
106
107
  })
107
108
  );
109
+ analytics.captureEvent("signIn", "success");
108
110
  } catch (err) {
109
111
  setError(err);
110
112
  setShowLoginPage(true);
@@ -1 +1 @@
1
- {"version":3,"file":"SignInPage.esm.js","sources":["../../../src/layout/SignInPage/SignInPage.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageIdentityResponse,\n configApiRef,\n SignInPageProps,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { UserIdentity } from './UserIdentity';\nimport Button from '@material-ui/core/Button';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport { ComponentType, ReactNode, useState } from 'react';\nimport { useMountEffect } from '@react-hookz/web';\nimport { Progress } from '../../components/Progress';\nimport { Content } from '../Content/Content';\nimport { ContentHeader } from '../ContentHeader/ContentHeader';\nimport { Header } from '../Header';\nimport { InfoCard } from '../InfoCard';\nimport { Page } from '../Page';\nimport { getSignInProviders, useSignInProviders } from './providers';\nimport { GridItem, useStyles } from './styles';\nimport { IdentityProviders, SignInProviderConfig } from './types';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { useSearchParams } from 'react-router-dom';\n\ntype CommonSignInPageProps = SignInPageProps & {\n /**\n * Error component to be rendered instead of the default error panel in case\n * sign in fails.\n */\n ErrorComponent?: ComponentType<{ error?: Error }>;\n};\n\ntype MultiSignInPageProps = CommonSignInPageProps & {\n providers: IdentityProviders;\n title?: string;\n titleComponent?: ReactNode;\n align?: 'center' | 'left';\n};\n\ntype SingleSignInPageProps = CommonSignInPageProps & {\n provider: SignInProviderConfig;\n auto?: boolean;\n};\n\nexport type Props = MultiSignInPageProps | SingleSignInPageProps;\n\nexport const MultiSignInPage = ({\n onSignInSuccess,\n providers = [],\n title,\n titleComponent,\n align = 'left',\n}: MultiSignInPageProps) => {\n const configApi = useApi(configApiRef);\n const classes = useStyles();\n\n const signInProviders = getSignInProviders(providers);\n const [loading, providerElements] = useSignInProviders(\n signInProviders,\n onSignInSuccess,\n );\n\n if (loading) {\n return <Progress />;\n }\n\n return (\n <Page themeId=\"home\">\n <Header title={configApi.getString('app.title')} />\n <Content>\n {(title || titleComponent) && (\n <ContentHeader\n title={title}\n titleComponent={titleComponent}\n textAlign={align}\n />\n )}\n <Grid\n container\n justifyContent={align === 'center' ? align : 'flex-start'}\n spacing={2}\n component=\"ul\"\n classes={classes}\n >\n {providerElements}\n </Grid>\n </Content>\n </Page>\n );\n};\n\nexport const SingleSignInPage = ({\n provider,\n auto,\n onSignInSuccess,\n ErrorComponent,\n}: SingleSignInPageProps) => {\n const classes = useStyles();\n const authApi = useApi(provider.apiRef);\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const [error, setError] = useState<Error>();\n\n // The SignIn component takes some time to decide whether the user is logged-in or not.\n // showLoginPage is used to prevent a glitch-like experience where the sign-in page is\n // displayed for a split second when the user is already logged-in.\n const [showLoginPage, setShowLoginPage] = useState<boolean>(false);\n\n // User was redirected back to sign in page with error from auth redirect flow\n const [searchParams, _setSearchParams] = useSearchParams();\n const errorParam = searchParams.get('error');\n\n type LoginOpts = { checkExisting?: boolean; showPopup?: boolean };\n const login = async ({ checkExisting, showPopup }: LoginOpts) => {\n try {\n let identityResponse: BackstageIdentityResponse | undefined;\n if (checkExisting) {\n // Do an initial check if any logged-in session exists\n identityResponse = await authApi.getBackstageIdentity({\n optional: true,\n });\n }\n\n // If no session exists, show the sign-in page\n if (!identityResponse && (showPopup || auto) && !errorParam) {\n // Unless auto is set to true, this step should not happen.\n // When user intentionally clicks the Sign In button, autoShowPopup is set to true\n setShowLoginPage(true);\n identityResponse = await authApi.getBackstageIdentity({\n instantPopup: true,\n });\n if (!identityResponse) {\n throw new Error(\n `The ${provider.title} provider is not configured to support sign-in`,\n );\n }\n }\n\n if (!identityResponse) {\n setShowLoginPage(true);\n return;\n }\n\n const profile = await authApi.getProfile();\n onSignInSuccess(\n UserIdentity.create({\n identity: identityResponse.identity,\n authApi,\n profile,\n }),\n );\n } catch (err: any) {\n // User closed the sign-in modal\n setError(err);\n setShowLoginPage(true);\n }\n };\n\n useMountEffect(() => {\n if (errorParam) {\n setError(new Error(errorParam));\n }\n login({ checkExisting: true });\n });\n\n return showLoginPage ? (\n <Page themeId=\"home\">\n <Header title={configApi.getString('app.title')} />\n <Content>\n <Grid\n container\n justifyContent=\"center\"\n spacing={2}\n component=\"ul\"\n classes={classes}\n >\n <GridItem>\n <InfoCard\n variant=\"fullHeight\"\n title={provider.title}\n actions={\n <Button\n color=\"primary\"\n variant=\"outlined\"\n onClick={() => {\n login({ showPopup: true });\n }}\n >\n {t('signIn.title')}\n </Button>\n }\n >\n <Typography variant=\"body1\">{provider.message}</Typography>\n {error &&\n error.name !== 'PopupRejectedError' &&\n (ErrorComponent ? (\n <ErrorComponent error={error} />\n ) : (\n <Typography variant=\"body1\" color=\"error\">\n {error.message}\n </Typography>\n ))}\n </InfoCard>\n </GridItem>\n </Grid>\n </Content>\n </Page>\n ) : (\n <Progress />\n );\n};\n\nexport function SignInPage(props: Props) {\n if ('provider' in props) {\n return <SingleSignInPage {...props} />;\n }\n\n return <MultiSignInPage {...props} />;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SignInPage.esm.js","sources":["../../../src/layout/SignInPage/SignInPage.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageIdentityResponse,\n configApiRef,\n SignInPageProps,\n useAnalytics,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { UserIdentity } from './UserIdentity';\nimport Button from '@material-ui/core/Button';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport { ComponentType, ReactNode, useState } from 'react';\nimport { useMountEffect } from '@react-hookz/web';\nimport { Progress } from '../../components/Progress';\nimport { Content } from '../Content/Content';\nimport { ContentHeader } from '../ContentHeader/ContentHeader';\nimport { Header } from '../Header';\nimport { InfoCard } from '../InfoCard';\nimport { Page } from '../Page';\nimport { getSignInProviders, useSignInProviders } from './providers';\nimport { GridItem, useStyles } from './styles';\nimport { IdentityProviders, SignInProviderConfig } from './types';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { useSearchParams } from 'react-router-dom';\n\ntype CommonSignInPageProps = SignInPageProps & {\n /**\n * Error component to be rendered instead of the default error panel in case\n * sign in fails.\n */\n ErrorComponent?: ComponentType<{ error?: Error }>;\n};\n\ntype MultiSignInPageProps = CommonSignInPageProps & {\n providers: IdentityProviders;\n title?: string;\n titleComponent?: ReactNode;\n align?: 'center' | 'left';\n};\n\ntype SingleSignInPageProps = CommonSignInPageProps & {\n provider: SignInProviderConfig;\n auto?: boolean;\n};\n\nexport type Props = MultiSignInPageProps | SingleSignInPageProps;\n\nexport const MultiSignInPage = ({\n onSignInSuccess,\n providers = [],\n title,\n titleComponent,\n align = 'left',\n}: MultiSignInPageProps) => {\n const configApi = useApi(configApiRef);\n const classes = useStyles();\n\n const signInProviders = getSignInProviders(providers);\n const [loading, providerElements] = useSignInProviders(\n signInProviders,\n onSignInSuccess,\n );\n\n if (loading) {\n return <Progress />;\n }\n\n return (\n <Page themeId=\"home\">\n <Header title={configApi.getString('app.title')} />\n <Content>\n {(title || titleComponent) && (\n <ContentHeader\n title={title}\n titleComponent={titleComponent}\n textAlign={align}\n />\n )}\n <Grid\n container\n justifyContent={align === 'center' ? align : 'flex-start'}\n spacing={2}\n component=\"ul\"\n classes={classes}\n >\n {providerElements}\n </Grid>\n </Content>\n </Page>\n );\n};\n\nexport const SingleSignInPage = ({\n provider,\n auto,\n onSignInSuccess,\n ErrorComponent,\n}: SingleSignInPageProps) => {\n const classes = useStyles();\n const authApi = useApi(provider.apiRef);\n const configApi = useApi(configApiRef);\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const analytics = useAnalytics();\n\n const [error, setError] = useState<Error>();\n\n // The SignIn component takes some time to decide whether the user is logged-in or not.\n // showLoginPage is used to prevent a glitch-like experience where the sign-in page is\n // displayed for a split second when the user is already logged-in.\n const [showLoginPage, setShowLoginPage] = useState<boolean>(false);\n\n // User was redirected back to sign in page with error from auth redirect flow\n const [searchParams, _setSearchParams] = useSearchParams();\n const errorParam = searchParams.get('error');\n\n type LoginOpts = { checkExisting?: boolean; showPopup?: boolean };\n const login = async ({ checkExisting, showPopup }: LoginOpts) => {\n try {\n let identityResponse: BackstageIdentityResponse | undefined;\n if (checkExisting) {\n // Do an initial check if any logged-in session exists\n identityResponse = await authApi.getBackstageIdentity({\n optional: true,\n });\n }\n\n // If no session exists, show the sign-in page\n if (!identityResponse && (showPopup || auto) && !errorParam) {\n // Unless auto is set to true, this step should not happen.\n // When user intentionally clicks the Sign In button, autoShowPopup is set to true\n setShowLoginPage(true);\n identityResponse = await authApi.getBackstageIdentity({\n instantPopup: true,\n });\n if (!identityResponse) {\n throw new Error(\n `The ${provider.title} provider is not configured to support sign-in`,\n );\n }\n }\n\n if (!identityResponse) {\n setShowLoginPage(true);\n return;\n }\n\n const profile = await authApi.getProfile();\n onSignInSuccess(\n UserIdentity.create({\n identity: identityResponse.identity,\n authApi,\n profile,\n }),\n );\n analytics.captureEvent('signIn', 'success');\n } catch (err: any) {\n // User closed the sign-in modal\n setError(err);\n setShowLoginPage(true);\n }\n };\n\n useMountEffect(() => {\n if (errorParam) {\n setError(new Error(errorParam));\n }\n login({ checkExisting: true });\n });\n\n return showLoginPage ? (\n <Page themeId=\"home\">\n <Header title={configApi.getString('app.title')} />\n <Content>\n <Grid\n container\n justifyContent=\"center\"\n spacing={2}\n component=\"ul\"\n classes={classes}\n >\n <GridItem>\n <InfoCard\n variant=\"fullHeight\"\n title={provider.title}\n actions={\n <Button\n color=\"primary\"\n variant=\"outlined\"\n onClick={() => {\n login({ showPopup: true });\n }}\n >\n {t('signIn.title')}\n </Button>\n }\n >\n <Typography variant=\"body1\">{provider.message}</Typography>\n {error &&\n error.name !== 'PopupRejectedError' &&\n (ErrorComponent ? (\n <ErrorComponent error={error} />\n ) : (\n <Typography variant=\"body1\" color=\"error\">\n {error.message}\n </Typography>\n ))}\n </InfoCard>\n </GridItem>\n </Grid>\n </Content>\n </Page>\n ) : (\n <Progress />\n );\n};\n\nexport function SignInPage(props: Props) {\n if ('provider' in props) {\n return <SingleSignInPage {...props} />;\n }\n\n return <MultiSignInPage {...props} />;\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useState, useCallback, useLayoutEffect, useMemo } from 'react';
3
- import { useApi, errorApiRef, useApiHolder } from '@backstage/core-plugin-api';
3
+ import { useApi, errorApiRef, useApiHolder, useAnalytics } from '@backstage/core-plugin-api';
4
4
  import { commonProvider } from './commonProvider.esm.js';
5
5
  import { guestProvider } from './guestProvider.esm.js';
6
6
  import { customProvider } from './customProvider.esm.js';
@@ -44,6 +44,7 @@ const useSignInProviders = (providers, onSignInSuccess) => {
44
44
  const errorApi = useApi(errorApiRef);
45
45
  const apiHolder = useApiHolder();
46
46
  const [loading, setLoading] = useState(true);
47
+ const analytics = useAnalytics();
47
48
  const { t } = useTranslationRef(coreComponentsTranslationRef);
48
49
  const [searchParams, _setSearchParams] = useSearchParams();
49
50
  useMountEffect(() => {
@@ -55,18 +56,20 @@ const useSignInProviders = (providers, onSignInSuccess) => {
55
56
  }
56
57
  });
57
58
  const handleWrappedResult = useCallback(
58
- (identityApi) => {
59
+ async (identityApi) => {
59
60
  onSignInSuccess(
60
61
  IdentityApiSignOutProxy.from({
61
62
  identityApi,
62
63
  signOut: async () => {
63
64
  localStorage.removeItem(PROVIDER_STORAGE_KEY);
64
65
  await identityApi.signOut?.();
66
+ analytics.captureEvent("signOut", "success");
65
67
  }
66
68
  })
67
69
  );
70
+ analytics.captureEvent("signIn", "success");
68
71
  },
69
- [onSignInSuccess]
72
+ [onSignInSuccess, analytics]
70
73
  );
71
74
  useLayoutEffect(() => {
72
75
  if (!loading) {
@@ -1 +1 @@
1
- {"version":3,"file":"providers.esm.js","sources":["../../../src/layout/SignInPage/providers.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useLayoutEffect, useState, useMemo, useCallback } from 'react';\nimport {\n SignInPageProps,\n useApi,\n useApiHolder,\n errorApiRef,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport {\n IdentityProviders,\n SignInProvider,\n SignInProviderConfig,\n} from './types';\nimport { commonProvider } from './commonProvider';\nimport { guestProvider } from './guestProvider';\nimport { customProvider } from './customProvider';\nimport { IdentityApiSignOutProxy } from './IdentityApiSignOutProxy';\nimport { useSearchParams } from 'react-router-dom';\nimport { useMountEffect } from '@react-hookz/web';\nimport { ForwardedError } from '@backstage/errors';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider';\n\nexport type SignInProviderType = {\n [key: string]: {\n components: SignInProvider;\n id: string;\n config?: SignInProviderConfig;\n };\n};\n\nconst signInProviders: { [key: string]: SignInProvider } = {\n guest: guestProvider,\n custom: customProvider,\n common: commonProvider,\n};\n\nfunction validateIDs(id: string, providers: SignInProviderType): void {\n if (id in providers)\n throw new Error(\n `\"${id}\" ID is duplicated. IDs of identity providers have to be unique.`,\n );\n}\n\nexport function getSignInProviders(\n identityProviders: IdentityProviders,\n): SignInProviderType {\n const providers = identityProviders.reduce(\n (acc: SignInProviderType, config) => {\n if (typeof config === 'string') {\n validateIDs(config, acc);\n acc[config] = { components: signInProviders[config], id: config };\n\n return acc;\n }\n\n const { id } = config as SignInProviderConfig;\n validateIDs(id, acc);\n\n acc[id] = { components: signInProviders.common, id, config };\n\n return acc;\n },\n {},\n );\n\n return providers;\n}\n\nexport const useSignInProviders = (\n providers: SignInProviderType,\n onSignInSuccess: SignInPageProps['onSignInSuccess'],\n) => {\n const errorApi = useApi(errorApiRef);\n const apiHolder = useApiHolder();\n const [loading, setLoading] = useState(true);\n\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n // User was redirected back to sign in page with error from auth redirect flow\n const [searchParams, _setSearchParams] = useSearchParams();\n\n useMountEffect(() => {\n const errorParam = searchParams.get('error');\n if (errorParam) {\n errorApi.post(\n new ForwardedError(t('signIn.loginFailed'), new Error(errorParam)),\n );\n }\n });\n\n // This decorates the result with sign out logic from this hook\n const handleWrappedResult = useCallback(\n (identityApi: IdentityApi) => {\n onSignInSuccess(\n IdentityApiSignOutProxy.from({\n identityApi,\n signOut: async () => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n await identityApi.signOut?.();\n },\n }),\n );\n },\n [onSignInSuccess],\n );\n\n // In this effect we check if the user has already selected an existing login\n // provider, and in that case try to load an existing session for the provider.\n useLayoutEffect(() => {\n if (!loading) {\n return undefined;\n }\n\n // We can't use storageApi here, as it might have a dependency on the IdentityApi\n const selectedProviderId = localStorage.getItem(\n PROVIDER_STORAGE_KEY,\n ) as string;\n\n // No provider selected, let the user pick one\n if (selectedProviderId === null) {\n setLoading(false);\n return undefined;\n }\n\n const provider = providers[selectedProviderId];\n if (!provider) {\n setLoading(false);\n return undefined;\n }\n\n let didCancel = false;\n\n provider.components\n .loader(apiHolder, provider.config?.apiRef!)\n .then(result => {\n if (didCancel) {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n return;\n }\n if (result) {\n handleWrappedResult(result);\n } else {\n setLoading(false);\n }\n })\n .catch(error => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n if (didCancel) {\n return;\n }\n errorApi.post(error);\n setLoading(false);\n });\n\n return () => {\n didCancel = true;\n };\n }, [\n loading,\n errorApi,\n onSignInSuccess,\n apiHolder,\n providers,\n handleWrappedResult,\n ]);\n\n // This renders all available sign-in providers\n const elements = useMemo(\n () =>\n Object.keys(providers).map(key => {\n const provider = providers[key];\n\n const { Component } = provider.components;\n\n const handleSignInSuccess = (result: IdentityApi) => {\n handleWrappedResult(result);\n };\n\n const handleSignInStarted = () => {\n localStorage.setItem(\n PROVIDER_STORAGE_KEY,\n provider?.config?.id || provider.id,\n );\n };\n\n const handleSignInFailure = () => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n };\n\n return (\n <Component\n key={provider.id}\n config={provider.config!}\n onSignInStarted={handleSignInStarted}\n onSignInSuccess={handleSignInSuccess}\n onSignInFailure={handleSignInFailure}\n />\n );\n }),\n [providers, handleWrappedResult],\n );\n\n return [loading, elements];\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"providers.esm.js","sources":["../../../src/layout/SignInPage/providers.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useLayoutEffect, useState, useMemo, useCallback } from 'react';\nimport {\n SignInPageProps,\n useApi,\n useApiHolder,\n errorApiRef,\n IdentityApi,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport {\n IdentityProviders,\n SignInProvider,\n SignInProviderConfig,\n} from './types';\nimport { commonProvider } from './commonProvider';\nimport { guestProvider } from './guestProvider';\nimport { customProvider } from './customProvider';\nimport { IdentityApiSignOutProxy } from './IdentityApiSignOutProxy';\nimport { useSearchParams } from 'react-router-dom';\nimport { useMountEffect } from '@react-hookz/web';\nimport { ForwardedError } from '@backstage/errors';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider';\n\nexport type SignInProviderType = {\n [key: string]: {\n components: SignInProvider;\n id: string;\n config?: SignInProviderConfig;\n };\n};\n\nconst signInProviders: { [key: string]: SignInProvider } = {\n guest: guestProvider,\n custom: customProvider,\n common: commonProvider,\n};\n\nfunction validateIDs(id: string, providers: SignInProviderType): void {\n if (id in providers)\n throw new Error(\n `\"${id}\" ID is duplicated. IDs of identity providers have to be unique.`,\n );\n}\n\nexport function getSignInProviders(\n identityProviders: IdentityProviders,\n): SignInProviderType {\n const providers = identityProviders.reduce(\n (acc: SignInProviderType, config) => {\n if (typeof config === 'string') {\n validateIDs(config, acc);\n acc[config] = { components: signInProviders[config], id: config };\n\n return acc;\n }\n\n const { id } = config as SignInProviderConfig;\n validateIDs(id, acc);\n\n acc[id] = { components: signInProviders.common, id, config };\n\n return acc;\n },\n {},\n );\n\n return providers;\n}\n\nexport const useSignInProviders = (\n providers: SignInProviderType,\n onSignInSuccess: SignInPageProps['onSignInSuccess'],\n) => {\n const errorApi = useApi(errorApiRef);\n const apiHolder = useApiHolder();\n const [loading, setLoading] = useState(true);\n const analytics = useAnalytics();\n\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n // User was redirected back to sign in page with error from auth redirect flow\n const [searchParams, _setSearchParams] = useSearchParams();\n\n useMountEffect(() => {\n const errorParam = searchParams.get('error');\n if (errorParam) {\n errorApi.post(\n new ForwardedError(t('signIn.loginFailed'), new Error(errorParam)),\n );\n }\n });\n\n // This decorates the result with sign out logic from this hook\n const handleWrappedResult = useCallback(\n async (identityApi: IdentityApi) => {\n onSignInSuccess(\n IdentityApiSignOutProxy.from({\n identityApi,\n signOut: async () => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n await identityApi.signOut?.();\n analytics.captureEvent('signOut', 'success');\n },\n }),\n );\n analytics.captureEvent('signIn', 'success');\n },\n [onSignInSuccess, analytics],\n );\n\n // In this effect we check if the user has already selected an existing login\n // provider, and in that case try to load an existing session for the provider.\n useLayoutEffect(() => {\n if (!loading) {\n return undefined;\n }\n\n // We can't use storageApi here, as it might have a dependency on the IdentityApi\n const selectedProviderId = localStorage.getItem(\n PROVIDER_STORAGE_KEY,\n ) as string;\n\n // No provider selected, let the user pick one\n if (selectedProviderId === null) {\n setLoading(false);\n return undefined;\n }\n\n const provider = providers[selectedProviderId];\n if (!provider) {\n setLoading(false);\n return undefined;\n }\n\n let didCancel = false;\n\n provider.components\n .loader(apiHolder, provider.config?.apiRef!)\n .then(result => {\n if (didCancel) {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n return;\n }\n if (result) {\n handleWrappedResult(result);\n } else {\n setLoading(false);\n }\n })\n .catch(error => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n if (didCancel) {\n return;\n }\n errorApi.post(error);\n setLoading(false);\n });\n\n return () => {\n didCancel = true;\n };\n }, [\n loading,\n errorApi,\n onSignInSuccess,\n apiHolder,\n providers,\n handleWrappedResult,\n ]);\n\n // This renders all available sign-in providers\n const elements = useMemo(\n () =>\n Object.keys(providers).map(key => {\n const provider = providers[key];\n\n const { Component } = provider.components;\n\n const handleSignInSuccess = (result: IdentityApi) => {\n handleWrappedResult(result);\n };\n\n const handleSignInStarted = () => {\n localStorage.setItem(\n PROVIDER_STORAGE_KEY,\n provider?.config?.id || provider.id,\n );\n };\n\n const handleSignInFailure = () => {\n localStorage.removeItem(PROVIDER_STORAGE_KEY);\n };\n\n return (\n <Component\n key={provider.id}\n config={provider.config!}\n onSignInStarted={handleSignInStarted}\n onSignInSuccess={handleSignInSuccess}\n onSignInFailure={handleSignInFailure}\n />\n );\n }),\n [providers, handleWrappedResult],\n );\n\n return [loading, elements];\n};\n"],"names":[],"mappings":"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"}
@@ -58,7 +58,8 @@ const coreComponentsTranslationRef = createTranslationRef({
58
58
  title: "Login Required",
59
59
  authRedirectTitle: "This will trigger a http redirect to OAuth Login.",
60
60
  login: "Log in",
61
- rejectAll: "Reject All"
61
+ rejectAll: "Reject All",
62
+ message: "Sign-in to allow {{appTitle}} access to {{provider}} APIs and identities."
62
63
  },
63
64
  supportButton: {
64
65
  title: "Support",
@@ -1 +1 @@
1
- {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport const coreComponentsTranslationRef = createTranslationRef({\n id: 'core-components',\n messages: {\n signIn: {\n title: 'Sign In',\n loginFailed: 'Login failed',\n customProvider: {\n title: 'Custom User',\n subtitle:\n 'Enter your own User ID and credentials.\\n This selection will not be stored.',\n userId: 'User ID',\n tokenInvalid: 'Token is not a valid OpenID Connect JWT Token',\n continue: 'Continue',\n idToken: 'ID Token (optional)',\n },\n guestProvider: {\n title: 'Guest',\n subtitle:\n 'Enter as a Guest User.\\n You will not have a verified identity, meaning some features might be unavailable.',\n enter: 'Enter',\n },\n },\n skipToContent: 'Skip to content',\n copyTextButton: {\n tooltipText: 'Text copied to clipboard',\n },\n simpleStepper: {\n reset: 'Reset',\n finish: 'Finish',\n next: 'Next',\n skip: 'Skip',\n back: 'Back',\n },\n errorPage: {\n subtitle: 'ERROR {{status}}: {{statusMessage}}',\n title: 'Looks like someone dropped the mic!',\n goBack: 'Go back',\n showMoreDetails: 'Show more details',\n showLessDetails: 'Show less details',\n },\n emptyState: {\n missingAnnotation: {\n title: 'Missing Annotation',\n actionTitle:\n 'Add the annotation to your component YAML as shown in the highlighted example below:',\n readMore: 'Read more',\n },\n },\n supportConfig: {\n default: {\n title: 'Support Not Configured',\n linkTitle: 'Add `app.support` config key',\n },\n },\n errorBoundary: {\n title: 'Please contact {{slackChannel}} for help.',\n },\n oauthRequestDialog: {\n title: 'Login Required',\n authRedirectTitle: 'This will trigger a http redirect to OAuth Login.',\n login: 'Log in',\n rejectAll: 'Reject All',\n },\n supportButton: {\n title: 'Support',\n close: 'Close',\n },\n table: {\n filter: {\n title: 'Filters',\n clearAll: 'Clear all',\n placeholder: 'All results',\n },\n body: {\n emptyDataSourceMessage: 'No records to display',\n },\n pagination: {\n firstTooltip: 'First Page',\n labelDisplayedRows: '{from}-{to} of {count}',\n labelRowsSelect: 'rows',\n lastTooltip: 'Last Page',\n nextTooltip: 'Next Page',\n previousTooltip: 'Previous Page',\n },\n toolbar: {\n search: 'Filter',\n },\n header: {\n actions: 'Actions',\n },\n },\n alertDisplay: {\n message_one: '({{ count }} newer message)',\n message_other: '({{ count }} newer messages)',\n },\n autoLogout: {\n stillTherePrompt: {\n title: 'Logging out due to inactivity',\n buttonText: \"Yes! Don't log me out\",\n },\n },\n proxiedSignInPage: {\n title:\n 'You do not appear to be signed in. Please try reloading the browser page.',\n },\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport const coreComponentsTranslationRef = createTranslationRef({\n id: 'core-components',\n messages: {\n signIn: {\n title: 'Sign In',\n loginFailed: 'Login failed',\n customProvider: {\n title: 'Custom User',\n subtitle:\n 'Enter your own User ID and credentials.\\n This selection will not be stored.',\n userId: 'User ID',\n tokenInvalid: 'Token is not a valid OpenID Connect JWT Token',\n continue: 'Continue',\n idToken: 'ID Token (optional)',\n },\n guestProvider: {\n title: 'Guest',\n subtitle:\n 'Enter as a Guest User.\\n You will not have a verified identity, meaning some features might be unavailable.',\n enter: 'Enter',\n },\n },\n skipToContent: 'Skip to content',\n copyTextButton: {\n tooltipText: 'Text copied to clipboard',\n },\n simpleStepper: {\n reset: 'Reset',\n finish: 'Finish',\n next: 'Next',\n skip: 'Skip',\n back: 'Back',\n },\n errorPage: {\n subtitle: 'ERROR {{status}}: {{statusMessage}}',\n title: 'Looks like someone dropped the mic!',\n goBack: 'Go back',\n showMoreDetails: 'Show more details',\n showLessDetails: 'Show less details',\n },\n emptyState: {\n missingAnnotation: {\n title: 'Missing Annotation',\n actionTitle:\n 'Add the annotation to your component YAML as shown in the highlighted example below:',\n readMore: 'Read more',\n },\n },\n supportConfig: {\n default: {\n title: 'Support Not Configured',\n linkTitle: 'Add `app.support` config key',\n },\n },\n errorBoundary: {\n title: 'Please contact {{slackChannel}} for help.',\n },\n oauthRequestDialog: {\n title: 'Login Required',\n authRedirectTitle: 'This will trigger a http redirect to OAuth Login.',\n login: 'Log in',\n rejectAll: 'Reject All',\n message:\n 'Sign-in to allow {{appTitle}} access to {{provider}} APIs and identities.',\n },\n supportButton: {\n title: 'Support',\n close: 'Close',\n },\n table: {\n filter: {\n title: 'Filters',\n clearAll: 'Clear all',\n placeholder: 'All results',\n },\n body: {\n emptyDataSourceMessage: 'No records to display',\n },\n pagination: {\n firstTooltip: 'First Page',\n labelDisplayedRows: '{from}-{to} of {count}',\n labelRowsSelect: 'rows',\n lastTooltip: 'Last Page',\n nextTooltip: 'Next Page',\n previousTooltip: 'Previous Page',\n },\n toolbar: {\n search: 'Filter',\n },\n header: {\n actions: 'Actions',\n },\n },\n alertDisplay: {\n message_one: '({{ count }} newer message)',\n message_other: '({{ count }} newer messages)',\n },\n autoLogout: {\n stillTherePrompt: {\n title: 'Logging out due to inactivity',\n buttonText: \"Yes! Don't log me out\",\n },\n },\n proxiedSignInPage: {\n title:\n 'You do not appear to be signed in. Please try reloading the browser page.',\n },\n },\n});\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-components",
3
- "version": "0.17.4-next.1",
3
+ "version": "0.17.4",
4
4
  "description": "Core components used by Backstage plugins and apps",
5
5
  "backstage": {
6
6
  "role": "web-library"
@@ -66,11 +66,11 @@
66
66
  "test": "backstage-cli package test"
67
67
  },
68
68
  "dependencies": {
69
- "@backstage/config": "1.3.3-next.0",
70
- "@backstage/core-plugin-api": "1.10.9-next.0",
71
- "@backstage/errors": "1.2.7",
72
- "@backstage/theme": "0.6.7-next.0",
73
- "@backstage/version-bridge": "1.0.11",
69
+ "@backstage/config": "^1.3.3",
70
+ "@backstage/core-plugin-api": "^1.10.9",
71
+ "@backstage/errors": "^1.2.7",
72
+ "@backstage/theme": "^0.6.7",
73
+ "@backstage/version-bridge": "^1.0.11",
74
74
  "@dagrejs/dagre": "^1.1.4",
75
75
  "@date-io/core": "^1.3.13",
76
76
  "@material-table/core": "^3.1.0",
@@ -106,10 +106,10 @@
106
106
  "zod": "^3.22.4"
107
107
  },
108
108
  "devDependencies": {
109
- "@backstage/app-defaults": "1.6.4-next.1",
110
- "@backstage/cli": "0.33.1-next.1",
111
- "@backstage/core-app-api": "1.17.2-next.0",
112
- "@backstage/test-utils": "1.7.10-next.1",
109
+ "@backstage/app-defaults": "^1.6.4",
110
+ "@backstage/cli": "^0.33.1",
111
+ "@backstage/core-app-api": "^1.18.0",
112
+ "@backstage/test-utils": "^1.7.10",
113
113
  "@testing-library/dom": "^10.0.0",
114
114
  "@testing-library/jest-dom": "^6.0.0",
115
115
  "@testing-library/user-event": "^14.0.0",