@backstage/plugin-home 0.4.6 → 0.4.10

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,42 @@
1
1
  # @backstage/plugin-home
2
2
 
3
+ ## 0.4.10
4
+
5
+ ### Patch Changes
6
+
7
+ - bdf1419d20: Adds two new home components - CompanyLogo and Toolkit.
8
+ - Updated dependencies
9
+ - @backstage/core-components@0.8.4
10
+ - @backstage/core-plugin-api@0.5.0
11
+ - @backstage/plugin-search@0.5.5
12
+
13
+ ## 0.4.9
14
+
15
+ ### Patch Changes
16
+
17
+ - 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead.
18
+ - Updated dependencies
19
+ - @backstage/core-plugin-api@0.4.1
20
+ - @backstage/core-components@0.8.3
21
+
22
+ ## 0.4.8
23
+
24
+ ### Patch Changes
25
+
26
+ - 6d36220ef2: Fix undefined identity bug in `WelcomeTitle` caused by using deprecated methods of the IdentityApi
27
+ - Updated dependencies
28
+ - @backstage/core-plugin-api@0.4.0
29
+ - @backstage/core-components@0.8.2
30
+
31
+ ## 0.4.7
32
+
33
+ ### Patch Changes
34
+
35
+ - cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
36
+ - Updated dependencies
37
+ - @backstage/core-components@0.8.0
38
+ - @backstage/core-plugin-api@0.3.0
39
+
3
40
  ## 0.4.6
4
41
 
5
42
  ### Patch Changes
package/README.md CHANGED
@@ -1,9 +1,5 @@
1
1
  # Home
2
2
 
3
- Development is ongoing. You can follow the progress and contribute at the Backstage [Home Project Board](https://github.com/backstage/backstage/projects/7) or reach out to us in the [`#support` Discord channel](https://discord.com/channels/687207715902193673/687235481154617364).
4
-
5
- ## Overview
6
-
7
3
  The Home plugin introduces a system for composing a Home Page for Backstage in order to surface relevant info and provide convenient shortcuts for common tasks. It's designed with composability in mind with an open ecosystem that allows anyone to contribute with any component, to be included in any Home Page.
8
4
 
9
5
  For App Integrators, the system is designed to be composable to give total freedom in designing a Home Page that suits the needs of the organization. From the perspective of a Component Developer who wishes to contribute with building blocks to be included in Home Pages, there's a convenient interface for bundling the different parts and exporting them with both error boundary and lazy loading handled under the surface.
@@ -90,6 +86,12 @@ Additionally, the App Integrator is provided an escape hatch in case the way the
90
86
 
91
87
  ## Contributing
92
88
 
89
+ ### Homepage Components
90
+
93
91
  We believe that people have great ideas for what makes a useful Home Page, and we want to make it easy for every to benefit from the effort you put in to create something cool for the Home Page. Therefore, a great way of contributing is by simply creating more Home Page Components, than can then be used by everyone when composing their own Home Page. If they are tightly coupled to an existing plugin, it is recommended to allow them to live within that plugin, for convenience and to limit complex dependencies. On the other hand, if there's no clear plugin that the component is based on, it's also fine to contribute them into the [home plugin](/plugins/home/src/homePageComponents)
94
92
 
95
93
  Additionally, the API is at a very early state, so contributing with additional use cases may expose weaknesses in the current solution that we may iterate on, to provide more flexibility and ease of use for those who wish to develop components for the Home Page.
94
+
95
+ ### Homepage Templates
96
+
97
+ We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates). If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example to create your own](/plugins/home/src/templates/DefaultTemplate.stories.tsx), and then open a PR with your suggestion.
@@ -47,7 +47,7 @@ const useRandomJoke = () => {
47
47
  };
48
48
 
49
49
  const Actions = () => {
50
- const {rerollJoke} = useRandomJoke();
50
+ const { rerollJoke } = useRandomJoke();
51
51
  return /* @__PURE__ */ React.createElement(Button, {
52
52
  variant: "contained",
53
53
  color: "primary",
@@ -56,14 +56,14 @@ const Actions = () => {
56
56
  };
57
57
 
58
58
  const Content = () => {
59
- const {joke, loading} = useRandomJoke();
59
+ const { joke, loading } = useRandomJoke();
60
60
  if (loading)
61
61
  return /* @__PURE__ */ React.createElement("p", null, "Loading...");
62
62
  return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", null, joke.setup), /* @__PURE__ */ React.createElement("p", null, joke.punchline));
63
63
  };
64
64
 
65
65
  const Settings = () => {
66
- const {type, handleChangeType} = useRandomJoke();
66
+ const { type, handleChangeType } = useRandomJoke();
67
67
  const JOKE_TYPES = ["any", "programming"];
68
68
  return /* @__PURE__ */ React.createElement(FormControl, {
69
69
  component: "fieldset"
@@ -82,4 +82,4 @@ const Settings = () => {
82
82
  };
83
83
 
84
84
  export { Actions, Content, ContextProvider, Settings };
85
- //# sourceMappingURL=index-1baf251a.esm.js.map
85
+ //# sourceMappingURL=index-22929ade.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-1baf251a.esm.js","sources":["../../src/homePageComponents/RandomJoke/Context.tsx","../../src/homePageComponents/RandomJoke/Actions.tsx","../../src/homePageComponents/RandomJoke/Content.tsx","../../src/homePageComponents/RandomJoke/Settings.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React, { createContext } from 'react';\n\nexport type JokeType = 'any' | 'programming';\n\ntype Joke = {\n setup: string;\n punchline: string;\n};\n\ntype RandomJokeContextValue = {\n loading: boolean;\n joke: Joke;\n type: JokeType;\n rerollJoke: Function;\n handleChangeType: Function;\n};\n\nconst Context = createContext<RandomJokeContextValue | undefined>(undefined);\n\nconst getNewJoke = (type: string): Promise<Joke> =>\n fetch(\n `https://official-joke-api.appspot.com/jokes${\n type !== 'any' ? `/${type}` : ''\n }/random`,\n )\n .then(res => res.json())\n .then(data => (Array.isArray(data) ? data[0] : data));\n\nexport const ContextProvider = ({\n children,\n defaultCategory,\n}: {\n children: JSX.Element;\n defaultCategory?: JokeType;\n}) => {\n const [loading, setLoading] = React.useState(true);\n const [joke, setJoke] = React.useState<Joke>({\n setup: '',\n punchline: '',\n });\n const [type, setType] = React.useState<JokeType>(\n defaultCategory || ('programming' as JokeType),\n );\n\n const rerollJoke = React.useCallback(() => {\n setLoading(true);\n getNewJoke(type).then(newJoke => setJoke(newJoke));\n }, [type]);\n\n const handleChangeType = (newType: JokeType) => {\n setType(newType);\n };\n\n React.useEffect(() => {\n setLoading(false);\n }, [joke]);\n\n React.useEffect(() => {\n rerollJoke();\n }, [rerollJoke]);\n\n const value: RandomJokeContextValue = {\n loading,\n joke,\n type,\n rerollJoke,\n handleChangeType,\n };\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n};\n\nexport const useRandomJoke = () => {\n const value = React.useContext(Context);\n\n if (value === undefined) {\n throw new Error('useRandomJoke must be used within a RandomJokeProvider');\n }\n\n return value;\n};\n\nexport default Context;\n","/*\n * Copyright 2021 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 React from 'react';\n\nimport { Button } from '@material-ui/core';\nimport { useRandomJoke } from './Context';\n\nexport const Actions = () => {\n const { rerollJoke } = useRandomJoke();\n return (\n <Button variant=\"contained\" color=\"primary\" onClick={() => rerollJoke()}>\n Reroll\n </Button>\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\nimport { useRandomJoke } from './Context';\n\nexport const Content = () => {\n const { joke, loading } = useRandomJoke();\n\n if (loading) return <p>Loading...</p>;\n\n return (\n <div>\n <p>{joke.setup}</p>\n <p>{joke.punchline}</p>\n </div>\n );\n};\n","/*\n * Copyright 2021 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 */\nimport {\n FormControl,\n FormLabel,\n RadioGroup,\n FormControlLabel,\n Radio,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRandomJoke, JokeType } from './Context';\nimport upperFirst from 'lodash/upperFirst';\n\nexport const Settings = () => {\n const { type, handleChangeType } = useRandomJoke();\n const JOKE_TYPES: JokeType[] = ['any' as JokeType, 'programming' as JokeType];\n return (\n <FormControl component=\"fieldset\">\n <FormLabel component=\"legend\">Joke Type</FormLabel>\n <RadioGroup\n aria-label=\"joke type\"\n value={type}\n onChange={e => handleChangeType(e.target.value)}\n >\n {JOKE_TYPES.map(t => (\n <FormControlLabel\n key={t}\n value={t}\n control={<Radio />}\n label={upperFirst(t)}\n />\n ))}\n </RadioGroup>\n </FormControl>\n );\n};\n"],"names":[],"mappings":";;;;AAiCA,MAAM,UAAU,cAAkD;AAElE,MAAM,aAAa,CAAC,SAClB,MACE,8CACE,SAAS,QAAQ,IAAI,SAAS,aAG/B,KAAK,SAAO,IAAI,QAChB,KAAK,UAAS,MAAM,QAAQ,QAAQ,KAAK,KAAK;MAEtC,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,MAII;AACJ,QAAM,CAAC,SAAS,cAAc,MAAM,SAAS;AAC7C,QAAM,CAAC,MAAM,WAAW,MAAM,SAAe;AAAA,IAC3C,OAAO;AAAA,IACP,WAAW;AAAA;AAEb,QAAM,CAAC,MAAM,WAAW,MAAM,SAC5B,mBAAoB;AAGtB,QAAM,aAAa,MAAM,YAAY,MAAM;AACzC,eAAW;AACX,eAAW,MAAM,KAAK,aAAW,QAAQ;AAAA,KACxC,CAAC;AAEJ,QAAM,mBAAmB,CAAC,YAAsB;AAC9C,YAAQ;AAAA;AAGV,QAAM,UAAU,MAAM;AACpB,eAAW;AAAA,KACV,CAAC;AAEJ,QAAM,UAAU,MAAM;AACpB;AAAA,KACC,CAAC;AAEJ,QAAM,QAAgC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGF,6CAAQ,QAAQ,UAAT;AAAA,IAAkB;AAAA,KAAe;AAAA;MAG7B,gBAAgB,MAAM;AACjC,QAAM,QAAQ,MAAM,WAAW;AAE/B,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM;AAAA;AAGlB,SAAO;AAAA;;MC1EI,UAAU,MAAM;AAC3B,QAAM,CAAE,cAAe;AACvB,6CACG,QAAD;AAAA,IAAQ,SAAQ;AAAA,IAAY,OAAM;AAAA,IAAU,SAAS,MAAM;AAAA,KAAc;AAAA;;MCLhE,UAAU,MAAM;AAC3B,QAAM,CAAE,MAAM,WAAY;AAE1B,MAAI;AAAS,+CAAQ,KAAD,MAAG;AAEvB,6CACG,OAAD,0CACG,KAAD,MAAI,KAAK,4CACR,KAAD,MAAI,KAAK;AAAA;;MCDF,WAAW,MAAM;AAC5B,QAAM,CAAE,MAAM,oBAAqB;AACnC,QAAM,aAAyB,CAAC,OAAmB;AACnD,6CACG,aAAD;AAAA,IAAa,WAAU;AAAA,yCACpB,WAAD;AAAA,IAAW,WAAU;AAAA,KAAS,kDAC7B,YAAD;AAAA,IACE,cAAW;AAAA,IACX,OAAO;AAAA,IACP,UAAU,OAAK,iBAAiB,EAAE,OAAO;AAAA,KAExC,WAAW,IAAI,2CACb,kBAAD;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,6CAAU,OAAD;AAAA,IACT,OAAO,WAAW;AAAA;AAAA;;;;"}
1
+ {"version":3,"file":"index-22929ade.esm.js","sources":["../../src/homePageComponents/RandomJoke/Context.tsx","../../src/homePageComponents/RandomJoke/Actions.tsx","../../src/homePageComponents/RandomJoke/Content.tsx","../../src/homePageComponents/RandomJoke/Settings.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React, { createContext } from 'react';\n\nexport type JokeType = 'any' | 'programming';\n\ntype Joke = {\n setup: string;\n punchline: string;\n};\n\ntype RandomJokeContextValue = {\n loading: boolean;\n joke: Joke;\n type: JokeType;\n rerollJoke: Function;\n handleChangeType: Function;\n};\n\nconst Context = createContext<RandomJokeContextValue | undefined>(undefined);\n\nconst getNewJoke = (type: string): Promise<Joke> =>\n fetch(\n `https://official-joke-api.appspot.com/jokes${\n type !== 'any' ? `/${type}` : ''\n }/random`,\n )\n .then(res => res.json())\n .then(data => (Array.isArray(data) ? data[0] : data));\n\nexport const ContextProvider = ({\n children,\n defaultCategory,\n}: {\n children: JSX.Element;\n defaultCategory?: JokeType;\n}) => {\n const [loading, setLoading] = React.useState(true);\n const [joke, setJoke] = React.useState<Joke>({\n setup: '',\n punchline: '',\n });\n const [type, setType] = React.useState<JokeType>(\n defaultCategory || ('programming' as JokeType),\n );\n\n const rerollJoke = React.useCallback(() => {\n setLoading(true);\n getNewJoke(type).then(newJoke => setJoke(newJoke));\n }, [type]);\n\n const handleChangeType = (newType: JokeType) => {\n setType(newType);\n };\n\n React.useEffect(() => {\n setLoading(false);\n }, [joke]);\n\n React.useEffect(() => {\n rerollJoke();\n }, [rerollJoke]);\n\n const value: RandomJokeContextValue = {\n loading,\n joke,\n type,\n rerollJoke,\n handleChangeType,\n };\n\n return <Context.Provider value={value}>{children}</Context.Provider>;\n};\n\nexport const useRandomJoke = () => {\n const value = React.useContext(Context);\n\n if (value === undefined) {\n throw new Error('useRandomJoke must be used within a RandomJokeProvider');\n }\n\n return value;\n};\n\nexport default Context;\n","/*\n * Copyright 2021 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 React from 'react';\n\nimport { Button } from '@material-ui/core';\nimport { useRandomJoke } from './Context';\n\nexport const Actions = () => {\n const { rerollJoke } = useRandomJoke();\n return (\n <Button variant=\"contained\" color=\"primary\" onClick={() => rerollJoke()}>\n Reroll\n </Button>\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\nimport { useRandomJoke } from './Context';\n\nexport const Content = () => {\n const { joke, loading } = useRandomJoke();\n\n if (loading) return <p>Loading...</p>;\n\n return (\n <div>\n <p>{joke.setup}</p>\n <p>{joke.punchline}</p>\n </div>\n );\n};\n","/*\n * Copyright 2021 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 */\nimport {\n FormControl,\n FormLabel,\n RadioGroup,\n FormControlLabel,\n Radio,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRandomJoke, JokeType } from './Context';\nimport upperFirst from 'lodash/upperFirst';\n\nexport const Settings = () => {\n const { type, handleChangeType } = useRandomJoke();\n const JOKE_TYPES: JokeType[] = ['any' as JokeType, 'programming' as JokeType];\n return (\n <FormControl component=\"fieldset\">\n <FormLabel component=\"legend\">Joke Type</FormLabel>\n <RadioGroup\n aria-label=\"joke type\"\n value={type}\n onChange={e => handleChangeType(e.target.value)}\n >\n {JOKE_TYPES.map(t => (\n <FormControlLabel\n key={t}\n value={t}\n control={<Radio />}\n label={upperFirst(t)}\n />\n ))}\n </RadioGroup>\n </FormControl>\n );\n};\n"],"names":[],"mappings":";;;;AAiCA,MAAM,UAAU,cAAkD;AAElE,MAAM,aAAa,CAAC,SAClB,MACE,8CACE,SAAS,QAAQ,IAAI,SAAS,aAG/B,KAAK,SAAO,IAAI,QAChB,KAAK,UAAS,MAAM,QAAQ,QAAQ,KAAK,KAAK;MAEtC,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,MAII;AACJ,QAAM,CAAC,SAAS,cAAc,MAAM,SAAS;AAC7C,QAAM,CAAC,MAAM,WAAW,MAAM,SAAe;AAAA,IAC3C,OAAO;AAAA,IACP,WAAW;AAAA;AAEb,QAAM,CAAC,MAAM,WAAW,MAAM,SAC5B,mBAAoB;AAGtB,QAAM,aAAa,MAAM,YAAY,MAAM;AACzC,eAAW;AACX,eAAW,MAAM,KAAK,aAAW,QAAQ;AAAA,KACxC,CAAC;AAEJ,QAAM,mBAAmB,CAAC,YAAsB;AAC9C,YAAQ;AAAA;AAGV,QAAM,UAAU,MAAM;AACpB,eAAW;AAAA,KACV,CAAC;AAEJ,QAAM,UAAU,MAAM;AACpB;AAAA,KACC,CAAC;AAEJ,QAAM,QAAgC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGF,6CAAQ,QAAQ,UAAT;AAAA,IAAkB;AAAA,KAAe;AAAA;MAG7B,gBAAgB,MAAM;AACjC,QAAM,QAAQ,MAAM,WAAW;AAE/B,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM;AAAA;AAGlB,SAAO;AAAA;;MC1EI,UAAU,MAAM;AAC3B,QAAM,EAAE,eAAe;AACvB,6CACG,QAAD;AAAA,IAAQ,SAAQ;AAAA,IAAY,OAAM;AAAA,IAAU,SAAS,MAAM;AAAA,KAAc;AAAA;;MCLhE,UAAU,MAAM;AAC3B,QAAM,EAAE,MAAM,YAAY;AAE1B,MAAI;AAAS,+CAAQ,KAAD,MAAG;AAEvB,6CACG,OAAD,0CACG,KAAD,MAAI,KAAK,4CACR,KAAD,MAAI,KAAK;AAAA;;MCDF,WAAW,MAAM;AAC5B,QAAM,EAAE,MAAM,qBAAqB;AACnC,QAAM,aAAyB,CAAC,OAAmB;AACnD,6CACG,aAAD;AAAA,IAAa,WAAU;AAAA,yCACpB,WAAD;AAAA,IAAW,WAAU;AAAA,KAAS,kDAC7B,YAAD;AAAA,IACE,cAAW;AAAA,IACX,OAAO;AAAA,IACP,UAAU,OAAK,iBAAiB,EAAE,OAAO;AAAA,KAExC,WAAW,IAAI,2CACb,kBAAD;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,6CAAU,OAAD;AAAA,IACT,OAAO,WAAW;AAAA;AAAA;;;;"}
@@ -14,4 +14,4 @@ const HomepageCompositionRoot = (props) => {
14
14
  };
15
15
 
16
16
  export { HomepageCompositionRoot };
17
- //# sourceMappingURL=index-64b176b7.esm.js.map
17
+ //# sourceMappingURL=index-405b0ea2.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-64b176b7.esm.js","sources":["../../src/components/HomepageCompositionRoot.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React, { ReactNode } from 'react';\nimport { useOutlet } from 'react-router';\n\nexport const HomepageCompositionRoot = (props: {\n title?: string;\n children?: ReactNode;\n}) => {\n const outlet = useOutlet();\n const children = props.children ?? outlet;\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;;;;MAmBa,0BAA0B,CAAC,UAGlC;AAtBN;AAuBE,QAAM,SAAS;AACf,QAAM,WAAW,YAAM,aAAN,YAAkB;AACnC,mEAAU;AAAA;;;;"}
1
+ {"version":3,"file":"index-405b0ea2.esm.js","sources":["../../src/components/HomepageCompositionRoot.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React, { ReactNode } from 'react';\nimport { useOutlet } from 'react-router';\n\nexport const HomepageCompositionRoot = (props: {\n title?: string;\n children?: ReactNode;\n}) => {\n const outlet = useOutlet();\n const children = props.children ?? outlet;\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;;;;MAmBa,0BAA0B,CAAC,UAGlC;AAtBN;AAuBE,QAAM,SAAS;AACf,QAAM,WAAW,YAAM,aAAN,YAAkB;AACnC,mEAAU;AAAA;;;;"}
@@ -1,6 +1,7 @@
1
- import { useApi, identityApiRef } from '@backstage/core-plugin-api';
1
+ import { useApi, identityApiRef, alertApiRef } from '@backstage/core-plugin-api';
2
2
  import { Tooltip } from '@material-ui/core';
3
- import React, { useMemo } from 'react';
3
+ import React, { useMemo, useEffect } from 'react';
4
+ import useAsync from 'react-use/lib/useAsync';
4
5
 
5
6
  var English$2 = "Good morning";
6
7
  var Afrikaans$2 = "Goeiemôre, Môre";
@@ -606,13 +607,21 @@ function getTimeBasedGreeting() {
606
607
 
607
608
  const WelcomeTitle = () => {
608
609
  const identityApi = useApi(identityApiRef);
609
- const profile = identityApi.getProfile();
610
- const userId = identityApi.getUserId();
610
+ const alertApi = useApi(alertApiRef);
611
611
  const greeting = useMemo(() => getTimeBasedGreeting(), []);
612
+ const { value: profile, error } = useAsync(() => identityApi.getProfileInfo());
613
+ useEffect(() => {
614
+ if (error) {
615
+ alertApi.post({
616
+ message: `Failed to load user identity: ${error}`,
617
+ severity: "error"
618
+ });
619
+ }
620
+ }, [error, alertApi]);
612
621
  return /* @__PURE__ */ React.createElement(Tooltip, {
613
622
  title: greeting.language
614
- }, /* @__PURE__ */ React.createElement("span", null, `${greeting.greeting}, ${profile.displayName || userId}!`));
623
+ }, /* @__PURE__ */ React.createElement("span", null, `${greeting.greeting}${(profile == null ? void 0 : profile.displayName) ? `, ${profile == null ? void 0 : profile.displayName}` : ""}!`));
615
624
  };
616
625
 
617
626
  export { WelcomeTitle };
618
- //# sourceMappingURL=index-20e36a68.esm.js.map
627
+ //# sourceMappingURL=index-56def6f8.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-20e36a68.esm.js","sources":["../../src/homePageComponents/WelcomeTitle/timeUtil.ts","../../src/homePageComponents/WelcomeTitle/WelcomeTitle.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 goodMorning from './locales/goodMorning.locales.json';\nimport goodAfternoon from './locales/goodAfternoon.locales.json';\nimport goodEvening from './locales/goodEvening.locales.json';\n\n// Select a large random integer at startup, to prevent the greetings to change\n// every time the user navigates.\nconst greetingRandomSeed = Math.floor(Math.random() * 1000000);\n\nexport function getTimeBasedGreeting(): { language: string; greeting: string } {\n const random = (array: string[]) => array[greetingRandomSeed % array.length];\n\n const currentHour = new Date(Date.now()).getHours();\n if (currentHour >= 23) {\n return {\n language: 'Seriously',\n greeting: 'Get some rest',\n };\n }\n const timeOfDay = (hour: number): { [language: string]: string } => {\n if (hour < 12) return goodMorning;\n if (hour < 17) return goodAfternoon;\n return goodEvening;\n };\n const greetings = timeOfDay(currentHour);\n const greetingsKey = random(Object.keys(greetings));\n return {\n language: greetingsKey,\n greeting: greetings[greetingsKey],\n };\n}\n","/*\n * Copyright 2021 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 */\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Tooltip } from '@material-ui/core';\nimport React, { useMemo } from 'react';\nimport { getTimeBasedGreeting } from './timeUtil';\n\nexport const WelcomeTitle = () => {\n const identityApi = useApi(identityApiRef);\n const profile = identityApi.getProfile();\n const userId = identityApi.getUserId();\n const greeting = useMemo(() => getTimeBasedGreeting(), []);\n\n return (\n <Tooltip title={greeting.language}>\n <span>{`${greeting.greeting}, ${profile.displayName || userId}!`}</span>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAM,qBAAqB,KAAK,MAAM,KAAK,WAAW;gCAEyB;AAC7E,QAAM,SAAS,CAAC,UAAoB,MAAM,qBAAqB,MAAM;AAErE,QAAM,cAAc,IAAI,KAAK,KAAK,OAAO;AACzC,MAAI,eAAe,IAAI;AACrB,WAAO;AAAA,MACL,UAAU;AAAA,MACV,UAAU;AAAA;AAAA;AAGd,QAAM,YAAY,CAAC,SAAiD;AAClE,QAAI,OAAO;AAAI,aAAO;AACtB,QAAI,OAAO;AAAI,aAAO;AACtB,WAAO;AAAA;AAET,QAAM,YAAY,UAAU;AAC5B,QAAM,eAAe,OAAO,OAAO,KAAK;AACxC,SAAO;AAAA,IACL,UAAU;AAAA,IACV,UAAU,UAAU;AAAA;AAAA;;MCvBX,eAAe,MAAM;AAChC,QAAM,cAAc,OAAO;AAC3B,QAAM,UAAU,YAAY;AAC5B,QAAM,SAAS,YAAY;AAC3B,QAAM,WAAW,QAAQ,MAAM,wBAAwB;AAEvD,6CACG,SAAD;AAAA,IAAS,OAAO,SAAS;AAAA,yCACtB,QAAD,MAAO,GAAG,SAAS,aAAa,QAAQ,eAAe;AAAA;;;;"}
1
+ {"version":3,"file":"index-56def6f8.esm.js","sources":["../../src/homePageComponents/WelcomeTitle/timeUtil.ts","../../src/homePageComponents/WelcomeTitle/WelcomeTitle.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 goodMorning from './locales/goodMorning.locales.json';\nimport goodAfternoon from './locales/goodAfternoon.locales.json';\nimport goodEvening from './locales/goodEvening.locales.json';\n\n// Select a large random integer at startup, to prevent the greetings to change\n// every time the user navigates.\nconst greetingRandomSeed = Math.floor(Math.random() * 1000000);\n\nexport function getTimeBasedGreeting(): { language: string; greeting: string } {\n const random = (array: string[]) => array[greetingRandomSeed % array.length];\n\n const currentHour = new Date(Date.now()).getHours();\n if (currentHour >= 23) {\n return {\n language: 'Seriously',\n greeting: 'Get some rest',\n };\n }\n const timeOfDay = (hour: number): { [language: string]: string } => {\n if (hour < 12) return goodMorning;\n if (hour < 17) return goodAfternoon;\n return goodEvening;\n };\n const greetings = timeOfDay(currentHour);\n const greetingsKey = random(Object.keys(greetings));\n return {\n language: greetingsKey,\n greeting: greetings[greetingsKey],\n };\n}\n","/*\n * Copyright 2021 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 */\nimport {\n alertApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { Tooltip } from '@material-ui/core';\nimport React, { useEffect, useMemo } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { getTimeBasedGreeting } from './timeUtil';\n\nexport const WelcomeTitle = () => {\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const greeting = useMemo(() => getTimeBasedGreeting(), []);\n\n const { value: profile, error } = useAsync(() =>\n identityApi.getProfileInfo(),\n );\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load user identity: ${error}`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n return (\n <Tooltip title={greeting.language}>\n <span>{`${greeting.greeting}${\n profile?.displayName ? `, ${profile?.displayName}` : ''\n }!`}</span>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAM,qBAAqB,KAAK,MAAM,KAAK,WAAW;gCAEyB;AAC7E,QAAM,SAAS,CAAC,UAAoB,MAAM,qBAAqB,MAAM;AAErE,QAAM,cAAc,IAAI,KAAK,KAAK,OAAO;AACzC,MAAI,eAAe,IAAI;AACrB,WAAO;AAAA,MACL,UAAU;AAAA,MACV,UAAU;AAAA;AAAA;AAGd,QAAM,YAAY,CAAC,SAAiD;AAClE,QAAI,OAAO;AAAI,aAAO;AACtB,QAAI,OAAO;AAAI,aAAO;AACtB,WAAO;AAAA;AAET,QAAM,YAAY,UAAU;AAC5B,QAAM,eAAe,OAAO,OAAO,KAAK;AACxC,SAAO;AAAA,IACL,UAAU;AAAA,IACV,UAAU,UAAU;AAAA;AAAA;;MClBX,eAAe,MAAM;AAChC,QAAM,cAAc,OAAO;AAC3B,QAAM,WAAW,OAAO;AACxB,QAAM,WAAW,QAAQ,MAAM,wBAAwB;AAEvD,QAAM,EAAE,OAAO,SAAS,UAAU,SAAS,MACzC,YAAY;AAGd,YAAU,MAAM;AACd,QAAI,OAAO;AACT,eAAS,KAAK;AAAA,QACZ,SAAS,iCAAiC;AAAA,QAC1C,UAAU;AAAA;AAAA;AAAA,KAGb,CAAC,OAAO;AAEX,6CACG,SAAD;AAAA,IAAS,OAAO,SAAS;AAAA,yCACtB,QAAD,MAAO,GAAG,SAAS,WACjB,oCAAS,eAAc,KAAK,mCAAS,gBAAgB;AAAA;;;;"}
@@ -0,0 +1,47 @@
1
+ import { Link } from '@backstage/core-components';
2
+ import { makeStyles, List, ListItemIcon, ListItemText } from '@material-ui/core';
3
+ import React from 'react';
4
+
5
+ const useStyles = makeStyles((theme) => ({
6
+ toolkit: {
7
+ display: "flex",
8
+ flexWrap: "wrap",
9
+ textAlign: "center"
10
+ },
11
+ tool: {
12
+ margin: theme.spacing(0.5, 1)
13
+ },
14
+ label: {
15
+ marginTop: theme.spacing(1),
16
+ fontSize: "0.9em",
17
+ lineHeight: "1.25",
18
+ color: theme.palette.text.secondary
19
+ },
20
+ icon: {
21
+ width: "64px",
22
+ height: "64px",
23
+ borderRadius: "50px",
24
+ justifyContent: "center",
25
+ alignItems: "center",
26
+ boxShadow: theme.shadows[1],
27
+ backgroundColor: theme.palette.background.default
28
+ }
29
+ }));
30
+ const Content = (props) => {
31
+ const classes = useStyles();
32
+ return /* @__PURE__ */ React.createElement(List, {
33
+ className: classes.toolkit
34
+ }, props.tools.map((tool) => /* @__PURE__ */ React.createElement(Link, {
35
+ key: tool.url,
36
+ to: tool.url,
37
+ className: classes.tool
38
+ }, /* @__PURE__ */ React.createElement(ListItemIcon, {
39
+ className: classes.icon
40
+ }, tool.icon), /* @__PURE__ */ React.createElement(ListItemText, {
41
+ secondaryTypographyProps: { className: classes.label },
42
+ secondary: tool.label
43
+ }))));
44
+ };
45
+
46
+ export { Content };
47
+ //# sourceMappingURL=index-e6d55b70.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-e6d55b70.esm.js","sources":["../../src/homePageComponents/Toolkit/Content.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 { Link } from '@backstage/core-components';\nimport {\n makeStyles,\n List,\n ListItemIcon,\n ListItemText,\n} from '@material-ui/core';\nimport React from 'react';\n\nconst useStyles = makeStyles(theme => ({\n toolkit: {\n display: 'flex',\n flexWrap: 'wrap',\n textAlign: 'center',\n },\n tool: {\n margin: theme.spacing(0.5, 1),\n },\n label: {\n marginTop: theme.spacing(1),\n fontSize: '0.9em',\n lineHeight: '1.25',\n color: theme.palette.text.secondary,\n },\n icon: {\n width: '64px',\n height: '64px',\n borderRadius: '50px',\n justifyContent: 'center',\n alignItems: 'center',\n boxShadow: theme.shadows[1],\n backgroundColor: theme.palette.background.default,\n },\n}));\n\ntype Tool = {\n label: string;\n url: string;\n icon: React.ReactNode;\n};\n\n/**\n * Props for Toolkit content component {@link Content}.\n *\n * @public\n */\nexport type ToolkitContentProps = {\n tools: Tool[];\n};\n\n/**\n * A component to display a list of tools for the user.\n *\n * @public\n */\nexport const Content = (props: ToolkitContentProps) => {\n const classes = useStyles();\n\n return (\n <List className={classes.toolkit}>\n {props.tools.map((tool: Tool) => (\n <Link key={tool.url} to={tool.url} className={classes.tool}>\n <ListItemIcon className={classes.icon}>{tool.icon}</ListItemIcon>\n <ListItemText\n secondaryTypographyProps={{ className: classes.label }}\n secondary={tool.label}\n />\n </Link>\n ))}\n </List>\n );\n};\n"],"names":[],"mappings":";;;;AAyBA,MAAM,YAAY,WAAW;AAAU,EACrC,SAAS;AAAA,IACP,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA;AAAA,EAEb,MAAM;AAAA,IACJ,QAAQ,MAAM,QAAQ,KAAK;AAAA;AAAA,EAE7B,OAAO;AAAA,IACL,WAAW,MAAM,QAAQ;AAAA,IACzB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO,MAAM,QAAQ,KAAK;AAAA;AAAA,EAE5B,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,WAAW,MAAM,QAAQ;AAAA,IACzB,iBAAiB,MAAM,QAAQ,WAAW;AAAA;AAAA;MAwBjC,UAAU,CAAC,UAA+B;AACrD,QAAM,UAAU;AAEhB,6CACG,MAAD;AAAA,IAAM,WAAW,QAAQ;AAAA,KACtB,MAAM,MAAM,IAAI,CAAC,6CACf,MAAD;AAAA,IAAM,KAAK,KAAK;AAAA,IAAK,IAAI,KAAK;AAAA,IAAK,WAAW,QAAQ;AAAA,yCACnD,cAAD;AAAA,IAAc,WAAW,QAAQ;AAAA,KAAO,KAAK,2CAC5C,cAAD;AAAA,IACE,0BAA0B,EAAE,WAAW,QAAQ;AAAA,IAC/C,WAAW,KAAK;AAAA;AAAA;;;;"}
@@ -0,0 +1,16 @@
1
+ import { Typography } from '@material-ui/core';
2
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
3
+ import React from 'react';
4
+
5
+ const CompanyLogo = (props) => {
6
+ const { logo, className } = props;
7
+ const configApi = useApi(configApiRef);
8
+ return /* @__PURE__ */ React.createElement("div", {
9
+ className
10
+ }, logo ? /* @__PURE__ */ React.createElement(React.Fragment, null, logo) : /* @__PURE__ */ React.createElement(Typography, {
11
+ variant: "h1"
12
+ }, configApi.getString("app.title")));
13
+ };
14
+
15
+ export { CompanyLogo };
16
+ //# sourceMappingURL=index-e9dbf86a.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-e9dbf86a.esm.js","sources":["../../src/homePageComponents/CompanyLogo/CompanyLogo.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\nimport { Typography } from '@material-ui/core';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport React from 'react';\n\ntype CompanyLogoProps = {\n logo?: React.ReactNode;\n className?: string;\n};\n\n/**\n * A component to display a company logo for the user.\n *\n * @public\n */\nexport const CompanyLogo = (props: CompanyLogoProps) => {\n const { logo, className } = props;\n const configApi = useApi(configApiRef);\n\n return (\n <div className={className}>\n {logo ? (\n <>{logo}</>\n ) : (\n <Typography variant=\"h1\">{configApi.getString('app.title')}</Typography>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;MA6Ba,cAAc,CAAC,UAA4B;AACtD,QAAM,EAAE,MAAM,cAAc;AAC5B,QAAM,YAAY,OAAO;AAEzB,6CACG,OAAD;AAAA,IAAK;AAAA,KACF,iEACI,4CAEF,YAAD;AAAA,IAAY,SAAQ;AAAA,KAAM,UAAU,UAAU;AAAA;;;;"}
@@ -62,9 +62,9 @@ const ComponentTabs = ({
62
62
  }, tabs.map((t) => /* @__PURE__ */ React.createElement(Tab, {
63
63
  key: t.label,
64
64
  label: t.label
65
- }))), tabs.map(({Component}, idx) => /* @__PURE__ */ React.createElement("div", {
65
+ }))), tabs.map(({ Component }, idx) => /* @__PURE__ */ React.createElement("div", {
66
66
  key: idx,
67
- ...idx !== value ? {style: {display: "none"}} : {}
67
+ ...idx !== value ? { style: { display: "none" } } : {}
68
68
  }, /* @__PURE__ */ React.createElement(Component, null))));
69
69
  };
70
70
 
@@ -80,4 +80,4 @@ const ComponentTab = ({
80
80
  };
81
81
 
82
82
  export { ComponentAccordion, ComponentTab, ComponentTabs };
83
- //# sourceMappingURL=index-57301ff6.esm.js.map
83
+ //# sourceMappingURL=index-eddf0731.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-57301ff6.esm.js","sources":["../../src/componentRenderers/ComponentAccordion.tsx","../../src/componentRenderers/ComponentTabs/ComponentTabs.tsx","../../src/componentRenderers/ComponentTabs/ComponentTab.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React from 'react';\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Typography,\n IconButton,\n Theme,\n} from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport SettingsIcon from '@material-ui/icons/Settings';\n\nimport { SettingsModal } from '../components';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n settingsIconButton: {\n padding: theme.spacing(0, 1, 0, 0),\n },\n}));\n\nexport const ComponentAccordion = ({\n title,\n Content,\n Actions,\n Settings,\n ContextProvider,\n ...childProps\n}: {\n title: string;\n Content: () => JSX.Element;\n Actions?: () => JSX.Element;\n Settings?: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n}) => {\n const classes = useStyles();\n const [settingsIsExpanded, setSettingsIsExpanded] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n\n const handleOpenSettings = (e: any) => {\n e.stopPropagation();\n setSettingsIsExpanded(prevState => !prevState);\n };\n\n const innerContent = (\n <>\n {Settings && (\n <SettingsModal\n open={settingsIsExpanded}\n close={() => setSettingsIsExpanded(false)}\n componentName={title}\n >\n <Settings />\n </SettingsModal>\n )}\n <Accordion\n expanded={isExpanded}\n onChange={(_e: any, expanded: boolean) => setIsExpanded(expanded)}\n >\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n {Settings && (\n <IconButton\n onClick={handleOpenSettings}\n className={classes.settingsIconButton}\n >\n <SettingsIcon />\n </IconButton>\n )}\n <Typography>{title}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <Content />\n {Actions && <Actions />}\n </div>\n </AccordionDetails>\n </Accordion>\n </>\n );\n\n return ContextProvider ? (\n <ContextProvider {...childProps}>{innerContent}</ContextProvider>\n ) : (\n innerContent\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\nimport { Tabs, Tab } from '@material-ui/core';\nimport { InfoCard } from '@backstage/core-components';\n\ntype TabType = {\n label: string;\n Component: () => JSX.Element;\n};\n\nexport const ComponentTabs = ({\n title,\n tabs,\n}: {\n title: string;\n tabs: TabType[];\n}) => {\n const [value, setValue] = React.useState(0);\n\n const handleChange = (_event: any, newValue: number) => {\n setValue(newValue);\n };\n\n return (\n <InfoCard title={title}>\n <Tabs value={value} onChange={handleChange}>\n {tabs.map(t => (\n <Tab key={t.label} label={t.label} />\n ))}\n </Tabs>\n {tabs.map(({ Component }, idx) => (\n <div\n key={idx}\n {...(idx !== value ? { style: { display: 'none' } } : {})}\n >\n <Component />\n </div>\n ))}\n </InfoCard>\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\n\nexport const ComponentTab = ({\n title,\n Content,\n ContextProvider,\n ...childProps\n}: {\n title: string;\n Content: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n}) => {\n return ContextProvider ? (\n <ContextProvider {...childProps}>\n <Content />\n </ContextProvider>\n ) : (\n <Content />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA+BA,MAAM,YAAY,WAAW,CAAC;AAAkB,EAC9C,oBAAoB;AAAA,IAClB,SAAS,MAAM,QAAQ,GAAG,GAAG,GAAG;AAAA;AAAA;MAIvB,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,KACG;AAAA,MAOC;AACJ,QAAM,UAAU;AAChB,QAAM,CAAC,oBAAoB,yBAAyB,MAAM,SAAS;AACnE,QAAM,CAAC,YAAY,iBAAiB,MAAM,SAAS;AAEnD,QAAM,qBAAqB,CAAC,MAAW;AACrC,MAAE;AACF,0BAAsB,eAAa,CAAC;AAAA;AAGtC,QAAM,yEAED,gDACE,eAAD;AAAA,IACE,MAAM;AAAA,IACN,OAAO,MAAM,sBAAsB;AAAA,IACnC,eAAe;AAAA,yCAEd,UAAD,4CAGH,WAAD;AAAA,IACE,UAAU;AAAA,IACV,UAAU,CAAC,IAAS,aAAsB,cAAc;AAAA,yCAEvD,kBAAD;AAAA,IAAkB,gDAAa,gBAAD;AAAA,KAC3B,gDACE,YAAD;AAAA,IACE,SAAS;AAAA,IACT,WAAW,QAAQ;AAAA,yCAElB,cAAD,4CAGH,YAAD,MAAa,6CAEd,kBAAD,0CACG,OAAD,0CACG,SAAD,OACC,+CAAY,SAAD;AAOtB,SAAO,sDACJ,iBAAD;AAAA,OAAqB;AAAA,KAAa,gBAElC;AAAA;;MC1ES,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,MAII;AACJ,QAAM,CAAC,OAAO,YAAY,MAAM,SAAS;AAEzC,QAAM,eAAe,CAAC,QAAa,aAAqB;AACtD,aAAS;AAAA;AAGX,6CACG,UAAD;AAAA,IAAU;AAAA,yCACP,MAAD;AAAA,IAAM;AAAA,IAAc,UAAU;AAAA,KAC3B,KAAK,IAAI,2CACP,KAAD;AAAA,IAAK,KAAK,EAAE;AAAA,IAAO,OAAO,EAAE;AAAA,QAG/B,KAAK,IAAI,CAAC,CAAE,YAAa,4CACvB,OAAD;AAAA,IACE,KAAK;AAAA,OACA,QAAQ,QAAQ,CAAE,OAAO,CAAE,SAAS,WAAa;AAAA,yCAErD,WAAD;AAAA;;MChCG,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,KACG;AAAA,MAKC;AACJ,SAAO,sDACJ,iBAAD;AAAA,OAAqB;AAAA,yCAClB,SAAD,6CAGD,SAAD;AAAA;;;;"}
1
+ {"version":3,"file":"index-eddf0731.esm.js","sources":["../../src/componentRenderers/ComponentAccordion.tsx","../../src/componentRenderers/ComponentTabs/ComponentTabs.tsx","../../src/componentRenderers/ComponentTabs/ComponentTab.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 React from 'react';\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Typography,\n IconButton,\n Theme,\n} from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport SettingsIcon from '@material-ui/icons/Settings';\n\nimport { SettingsModal } from '../components';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n settingsIconButton: {\n padding: theme.spacing(0, 1, 0, 0),\n },\n}));\n\nexport const ComponentAccordion = ({\n title,\n Content,\n Actions,\n Settings,\n ContextProvider,\n ...childProps\n}: {\n title: string;\n Content: () => JSX.Element;\n Actions?: () => JSX.Element;\n Settings?: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n}) => {\n const classes = useStyles();\n const [settingsIsExpanded, setSettingsIsExpanded] = React.useState(false);\n const [isExpanded, setIsExpanded] = React.useState(false);\n\n const handleOpenSettings = (e: any) => {\n e.stopPropagation();\n setSettingsIsExpanded(prevState => !prevState);\n };\n\n const innerContent = (\n <>\n {Settings && (\n <SettingsModal\n open={settingsIsExpanded}\n close={() => setSettingsIsExpanded(false)}\n componentName={title}\n >\n <Settings />\n </SettingsModal>\n )}\n <Accordion\n expanded={isExpanded}\n onChange={(_e: any, expanded: boolean) => setIsExpanded(expanded)}\n >\n <AccordionSummary expandIcon={<ExpandMoreIcon />}>\n {Settings && (\n <IconButton\n onClick={handleOpenSettings}\n className={classes.settingsIconButton}\n >\n <SettingsIcon />\n </IconButton>\n )}\n <Typography>{title}</Typography>\n </AccordionSummary>\n <AccordionDetails>\n <div>\n <Content />\n {Actions && <Actions />}\n </div>\n </AccordionDetails>\n </Accordion>\n </>\n );\n\n return ContextProvider ? (\n <ContextProvider {...childProps}>{innerContent}</ContextProvider>\n ) : (\n innerContent\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\nimport { Tabs, Tab } from '@material-ui/core';\nimport { InfoCard } from '@backstage/core-components';\n\ntype TabType = {\n label: string;\n Component: () => JSX.Element;\n};\n\nexport const ComponentTabs = ({\n title,\n tabs,\n}: {\n title: string;\n tabs: TabType[];\n}) => {\n const [value, setValue] = React.useState(0);\n\n const handleChange = (_event: any, newValue: number) => {\n setValue(newValue);\n };\n\n return (\n <InfoCard title={title}>\n <Tabs value={value} onChange={handleChange}>\n {tabs.map(t => (\n <Tab key={t.label} label={t.label} />\n ))}\n </Tabs>\n {tabs.map(({ Component }, idx) => (\n <div\n key={idx}\n {...(idx !== value ? { style: { display: 'none' } } : {})}\n >\n <Component />\n </div>\n ))}\n </InfoCard>\n );\n};\n","/*\n * Copyright 2021 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 React from 'react';\n\nexport const ComponentTab = ({\n title,\n Content,\n ContextProvider,\n ...childProps\n}: {\n title: string;\n Content: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n}) => {\n return ContextProvider ? (\n <ContextProvider {...childProps}>\n <Content />\n </ContextProvider>\n ) : (\n <Content />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AA+BA,MAAM,YAAY,WAAW,CAAC;AAAkB,EAC9C,oBAAoB;AAAA,IAClB,SAAS,MAAM,QAAQ,GAAG,GAAG,GAAG;AAAA;AAAA;MAIvB,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,KACG;AAAA,MAOC;AACJ,QAAM,UAAU;AAChB,QAAM,CAAC,oBAAoB,yBAAyB,MAAM,SAAS;AACnE,QAAM,CAAC,YAAY,iBAAiB,MAAM,SAAS;AAEnD,QAAM,qBAAqB,CAAC,MAAW;AACrC,MAAE;AACF,0BAAsB,eAAa,CAAC;AAAA;AAGtC,QAAM,yEAED,gDACE,eAAD;AAAA,IACE,MAAM;AAAA,IACN,OAAO,MAAM,sBAAsB;AAAA,IACnC,eAAe;AAAA,yCAEd,UAAD,4CAGH,WAAD;AAAA,IACE,UAAU;AAAA,IACV,UAAU,CAAC,IAAS,aAAsB,cAAc;AAAA,yCAEvD,kBAAD;AAAA,IAAkB,gDAAa,gBAAD;AAAA,KAC3B,gDACE,YAAD;AAAA,IACE,SAAS;AAAA,IACT,WAAW,QAAQ;AAAA,yCAElB,cAAD,4CAGH,YAAD,MAAa,6CAEd,kBAAD,0CACG,OAAD,0CACG,SAAD,OACC,+CAAY,SAAD;AAOtB,SAAO,sDACJ,iBAAD;AAAA,OAAqB;AAAA,KAAa,gBAElC;AAAA;;MC1ES,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,MAII;AACJ,QAAM,CAAC,OAAO,YAAY,MAAM,SAAS;AAEzC,QAAM,eAAe,CAAC,QAAa,aAAqB;AACtD,aAAS;AAAA;AAGX,6CACG,UAAD;AAAA,IAAU;AAAA,yCACP,MAAD;AAAA,IAAM;AAAA,IAAc,UAAU;AAAA,KAC3B,KAAK,IAAI,2CACP,KAAD;AAAA,IAAK,KAAK,EAAE;AAAA,IAAO,OAAO,EAAE;AAAA,QAG/B,KAAK,IAAI,CAAC,EAAE,aAAa,4CACvB,OAAD;AAAA,IACE,KAAK;AAAA,OACA,QAAQ,QAAQ,EAAE,OAAO,EAAE,SAAS,aAAa;AAAA,yCAErD,WAAD;AAAA;;MChCG,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,KACG;AAAA,MAKC;AACJ,SAAO,sDACJ,iBAAD;AAAA,OAAqB;AAAA,yCAClB,SAAD,6CAGD,SAAD;AAAA;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  /// <reference types="react" />
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
- import * as react from 'react';
3
+ import * as React from 'react';
4
+ import React__default from 'react';
4
5
 
5
6
  declare type ComponentRenderer = {
6
7
  Renderer?: (props: RendererProps) => JSX.Element;
7
8
  };
8
9
  declare type ComponentParts = {
9
- Content: () => JSX.Element;
10
+ Content: (props?: any) => JSX.Element;
10
11
  Actions?: () => JSX.Element;
11
12
  Settings?: () => JSX.Element;
12
13
  ContextProvider?: (props: any) => JSX.Element;
@@ -14,20 +15,40 @@ declare type ComponentParts = {
14
15
  declare type RendererProps = {
15
16
  title: string;
16
17
  } & ComponentParts;
18
+ declare type CardExtensionProps<T> = ComponentRenderer & {
19
+ title?: string;
20
+ } & T;
21
+ /**
22
+ * An extension creator to create card based components for the homepage
23
+ *
24
+ * @public
25
+ */
17
26
  declare function createCardExtension<T>({ title, components, name, }: {
18
27
  title: string;
19
28
  components: () => Promise<ComponentParts>;
20
29
  name?: string;
21
- }): _backstage_core_plugin_api.Extension<({ Renderer, title: overrideTitle, ...childProps }: ComponentRenderer & {
22
- title?: string;
23
- } & T) => JSX.Element>;
30
+ }): _backstage_core_plugin_api.Extension<(props: CardExtensionProps<T>) => JSX.Element>;
31
+
32
+ declare type Tool = {
33
+ label: string;
34
+ url: string;
35
+ icon: React__default.ReactNode;
36
+ };
37
+ /**
38
+ * Props for Toolkit content component {@link Content}.
39
+ *
40
+ * @public
41
+ */
42
+ declare type ToolkitContentProps = {
43
+ tools: Tool[];
44
+ };
24
45
 
25
46
  declare const homePlugin: _backstage_core_plugin_api.BackstagePlugin<{
26
47
  root: _backstage_core_plugin_api.RouteRef<undefined>;
27
48
  }, {}>;
28
49
  declare const HomepageCompositionRoot: (props: {
29
50
  title?: string | undefined;
30
- children?: react.ReactNode;
51
+ children?: React.ReactNode;
31
52
  }) => JSX.Element;
32
53
  declare const ComponentAccordion: ({ title, Content, Actions, Settings, ContextProvider, ...childProps }: {
33
54
  title: string;
@@ -54,11 +75,28 @@ declare const ComponentTab: ({ title, Content, ContextProvider, ...childProps }:
54
75
  * @public
55
76
  */
56
77
  declare const WelcomeTitle: () => JSX.Element;
57
- declare const HomePageRandomJoke: ({ Renderer, title: overrideTitle, ...childProps }: ComponentRenderer & {
78
+ /**
79
+ * A component to display a company logo for the user.
80
+ *
81
+ * @public
82
+ */
83
+ declare const HomePageCompanyLogo: (props: {
84
+ logo?: React.ReactNode;
85
+ className?: string | undefined;
86
+ }) => JSX.Element;
87
+ declare const HomePageRandomJoke: (props: ComponentRenderer & {
58
88
  title?: string | undefined;
59
89
  } & {
60
90
  defaultCategory?: "any" | "programming" | undefined;
61
91
  }) => JSX.Element;
92
+ /**
93
+ * A component to display a list of tools for the user.
94
+ *
95
+ * @public
96
+ */
97
+ declare const HomePageToolkit: (props: ComponentRenderer & {
98
+ title?: string | undefined;
99
+ } & ToolkitContentProps) => JSX.Element;
62
100
 
63
101
  declare const SettingsModal: ({ open, close, componentName, children, }: {
64
102
  open: boolean;
@@ -75,4 +113,4 @@ declare const HeaderWorldClock: ({ clockConfigs, }: {
75
113
  clockConfigs: ClockConfig[];
76
114
  }) => JSX.Element | null;
77
115
 
78
- export { ClockConfig, ComponentAccordion, ComponentTab, ComponentTabs, HeaderWorldClock, HomePageRandomJoke, HomepageCompositionRoot, SettingsModal, WelcomeTitle, createCardExtension, homePlugin };
116
+ export { ClockConfig, ComponentAccordion, ComponentTab, ComponentTabs, HeaderWorldClock, HomePageCompanyLogo, HomePageRandomJoke, HomePageToolkit, HomepageCompositionRoot, SettingsModal, WelcomeTitle, createCardExtension, homePlugin };
package/dist/index.esm.js CHANGED
@@ -46,7 +46,7 @@ function getTimes(clockConfigs) {
46
46
  label = "GMT";
47
47
  }
48
48
  const time = d.toLocaleTimeString(lang, options);
49
- clocks.push({time, label});
49
+ clocks.push({ time, label });
50
50
  }
51
51
  return clocks;
52
52
  }
@@ -82,14 +82,11 @@ function createCardExtension({
82
82
  return createReactExtension({
83
83
  name,
84
84
  component: {
85
- lazy: () => components().then(({Content, Actions, Settings, ContextProvider}) => {
86
- const CardExtension = ({
87
- Renderer,
88
- title: overrideTitle,
89
- ...childProps
90
- }) => {
85
+ lazy: () => components().then(({ Content, Actions, Settings, ContextProvider }) => {
86
+ const CardExtension = (props) => {
87
+ const { Renderer, title: overrideTitle, ...childProps } = props;
91
88
  const app = useApp();
92
- const {Progress} = app.getComponents();
89
+ const { Progress } = app.getComponents();
93
90
  const [settingsOpen, setSettingsOpen] = React.useState(false);
94
91
  if (Renderer) {
95
92
  return /* @__PURE__ */ React.createElement(Suspense, {
@@ -98,9 +95,9 @@ function createCardExtension({
98
95
  title: overrideTitle || title,
99
96
  ...{
100
97
  Content,
101
- ...Actions ? {Actions} : {},
102
- ...Settings ? {Settings} : {},
103
- ...ContextProvider ? {ContextProvider} : {},
98
+ ...Actions ? { Actions } : {},
99
+ ...Settings ? { Settings } : {},
100
+ ...ContextProvider ? { ContextProvider } : {},
104
101
  ...childProps
105
102
  }
106
103
  }));
@@ -122,7 +119,9 @@ function createCardExtension({
122
119
  open: settingsOpen,
123
120
  componentName: title,
124
121
  close: () => setSettingsOpen(false)
125
- }, /* @__PURE__ */ React.createElement(Settings, null)), /* @__PURE__ */ React.createElement(Content, null));
122
+ }, /* @__PURE__ */ React.createElement(Settings, null)), /* @__PURE__ */ React.createElement(Content, {
123
+ ...childProps
124
+ }));
126
125
  return /* @__PURE__ */ React.createElement(Suspense, {
127
126
  fallback: /* @__PURE__ */ React.createElement(Progress, null)
128
127
  }, ContextProvider ? /* @__PURE__ */ React.createElement(ContextProvider, {
@@ -147,38 +146,49 @@ const homePlugin = createPlugin({
147
146
  });
148
147
  const HomepageCompositionRoot = homePlugin.provide(createRoutableExtension({
149
148
  name: "HomepageCompositionRoot",
150
- component: () => import('./esm/index-64b176b7.esm.js').then((m) => m.HomepageCompositionRoot),
149
+ component: () => import('./esm/index-405b0ea2.esm.js').then((m) => m.HomepageCompositionRoot),
151
150
  mountPoint: rootRouteRef
152
151
  }));
153
152
  const ComponentAccordion = homePlugin.provide(createComponentExtension({
154
153
  name: "ComponentAccordion",
155
154
  component: {
156
- lazy: () => import('./esm/index-57301ff6.esm.js').then((m) => m.ComponentAccordion)
155
+ lazy: () => import('./esm/index-eddf0731.esm.js').then((m) => m.ComponentAccordion)
157
156
  }
158
157
  }));
159
158
  const ComponentTabs = homePlugin.provide(createComponentExtension({
160
159
  name: "ComponentTabs",
161
160
  component: {
162
- lazy: () => import('./esm/index-57301ff6.esm.js').then((m) => m.ComponentTabs)
161
+ lazy: () => import('./esm/index-eddf0731.esm.js').then((m) => m.ComponentTabs)
163
162
  }
164
163
  }));
165
164
  const ComponentTab = homePlugin.provide(createComponentExtension({
166
165
  name: "ComponentTab",
167
166
  component: {
168
- lazy: () => import('./esm/index-57301ff6.esm.js').then((m) => m.ComponentTab)
167
+ lazy: () => import('./esm/index-eddf0731.esm.js').then((m) => m.ComponentTab)
169
168
  }
170
169
  }));
171
170
  const WelcomeTitle = homePlugin.provide(createComponentExtension({
172
171
  name: "WelcomeTitle",
173
172
  component: {
174
- lazy: () => import('./esm/index-20e36a68.esm.js').then((m) => m.WelcomeTitle)
173
+ lazy: () => import('./esm/index-56def6f8.esm.js').then((m) => m.WelcomeTitle)
174
+ }
175
+ }));
176
+ const HomePageCompanyLogo = homePlugin.provide(createComponentExtension({
177
+ name: "CompanyLogo",
178
+ component: {
179
+ lazy: () => import('./esm/index-e9dbf86a.esm.js').then((m) => m.CompanyLogo)
175
180
  }
176
181
  }));
177
182
  const HomePageRandomJoke = homePlugin.provide(createCardExtension({
178
183
  name: "HomePageRandomJoke",
179
184
  title: "Random Joke",
180
- components: () => import('./esm/index-1baf251a.esm.js')
185
+ components: () => import('./esm/index-22929ade.esm.js')
186
+ }));
187
+ const HomePageToolkit = homePlugin.provide(createCardExtension({
188
+ name: "HomePageToolkit",
189
+ title: "Toolkit",
190
+ components: () => import('./esm/index-e6d55b70.esm.js')
181
191
  }));
182
192
 
183
- export { ComponentAccordion, ComponentTab, ComponentTabs, HeaderWorldClock, HomePageRandomJoke, HomepageCompositionRoot, SettingsModal, WelcomeTitle, createCardExtension, homePlugin };
193
+ export { ComponentAccordion, ComponentTab, ComponentTabs, HeaderWorldClock, HomePageCompanyLogo, HomePageRandomJoke, HomePageToolkit, HomepageCompositionRoot, SettingsModal, WelcomeTitle, createCardExtension, homePlugin };
184
194
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/components/SettingsModal.tsx","../src/components/HeaderWorldClock/HeaderWorldClock.tsx","../src/extensions.tsx","../src/routes.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2021 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 React from 'react';\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core';\n\nexport const SettingsModal = ({\n open,\n close,\n componentName,\n children,\n}: {\n open: boolean;\n close: Function;\n componentName: string;\n children: JSX.Element;\n}) => {\n return (\n <Dialog open={open} onClose={() => close()}>\n <DialogTitle>Settings - {componentName}</DialogTitle>\n <DialogContent>{children}</DialogContent>\n <DialogActions>\n <Button onClick={() => close()} color=\"primary\" variant=\"contained\">\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","/*\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 React from 'react';\nimport { HeaderLabel } from '@backstage/core-components';\n\nconst timeFormat: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n};\n\ntype TimeObj = {\n time: string;\n label: string;\n};\n\nexport type ClockConfig = {\n label: string;\n timeZone: string;\n};\n\nfunction getTimes(clockConfigs: ClockConfig[]) {\n const d = new Date();\n const lang = window.navigator.language;\n\n const clocks: TimeObj[] = [];\n\n if (!clockConfigs) {\n return clocks;\n }\n\n for (const clockConfig of clockConfigs) {\n let label = clockConfig.label;\n\n const options: Intl.DateTimeFormatOptions = {\n timeZone: clockConfig.timeZone,\n ...timeFormat,\n };\n\n try {\n new Date().toLocaleString(lang, options);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n `The timezone ${options.timeZone} is invalid. Defaulting to GMT`,\n );\n options.timeZone = 'GMT';\n label = 'GMT';\n }\n\n const time = d.toLocaleTimeString(lang, options);\n clocks.push({ time, label });\n }\n\n return clocks;\n}\n\nexport const HeaderWorldClock = ({\n clockConfigs,\n}: {\n clockConfigs: ClockConfig[];\n}) => {\n const defaultTimes: TimeObj[] = [];\n const [clocks, setTimes] = React.useState(defaultTimes);\n\n React.useEffect(() => {\n setTimes(getTimes(clockConfigs));\n\n const intervalId = setInterval(() => {\n setTimes(getTimes(clockConfigs));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [clockConfigs]);\n\n if (clocks.length !== 0) {\n return (\n <>\n {clocks.map(clock => (\n <HeaderLabel\n label={clock.label}\n value={clock.time}\n key={clock.label}\n />\n ))}\n </>\n );\n }\n return null;\n};\n","/*\n * Copyright 2021 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 React, { Suspense } from 'react';\nimport { IconButton } from '@material-ui/core';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport { InfoCard } from '@backstage/core-components';\nimport { SettingsModal } from './components';\nimport { createReactExtension, useApp } from '@backstage/core-plugin-api';\n\nexport type ComponentRenderer = {\n Renderer?: (props: RendererProps) => JSX.Element;\n};\n\ntype ComponentParts = {\n Content: () => JSX.Element;\n Actions?: () => JSX.Element;\n Settings?: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n};\n\ntype RendererProps = { title: string } & ComponentParts;\n\nexport function createCardExtension<T>({\n title,\n components,\n name,\n}: {\n title: string;\n components: () => Promise<ComponentParts>;\n name?: string;\n}) {\n return createReactExtension({\n name,\n component: {\n lazy: () =>\n components().then(({ Content, Actions, Settings, ContextProvider }) => {\n const CardExtension = ({\n Renderer,\n title: overrideTitle,\n ...childProps\n }: ComponentRenderer & { title?: string } & T) => {\n const app = useApp();\n const { Progress } = app.getComponents();\n const [settingsOpen, setSettingsOpen] = React.useState(false);\n\n if (Renderer) {\n return (\n <Suspense fallback={<Progress />}>\n <Renderer\n title={overrideTitle || title}\n {...{\n Content,\n ...(Actions ? { Actions } : {}),\n ...(Settings ? { Settings } : {}),\n ...(ContextProvider ? { ContextProvider } : {}),\n ...childProps,\n }}\n />\n </Suspense>\n );\n }\n\n const cardProps = {\n title: overrideTitle ?? title,\n ...(Settings\n ? {\n action: (\n <IconButton onClick={() => setSettingsOpen(true)}>\n <SettingsIcon>Settings</SettingsIcon>\n </IconButton>\n ),\n }\n : {}),\n ...(Actions\n ? {\n actions: <Actions />,\n }\n : {}),\n };\n\n const innerContent = (\n <InfoCard {...cardProps}>\n {Settings && (\n <SettingsModal\n open={settingsOpen}\n componentName={title}\n close={() => setSettingsOpen(false)}\n >\n <Settings />\n </SettingsModal>\n )}\n <Content />\n </InfoCard>\n );\n\n return (\n <Suspense fallback={<Progress />}>\n {ContextProvider ? (\n <ContextProvider {...childProps}>\n {innerContent}\n </ContextProvider>\n ) : (\n innerContent\n )}\n </Suspense>\n );\n };\n return CardExtension;\n }),\n },\n });\n}\n","/*\n * Copyright 2021 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 */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'home',\n});\n","/*\n * Copyright 2021 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 */\nimport {\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n} from '@backstage/core-plugin-api';\nimport { createCardExtension } from './extensions';\n\nimport { rootRouteRef } from './routes';\n\nexport const homePlugin = createPlugin({\n id: 'home',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const HomepageCompositionRoot = homePlugin.provide(\n createRoutableExtension({\n name: 'HomepageCompositionRoot',\n component: () =>\n import('./components').then(m => m.HomepageCompositionRoot),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ComponentAccordion = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentAccordion',\n component: {\n lazy: () =>\n import('./componentRenderers').then(m => m.ComponentAccordion),\n },\n }),\n);\nexport const ComponentTabs = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentTabs',\n component: {\n lazy: () => import('./componentRenderers').then(m => m.ComponentTabs),\n },\n }),\n);\nexport const ComponentTab = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentTab',\n component: {\n lazy: () => import('./componentRenderers').then(m => m.ComponentTab),\n },\n }),\n);\n\n/**\n * A component to display a playful greeting for the user.\n *\n * @public\n */\nexport const WelcomeTitle = homePlugin.provide(\n createComponentExtension({\n name: 'WelcomeTitle',\n component: {\n lazy: () =>\n import('./homePageComponents/WelcomeTitle').then(m => m.WelcomeTitle),\n },\n }),\n);\n\nexport const HomePageRandomJoke = homePlugin.provide(\n createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({\n name: 'HomePageRandomJoke',\n title: 'Random Joke',\n components: () => import('./homePageComponents/RandomJoke'),\n }),\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/components/SettingsModal.tsx","../src/components/HeaderWorldClock/HeaderWorldClock.tsx","../src/extensions.tsx","../src/routes.ts","../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2021 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 React from 'react';\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core';\n\nexport const SettingsModal = ({\n open,\n close,\n componentName,\n children,\n}: {\n open: boolean;\n close: Function;\n componentName: string;\n children: JSX.Element;\n}) => {\n return (\n <Dialog open={open} onClose={() => close()}>\n <DialogTitle>Settings - {componentName}</DialogTitle>\n <DialogContent>{children}</DialogContent>\n <DialogActions>\n <Button onClick={() => close()} color=\"primary\" variant=\"contained\">\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","/*\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 React from 'react';\nimport { HeaderLabel } from '@backstage/core-components';\n\nconst timeFormat: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n};\n\ntype TimeObj = {\n time: string;\n label: string;\n};\n\nexport type ClockConfig = {\n label: string;\n timeZone: string;\n};\n\nfunction getTimes(clockConfigs: ClockConfig[]) {\n const d = new Date();\n const lang = window.navigator.language;\n\n const clocks: TimeObj[] = [];\n\n if (!clockConfigs) {\n return clocks;\n }\n\n for (const clockConfig of clockConfigs) {\n let label = clockConfig.label;\n\n const options: Intl.DateTimeFormatOptions = {\n timeZone: clockConfig.timeZone,\n ...timeFormat,\n };\n\n try {\n new Date().toLocaleString(lang, options);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n `The timezone ${options.timeZone} is invalid. Defaulting to GMT`,\n );\n options.timeZone = 'GMT';\n label = 'GMT';\n }\n\n const time = d.toLocaleTimeString(lang, options);\n clocks.push({ time, label });\n }\n\n return clocks;\n}\n\nexport const HeaderWorldClock = ({\n clockConfigs,\n}: {\n clockConfigs: ClockConfig[];\n}) => {\n const defaultTimes: TimeObj[] = [];\n const [clocks, setTimes] = React.useState(defaultTimes);\n\n React.useEffect(() => {\n setTimes(getTimes(clockConfigs));\n\n const intervalId = setInterval(() => {\n setTimes(getTimes(clockConfigs));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [clockConfigs]);\n\n if (clocks.length !== 0) {\n return (\n <>\n {clocks.map(clock => (\n <HeaderLabel\n label={clock.label}\n value={clock.time}\n key={clock.label}\n />\n ))}\n </>\n );\n }\n return null;\n};\n","/*\n * Copyright 2021 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 React, { Suspense } from 'react';\nimport { IconButton } from '@material-ui/core';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport { InfoCard } from '@backstage/core-components';\nimport { SettingsModal } from './components';\nimport { createReactExtension, useApp } from '@backstage/core-plugin-api';\n\nexport type ComponentRenderer = {\n Renderer?: (props: RendererProps) => JSX.Element;\n};\n\ntype ComponentParts = {\n Content: (props?: any) => JSX.Element;\n Actions?: () => JSX.Element;\n Settings?: () => JSX.Element;\n ContextProvider?: (props: any) => JSX.Element;\n};\n\ntype RendererProps = { title: string } & ComponentParts;\n\ntype CardExtensionProps<T> = ComponentRenderer & { title?: string } & T;\n\n/**\n * An extension creator to create card based components for the homepage\n *\n * @public\n */\nexport function createCardExtension<T>({\n title,\n components,\n name,\n}: {\n title: string;\n components: () => Promise<ComponentParts>;\n name?: string;\n}) {\n return createReactExtension({\n name,\n component: {\n lazy: () =>\n components().then(({ Content, Actions, Settings, ContextProvider }) => {\n const CardExtension = (props: CardExtensionProps<T>) => {\n const { Renderer, title: overrideTitle, ...childProps } = props;\n const app = useApp();\n const { Progress } = app.getComponents();\n const [settingsOpen, setSettingsOpen] = React.useState(false);\n\n if (Renderer) {\n return (\n <Suspense fallback={<Progress />}>\n <Renderer\n title={overrideTitle || title}\n {...{\n Content,\n ...(Actions ? { Actions } : {}),\n ...(Settings ? { Settings } : {}),\n ...(ContextProvider ? { ContextProvider } : {}),\n ...childProps,\n }}\n />\n </Suspense>\n );\n }\n\n const cardProps = {\n title: overrideTitle ?? title,\n ...(Settings\n ? {\n action: (\n <IconButton onClick={() => setSettingsOpen(true)}>\n <SettingsIcon>Settings</SettingsIcon>\n </IconButton>\n ),\n }\n : {}),\n ...(Actions\n ? {\n actions: <Actions />,\n }\n : {}),\n };\n\n const innerContent = (\n <InfoCard {...cardProps}>\n {Settings && (\n <SettingsModal\n open={settingsOpen}\n componentName={title}\n close={() => setSettingsOpen(false)}\n >\n <Settings />\n </SettingsModal>\n )}\n <Content {...childProps} />\n </InfoCard>\n );\n\n return (\n <Suspense fallback={<Progress />}>\n {ContextProvider ? (\n <ContextProvider {...childProps}>\n {innerContent}\n </ContextProvider>\n ) : (\n innerContent\n )}\n </Suspense>\n );\n };\n return CardExtension;\n }),\n },\n });\n}\n","/*\n * Copyright 2021 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 */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'home',\n});\n","/*\n * Copyright 2021 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 */\nimport {\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n} from '@backstage/core-plugin-api';\nimport { createCardExtension } from './extensions';\nimport { ToolkitContentProps } from './homePageComponents';\n\nimport { rootRouteRef } from './routes';\n\nexport const homePlugin = createPlugin({\n id: 'home',\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport const HomepageCompositionRoot = homePlugin.provide(\n createRoutableExtension({\n name: 'HomepageCompositionRoot',\n component: () =>\n import('./components').then(m => m.HomepageCompositionRoot),\n mountPoint: rootRouteRef,\n }),\n);\n\nexport const ComponentAccordion = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentAccordion',\n component: {\n lazy: () =>\n import('./componentRenderers').then(m => m.ComponentAccordion),\n },\n }),\n);\nexport const ComponentTabs = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentTabs',\n component: {\n lazy: () => import('./componentRenderers').then(m => m.ComponentTabs),\n },\n }),\n);\nexport const ComponentTab = homePlugin.provide(\n createComponentExtension({\n name: 'ComponentTab',\n component: {\n lazy: () => import('./componentRenderers').then(m => m.ComponentTab),\n },\n }),\n);\n\n/**\n * A component to display a playful greeting for the user.\n *\n * @public\n */\nexport const WelcomeTitle = homePlugin.provide(\n createComponentExtension({\n name: 'WelcomeTitle',\n component: {\n lazy: () =>\n import('./homePageComponents/WelcomeTitle').then(m => m.WelcomeTitle),\n },\n }),\n);\n\n/**\n * A component to display a company logo for the user.\n *\n * @public\n */\nexport const HomePageCompanyLogo = homePlugin.provide(\n createComponentExtension({\n name: 'CompanyLogo',\n component: {\n lazy: () =>\n import('./homePageComponents/CompanyLogo').then(m => m.CompanyLogo),\n },\n }),\n);\n\nexport const HomePageRandomJoke = homePlugin.provide(\n createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({\n name: 'HomePageRandomJoke',\n title: 'Random Joke',\n components: () => import('./homePageComponents/RandomJoke'),\n }),\n);\n\n/**\n * A component to display a list of tools for the user.\n *\n * @public\n */\nexport const HomePageToolkit = homePlugin.provide(\n createCardExtension<ToolkitContentProps>({\n name: 'HomePageToolkit',\n title: 'Toolkit',\n components: () => import('./homePageComponents/Toolkit'),\n }),\n);\n"],"names":[],"mappings":";;;;;;;MAyBa,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,MAMI;AACJ,6CACG,QAAD;AAAA,IAAQ;AAAA,IAAY,SAAS,MAAM;AAAA,yCAChC,aAAD,MAAa,eAAY,oDACxB,eAAD,MAAgB,+CACf,eAAD,0CACG,QAAD;AAAA,IAAQ,SAAS,MAAM;AAAA,IAAS,OAAM;AAAA,IAAU,SAAQ;AAAA,KAAY;AAAA;;ACtB5E,MAAM,aAAyC;AAAA,EAC7C,MAAM;AAAA,EACN,QAAQ;AAAA;AAaV,kBAAkB,cAA6B;AAC7C,QAAM,IAAI,IAAI;AACd,QAAM,OAAO,OAAO,UAAU;AAE9B,QAAM,SAAoB;AAE1B,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA;AAGT,aAAW,eAAe,cAAc;AACtC,QAAI,QAAQ,YAAY;AAExB,UAAM,UAAsC;AAAA,MAC1C,UAAU,YAAY;AAAA,SACnB;AAAA;AAGL,QAAI;AACF,UAAI,OAAO,eAAe,MAAM;AAAA,aACzB,GAAP;AAEA,cAAQ,KACN,gBAAgB,QAAQ;AAE1B,cAAQ,WAAW;AACnB,cAAQ;AAAA;AAGV,UAAM,OAAO,EAAE,mBAAmB,MAAM;AACxC,WAAO,KAAK,EAAE,MAAM;AAAA;AAGtB,SAAO;AAAA;MAGI,mBAAmB,CAAC;AAAA,EAC/B;AAAA,MAGI;AACJ,QAAM,eAA0B;AAChC,QAAM,CAAC,QAAQ,YAAY,MAAM,SAAS;AAE1C,QAAM,UAAU,MAAM;AACpB,aAAS,SAAS;AAElB,UAAM,aAAa,YAAY,MAAM;AACnC,eAAS,SAAS;AAAA,OACjB;AAEH,WAAO,MAAM;AACX,oBAAc;AAAA;AAAA,KAEf,CAAC;AAEJ,MAAI,OAAO,WAAW,GAAG;AACvB,qEAEK,OAAO,IAAI,+CACT,aAAD;AAAA,MACE,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,KAAK,MAAM;AAAA;AAAA;AAMrB,SAAO;AAAA;;6BC5D8B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,GAKC;AACD,SAAO,qBAAqB;AAAA,IAC1B;AAAA,IACA,WAAW;AAAA,MACT,MAAM,MACJ,aAAa,KAAK,CAAC,EAAE,SAAS,SAAS,UAAU,sBAAsB;AACrE,cAAM,gBAAgB,CAAC,UAAiC;AACtD,gBAAM,EAAE,UAAU,OAAO,kBAAkB,eAAe;AAC1D,gBAAM,MAAM;AACZ,gBAAM,EAAE,aAAa,IAAI;AACzB,gBAAM,CAAC,cAAc,mBAAmB,MAAM,SAAS;AAEvD,cAAI,UAAU;AACZ,uDACG,UAAD;AAAA,cAAU,8CAAW,UAAD;AAAA,mDACjB,UAAD;AAAA,cACE,OAAO,iBAAiB;AAAA,iBACpB;AAAA,gBACF;AAAA,mBACI,UAAU,EAAE,YAAY;AAAA,mBACxB,WAAW,EAAE,aAAa;AAAA,mBAC1B,kBAAkB,EAAE,oBAAoB;AAAA,mBACzC;AAAA;AAAA;AAAA;AAOb,gBAAM,YAAY;AAAA,YAChB,OAAO,wCAAiB;AAAA,eACpB,WACA;AAAA,cACE,4CACG,YAAD;AAAA,gBAAY,SAAS,MAAM,gBAAgB;AAAA,qDACxC,cAAD,MAAc;AAAA,gBAIpB;AAAA,eACA,UACA;AAAA,cACE,6CAAU,SAAD;AAAA,gBAEX;AAAA;AAGN,gBAAM,mDACH,UAAD;AAAA,eAAc;AAAA,aACX,gDACE,eAAD;AAAA,YACE,MAAM;AAAA,YACN,eAAe;AAAA,YACf,OAAO,MAAM,gBAAgB;AAAA,iDAE5B,UAAD,4CAGH,SAAD;AAAA,eAAa;AAAA;AAIjB,qDACG,UAAD;AAAA,YAAU,8CAAW,UAAD;AAAA,aACjB,sDACE,iBAAD;AAAA,eAAqB;AAAA,aAClB,gBAGH;AAAA;AAKR,eAAO;AAAA;AAAA;AAAA;AAAA;;MC5GJ,eAAe,eAAe;AAAA,EACzC,IAAI;AAAA;;MCOO,aAAa,aAAa;AAAA,EACrC,IAAI;AAAA,EACJ,QAAQ;AAAA,IACN,MAAM;AAAA;AAAA;MAIG,0BAA0B,WAAW,QAChD,wBAAwB;AAAA,EACtB,MAAM;AAAA,EACN,WAAW,MACT,OAAO,+BAAgB,KAAK,OAAK,EAAE;AAAA,EACrC,YAAY;AAAA;MAIH,qBAAqB,WAAW,QAC3C,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,+BAAwB,KAAK,OAAK,EAAE;AAAA;AAAA;MAItC,gBAAgB,WAAW,QACtC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,+BAAwB,KAAK,OAAK,EAAE;AAAA;AAAA;MAIhD,eAAe,WAAW,QACrC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MAAM,OAAO,+BAAwB,KAAK,OAAK,EAAE;AAAA;AAAA;MAUhD,eAAe,WAAW,QACrC,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,+BAAqC,KAAK,OAAK,EAAE;AAAA;AAAA;MAUnD,sBAAsB,WAAW,QAC5C,yBAAyB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,IACT,MAAM,MACJ,OAAO,+BAAoC,KAAK,OAAK,EAAE;AAAA;AAAA;MAKlD,qBAAqB,WAAW,QAC3C,oBAAiE;AAAA,EAC/D,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY,MAAM,OAAO;AAAA;MAShB,kBAAkB,WAAW,QACxC,oBAAyC;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY,MAAM,OAAO;AAAA;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
3
  "description": "A Backstage plugin that helps you build a home page",
4
- "version": "0.4.6",
4
+ "version": "0.4.10",
5
5
  "main": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -21,24 +21,26 @@
21
21
  "clean": "backstage-cli clean"
22
22
  },
23
23
  "dependencies": {
24
- "@backstage/core-components": "^0.7.4",
25
- "@backstage/core-plugin-api": "^0.2.0",
26
- "@backstage/theme": "^0.2.13",
24
+ "@backstage/core-components": "^0.8.4",
25
+ "@backstage/core-plugin-api": "^0.5.0",
26
+ "@backstage/plugin-search": "^0.5.5",
27
+ "@backstage/theme": "^0.2.14",
27
28
  "@material-ui/core": "^4.12.2",
28
29
  "@material-ui/icons": "^4.9.1",
29
30
  "@material-ui/lab": "4.0.0-alpha.57",
30
- "@types/react": "*",
31
31
  "lodash": "^4.17.21",
32
- "react": "^16.13.1",
33
- "react-dom": "^16.13.1",
34
32
  "react-router": "6.0.0-beta.0",
35
33
  "react-use": "^17.2.4"
36
34
  },
35
+ "peerDependencies": {
36
+ "@types/react": "^16.13.1 || ^17.0.0",
37
+ "react": "^16.13.1 || ^17.0.0"
38
+ },
37
39
  "devDependencies": {
38
- "@backstage/cli": "^0.9.0",
39
- "@backstage/core-app-api": "^0.1.21",
40
- "@backstage/dev-utils": "^0.2.13",
41
- "@backstage/test-utils": "^0.1.22",
40
+ "@backstage/cli": "^0.11.0",
41
+ "@backstage/core-app-api": "^0.4.0",
42
+ "@backstage/dev-utils": "^0.2.17",
43
+ "@backstage/test-utils": "^0.2.2",
42
44
  "@testing-library/jest-dom": "^5.10.1",
43
45
  "@testing-library/react": "^11.2.5",
44
46
  "@testing-library/user-event": "^13.1.8",
@@ -50,5 +52,5 @@
50
52
  "files": [
51
53
  "dist"
52
54
  ],
53
- "gitHead": "ddfdcd2b44dc9848cf550cea5346d5f9916a36d9"
55
+ "gitHead": "da66c61bdd63cdb3f0f0cd2e26dc9e6454d93c7b"
54
56
  }