@backstage/plugin-home 0.7.4 → 0.7.5-next.1

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/alpha/package.json +1 -1
  3. package/dist/alpha.esm.js +9 -12
  4. package/dist/alpha.esm.js.map +1 -1
  5. package/dist/api/VisitsStorageApi.esm.js +13 -23
  6. package/dist/api/VisitsStorageApi.esm.js.map +1 -1
  7. package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js +14 -19
  8. package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js.map +1 -1
  9. package/dist/components/HomepageCompositionRoot.esm.js +1 -2
  10. package/dist/components/HomepageCompositionRoot.esm.js.map +1 -1
  11. package/dist/components/StarredEntityListItem/StarredEntityListItem.esm.js +1 -2
  12. package/dist/components/StarredEntityListItem/StarredEntityListItem.esm.js.map +1 -1
  13. package/dist/components/VisitList/ItemCategory.esm.js +2 -4
  14. package/dist/components/VisitList/ItemCategory.esm.js.map +1 -1
  15. package/dist/components/VisitList/ItemDetail.esm.js +1 -2
  16. package/dist/components/VisitList/ItemDetail.esm.js.map +1 -1
  17. package/dist/components/VisitListener.esm.js +5 -5
  18. package/dist/components/VisitListener.esm.js.map +1 -1
  19. package/dist/homePageComponents/FeaturedDocsCard/Content.esm.js +1 -1
  20. package/dist/homePageComponents/FeaturedDocsCard/Content.esm.js.map +1 -1
  21. package/dist/homePageComponents/HeaderWorldClock/HeaderWorldClock.esm.js +1 -1
  22. package/dist/homePageComponents/HeaderWorldClock/HeaderWorldClock.esm.js.map +1 -1
  23. package/dist/homePageComponents/StarredEntities/Content.esm.js +9 -16
  24. package/dist/homePageComponents/StarredEntities/Content.esm.js.map +1 -1
  25. package/dist/homePageComponents/Toolkit/Content.esm.js +1 -2
  26. package/dist/homePageComponents/Toolkit/Content.esm.js.map +1 -1
  27. package/dist/homePageComponents/VisitedByType/Content.esm.js +4 -5
  28. package/dist/homePageComponents/VisitedByType/Content.esm.js.map +1 -1
  29. package/dist/homePageComponents/WelcomeTitle/WelcomeTitle.esm.js +1 -1
  30. package/dist/homePageComponents/WelcomeTitle/WelcomeTitle.esm.js.map +1 -1
  31. package/package.json +12 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @backstage/plugin-home
2
2
 
3
+ ## 0.7.5-next.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/core-components@0.14.8-next.1
9
+ - @backstage/core-compat-api@0.2.6-next.1
10
+ - @backstage/core-plugin-api@1.9.3-next.0
11
+ - @backstage/core-app-api@1.12.6-next.0
12
+ - @backstage/frontend-plugin-api@0.6.6-next.1
13
+ - @backstage/plugin-catalog-react@1.12.1-next.1
14
+ - @backstage/plugin-home-react@0.1.14-next.1
15
+ - @backstage/catalog-client@1.6.5
16
+ - @backstage/catalog-model@1.5.0
17
+ - @backstage/config@1.2.0
18
+ - @backstage/theme@0.5.6-next.0
19
+
20
+ ## 0.7.5-next.0
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+ - @backstage/theme@0.5.6-next.0
26
+ - @backstage/core-components@0.14.8-next.0
27
+ - @backstage/catalog-client@1.6.5
28
+ - @backstage/catalog-model@1.5.0
29
+ - @backstage/config@1.2.0
30
+ - @backstage/core-app-api@1.12.5
31
+ - @backstage/core-compat-api@0.2.6-next.0
32
+ - @backstage/core-plugin-api@1.9.2
33
+ - @backstage/frontend-plugin-api@0.6.6-next.0
34
+ - @backstage/plugin-catalog-react@1.12.1-next.0
35
+ - @backstage/plugin-home-react@0.1.14-next.0
36
+
3
37
  ## 0.7.4
4
38
 
5
39
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
- "version": "0.7.4",
3
+ "version": "0.7.5-next.1",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
package/dist/alpha.esm.js CHANGED
@@ -20,18 +20,15 @@ const homePage = createPageExtension({
20
20
  )
21
21
  },
22
22
  loader: ({ inputs }) => import('./components/index.esm.js').then(
23
- (m) => {
24
- var _a, _b;
25
- return compatWrapper(
26
- /* @__PURE__ */ React.createElement(
27
- m.HomepageCompositionRoot,
28
- {
29
- children: (_a = inputs.props) == null ? void 0 : _a.output.children,
30
- title: (_b = inputs.props) == null ? void 0 : _b.output.title
31
- }
32
- )
33
- );
34
- }
23
+ (m) => compatWrapper(
24
+ /* @__PURE__ */ React.createElement(
25
+ m.HomepageCompositionRoot,
26
+ {
27
+ children: inputs.props?.output.children,
28
+ title: inputs.props?.output.title
29
+ }
30
+ )
31
+ )
35
32
  )
36
33
  });
37
34
  var alpha = createPlugin({
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"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 React from 'react';\n\nimport {\n coreExtensionData,\n createExtensionDataRef,\n createExtensionInput,\n createPageExtension,\n createPlugin,\n createRouteRef,\n} from '@backstage/frontend-plugin-api';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst rootRouteRef = createRouteRef();\n\n/**\n * @alpha\n */\nexport const titleExtensionDataRef = createExtensionDataRef<string>('title');\n\nconst homePage = createPageExtension({\n defaultPath: '/home',\n routeRef: rootRouteRef,\n inputs: {\n props: createExtensionInput(\n {\n children: coreExtensionData.reactElement.optional(),\n title: titleExtensionDataRef.optional(),\n },\n\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n loader: ({ inputs }) =>\n import('./components/').then(m =>\n compatWrapper(\n <m.HomepageCompositionRoot\n children={inputs.props?.output.children}\n title={inputs.props?.output.title}\n />,\n ),\n ),\n});\n\n/**\n * @alpha\n */\nexport default createPlugin({\n id: 'home',\n extensions: [homePage],\n});\n"],"names":[],"mappings":";;;;AA4BA,MAAM,eAAe,cAAe,EAAA,CAAA;AAKvB,MAAA,qBAAA,GAAwB,uBAA+B,OAAO,EAAA;AAE3E,MAAM,WAAW,mBAAoB,CAAA;AAAA,EACnC,WAAa,EAAA,OAAA;AAAA,EACb,QAAU,EAAA,YAAA;AAAA,EACV,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA,oBAAA;AAAA,MACL;AAAA,QACE,QAAA,EAAU,iBAAkB,CAAA,YAAA,CAAa,QAAS,EAAA;AAAA,QAClD,KAAA,EAAO,sBAAsB,QAAS,EAAA;AAAA,OACxC;AAAA,MAEA;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,QAAU,EAAA,IAAA;AAAA,OACZ;AAAA,KACF;AAAA,GACF;AAAA,EACA,QAAQ,CAAC,EAAE,QACT,KAAA,OAAO,2BAAe,CAAE,CAAA,IAAA;AAAA,IAAK,CAAE,CAAA,KAAA;AApDnC,MAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAqDM,MAAA,OAAA,aAAA;AAAA,wBACE,KAAA,CAAA,aAAA;AAAA,UAAC,CAAE,CAAA,uBAAA;AAAA,UAAF;AAAA,YACC,QAAU,EAAA,CAAA,EAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAc,MAAO,CAAA,QAAA;AAAA,YAC/B,KAAO,EAAA,CAAA,EAAA,GAAA,MAAA,CAAO,KAAP,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAc,MAAO,CAAA,KAAA;AAAA,WAAA;AAAA,SAC9B;AAAA,OACF,CAAA;AAAA,KAAA;AAAA,GACF;AACJ,CAAC,CAAA,CAAA;AAKD,YAAe,YAAa,CAAA;AAAA,EAC1B,EAAI,EAAA,MAAA;AAAA,EACJ,UAAA,EAAY,CAAC,QAAQ,CAAA;AACvB,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"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 React from 'react';\n\nimport {\n coreExtensionData,\n createExtensionDataRef,\n createExtensionInput,\n createPageExtension,\n createPlugin,\n createRouteRef,\n} from '@backstage/frontend-plugin-api';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst rootRouteRef = createRouteRef();\n\n/**\n * @alpha\n */\nexport const titleExtensionDataRef = createExtensionDataRef<string>('title');\n\nconst homePage = createPageExtension({\n defaultPath: '/home',\n routeRef: rootRouteRef,\n inputs: {\n props: createExtensionInput(\n {\n children: coreExtensionData.reactElement.optional(),\n title: titleExtensionDataRef.optional(),\n },\n\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n loader: ({ inputs }) =>\n import('./components/').then(m =>\n compatWrapper(\n <m.HomepageCompositionRoot\n children={inputs.props?.output.children}\n title={inputs.props?.output.title}\n />,\n ),\n ),\n});\n\n/**\n * @alpha\n */\nexport default createPlugin({\n id: 'home',\n extensions: [homePage],\n});\n"],"names":[],"mappings":";;;;AA4BA,MAAM,eAAe,cAAe,EAAA,CAAA;AAKvB,MAAA,qBAAA,GAAwB,uBAA+B,OAAO,EAAA;AAE3E,MAAM,WAAW,mBAAoB,CAAA;AAAA,EACnC,WAAa,EAAA,OAAA;AAAA,EACb,QAAU,EAAA,YAAA;AAAA,EACV,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA,oBAAA;AAAA,MACL;AAAA,QACE,QAAA,EAAU,iBAAkB,CAAA,YAAA,CAAa,QAAS,EAAA;AAAA,QAClD,KAAA,EAAO,sBAAsB,QAAS,EAAA;AAAA,OACxC;AAAA,MAEA;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,QAAU,EAAA,IAAA;AAAA,OACZ;AAAA,KACF;AAAA,GACF;AAAA,EACA,QAAQ,CAAC,EAAE,QACT,KAAA,OAAO,2BAAe,CAAE,CAAA,IAAA;AAAA,IAAK,CAC3B,CAAA,KAAA,aAAA;AAAA,sBACE,KAAA,CAAA,aAAA;AAAA,QAAC,CAAE,CAAA,uBAAA;AAAA,QAAF;AAAA,UACC,QAAA,EAAU,MAAO,CAAA,KAAA,EAAO,MAAO,CAAA,QAAA;AAAA,UAC/B,KAAA,EAAO,MAAO,CAAA,KAAA,EAAO,MAAO,CAAA,KAAA;AAAA,SAAA;AAAA,OAC9B;AAAA,KACF;AAAA,GACF;AACJ,CAAC,CAAA,CAAA;AAKD,YAAe,YAAa,CAAA;AAAA,EAC1B,EAAI,EAAA,MAAA;AAAA,EACJ,UAAA,EAAY,CAAC,QAAQ,CAAA;AACvB,CAAC,CAAA;;;;"}
@@ -1,37 +1,29 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
1
  class VisitsStorageApi {
2
+ limit;
3
+ storageApi;
4
+ storageKeyPrefix = "@backstage/plugin-home:visits";
5
+ identityApi;
6
+ static create(options) {
7
+ return new VisitsStorageApi(options);
8
+ }
8
9
  constructor(options) {
9
- __publicField(this, "limit");
10
- __publicField(this, "storageApi");
11
- __publicField(this, "storageKeyPrefix", "@backstage/plugin-home:visits");
12
- __publicField(this, "identityApi");
13
- var _a;
14
- this.limit = Math.abs((_a = options.limit) != null ? _a : 100);
10
+ this.limit = Math.abs(options.limit ?? 100);
15
11
  this.storageApi = options.storageApi;
16
12
  this.identityApi = options.identityApi;
17
13
  }
18
- static create(options) {
19
- return new VisitsStorageApi(options);
20
- }
21
14
  /**
22
15
  * Returns a list of visits through the visitsApi
23
16
  */
24
17
  async list(queryParams) {
25
- var _a, _b;
26
18
  let visits = [...await this.retrieveAll()];
27
- ((_a = queryParams == null ? void 0 : queryParams.orderBy) != null ? _a : []).reverse().forEach((order) => {
19
+ (queryParams?.orderBy ?? []).reverse().forEach((order) => {
28
20
  if (order.direction === "asc") {
29
21
  visits.sort((a, b) => this.compare(order, a, b));
30
22
  } else {
31
23
  visits.sort((a, b) => this.compare(order, b, a));
32
24
  }
33
25
  });
34
- ((_b = queryParams == null ? void 0 : queryParams.filterBy) != null ? _b : []).reverse().forEach((filter) => {
26
+ (queryParams?.filterBy ?? []).reverse().forEach((filter) => {
35
27
  visits = visits.filter((visit) => {
36
28
  const field = visit[filter.field];
37
29
  if (filter.operator === ">")
@@ -81,17 +73,15 @@ class VisitsStorageApi {
81
73
  return this.storageApi.set(storageKey, visits);
82
74
  }
83
75
  async retrieveAll() {
84
- var _a;
85
76
  const storageKey = await this.getStorageKey();
86
77
  const snapshot = this.storageApi.snapshot(storageKey);
87
- if ((snapshot == null ? void 0 : snapshot.presence) !== "unknown") {
88
- return (_a = snapshot == null ? void 0 : snapshot.value) != null ? _a : [];
78
+ if (snapshot?.presence !== "unknown") {
79
+ return snapshot?.value ?? [];
89
80
  }
90
81
  return new Promise((resolve, reject) => {
91
82
  const subscription = this.storageApi.observe$(storageKey).subscribe({
92
83
  next: (next) => {
93
- var _a2;
94
- const visits = (_a2 = next.value) != null ? _a2 : [];
84
+ const visits = next.value ?? [];
95
85
  subscription.unsubscribe();
96
86
  resolve(visits);
97
87
  },
@@ -1 +1 @@
1
- {"version":3,"file":"VisitsStorageApi.esm.js","sources":["../../src/api/VisitsStorageApi.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 */\nimport { IdentityApi, StorageApi } from '@backstage/core-plugin-api';\nimport {\n Visit,\n VisitsApi,\n VisitsApiQueryParams,\n VisitsApiSaveParams,\n} from './VisitsApi';\n\n/** @public */\nexport type VisitsStorageApiOptions = {\n limit?: number;\n storageApi: StorageApi;\n identityApi: IdentityApi;\n};\n\ntype ArrayElement<A> = A extends readonly (infer T)[] ? T : never;\n\n/**\n * @public\n * This is an implementation of VisitsApi that relies on a StorageApi.\n * Beware that filtering and ordering are done in memory therefore it is\n * prudent to keep limit to a reasonable size.\n */\nexport class VisitsStorageApi implements VisitsApi {\n private readonly limit: number;\n private readonly storageApi: StorageApi;\n private readonly storageKeyPrefix = '@backstage/plugin-home:visits';\n private readonly identityApi: IdentityApi;\n\n static create(options: VisitsStorageApiOptions) {\n return new VisitsStorageApi(options);\n }\n\n private constructor(options: VisitsStorageApiOptions) {\n this.limit = Math.abs(options.limit ?? 100);\n this.storageApi = options.storageApi;\n this.identityApi = options.identityApi;\n }\n\n /**\n * Returns a list of visits through the visitsApi\n */\n async list(queryParams?: VisitsApiQueryParams): Promise<Visit[]> {\n let visits = [...(await this.retrieveAll())];\n\n // reversing order to guarantee orderBy priority\n (queryParams?.orderBy ?? []).reverse().forEach(order => {\n if (order.direction === 'asc') {\n visits.sort((a, b) => this.compare(order, a, b));\n } else {\n visits.sort((a, b) => this.compare(order, b, a));\n }\n });\n\n // reversing order to guarantee filterBy priority\n (queryParams?.filterBy ?? []).reverse().forEach(filter => {\n visits = visits.filter(visit => {\n const field = visit[filter.field] as number | string;\n if (filter.operator === '>') return field > filter.value;\n if (filter.operator === '>=') return field >= filter.value;\n if (filter.operator === '<') return field < filter.value;\n if (filter.operator === '<=') return field <= filter.value;\n if (filter.operator === '==') return field === filter.value;\n if (filter.operator === '!=') return field !== filter.value;\n if (filter.operator === 'contains')\n return `${field}`.includes(`${filter.value}`);\n return false;\n });\n });\n\n return visits;\n }\n\n /**\n * Saves a visit through the visitsApi\n */\n async save(saveParams: VisitsApiSaveParams): Promise<Visit> {\n const visits: Visit[] = [...(await this.retrieveAll())];\n\n const visit: Visit = {\n ...saveParams.visit,\n id: window.crypto.randomUUID(),\n hits: 1,\n timestamp: Date.now(),\n };\n\n // Updates entry if pathname is already registered\n const visitIndex = visits.findIndex(e => e.pathname === visit.pathname);\n if (visitIndex >= 0) {\n visit.id = visits[visitIndex].id;\n visit.hits = visits[visitIndex].hits + 1;\n visits[visitIndex] = visit;\n } else {\n visits.push(visit);\n }\n\n // Sort by time, most recent first\n visits.sort((a, b) => b.timestamp - a.timestamp);\n // Keep the most recent items up to limit\n await this.persistAll(visits.splice(0, this.limit));\n return visit;\n }\n\n private async persistAll(visits: Array<Visit>) {\n const storageKey = await this.getStorageKey();\n return this.storageApi.set<Array<Visit>>(storageKey, visits);\n }\n\n private async retrieveAll(): Promise<Array<Visit>> {\n const storageKey = await this.getStorageKey();\n // Handles for case when snapshot is and is not referenced per storaged type used\n const snapshot = this.storageApi.snapshot<Array<Visit>>(storageKey);\n if (snapshot?.presence !== 'unknown') {\n return snapshot?.value ?? [];\n }\n\n return new Promise((resolve, reject) => {\n const subscription = this.storageApi\n .observe$<Visit[]>(storageKey)\n .subscribe({\n next: next => {\n const visits = next.value ?? [];\n subscription.unsubscribe();\n resolve(visits);\n },\n error: err => {\n subscription.unsubscribe();\n reject(err);\n },\n });\n });\n }\n\n private async getStorageKey(): Promise<string> {\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n const storageKey = `${this.storageKeyPrefix}:${userEntityRef}`;\n return storageKey;\n }\n\n // This assumes Visit fields are either numbers or strings\n private compare(\n order: ArrayElement<VisitsApiQueryParams['orderBy']>,\n a: Visit,\n b: Visit,\n ): number {\n const isNumber = typeof a[order.field] === 'number';\n return isNumber\n ? (a[order.field] as number) - (b[order.field] as number)\n : `${a[order.field]}`.localeCompare(`${b[order.field]}`);\n }\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"VisitsStorageApi.esm.js","sources":["../../src/api/VisitsStorageApi.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 */\nimport { IdentityApi, StorageApi } from '@backstage/core-plugin-api';\nimport {\n Visit,\n VisitsApi,\n VisitsApiQueryParams,\n VisitsApiSaveParams,\n} from './VisitsApi';\n\n/** @public */\nexport type VisitsStorageApiOptions = {\n limit?: number;\n storageApi: StorageApi;\n identityApi: IdentityApi;\n};\n\ntype ArrayElement<A> = A extends readonly (infer T)[] ? T : never;\n\n/**\n * @public\n * This is an implementation of VisitsApi that relies on a StorageApi.\n * Beware that filtering and ordering are done in memory therefore it is\n * prudent to keep limit to a reasonable size.\n */\nexport class VisitsStorageApi implements VisitsApi {\n private readonly limit: number;\n private readonly storageApi: StorageApi;\n private readonly storageKeyPrefix = '@backstage/plugin-home:visits';\n private readonly identityApi: IdentityApi;\n\n static create(options: VisitsStorageApiOptions) {\n return new VisitsStorageApi(options);\n }\n\n private constructor(options: VisitsStorageApiOptions) {\n this.limit = Math.abs(options.limit ?? 100);\n this.storageApi = options.storageApi;\n this.identityApi = options.identityApi;\n }\n\n /**\n * Returns a list of visits through the visitsApi\n */\n async list(queryParams?: VisitsApiQueryParams): Promise<Visit[]> {\n let visits = [...(await this.retrieveAll())];\n\n // reversing order to guarantee orderBy priority\n (queryParams?.orderBy ?? []).reverse().forEach(order => {\n if (order.direction === 'asc') {\n visits.sort((a, b) => this.compare(order, a, b));\n } else {\n visits.sort((a, b) => this.compare(order, b, a));\n }\n });\n\n // reversing order to guarantee filterBy priority\n (queryParams?.filterBy ?? []).reverse().forEach(filter => {\n visits = visits.filter(visit => {\n const field = visit[filter.field] as number | string;\n if (filter.operator === '>') return field > filter.value;\n if (filter.operator === '>=') return field >= filter.value;\n if (filter.operator === '<') return field < filter.value;\n if (filter.operator === '<=') return field <= filter.value;\n if (filter.operator === '==') return field === filter.value;\n if (filter.operator === '!=') return field !== filter.value;\n if (filter.operator === 'contains')\n return `${field}`.includes(`${filter.value}`);\n return false;\n });\n });\n\n return visits;\n }\n\n /**\n * Saves a visit through the visitsApi\n */\n async save(saveParams: VisitsApiSaveParams): Promise<Visit> {\n const visits: Visit[] = [...(await this.retrieveAll())];\n\n const visit: Visit = {\n ...saveParams.visit,\n id: window.crypto.randomUUID(),\n hits: 1,\n timestamp: Date.now(),\n };\n\n // Updates entry if pathname is already registered\n const visitIndex = visits.findIndex(e => e.pathname === visit.pathname);\n if (visitIndex >= 0) {\n visit.id = visits[visitIndex].id;\n visit.hits = visits[visitIndex].hits + 1;\n visits[visitIndex] = visit;\n } else {\n visits.push(visit);\n }\n\n // Sort by time, most recent first\n visits.sort((a, b) => b.timestamp - a.timestamp);\n // Keep the most recent items up to limit\n await this.persistAll(visits.splice(0, this.limit));\n return visit;\n }\n\n private async persistAll(visits: Array<Visit>) {\n const storageKey = await this.getStorageKey();\n return this.storageApi.set<Array<Visit>>(storageKey, visits);\n }\n\n private async retrieveAll(): Promise<Array<Visit>> {\n const storageKey = await this.getStorageKey();\n // Handles for case when snapshot is and is not referenced per storaged type used\n const snapshot = this.storageApi.snapshot<Array<Visit>>(storageKey);\n if (snapshot?.presence !== 'unknown') {\n return snapshot?.value ?? [];\n }\n\n return new Promise((resolve, reject) => {\n const subscription = this.storageApi\n .observe$<Visit[]>(storageKey)\n .subscribe({\n next: next => {\n const visits = next.value ?? [];\n subscription.unsubscribe();\n resolve(visits);\n },\n error: err => {\n subscription.unsubscribe();\n reject(err);\n },\n });\n });\n }\n\n private async getStorageKey(): Promise<string> {\n const { userEntityRef } = await this.identityApi.getBackstageIdentity();\n const storageKey = `${this.storageKeyPrefix}:${userEntityRef}`;\n return storageKey;\n }\n\n // This assumes Visit fields are either numbers or strings\n private compare(\n order: ArrayElement<VisitsApiQueryParams['orderBy']>,\n a: Visit,\n b: Visit,\n ): number {\n const isNumber = typeof a[order.field] === 'number';\n return isNumber\n ? (a[order.field] as number) - (b[order.field] as number)\n : `${a[order.field]}`.localeCompare(`${b[order.field]}`);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -80,7 +80,6 @@ function useHomeStorage(defaultWidgets) {
80
80
  }
81
81
  const convertConfigToDefaultWidgets = (config, availableWidgets) => {
82
82
  const ret = config.map((conf, i) => {
83
- var _a, _b;
84
83
  const c = LayoutConfigurationSchema.parse(conf);
85
84
  const name = React.isValidElement(c.component) ? getComponentData(c.component, "core.extensionName") : c.component;
86
85
  if (!name) {
@@ -97,8 +96,8 @@ const convertConfigToDefaultWidgets = (config, availableWidgets) => {
97
96
  i: widgetId,
98
97
  x: c.x,
99
98
  y: c.y,
100
- w: Math.min((_a = widget.maxWidth) != null ? _a : Number.MAX_VALUE, c.width),
101
- h: Math.min((_b = widget.maxHeight) != null ? _b : Number.MAX_VALUE, c.height),
99
+ w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, c.width),
100
+ h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, c.height),
102
101
  minW: widget.minWidth,
103
102
  maxW: widget.maxWidth,
104
103
  minH: widget.minHeight,
@@ -118,7 +117,6 @@ const availableWidgetsFilter = (elements) => {
118
117
  return elements.selectByComponentData({
119
118
  key: "core.extensionName"
120
119
  }).getElements().flatMap((elem) => {
121
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
122
120
  const config = getComponentData(elem, "home.widget.config");
123
121
  return [
124
122
  WidgetSchema.parse({
@@ -126,20 +124,19 @@ const availableWidgetsFilter = (elements) => {
126
124
  name: getComponentData(elem, "core.extensionName"),
127
125
  title: getComponentData(elem, "title"),
128
126
  description: getComponentData(elem, "description"),
129
- settingsSchema: (_a = config == null ? void 0 : config.settings) == null ? void 0 : _a.schema,
130
- uiSchema: (_b = config == null ? void 0 : config.settings) == null ? void 0 : _b.uiSchema,
131
- width: (_d = (_c = config == null ? void 0 : config.layout) == null ? void 0 : _c.width) == null ? void 0 : _d.defaultColumns,
132
- minWidth: (_f = (_e = config == null ? void 0 : config.layout) == null ? void 0 : _e.width) == null ? void 0 : _f.minColumns,
133
- maxWidth: (_h = (_g = config == null ? void 0 : config.layout) == null ? void 0 : _g.width) == null ? void 0 : _h.maxColumns,
134
- height: (_j = (_i = config == null ? void 0 : config.layout) == null ? void 0 : _i.height) == null ? void 0 : _j.defaultRows,
135
- minHeight: (_l = (_k = config == null ? void 0 : config.layout) == null ? void 0 : _k.height) == null ? void 0 : _l.minRows,
136
- maxHeight: (_n = (_m = config == null ? void 0 : config.layout) == null ? void 0 : _m.height) == null ? void 0 : _n.maxRows
127
+ settingsSchema: config?.settings?.schema,
128
+ uiSchema: config?.settings?.uiSchema,
129
+ width: config?.layout?.width?.defaultColumns,
130
+ minWidth: config?.layout?.width?.minColumns,
131
+ maxWidth: config?.layout?.width?.maxColumns,
132
+ height: config?.layout?.height?.defaultRows,
133
+ minHeight: config?.layout?.height?.minRows,
134
+ maxHeight: config?.layout?.height?.maxRows
137
135
  })
138
136
  ];
139
137
  });
140
138
  };
141
139
  const CustomHomepageGrid = (props) => {
142
- var _a;
143
140
  const styles = useStyles();
144
141
  const theme = useTheme();
145
142
  const availableWidgets = useElementFilter(
@@ -161,7 +158,6 @@ const CustomHomepageGrid = (props) => {
161
158
  return key.split("__")[0];
162
159
  };
163
160
  const handleAdd = (widget) => {
164
- var _a2, _b, _c, _d;
165
161
  const widgetId = `${widget.name}__${widgets.length + 1}${Math.random().toString(36).slice(2)}`;
166
162
  setWidgets([
167
163
  ...widgets,
@@ -171,8 +167,8 @@ const CustomHomepageGrid = (props) => {
171
167
  i: widgetId,
172
168
  x: 0,
173
169
  y: Math.max(...widgets.map((w) => w.layout.y + w.layout.h)) + 1,
174
- w: Math.min((_a2 = widget.maxWidth) != null ? _a2 : Number.MAX_VALUE, (_b = widget.width) != null ? _b : 12),
175
- h: Math.min((_c = widget.maxHeight) != null ? _c : Number.MAX_VALUE, (_d = widget.height) != null ? _d : 4),
170
+ w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, widget.width ?? 12),
171
+ h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, widget.height ?? 4),
176
172
  minW: widget.minWidth,
177
173
  maxW: widget.maxWidth,
178
174
  minH: widget.minHeight,
@@ -276,12 +272,11 @@ const CustomHomepageGrid = (props) => {
276
272
  margin: props.containerMargin,
277
273
  breakpoints: props.breakpoints ? props.breakpoints : theme.breakpoints.values,
278
274
  cols: props.cols ? props.cols : { xl: 12, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
279
- rowHeight: (_a = props.rowHeight) != null ? _a : 60,
275
+ rowHeight: props.rowHeight ?? 60,
280
276
  onLayoutChange: handleLayoutChange,
281
277
  layouts: { xl: widgets.map((w) => w.layout) }
282
278
  },
283
279
  widgets.map((w) => {
284
- var _a2;
285
280
  const l = w.layout;
286
281
  const widgetName = getWidgetNameFromKey(l.i);
287
282
  const widget = getWidgetByName(widgetName);
@@ -290,7 +285,7 @@ const CustomHomepageGrid = (props) => {
290
285
  }
291
286
  const widgetProps = {
292
287
  ...widget.component.props,
293
- ...(_a2 = w.settings) != null ? _a2 : {}
288
+ ...w.settings ?? {}
294
289
  };
295
290
  return /* @__PURE__ */ React.createElement(
296
291
  "div",
@@ -1 +1 @@
1
- {"version":3,"file":"CustomHomepageGrid.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageGrid.tsx"],"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 React, { useCallback, useMemo } from 'react';\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';\nimport {\n ElementCollection,\n getComponentData,\n storageApiRef,\n useApi,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport 'react-grid-layout/css/styles.css';\nimport 'react-resizable/css/styles.css';\nimport Dialog from '@material-ui/core/Dialog';\nimport {\n createStyles,\n makeStyles,\n Theme,\n useTheme,\n} from '@material-ui/core/styles';\nimport { compact } from 'lodash';\nimport useObservable from 'react-use/esm/useObservable';\nimport { ContentHeader, ErrorBoundary } from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { WidgetSettingsOverlay } from './WidgetSettingsOverlay';\nimport { AddWidgetDialog } from './AddWidgetDialog';\nimport { CustomHomepageButtons } from './CustomHomepageButtons';\nimport {\n CustomHomepageGridProps,\n CustomHomepageGridStateV1,\n CustomHomepageGridStateV1Schema,\n GridWidget,\n LayoutConfiguration,\n LayoutConfigurationSchema,\n Widget,\n WidgetSchema,\n} from './types';\nimport { CardConfig } from '@backstage/plugin-home-react';\n\n// eslint-disable-next-line new-cap\nconst ResponsiveGrid = WidthProvider(Responsive);\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n responsiveGrid: {\n '& .react-grid-item > .react-resizable-handle:after': {\n position: 'absolute',\n content: '\"\"',\n borderStyle: 'solid',\n borderWidth: '0 0 20px 20px',\n borderColor: `transparent transparent ${theme.palette.primary.light} transparent`,\n },\n },\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > div[class*=\"MuiCard-root\"]': {\n width: '100%',\n height: '100%',\n },\n '& div[class*=\"MuiCardContent-root\"]': {\n overflow: 'auto',\n },\n '& + .react-grid-placeholder': {\n backgroundColor: theme.palette.primary.light,\n },\n '&.edit > :active': {\n cursor: 'move',\n },\n },\n }),\n);\n\nfunction useHomeStorage(\n defaultWidgets: GridWidget[],\n): [GridWidget[], (value: GridWidget[]) => void] {\n const key = 'home';\n const storageApi = useApi(storageApiRef).forBucket('home.customHomepage');\n // TODO: Support multiple home pages\n const setWidgets = useCallback(\n (value: GridWidget[]) => {\n const grid: CustomHomepageGridStateV1 = {\n version: 1,\n pages: {\n default: value,\n },\n };\n storageApi.set(key, JSON.stringify(grid));\n },\n [key, storageApi],\n );\n const homeSnapshot = useObservable(\n storageApi.observe$<string>(key),\n storageApi.snapshot(key),\n );\n const widgets: GridWidget[] = useMemo(() => {\n if (homeSnapshot.presence === 'absent') {\n return defaultWidgets;\n }\n try {\n const grid: CustomHomepageGridStateV1 = JSON.parse(homeSnapshot.value!);\n return CustomHomepageGridStateV1Schema.parse(grid).pages.default;\n } catch (e) {\n return defaultWidgets;\n }\n }, [homeSnapshot, defaultWidgets]);\n\n return [widgets, setWidgets];\n}\n\nconst convertConfigToDefaultWidgets = (\n config: LayoutConfiguration[],\n availableWidgets: Widget[],\n): GridWidget[] => {\n const ret = config.map((conf, i) => {\n const c = LayoutConfigurationSchema.parse(conf);\n const name = React.isValidElement(c.component)\n ? getComponentData(c.component, 'core.extensionName')\n : (c.component as unknown as string);\n if (!name) {\n return null;\n }\n const widget = availableWidgets.find(w => w.name === name);\n if (!widget) {\n return null;\n }\n const widgetId = `${widget.name}__${i}${Math.random()\n .toString(36)\n .slice(2)}`;\n return {\n id: widgetId,\n layout: {\n i: widgetId,\n x: c.x,\n y: c.y,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, c.width),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, c.height),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isDraggable: false,\n isResizable: false,\n },\n settings: {},\n movable: conf.movable,\n deletable: conf.deletable,\n resizable: conf.resizable,\n };\n });\n return compact(ret);\n};\n\nconst availableWidgetsFilter = (elements: ElementCollection) => {\n return elements\n .selectByComponentData({\n key: 'core.extensionName',\n })\n .getElements<Widget>()\n .flatMap(elem => {\n const config = getComponentData<CardConfig>(elem, 'home.widget.config');\n return [\n WidgetSchema.parse({\n component: elem,\n name: getComponentData<string>(elem, 'core.extensionName'),\n title: getComponentData<string>(elem, 'title'),\n description: getComponentData<string>(elem, 'description'),\n settingsSchema: config?.settings?.schema,\n uiSchema: config?.settings?.uiSchema,\n width: config?.layout?.width?.defaultColumns,\n minWidth: config?.layout?.width?.minColumns,\n maxWidth: config?.layout?.width?.maxColumns,\n height: config?.layout?.height?.defaultRows,\n minHeight: config?.layout?.height?.minRows,\n maxHeight: config?.layout?.height?.maxRows,\n }),\n ];\n });\n};\n\n/**\n * A component that allows customizing components in home grid layout.\n *\n * @public\n */\nexport const CustomHomepageGrid = (props: CustomHomepageGridProps) => {\n const styles = useStyles();\n const theme = useTheme();\n const availableWidgets = useElementFilter(\n props.children,\n availableWidgetsFilter,\n [props],\n );\n const defaultLayout = useMemo(() => {\n return props.config\n ? convertConfigToDefaultWidgets(props.config, availableWidgets)\n : [];\n }, [props.config, availableWidgets]);\n const [widgets, setWidgets] = useHomeStorage(defaultLayout);\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = React.useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = React.useState(editModeOn);\n const getWidgetByName = (name: string) => {\n return availableWidgets.find(widget => widget.name === name);\n };\n\n const getWidgetNameFromKey = (key: string) => {\n return key.split('__')[0];\n };\n\n const handleAdd = (widget: Widget) => {\n const widgetId = `${widget.name}__${widgets.length + 1}${Math.random()\n .toString(36)\n .slice(2)}`;\n\n setWidgets([\n ...widgets,\n {\n id: widgetId,\n layout: {\n i: widgetId,\n x: 0,\n y: Math.max(...widgets.map(w => w.layout.y + w.layout.h)) + 1,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, widget.width ?? 12),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, widget.height ?? 4),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isResizable: editMode,\n isDraggable: editMode,\n },\n settings: {},\n movable: widget.movable,\n deletable: widget.deletable,\n resizable: widget.resizable,\n },\n ]);\n setAddWidgetDialogOpen(false);\n };\n\n const handleRemove = (widgetId: string) => {\n setWidgets(widgets.filter(w => w.id !== widgetId));\n };\n\n const handleSettingsSave = (\n widgetId: string,\n widgetSettings: Record<string, any>,\n ) => {\n const idx = widgets.findIndex(w => w.id === widgetId);\n if (idx >= 0) {\n const widget = widgets[idx];\n widget.settings = widgetSettings;\n widgets[idx] = widget;\n setWidgets(widgets);\n }\n };\n\n const clearLayout = () => {\n setWidgets([]);\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n setWidgets(\n widgets.map(w => {\n const resizable = w.resizable === false ? false : mode;\n const movable = w.movable === false ? false : mode;\n return {\n ...w,\n layout: { ...w.layout, isDraggable: movable, isResizable: resizable },\n };\n }),\n );\n };\n\n const handleLayoutChange = (newLayout: Layout[], _: Layouts) => {\n if (editMode) {\n const newWidgets = newLayout.map(l => {\n const widget = widgets.find(w => w.id === l.i);\n return {\n ...widget,\n layout: l,\n } as GridWidget;\n });\n setWidgets(newWidgets);\n }\n };\n\n const handleRestoreDefaultConfig = () => {\n setWidgets(\n defaultLayout.map(w => {\n const resizable = w.resizable === false ? false : editMode;\n const movable = w.movable === false ? false : editMode;\n return {\n ...w,\n layout: {\n ...w.layout,\n isDraggable: movable,\n isResizable: resizable,\n },\n };\n }),\n );\n };\n\n return (\n <>\n <ContentHeader title=\"\">\n <CustomHomepageButtons\n editMode={editMode}\n numWidgets={widgets.length}\n clearLayout={clearLayout}\n setAddWidgetDialogOpen={setAddWidgetDialogOpen}\n changeEditMode={changeEditMode}\n defaultConfigAvailable={props.config !== undefined}\n restoreDefault={handleRestoreDefaultConfig}\n />\n </ContentHeader>\n <Dialog\n open={addWidgetDialogOpen}\n onClose={() => setAddWidgetDialogOpen(false)}\n >\n <AddWidgetDialog widgets={availableWidgets} handleAdd={handleAdd} />\n </Dialog>\n {!editMode && widgets.length === 0 && (\n <Typography variant=\"h5\" align=\"center\">\n No widgets added. Start by clicking the 'Add widget' button.\n </Typography>\n )}\n <ResponsiveGrid\n className={styles.responsiveGrid}\n measureBeforeMount\n compactType={props.compactType}\n style={props.style}\n allowOverlap={props.allowOverlap}\n preventCollision={props.preventCollision}\n draggableCancel=\".overlayGridItem,.widgetSettingsDialog,.disabled\"\n containerPadding={props.containerPadding}\n margin={props.containerMargin}\n breakpoints={\n props.breakpoints ? props.breakpoints : theme.breakpoints.values\n }\n cols={\n props.cols\n ? props.cols\n : { xl: 12, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }\n }\n rowHeight={props.rowHeight ?? 60}\n onLayoutChange={handleLayoutChange}\n layouts={{ xl: widgets.map(w => w.layout) }}\n >\n {widgets.map((w: GridWidget) => {\n const l = w.layout;\n const widgetName = getWidgetNameFromKey(l.i);\n const widget = getWidgetByName(widgetName);\n if (!widget || !widget.component) {\n return null;\n }\n\n const widgetProps = {\n ...widget.component.props,\n ...(w.settings ?? {}),\n };\n\n return (\n <div\n key={l.i}\n className={`${styles.widgetWrapper} ${editMode && 'edit'} ${\n w.movable === false && 'disabled'\n }`}\n >\n <ErrorBoundary>\n <widget.component.type {...widgetProps} />\n </ErrorBoundary>\n {editMode && (\n <WidgetSettingsOverlay\n id={l.i}\n widget={widget}\n handleRemove={handleRemove}\n handleSettingsSave={handleSettingsSave}\n settings={w.settings}\n deletable={w.deletable}\n />\n )}\n </div>\n );\n })}\n </ResponsiveGrid>\n </>\n );\n};\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"CustomHomepageGrid.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageGrid.tsx"],"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 React, { useCallback, useMemo } from 'react';\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';\nimport {\n ElementCollection,\n getComponentData,\n storageApiRef,\n useApi,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport 'react-grid-layout/css/styles.css';\nimport 'react-resizable/css/styles.css';\nimport Dialog from '@material-ui/core/Dialog';\nimport {\n createStyles,\n makeStyles,\n Theme,\n useTheme,\n} from '@material-ui/core/styles';\nimport { compact } from 'lodash';\nimport useObservable from 'react-use/esm/useObservable';\nimport { ContentHeader, ErrorBoundary } from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { WidgetSettingsOverlay } from './WidgetSettingsOverlay';\nimport { AddWidgetDialog } from './AddWidgetDialog';\nimport { CustomHomepageButtons } from './CustomHomepageButtons';\nimport {\n CustomHomepageGridProps,\n CustomHomepageGridStateV1,\n CustomHomepageGridStateV1Schema,\n GridWidget,\n LayoutConfiguration,\n LayoutConfigurationSchema,\n Widget,\n WidgetSchema,\n} from './types';\nimport { CardConfig } from '@backstage/plugin-home-react';\n\n// eslint-disable-next-line new-cap\nconst ResponsiveGrid = WidthProvider(Responsive);\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n responsiveGrid: {\n '& .react-grid-item > .react-resizable-handle:after': {\n position: 'absolute',\n content: '\"\"',\n borderStyle: 'solid',\n borderWidth: '0 0 20px 20px',\n borderColor: `transparent transparent ${theme.palette.primary.light} transparent`,\n },\n },\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > div[class*=\"MuiCard-root\"]': {\n width: '100%',\n height: '100%',\n },\n '& div[class*=\"MuiCardContent-root\"]': {\n overflow: 'auto',\n },\n '& + .react-grid-placeholder': {\n backgroundColor: theme.palette.primary.light,\n },\n '&.edit > :active': {\n cursor: 'move',\n },\n },\n }),\n);\n\nfunction useHomeStorage(\n defaultWidgets: GridWidget[],\n): [GridWidget[], (value: GridWidget[]) => void] {\n const key = 'home';\n const storageApi = useApi(storageApiRef).forBucket('home.customHomepage');\n // TODO: Support multiple home pages\n const setWidgets = useCallback(\n (value: GridWidget[]) => {\n const grid: CustomHomepageGridStateV1 = {\n version: 1,\n pages: {\n default: value,\n },\n };\n storageApi.set(key, JSON.stringify(grid));\n },\n [key, storageApi],\n );\n const homeSnapshot = useObservable(\n storageApi.observe$<string>(key),\n storageApi.snapshot(key),\n );\n const widgets: GridWidget[] = useMemo(() => {\n if (homeSnapshot.presence === 'absent') {\n return defaultWidgets;\n }\n try {\n const grid: CustomHomepageGridStateV1 = JSON.parse(homeSnapshot.value!);\n return CustomHomepageGridStateV1Schema.parse(grid).pages.default;\n } catch (e) {\n return defaultWidgets;\n }\n }, [homeSnapshot, defaultWidgets]);\n\n return [widgets, setWidgets];\n}\n\nconst convertConfigToDefaultWidgets = (\n config: LayoutConfiguration[],\n availableWidgets: Widget[],\n): GridWidget[] => {\n const ret = config.map((conf, i) => {\n const c = LayoutConfigurationSchema.parse(conf);\n const name = React.isValidElement(c.component)\n ? getComponentData(c.component, 'core.extensionName')\n : (c.component as unknown as string);\n if (!name) {\n return null;\n }\n const widget = availableWidgets.find(w => w.name === name);\n if (!widget) {\n return null;\n }\n const widgetId = `${widget.name}__${i}${Math.random()\n .toString(36)\n .slice(2)}`;\n return {\n id: widgetId,\n layout: {\n i: widgetId,\n x: c.x,\n y: c.y,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, c.width),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, c.height),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isDraggable: false,\n isResizable: false,\n },\n settings: {},\n movable: conf.movable,\n deletable: conf.deletable,\n resizable: conf.resizable,\n };\n });\n return compact(ret);\n};\n\nconst availableWidgetsFilter = (elements: ElementCollection) => {\n return elements\n .selectByComponentData({\n key: 'core.extensionName',\n })\n .getElements<Widget>()\n .flatMap(elem => {\n const config = getComponentData<CardConfig>(elem, 'home.widget.config');\n return [\n WidgetSchema.parse({\n component: elem,\n name: getComponentData<string>(elem, 'core.extensionName'),\n title: getComponentData<string>(elem, 'title'),\n description: getComponentData<string>(elem, 'description'),\n settingsSchema: config?.settings?.schema,\n uiSchema: config?.settings?.uiSchema,\n width: config?.layout?.width?.defaultColumns,\n minWidth: config?.layout?.width?.minColumns,\n maxWidth: config?.layout?.width?.maxColumns,\n height: config?.layout?.height?.defaultRows,\n minHeight: config?.layout?.height?.minRows,\n maxHeight: config?.layout?.height?.maxRows,\n }),\n ];\n });\n};\n\n/**\n * A component that allows customizing components in home grid layout.\n *\n * @public\n */\nexport const CustomHomepageGrid = (props: CustomHomepageGridProps) => {\n const styles = useStyles();\n const theme = useTheme();\n const availableWidgets = useElementFilter(\n props.children,\n availableWidgetsFilter,\n [props],\n );\n const defaultLayout = useMemo(() => {\n return props.config\n ? convertConfigToDefaultWidgets(props.config, availableWidgets)\n : [];\n }, [props.config, availableWidgets]);\n const [widgets, setWidgets] = useHomeStorage(defaultLayout);\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = React.useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = React.useState(editModeOn);\n const getWidgetByName = (name: string) => {\n return availableWidgets.find(widget => widget.name === name);\n };\n\n const getWidgetNameFromKey = (key: string) => {\n return key.split('__')[0];\n };\n\n const handleAdd = (widget: Widget) => {\n const widgetId = `${widget.name}__${widgets.length + 1}${Math.random()\n .toString(36)\n .slice(2)}`;\n\n setWidgets([\n ...widgets,\n {\n id: widgetId,\n layout: {\n i: widgetId,\n x: 0,\n y: Math.max(...widgets.map(w => w.layout.y + w.layout.h)) + 1,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, widget.width ?? 12),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, widget.height ?? 4),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isResizable: editMode,\n isDraggable: editMode,\n },\n settings: {},\n movable: widget.movable,\n deletable: widget.deletable,\n resizable: widget.resizable,\n },\n ]);\n setAddWidgetDialogOpen(false);\n };\n\n const handleRemove = (widgetId: string) => {\n setWidgets(widgets.filter(w => w.id !== widgetId));\n };\n\n const handleSettingsSave = (\n widgetId: string,\n widgetSettings: Record<string, any>,\n ) => {\n const idx = widgets.findIndex(w => w.id === widgetId);\n if (idx >= 0) {\n const widget = widgets[idx];\n widget.settings = widgetSettings;\n widgets[idx] = widget;\n setWidgets(widgets);\n }\n };\n\n const clearLayout = () => {\n setWidgets([]);\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n setWidgets(\n widgets.map(w => {\n const resizable = w.resizable === false ? false : mode;\n const movable = w.movable === false ? false : mode;\n return {\n ...w,\n layout: { ...w.layout, isDraggable: movable, isResizable: resizable },\n };\n }),\n );\n };\n\n const handleLayoutChange = (newLayout: Layout[], _: Layouts) => {\n if (editMode) {\n const newWidgets = newLayout.map(l => {\n const widget = widgets.find(w => w.id === l.i);\n return {\n ...widget,\n layout: l,\n } as GridWidget;\n });\n setWidgets(newWidgets);\n }\n };\n\n const handleRestoreDefaultConfig = () => {\n setWidgets(\n defaultLayout.map(w => {\n const resizable = w.resizable === false ? false : editMode;\n const movable = w.movable === false ? false : editMode;\n return {\n ...w,\n layout: {\n ...w.layout,\n isDraggable: movable,\n isResizable: resizable,\n },\n };\n }),\n );\n };\n\n return (\n <>\n <ContentHeader title=\"\">\n <CustomHomepageButtons\n editMode={editMode}\n numWidgets={widgets.length}\n clearLayout={clearLayout}\n setAddWidgetDialogOpen={setAddWidgetDialogOpen}\n changeEditMode={changeEditMode}\n defaultConfigAvailable={props.config !== undefined}\n restoreDefault={handleRestoreDefaultConfig}\n />\n </ContentHeader>\n <Dialog\n open={addWidgetDialogOpen}\n onClose={() => setAddWidgetDialogOpen(false)}\n >\n <AddWidgetDialog widgets={availableWidgets} handleAdd={handleAdd} />\n </Dialog>\n {!editMode && widgets.length === 0 && (\n <Typography variant=\"h5\" align=\"center\">\n No widgets added. Start by clicking the 'Add widget' button.\n </Typography>\n )}\n <ResponsiveGrid\n className={styles.responsiveGrid}\n measureBeforeMount\n compactType={props.compactType}\n style={props.style}\n allowOverlap={props.allowOverlap}\n preventCollision={props.preventCollision}\n draggableCancel=\".overlayGridItem,.widgetSettingsDialog,.disabled\"\n containerPadding={props.containerPadding}\n margin={props.containerMargin}\n breakpoints={\n props.breakpoints ? props.breakpoints : theme.breakpoints.values\n }\n cols={\n props.cols\n ? props.cols\n : { xl: 12, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }\n }\n rowHeight={props.rowHeight ?? 60}\n onLayoutChange={handleLayoutChange}\n layouts={{ xl: widgets.map(w => w.layout) }}\n >\n {widgets.map((w: GridWidget) => {\n const l = w.layout;\n const widgetName = getWidgetNameFromKey(l.i);\n const widget = getWidgetByName(widgetName);\n if (!widget || !widget.component) {\n return null;\n }\n\n const widgetProps = {\n ...widget.component.props,\n ...(w.settings ?? {}),\n };\n\n return (\n <div\n key={l.i}\n className={`${styles.widgetWrapper} ${editMode && 'edit'} ${\n w.movable === false && 'disabled'\n }`}\n >\n <ErrorBoundary>\n <widget.component.type {...widgetProps} />\n </ErrorBoundary>\n {editMode && (\n <WidgetSettingsOverlay\n id={l.i}\n widget={widget}\n handleRemove={handleRemove}\n handleSettingsSave={handleSettingsSave}\n settings={w.settings}\n deletable={w.deletable}\n />\n )}\n </div>\n );\n })}\n </ResponsiveGrid>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -2,9 +2,8 @@ import React from 'react';
2
2
  import { useOutlet } from 'react-router-dom';
3
3
 
4
4
  const HomepageCompositionRoot = (props) => {
5
- var _a;
6
5
  const outlet = useOutlet();
7
- const children = (_a = props.children) != null ? _a : outlet;
6
+ const children = props.children ?? outlet;
8
7
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
9
8
  };
10
9
 
@@ -1 +1 @@
1
- {"version":3,"file":"HomepageCompositionRoot.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-dom';\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":";;;AAmBa,MAAA,uBAAA,GAA0B,CAAC,KAGlC,KAAA;AAtBN,EAAA,IAAA,EAAA,CAAA;AAuBE,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAM,MAAA,QAAA,GAAA,CAAW,EAAM,GAAA,KAAA,CAAA,QAAA,KAAN,IAAkB,GAAA,EAAA,GAAA,MAAA,CAAA;AACnC,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB;;;;"}
1
+ {"version":3,"file":"HomepageCompositionRoot.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-dom';\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":";;;AAmBa,MAAA,uBAAA,GAA0B,CAAC,KAGlC,KAAA;AACJ,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAM,MAAA,QAAA,GAAW,MAAM,QAAY,IAAA,MAAA,CAAA;AACnC,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB;;;;"}
@@ -14,7 +14,6 @@ const StarredEntityListItem = ({
14
14
  entity,
15
15
  onToggleStarredEntity
16
16
  }) => {
17
- var _a;
18
17
  const catalogEntityRoute = useRouteRef(entityRouteRef);
19
18
  return /* @__PURE__ */ React.createElement(ListItem, { key: stringifyEntityRef(entity) }, /* @__PURE__ */ React.createElement(ListItemIcon, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Remove from starred" }, /* @__PURE__ */ React.createElement(
20
19
  IconButton,
@@ -24,7 +23,7 @@ const StarredEntityListItem = ({
24
23
  onClick: () => onToggleStarredEntity(entity)
25
24
  },
26
25
  /* @__PURE__ */ React.createElement(StarIcon, { style: { color: "#f3ba37" } })
27
- ))), /* @__PURE__ */ React.createElement(Link, { to: catalogEntityRoute(entityRouteParams(entity)) }, /* @__PURE__ */ React.createElement(ListItemText, { primary: (_a = entity.metadata.title) != null ? _a : entity.metadata.name })));
26
+ ))), /* @__PURE__ */ React.createElement(Link, { to: catalogEntityRoute(entityRouteParams(entity)) }, /* @__PURE__ */ React.createElement(ListItemText, { primary: entity.metadata.title ?? entity.metadata.name })));
28
27
  };
29
28
 
30
29
  export { StarredEntityListItem };
@@ -1 +1 @@
1
- {"version":3,"file":"StarredEntityListItem.esm.js","sources":["../../../src/components/StarredEntityListItem/StarredEntityListItem.tsx"],"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 */\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { entityRouteParams } from '@backstage/plugin-catalog-react';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport StarIcon from '@material-ui/icons/Star';\n\ntype EntityListItemProps = {\n entity: Entity;\n onToggleStarredEntity: (entity: Entity) => void;\n};\n\nexport const StarredEntityListItem = ({\n entity,\n onToggleStarredEntity,\n}: EntityListItemProps) => {\n const catalogEntityRoute = useRouteRef(entityRouteRef);\n\n return (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemIcon>\n <Tooltip title=\"Remove from starred\">\n <IconButton\n edge=\"end\"\n aria-label=\"unstar\"\n onClick={() => onToggleStarredEntity(entity)}\n >\n <StarIcon style={{ color: '#f3ba37' }} />\n </IconButton>\n </Tooltip>\n </ListItemIcon>\n <Link to={catalogEntityRoute(entityRouteParams(entity))}>\n <ListItemText primary={entity.metadata.title ?? entity.metadata.name} />\n </Link>\n </ListItem>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;AAiCO,MAAM,wBAAwB,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,qBAAA;AACF,CAA2B,KAAA;AApC3B,EAAA,IAAA,EAAA,CAAA;AAqCE,EAAM,MAAA,kBAAA,GAAqB,YAAY,cAAc,CAAA,CAAA;AAErD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAS,EAAA,EAAA,GAAA,EAAK,kBAAmB,CAAA,MAAM,CACtC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,YACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,KAAA,EAAM,qBACb,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,KAAA;AAAA,MACL,YAAW,EAAA,QAAA;AAAA,MACX,OAAA,EAAS,MAAM,qBAAA,CAAsB,MAAM,CAAA;AAAA,KAAA;AAAA,wCAE1C,QAAS,EAAA,EAAA,KAAA,EAAO,EAAE,KAAA,EAAO,WAAa,EAAA,CAAA;AAAA,GAE3C,CACF,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,EAAI,EAAA,kBAAA,CAAmB,iBAAkB,CAAA,MAAM,CAAC,CAAA,EAAA,sCACnD,YAAa,EAAA,EAAA,OAAA,EAAA,CAAS,YAAO,QAAS,CAAA,KAAA,KAAhB,YAAyB,MAAO,CAAA,QAAA,CAAS,IAAM,EAAA,CACxE,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"StarredEntityListItem.esm.js","sources":["../../../src/components/StarredEntityListItem/StarredEntityListItem.tsx"],"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 */\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { entityRouteParams } from '@backstage/plugin-catalog-react';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport React from 'react';\nimport { Link } from 'react-router-dom';\nimport { entityRouteRef } from '@backstage/plugin-catalog-react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport StarIcon from '@material-ui/icons/Star';\n\ntype EntityListItemProps = {\n entity: Entity;\n onToggleStarredEntity: (entity: Entity) => void;\n};\n\nexport const StarredEntityListItem = ({\n entity,\n onToggleStarredEntity,\n}: EntityListItemProps) => {\n const catalogEntityRoute = useRouteRef(entityRouteRef);\n\n return (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemIcon>\n <Tooltip title=\"Remove from starred\">\n <IconButton\n edge=\"end\"\n aria-label=\"unstar\"\n onClick={() => onToggleStarredEntity(entity)}\n >\n <StarIcon style={{ color: '#f3ba37' }} />\n </IconButton>\n </Tooltip>\n </ListItemIcon>\n <Link to={catalogEntityRoute(entityRouteParams(entity))}>\n <ListItemText primary={entity.metadata.title ?? entity.metadata.name} />\n </Link>\n </ListItem>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;AAiCO,MAAM,wBAAwB,CAAC;AAAA,EACpC,MAAA;AAAA,EACA,qBAAA;AACF,CAA2B,KAAA;AACzB,EAAM,MAAA,kBAAA,GAAqB,YAAY,cAAc,CAAA,CAAA;AAErD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAS,EAAA,EAAA,GAAA,EAAK,kBAAmB,CAAA,MAAM,CACtC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,YACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,KAAA,EAAM,qBACb,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,KAAA;AAAA,MACL,YAAW,EAAA,QAAA;AAAA,MACX,OAAA,EAAS,MAAM,qBAAA,CAAsB,MAAM,CAAA;AAAA,KAAA;AAAA,wCAE1C,QAAS,EAAA,EAAA,KAAA,EAAO,EAAE,KAAA,EAAO,WAAa,EAAA,CAAA;AAAA,GAE3C,CACF,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,EAAI,EAAA,kBAAA,CAAmB,kBAAkB,MAAM,CAAC,qBACnD,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,SAAS,MAAO,CAAA,QAAA,CAAS,SAAS,MAAO,CAAA,QAAA,CAAS,IAAM,EAAA,CACxE,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -12,9 +12,8 @@ const useStyles = makeStyles((theme) => ({
12
12
  }
13
13
  }));
14
14
  const maybeEntity = (visit) => {
15
- var _a;
16
15
  try {
17
- return parseEntityRef((_a = visit == null ? void 0 : visit.entityRef) != null ? _a : "");
16
+ return parseEntityRef(visit?.entityRef ?? "");
18
17
  } catch (e) {
19
18
  return void 0;
20
19
  }
@@ -45,7 +44,6 @@ const getChipColor = (entity) => {
45
44
  return foundIndex === -1 ? defaultColor : getColorByIndex(foundIndex + 1);
46
45
  };
47
46
  const ItemCategory = ({ visit }) => {
48
- var _a;
49
47
  const classes = useStyles();
50
48
  const entity = maybeEntity(visit);
51
49
  return /* @__PURE__ */ React.createElement(
@@ -53,7 +51,7 @@ const ItemCategory = ({ visit }) => {
53
51
  {
54
52
  size: "small",
55
53
  className: classes.chip,
56
- label: ((_a = entity == null ? void 0 : entity.kind) != null ? _a : "Other").toLocaleLowerCase("en-US"),
54
+ label: (entity?.kind ?? "Other").toLocaleLowerCase("en-US"),
57
55
  style: { background: getChipColor(entity) }
58
56
  }
59
57
  );
@@ -1 +1 @@
1
- {"version":3,"file":"ItemCategory.esm.js","sources":["../../../src/components/VisitList/ItemCategory.tsx"],"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 React from 'react';\nimport Chip from '@material-ui/core/Chip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { colorVariants } from '@backstage/theme';\nimport { Visit } from '../../api/VisitsApi';\nimport { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';\n\nconst useStyles = makeStyles(theme => ({\n chip: {\n color: theme.palette.common.white,\n fontWeight: 'bold',\n margin: 0,\n },\n}));\nconst maybeEntity = (visit: Visit): CompoundEntityRef | undefined => {\n try {\n return parseEntityRef(visit?.entityRef ?? '');\n } catch (e) {\n return undefined;\n }\n};\nconst getColorByIndex = (index: number) => {\n const variants = Object.keys(colorVariants);\n const variantIndex = index % variants.length;\n return colorVariants[variants[variantIndex]][0];\n};\nconst getChipColor = (entity: CompoundEntityRef | undefined): string => {\n const defaultColor = getColorByIndex(0);\n if (!entity) return defaultColor;\n\n // IDEA: Use or replicate useAllKinds hook thus supporting all software catalog\n // registered kinds. See:\n // plugins/catalog-react/src/components/EntityKindPicker/kindFilterUtils.ts\n // Provide extension point to register your own color code.\n const entityKinds = [\n 'component',\n 'template',\n 'api',\n 'group',\n 'user',\n 'resource',\n 'system',\n 'domain',\n 'location',\n ];\n const foundIndex = entityKinds.indexOf(\n entity.kind.toLocaleLowerCase('en-US'),\n );\n return foundIndex === -1 ? defaultColor : getColorByIndex(foundIndex + 1);\n};\n\nexport const ItemCategory = ({ visit }: { visit: Visit }) => {\n const classes = useStyles();\n const entity = maybeEntity(visit);\n\n return (\n <Chip\n size=\"small\"\n className={classes.chip}\n label={(entity?.kind ?? 'Other').toLocaleLowerCase('en-US')}\n style={{ background: getChipColor(entity) }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;AAuBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA,KAAA;AAAA,IAC5B,UAAY,EAAA,MAAA;AAAA,IACZ,MAAQ,EAAA,CAAA;AAAA,GACV;AACF,CAAE,CAAA,CAAA,CAAA;AACF,MAAM,WAAA,GAAc,CAAC,KAAgD,KAAA;AA9BrE,EAAA,IAAA,EAAA,CAAA;AA+BE,EAAI,IAAA;AACF,IAAA,OAAO,cAAe,CAAA,CAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,KAAA,CAAO,SAAP,KAAA,IAAA,GAAA,EAAA,GAAoB,EAAE,CAAA,CAAA;AAAA,WACrC,CAAG,EAAA;AACV,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,MAAM,eAAA,GAAkB,CAAC,KAAkB,KAAA;AACzC,EAAM,MAAA,QAAA,GAAW,MAAO,CAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAC1C,EAAM,MAAA,YAAA,GAAe,QAAQ,QAAS,CAAA,MAAA,CAAA;AACtC,EAAA,OAAO,aAAc,CAAA,QAAA,CAAS,YAAY,CAAC,EAAE,CAAC,CAAA,CAAA;AAChD,CAAA,CAAA;AACA,MAAM,YAAA,GAAe,CAAC,MAAkD,KAAA;AACtE,EAAM,MAAA,YAAA,GAAe,gBAAgB,CAAC,CAAA,CAAA;AACtC,EAAA,IAAI,CAAC,MAAA;AAAQ,IAAO,OAAA,YAAA,CAAA;AAMpB,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,WAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,GACF,CAAA;AACA,EAAA,MAAM,aAAa,WAAY,CAAA,OAAA;AAAA,IAC7B,MAAA,CAAO,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,GACvC,CAAA;AACA,EAAA,OAAO,UAAe,KAAA,CAAA,CAAA,GAAK,YAAe,GAAA,eAAA,CAAgB,aAAa,CAAC,CAAA,CAAA;AAC1E,CAAA,CAAA;AAEO,MAAM,YAAe,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AAnE7D,EAAA,IAAA,EAAA,CAAA;AAoEE,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,MAAA,GAAS,YAAY,KAAK,CAAA,CAAA;AAEhC,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,OAAA;AAAA,MACL,WAAW,OAAQ,CAAA,IAAA;AAAA,MACnB,SAAQ,EAAQ,GAAA,MAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,IAAA,KAAR,IAAgB,GAAA,EAAA,GAAA,OAAA,EAAS,kBAAkB,OAAO,CAAA;AAAA,MAC1D,KAAO,EAAA,EAAE,UAAY,EAAA,YAAA,CAAa,MAAM,CAAE,EAAA;AAAA,KAAA;AAAA,GAC5C,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ItemCategory.esm.js","sources":["../../../src/components/VisitList/ItemCategory.tsx"],"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 React from 'react';\nimport Chip from '@material-ui/core/Chip';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { colorVariants } from '@backstage/theme';\nimport { Visit } from '../../api/VisitsApi';\nimport { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';\n\nconst useStyles = makeStyles(theme => ({\n chip: {\n color: theme.palette.common.white,\n fontWeight: 'bold',\n margin: 0,\n },\n}));\nconst maybeEntity = (visit: Visit): CompoundEntityRef | undefined => {\n try {\n return parseEntityRef(visit?.entityRef ?? '');\n } catch (e) {\n return undefined;\n }\n};\nconst getColorByIndex = (index: number) => {\n const variants = Object.keys(colorVariants);\n const variantIndex = index % variants.length;\n return colorVariants[variants[variantIndex]][0];\n};\nconst getChipColor = (entity: CompoundEntityRef | undefined): string => {\n const defaultColor = getColorByIndex(0);\n if (!entity) return defaultColor;\n\n // IDEA: Use or replicate useAllKinds hook thus supporting all software catalog\n // registered kinds. See:\n // plugins/catalog-react/src/components/EntityKindPicker/kindFilterUtils.ts\n // Provide extension point to register your own color code.\n const entityKinds = [\n 'component',\n 'template',\n 'api',\n 'group',\n 'user',\n 'resource',\n 'system',\n 'domain',\n 'location',\n ];\n const foundIndex = entityKinds.indexOf(\n entity.kind.toLocaleLowerCase('en-US'),\n );\n return foundIndex === -1 ? defaultColor : getColorByIndex(foundIndex + 1);\n};\n\nexport const ItemCategory = ({ visit }: { visit: Visit }) => {\n const classes = useStyles();\n const entity = maybeEntity(visit);\n\n return (\n <Chip\n size=\"small\"\n className={classes.chip}\n label={(entity?.kind ?? 'Other').toLocaleLowerCase('en-US')}\n style={{ background: getChipColor(entity) }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;AAuBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA,KAAA;AAAA,IAC5B,UAAY,EAAA,MAAA;AAAA,IACZ,MAAQ,EAAA,CAAA;AAAA,GACV;AACF,CAAE,CAAA,CAAA,CAAA;AACF,MAAM,WAAA,GAAc,CAAC,KAAgD,KAAA;AACnE,EAAI,IAAA;AACF,IAAO,OAAA,cAAA,CAAe,KAAO,EAAA,SAAA,IAAa,EAAE,CAAA,CAAA;AAAA,WACrC,CAAG,EAAA;AACV,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,MAAM,eAAA,GAAkB,CAAC,KAAkB,KAAA;AACzC,EAAM,MAAA,QAAA,GAAW,MAAO,CAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAC1C,EAAM,MAAA,YAAA,GAAe,QAAQ,QAAS,CAAA,MAAA,CAAA;AACtC,EAAA,OAAO,aAAc,CAAA,QAAA,CAAS,YAAY,CAAC,EAAE,CAAC,CAAA,CAAA;AAChD,CAAA,CAAA;AACA,MAAM,YAAA,GAAe,CAAC,MAAkD,KAAA;AACtE,EAAM,MAAA,YAAA,GAAe,gBAAgB,CAAC,CAAA,CAAA;AACtC,EAAA,IAAI,CAAC,MAAA;AAAQ,IAAO,OAAA,YAAA,CAAA;AAMpB,EAAA,MAAM,WAAc,GAAA;AAAA,IAClB,WAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,GACF,CAAA;AACA,EAAA,MAAM,aAAa,WAAY,CAAA,OAAA;AAAA,IAC7B,MAAA,CAAO,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,GACvC,CAAA;AACA,EAAA,OAAO,UAAe,KAAA,CAAA,CAAA,GAAK,YAAe,GAAA,eAAA,CAAgB,aAAa,CAAC,CAAA,CAAA;AAC1E,CAAA,CAAA;AAEO,MAAM,YAAe,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AAC3D,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAM,MAAA,MAAA,GAAS,YAAY,KAAK,CAAA,CAAA;AAEhC,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,OAAA;AAAA,MACL,WAAW,OAAQ,CAAA,IAAA;AAAA,MACnB,KAAQ,EAAA,CAAA,MAAA,EAAQ,IAAQ,IAAA,OAAA,EAAS,kBAAkB,OAAO,CAAA;AAAA,MAC1D,KAAO,EAAA,EAAE,UAAY,EAAA,YAAA,CAAa,MAAM,CAAE,EAAA;AAAA,KAAA;AAAA,GAC5C,CAAA;AAEJ;;;;"}
@@ -4,7 +4,6 @@ import { DateTime } from 'luxon';
4
4
 
5
5
  const ItemDetailHits = ({ visit }) => /* @__PURE__ */ React.createElement(Typography, { component: "span", variant: "caption", color: "textSecondary" }, visit.hits, " time", visit.hits > 1 ? "s" : "");
6
6
  const ItemDetailTimeAgo = ({ visit }) => {
7
- var _a;
8
7
  const visitDate = DateTime.fromMillis(visit.timestamp);
9
8
  return /* @__PURE__ */ React.createElement(
10
9
  Typography,
@@ -12,7 +11,7 @@ const ItemDetailTimeAgo = ({ visit }) => {
12
11
  component: "time",
13
12
  variant: "caption",
14
13
  color: "textSecondary",
15
- dateTime: (_a = visitDate.toISO()) != null ? _a : void 0
14
+ dateTime: visitDate.toISO() ?? void 0
16
15
  },
17
16
  visitDate.toRelative()
18
17
  );
@@ -1 +1 @@
1
- {"version":3,"file":"ItemDetail.esm.js","sources":["../../../src/components/VisitList/ItemDetail.tsx"],"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 React from 'react';\nimport Typography from '@material-ui/core/Typography';\nimport { Visit } from '../../api/VisitsApi';\nimport { DateTime } from 'luxon';\n\nconst ItemDetailHits = ({ visit }: { visit: Visit }) => (\n <Typography component=\"span\" variant=\"caption\" color=\"textSecondary\">\n {visit.hits} time{visit.hits > 1 ? 's' : ''}\n </Typography>\n);\n\nconst ItemDetailTimeAgo = ({ visit }: { visit: Visit }) => {\n const visitDate = DateTime.fromMillis(visit.timestamp);\n\n return (\n <Typography\n component=\"time\"\n variant=\"caption\"\n color=\"textSecondary\"\n dateTime={visitDate.toISO() ?? undefined}\n >\n {visitDate.toRelative()}\n </Typography>\n );\n};\n\nexport type ItemDetailType = 'time-ago' | 'hits';\n\nexport const ItemDetail = ({\n visit,\n type,\n}: {\n visit: Visit;\n type: ItemDetailType;\n}) =>\n type === 'time-ago' ? (\n <ItemDetailTimeAgo visit={visit} />\n ) : (\n <ItemDetailHits visit={visit} />\n );\n"],"names":[],"mappings":";;;;AAqBA,MAAM,cAAA,GAAiB,CAAC,EAAE,KAAA,uBACvB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,WAAU,MAAO,EAAA,OAAA,EAAQ,WAAU,KAAM,EAAA,eAAA,EAAA,EAClD,MAAM,IAAK,EAAA,OAAA,EAAM,MAAM,IAAO,GAAA,CAAA,GAAI,MAAM,EAC3C,CAAA,CAAA;AAGF,MAAM,iBAAoB,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AA3B3D,EAAA,IAAA,EAAA,CAAA;AA4BE,EAAA,MAAM,SAAY,GAAA,QAAA,CAAS,UAAW,CAAA,KAAA,CAAM,SAAS,CAAA,CAAA;AAErD,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,MAAA;AAAA,MACV,OAAQ,EAAA,SAAA;AAAA,MACR,KAAM,EAAA,eAAA;AAAA,MACN,QAAU,EAAA,CAAA,EAAA,GAAA,SAAA,CAAU,KAAM,EAAA,KAAhB,IAAqB,GAAA,EAAA,GAAA,KAAA,CAAA;AAAA,KAAA;AAAA,IAE9B,UAAU,UAAW,EAAA;AAAA,GACxB,CAAA;AAEJ,CAAA,CAAA;AAIO,MAAM,aAAa,CAAC;AAAA,EACzB,KAAA;AAAA,EACA,IAAA;AACF,CAIE,KAAA,IAAA,KAAS,6BACN,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,OAAc,CAEjC,mBAAA,KAAA,CAAA,aAAA,CAAC,kBAAe,KAAc,EAAA;;;;"}
1
+ {"version":3,"file":"ItemDetail.esm.js","sources":["../../../src/components/VisitList/ItemDetail.tsx"],"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 React from 'react';\nimport Typography from '@material-ui/core/Typography';\nimport { Visit } from '../../api/VisitsApi';\nimport { DateTime } from 'luxon';\n\nconst ItemDetailHits = ({ visit }: { visit: Visit }) => (\n <Typography component=\"span\" variant=\"caption\" color=\"textSecondary\">\n {visit.hits} time{visit.hits > 1 ? 's' : ''}\n </Typography>\n);\n\nconst ItemDetailTimeAgo = ({ visit }: { visit: Visit }) => {\n const visitDate = DateTime.fromMillis(visit.timestamp);\n\n return (\n <Typography\n component=\"time\"\n variant=\"caption\"\n color=\"textSecondary\"\n dateTime={visitDate.toISO() ?? undefined}\n >\n {visitDate.toRelative()}\n </Typography>\n );\n};\n\nexport type ItemDetailType = 'time-ago' | 'hits';\n\nexport const ItemDetail = ({\n visit,\n type,\n}: {\n visit: Visit;\n type: ItemDetailType;\n}) =>\n type === 'time-ago' ? (\n <ItemDetailTimeAgo visit={visit} />\n ) : (\n <ItemDetailHits visit={visit} />\n );\n"],"names":[],"mappings":";;;;AAqBA,MAAM,cAAA,GAAiB,CAAC,EAAE,KAAA,uBACvB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,WAAU,MAAO,EAAA,OAAA,EAAQ,WAAU,KAAM,EAAA,eAAA,EAAA,EAClD,MAAM,IAAK,EAAA,OAAA,EAAM,MAAM,IAAO,GAAA,CAAA,GAAI,MAAM,EAC3C,CAAA,CAAA;AAGF,MAAM,iBAAoB,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AACzD,EAAA,MAAM,SAAY,GAAA,QAAA,CAAS,UAAW,CAAA,KAAA,CAAM,SAAS,CAAA,CAAA;AAErD,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,MAAA;AAAA,MACV,OAAQ,EAAA,SAAA;AAAA,MACR,KAAM,EAAA,eAAA;AAAA,MACN,QAAA,EAAU,SAAU,CAAA,KAAA,EAAW,IAAA,KAAA,CAAA;AAAA,KAAA;AAAA,IAE9B,UAAU,UAAW,EAAA;AAAA,GACxB,CAAA;AAEJ,CAAA,CAAA;AAIO,MAAM,aAAa,CAAC;AAAA,EACzB,KAAA;AAAA,EACA,IAAA;AACF,CAIE,KAAA,IAAA,KAAS,6BACN,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,OAAc,CAEjC,mBAAA,KAAA,CAAA,aAAA,CAAC,kBAAe,KAAc,EAAA;;;;"}
@@ -13,7 +13,7 @@ const getToEntityRef = ({
13
13
  `^/${rootPath}/(?<namespace>[^/]+)/(?<kind>[^/]+)/(?<name>[^/]+)`
14
14
  );
15
15
  const result = regex.exec(pathname);
16
- if (!result || !(result == null ? void 0 : result.groups))
16
+ if (!result || !result?.groups)
17
17
  return void 0;
18
18
  const entity = {
19
19
  namespace: result.groups.namespace,
@@ -27,10 +27,10 @@ const getVisitName = ({ rootPath = "catalog", document = global.document } = {})
27
27
  `^/${rootPath}/(?<namespace>[^/]+)/(?<kind>[^/]+)/(?<name>[^/]+)`
28
28
  );
29
29
  let result = regex.exec(pathname);
30
- if (result && (result == null ? void 0 : result.groups))
30
+ if (result && result?.groups)
31
31
  return result.groups.name;
32
32
  result = /^\/(?<name>[^\/]+)$/.exec(pathname);
33
- if (result && (result == null ? void 0 : result.groups))
33
+ if (result && result?.groups)
34
34
  return result.groups.name;
35
35
  return document.title;
36
36
  };
@@ -41,8 +41,8 @@ const VisitListener = ({
41
41
  }) => {
42
42
  const visitsApi = useApi(visitsApiRef);
43
43
  const { pathname } = useLocation();
44
- const toEntityRefImpl = toEntityRef != null ? toEntityRef : getToEntityRef();
45
- const visitNameImpl = visitName != null ? visitName : getVisitName();
44
+ const toEntityRefImpl = toEntityRef ?? getToEntityRef();
45
+ const visitNameImpl = visitName ?? getVisitName();
46
46
  useEffect(() => {
47
47
  const requestId = requestAnimationFrame(() => {
48
48
  visitsApi.save({
@@ -1 +1 @@
1
- {"version":3,"file":"VisitListener.esm.js","sources":["../../src/components/VisitListener.tsx"],"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 */\nimport React, { useEffect } from 'react';\n\nimport { useLocation } from 'react-router-dom';\n\nimport { visitsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\n\n/**\n * This function returns an implementation of toEntityRef which is responsible\n * for receiving a pathname and maybe returning an entityRef compatible with the\n * catalog-model.\n * By default this function uses the url root \"/catalog\" and the\n * stringifyEntityRef implementation from catalog-model.\n * Example:\n * const toEntityRef = getToEntityRef();\n * toEntityRef(\\{ pathname: \"/catalog/default/component/playback-order\" \\})\n * // returns \"component:default/playback-order\"\n */\nconst getToEntityRef =\n ({\n rootPath = 'catalog',\n stringifyEntityRefImpl = stringifyEntityRef,\n } = {}) =>\n ({ pathname }: { pathname: string }): string | undefined => {\n const regex = new RegExp(\n `^\\/${rootPath}\\/(?<namespace>[^\\/]+)\\/(?<kind>[^\\/]+)\\/(?<name>[^\\/]+)`,\n );\n const result = regex.exec(pathname);\n if (!result || !result?.groups) return undefined;\n const entity = {\n namespace: result.groups.namespace,\n kind: result.groups.kind,\n name: result.groups.name,\n };\n return stringifyEntityRefImpl(entity);\n };\n\n/**\n * @internal\n * This function returns an implementation of visitName which is responsible\n * for receiving a pathname and returning a string (name).\n */\nconst getVisitName =\n ({ rootPath = 'catalog', document = global.document } = {}) =>\n ({ pathname }: { pathname: string }) => {\n // If it is a catalog entity, get the name from the path\n const regex = new RegExp(\n `^\\/${rootPath}\\/(?<namespace>[^\\/]+)\\/(?<kind>[^\\/]+)\\/(?<name>[^\\/]+)`,\n );\n let result = regex.exec(pathname);\n if (result && result?.groups) return result.groups.name;\n\n // If it is a root pathname, get the name from there\n result = /^\\/(?<name>[^\\/]+)$/.exec(pathname);\n if (result && result?.groups) return result.groups.name;\n\n // Fallback to document title\n return document.title;\n };\n\n/**\n * @public\n * Component responsible for listening to location changes and calling\n * the visitsApi to save visits.\n */\nexport const VisitListener = ({\n children,\n toEntityRef,\n visitName,\n}: {\n children?: React.ReactNode;\n toEntityRef?: ({ pathname }: { pathname: string }) => string | undefined;\n visitName?: ({ pathname }: { pathname: string }) => string;\n}): JSX.Element => {\n const visitsApi = useApi(visitsApiRef);\n const { pathname } = useLocation();\n const toEntityRefImpl = toEntityRef ?? getToEntityRef();\n const visitNameImpl = visitName ?? getVisitName();\n useEffect(() => {\n // Wait for the browser to finish with paint with the assumption react\n // has finished with dom reconciliation.\n const requestId = requestAnimationFrame(() => {\n visitsApi.save({\n visit: {\n name: visitNameImpl({ pathname }),\n pathname,\n entityRef: toEntityRefImpl({ pathname }),\n },\n });\n });\n return () => cancelAnimationFrame(requestId);\n }, [visitsApi, pathname, toEntityRefImpl, visitNameImpl]);\n\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;;;AAkCA,MAAM,iBACJ,CAAC;AAAA,EACC,QAAW,GAAA,SAAA;AAAA,EACX,sBAAyB,GAAA,kBAAA;AAC3B,CAAA,GAAI,EAAC,KACL,CAAC,EAAE,UAAyD,KAAA;AAC1D,EAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,IAChB,KAAM,QAAQ,CAAA,kDAAA,CAAA;AAAA,GAChB,CAAA;AACA,EAAM,MAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,QAAQ,CAAA,CAAA;AAClC,EAAI,IAAA,CAAC,MAAU,IAAA,EAAC,MAAQ,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,MAAA,CAAA;AAAQ,IAAO,OAAA,KAAA,CAAA,CAAA;AACvC,EAAA,MAAM,MAAS,GAAA;AAAA,IACb,SAAA,EAAW,OAAO,MAAO,CAAA,SAAA;AAAA,IACzB,IAAA,EAAM,OAAO,MAAO,CAAA,IAAA;AAAA,IACpB,IAAA,EAAM,OAAO,MAAO,CAAA,IAAA;AAAA,GACtB,CAAA;AACA,EAAA,OAAO,uBAAuB,MAAM,CAAA,CAAA;AACtC,CAAA,CAAA;AAOF,MAAM,YACJ,GAAA,CAAC,EAAE,QAAA,GAAW,WAAW,QAAW,GAAA,MAAA,CAAO,QAAS,EAAA,GAAI,EAAC,KACzD,CAAC,EAAE,UAAqC,KAAA;AAEtC,EAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,IAChB,KAAM,QAAQ,CAAA,kDAAA,CAAA;AAAA,GAChB,CAAA;AACA,EAAI,IAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,QAAQ,CAAA,CAAA;AAChC,EAAA,IAAI,WAAU,MAAQ,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,MAAA,CAAA;AAAQ,IAAA,OAAO,OAAO,MAAO,CAAA,IAAA,CAAA;AAGnD,EAAS,MAAA,GAAA,qBAAA,CAAsB,KAAK,QAAQ,CAAA,CAAA;AAC5C,EAAA,IAAI,WAAU,MAAQ,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,MAAA,CAAA,MAAA,CAAA;AAAQ,IAAA,OAAO,OAAO,MAAO,CAAA,IAAA,CAAA;AAGnD,EAAA,OAAO,QAAS,CAAA,KAAA,CAAA;AAClB,CAAA,CAAA;AAOK,MAAM,gBAAgB,CAAC;AAAA,EAC5B,QAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AACF,CAImB,KAAA;AACjB,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AACrC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA,CAAA;AACjC,EAAM,MAAA,eAAA,GAAkB,oCAAe,cAAe,EAAA,CAAA;AACtD,EAAM,MAAA,aAAA,GAAgB,gCAAa,YAAa,EAAA,CAAA;AAChD,EAAA,SAAA,CAAU,MAAM;AAGd,IAAM,MAAA,SAAA,GAAY,sBAAsB,MAAM;AAC5C,MAAA,SAAA,CAAU,IAAK,CAAA;AAAA,QACb,KAAO,EAAA;AAAA,UACL,IAAM,EAAA,aAAA,CAAc,EAAE,QAAA,EAAU,CAAA;AAAA,UAChC,QAAA;AAAA,UACA,SAAW,EAAA,eAAA,CAAgB,EAAE,QAAA,EAAU,CAAA;AAAA,SACzC;AAAA,OACD,CAAA,CAAA;AAAA,KACF,CAAA,CAAA;AACD,IAAO,OAAA,MAAM,qBAAqB,SAAS,CAAA,CAAA;AAAA,KAC1C,CAAC,SAAA,EAAW,QAAU,EAAA,eAAA,EAAiB,aAAa,CAAC,CAAA,CAAA;AAExD,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB;;;;"}
1
+ {"version":3,"file":"VisitListener.esm.js","sources":["../../src/components/VisitListener.tsx"],"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 */\nimport React, { useEffect } from 'react';\n\nimport { useLocation } from 'react-router-dom';\n\nimport { visitsApiRef } from '../api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\n\n/**\n * This function returns an implementation of toEntityRef which is responsible\n * for receiving a pathname and maybe returning an entityRef compatible with the\n * catalog-model.\n * By default this function uses the url root \"/catalog\" and the\n * stringifyEntityRef implementation from catalog-model.\n * Example:\n * const toEntityRef = getToEntityRef();\n * toEntityRef(\\{ pathname: \"/catalog/default/component/playback-order\" \\})\n * // returns \"component:default/playback-order\"\n */\nconst getToEntityRef =\n ({\n rootPath = 'catalog',\n stringifyEntityRefImpl = stringifyEntityRef,\n } = {}) =>\n ({ pathname }: { pathname: string }): string | undefined => {\n const regex = new RegExp(\n `^\\/${rootPath}\\/(?<namespace>[^\\/]+)\\/(?<kind>[^\\/]+)\\/(?<name>[^\\/]+)`,\n );\n const result = regex.exec(pathname);\n if (!result || !result?.groups) return undefined;\n const entity = {\n namespace: result.groups.namespace,\n kind: result.groups.kind,\n name: result.groups.name,\n };\n return stringifyEntityRefImpl(entity);\n };\n\n/**\n * @internal\n * This function returns an implementation of visitName which is responsible\n * for receiving a pathname and returning a string (name).\n */\nconst getVisitName =\n ({ rootPath = 'catalog', document = global.document } = {}) =>\n ({ pathname }: { pathname: string }) => {\n // If it is a catalog entity, get the name from the path\n const regex = new RegExp(\n `^\\/${rootPath}\\/(?<namespace>[^\\/]+)\\/(?<kind>[^\\/]+)\\/(?<name>[^\\/]+)`,\n );\n let result = regex.exec(pathname);\n if (result && result?.groups) return result.groups.name;\n\n // If it is a root pathname, get the name from there\n result = /^\\/(?<name>[^\\/]+)$/.exec(pathname);\n if (result && result?.groups) return result.groups.name;\n\n // Fallback to document title\n return document.title;\n };\n\n/**\n * @public\n * Component responsible for listening to location changes and calling\n * the visitsApi to save visits.\n */\nexport const VisitListener = ({\n children,\n toEntityRef,\n visitName,\n}: {\n children?: React.ReactNode;\n toEntityRef?: ({ pathname }: { pathname: string }) => string | undefined;\n visitName?: ({ pathname }: { pathname: string }) => string;\n}): JSX.Element => {\n const visitsApi = useApi(visitsApiRef);\n const { pathname } = useLocation();\n const toEntityRefImpl = toEntityRef ?? getToEntityRef();\n const visitNameImpl = visitName ?? getVisitName();\n useEffect(() => {\n // Wait for the browser to finish with paint with the assumption react\n // has finished with dom reconciliation.\n const requestId = requestAnimationFrame(() => {\n visitsApi.save({\n visit: {\n name: visitNameImpl({ pathname }),\n pathname,\n entityRef: toEntityRefImpl({ pathname }),\n },\n });\n });\n return () => cancelAnimationFrame(requestId);\n }, [visitsApi, pathname, toEntityRefImpl, visitNameImpl]);\n\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;;;AAkCA,MAAM,iBACJ,CAAC;AAAA,EACC,QAAW,GAAA,SAAA;AAAA,EACX,sBAAyB,GAAA,kBAAA;AAC3B,CAAA,GAAI,EAAC,KACL,CAAC,EAAE,UAAyD,KAAA;AAC1D,EAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,IAChB,KAAM,QAAQ,CAAA,kDAAA,CAAA;AAAA,GAChB,CAAA;AACA,EAAM,MAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,QAAQ,CAAA,CAAA;AAClC,EAAI,IAAA,CAAC,MAAU,IAAA,CAAC,MAAQ,EAAA,MAAA;AAAQ,IAAO,OAAA,KAAA,CAAA,CAAA;AACvC,EAAA,MAAM,MAAS,GAAA;AAAA,IACb,SAAA,EAAW,OAAO,MAAO,CAAA,SAAA;AAAA,IACzB,IAAA,EAAM,OAAO,MAAO,CAAA,IAAA;AAAA,IACpB,IAAA,EAAM,OAAO,MAAO,CAAA,IAAA;AAAA,GACtB,CAAA;AACA,EAAA,OAAO,uBAAuB,MAAM,CAAA,CAAA;AACtC,CAAA,CAAA;AAOF,MAAM,YACJ,GAAA,CAAC,EAAE,QAAA,GAAW,WAAW,QAAW,GAAA,MAAA,CAAO,QAAS,EAAA,GAAI,EAAC,KACzD,CAAC,EAAE,UAAqC,KAAA;AAEtC,EAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,IAChB,KAAM,QAAQ,CAAA,kDAAA,CAAA;AAAA,GAChB,CAAA;AACA,EAAI,IAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,QAAQ,CAAA,CAAA;AAChC,EAAA,IAAI,UAAU,MAAQ,EAAA,MAAA;AAAQ,IAAA,OAAO,OAAO,MAAO,CAAA,IAAA,CAAA;AAGnD,EAAS,MAAA,GAAA,qBAAA,CAAsB,KAAK,QAAQ,CAAA,CAAA;AAC5C,EAAA,IAAI,UAAU,MAAQ,EAAA,MAAA;AAAQ,IAAA,OAAO,OAAO,MAAO,CAAA,IAAA,CAAA;AAGnD,EAAA,OAAO,QAAS,CAAA,KAAA,CAAA;AAClB,CAAA,CAAA;AAOK,MAAM,gBAAgB,CAAC;AAAA,EAC5B,QAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AACF,CAImB,KAAA;AACjB,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AACrC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA,CAAA;AACjC,EAAM,MAAA,eAAA,GAAkB,eAAe,cAAe,EAAA,CAAA;AACtD,EAAM,MAAA,aAAA,GAAgB,aAAa,YAAa,EAAA,CAAA;AAChD,EAAA,SAAA,CAAU,MAAM;AAGd,IAAM,MAAA,SAAA,GAAY,sBAAsB,MAAM;AAC5C,MAAA,SAAA,CAAU,IAAK,CAAA;AAAA,QACb,KAAO,EAAA;AAAA,UACL,IAAM,EAAA,aAAA,CAAc,EAAE,QAAA,EAAU,CAAA;AAAA,UAChC,QAAA;AAAA,UACA,SAAW,EAAA,eAAA,CAAgB,EAAE,QAAA,EAAU,CAAA;AAAA,SACzC;AAAA,OACD,CAAA,CAAA;AAAA,KACF,CAAA,CAAA;AACD,IAAO,OAAA,MAAM,qBAAqB,SAAS,CAAA,CAAA;AAAA,KAC1C,CAAC,SAAA,EAAW,QAAU,EAAA,eAAA,EAAiB,aAAa,CAAC,CAAA,CAAA;AAExD,EAAA,iEAAU,QAAS,CAAA,CAAA;AACrB;;;;"}
@@ -50,7 +50,7 @@ const Content = (props) => {
50
50
  if (error) {
51
51
  return /* @__PURE__ */ React.createElement(ErrorPanel, { error });
52
52
  }
53
- return (entities == null ? void 0 : entities.length) ? /* @__PURE__ */ React.createElement(React.Fragment, null, entities.map((d) => /* @__PURE__ */ React.createElement(
53
+ return entities?.length ? /* @__PURE__ */ React.createElement(React.Fragment, null, entities.map((d) => /* @__PURE__ */ React.createElement(
54
54
  "div",
55
55
  {
56
56
  key: `${d.metadata.name}-${d.kind}-${d.metadata.namespace}`,
@@ -1 +1 @@
1
- {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/FeaturedDocsCard/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 useAsync from 'react-use/esm/useAsync';\nimport {\n LinkButton,\n EmptyState,\n Link,\n Progress,\n ErrorPanel,\n} from '@backstage/core-components';\nimport {\n catalogApiRef,\n CatalogApi,\n EntityDisplayName,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { EntityFilterQuery } from '@backstage/catalog-client';\n\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\n\n/**\n * Props customizing the <FeaturedDocsCard/> component.\n *\n * @public\n */\nexport type FeaturedDocsCardProps = {\n /** The entity filter used to display only the intended item/s */\n filter: EntityFilterQuery;\n /** An optional ReactNode for empty states */\n emptyState?: React.JSX.Element;\n /** An optional linkDestination to set for the Featured Doc */\n linkDestination?: string;\n /** An optional limit to set for link destination */\n responseLimit?: number;\n /** An optional string to customize sublink text */\n subLinkText?: string;\n};\n\nconst useStyles = makeStyles(\n theme => ({\n docDescription: {\n fontSize: theme.typography.body1.fontSize,\n fontWeight: theme.typography.body1.fontWeight,\n marginBottom: theme.spacing(2),\n marginTop: theme.spacing(2),\n },\n docSubLink: {\n fontSize: theme.typography.subtitle1.fontSize,\n fontWeight: theme.typography.subtitle1.fontWeight,\n lineHeight: theme.typography.subtitle1.lineHeight,\n },\n docsTitleLink: {\n fontSize: theme.typography.h6.fontSize,\n fontWeight: theme.typography.h6.fontWeight,\n lineHeight: theme.typography.h6.lineHeight,\n },\n }),\n { name: 'HomeFeaturedDocsCard' },\n);\n\n/**\n * A component to display specific Featured Docs.\n *\n * @public\n */\nexport const Content = (props: FeaturedDocsCardProps): JSX.Element => {\n const { emptyState, filter, linkDestination, responseLimit, subLinkText } =\n props;\n const linkText = subLinkText || 'LEARN MORE';\n const styles = useStyles();\n const catalogApi: CatalogApi = useApi(catalogApiRef);\n const {\n value: entities,\n loading,\n error,\n } = useAsync(async () => {\n const response = await catalogApi.getEntities({\n filter: filter,\n limit: responseLimit || 10,\n });\n return response.items;\n });\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n return entities?.length ? (\n <>\n {entities.map(d => (\n <div\n key={`${d.metadata.name}-${d.kind}-${d.metadata.namespace}`}\n data-testid=\"docs-card-content\"\n >\n <Link\n className={styles.docsTitleLink}\n data-testid=\"docs-card-title\"\n to={\n linkDestination ||\n `/docs/${d.metadata.namespace || 'default'}/${d.kind}/${\n d.metadata.name\n }/`\n }\n >\n <EntityDisplayName entityRef={stringifyEntityRef(d)} />\n </Link>\n {d.metadata.description && (\n <Typography className={styles.docDescription}>\n {d.metadata.description}\n </Typography>\n )}\n <Link\n className={styles.docSubLink}\n data-testid=\"docs-card-sub-link\"\n to={\n linkDestination ||\n `/docs/${d.metadata.namespace || 'default'}/${d.kind}/${\n d.metadata.name\n }/`\n }\n >\n {linkText}\n </Link>\n </div>\n ))}\n </>\n ) : (\n emptyState || (\n <EmptyState\n missing=\"data\"\n title=\"No documents to show\"\n description=\"Create your own document. Check out our Getting Started Information\"\n action={\n <LinkButton\n to=\"https://backstage.io/docs/features/techdocs/getting-started\"\n variant=\"contained\"\n >\n DOCS\n </LinkButton>\n }\n />\n )\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/FeaturedDocsCard/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 useAsync from 'react-use/esm/useAsync';\nimport {\n LinkButton,\n EmptyState,\n Link,\n Progress,\n ErrorPanel,\n} from '@backstage/core-components';\nimport {\n catalogApiRef,\n CatalogApi,\n EntityDisplayName,\n} from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { EntityFilterQuery } from '@backstage/catalog-client';\n\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\n\n/**\n * Props customizing the <FeaturedDocsCard/> component.\n *\n * @public\n */\nexport type FeaturedDocsCardProps = {\n /** The entity filter used to display only the intended item/s */\n filter: EntityFilterQuery;\n /** An optional ReactNode for empty states */\n emptyState?: React.JSX.Element;\n /** An optional linkDestination to set for the Featured Doc */\n linkDestination?: string;\n /** An optional limit to set for link destination */\n responseLimit?: number;\n /** An optional string to customize sublink text */\n subLinkText?: string;\n};\n\nconst useStyles = makeStyles(\n theme => ({\n docDescription: {\n fontSize: theme.typography.body1.fontSize,\n fontWeight: theme.typography.body1.fontWeight,\n marginBottom: theme.spacing(2),\n marginTop: theme.spacing(2),\n },\n docSubLink: {\n fontSize: theme.typography.subtitle1.fontSize,\n fontWeight: theme.typography.subtitle1.fontWeight,\n lineHeight: theme.typography.subtitle1.lineHeight,\n },\n docsTitleLink: {\n fontSize: theme.typography.h6.fontSize,\n fontWeight: theme.typography.h6.fontWeight,\n lineHeight: theme.typography.h6.lineHeight,\n },\n }),\n { name: 'HomeFeaturedDocsCard' },\n);\n\n/**\n * A component to display specific Featured Docs.\n *\n * @public\n */\nexport const Content = (props: FeaturedDocsCardProps): JSX.Element => {\n const { emptyState, filter, linkDestination, responseLimit, subLinkText } =\n props;\n const linkText = subLinkText || 'LEARN MORE';\n const styles = useStyles();\n const catalogApi: CatalogApi = useApi(catalogApiRef);\n const {\n value: entities,\n loading,\n error,\n } = useAsync(async () => {\n const response = await catalogApi.getEntities({\n filter: filter,\n limit: responseLimit || 10,\n });\n return response.items;\n });\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return <ErrorPanel error={error} />;\n }\n\n return entities?.length ? (\n <>\n {entities.map(d => (\n <div\n key={`${d.metadata.name}-${d.kind}-${d.metadata.namespace}`}\n data-testid=\"docs-card-content\"\n >\n <Link\n className={styles.docsTitleLink}\n data-testid=\"docs-card-title\"\n to={\n linkDestination ||\n `/docs/${d.metadata.namespace || 'default'}/${d.kind}/${\n d.metadata.name\n }/`\n }\n >\n <EntityDisplayName entityRef={stringifyEntityRef(d)} />\n </Link>\n {d.metadata.description && (\n <Typography className={styles.docDescription}>\n {d.metadata.description}\n </Typography>\n )}\n <Link\n className={styles.docSubLink}\n data-testid=\"docs-card-sub-link\"\n to={\n linkDestination ||\n `/docs/${d.metadata.namespace || 'default'}/${d.kind}/${\n d.metadata.name\n }/`\n }\n >\n {linkText}\n </Link>\n </div>\n ))}\n </>\n ) : (\n emptyState || (\n <EmptyState\n missing=\"data\"\n title=\"No documents to show\"\n description=\"Create your own document. Check out our Getting Started Information\"\n action={\n <LinkButton\n to=\"https://backstage.io/docs/features/techdocs/getting-started\"\n variant=\"contained\"\n >\n DOCS\n </LinkButton>\n }\n />\n )\n );\n};\n"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ function getTimes(clockConfigs, customTimeFormat) {
16
16
  let label = clockConfig.label;
17
17
  const options = {
18
18
  timeZone: clockConfig.timeZone,
19
- ...customTimeFormat != null ? customTimeFormat : timeFormat
19
+ ...customTimeFormat ?? timeFormat
20
20
  };
21
21
  try {
22
22
  (/* @__PURE__ */ new Date()).toLocaleString(lang, options);
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderWorldClock.esm.js","sources":["../../../src/homePageComponents/HeaderWorldClock/HeaderWorldClock.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 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 label: string;\n value: string;\n dateTime: string;\n};\n\n/** @public */\nexport type ClockConfig = {\n label: string;\n timeZone: string;\n};\n\nfunction getTimes(\n clockConfigs: ClockConfig[],\n customTimeFormat?: Intl.DateTimeFormatOptions,\n) {\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 ...(customTimeFormat ?? 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 value = d.toLocaleTimeString(lang, options);\n const dateTime = d.toLocaleTimeString(lang, {\n timeZone: options.timeZone,\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n clocks.push({ label, value, dateTime });\n }\n\n return clocks;\n}\n\n/**\n * A component to display a configurable list of clocks for various time zones.\n *\n * @example\n * Here's a simple example:\n * ```\n * // This will give you a clock for the time zone that Stockholm is in\n * // you can add more than one but keep in mind space may be limited\n * const clockConfigs: ClockConfig[] = [\n * {\n * label: 'STO',\n * timeZone: 'Europe/Stockholm',\n * },\n * ];\n *\n * // Setting hour12 to false will make all the clocks show in the 24hr format\n * const timeFormat: Intl.DateTimeFormatOptions = {\n * hour: '2-digit',\n * minute: '2-digit',\n * hour12: false,\n * };\n *\n * // Here is the component in use:\n * <HeaderWorldClock\n * clockConfigs={clockConfigs}\n * customTimeFormat={timeFormat}\n * />\n * ```\n *\n * @public\n */\nexport const HeaderWorldClock = (props: {\n clockConfigs: ClockConfig[];\n customTimeFormat?: Intl.DateTimeFormatOptions;\n}) => {\n const { clockConfigs, customTimeFormat } = props;\n\n const defaultTimes: TimeObj[] = [];\n const [clocks, setTimes] = React.useState(defaultTimes);\n\n React.useEffect(() => {\n setTimes(getTimes(clockConfigs, customTimeFormat));\n\n const intervalId = setInterval(() => {\n setTimes(getTimes(clockConfigs, customTimeFormat));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [clockConfigs, customTimeFormat]);\n\n if (clocks.length !== 0) {\n return (\n <>\n {clocks.map(clock => (\n <HeaderLabel\n key={clock.label}\n label={clock.label}\n value={<time dateTime={clock.dateTime}>{clock.value}</time>}\n />\n ))}\n </>\n );\n }\n return null;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HeaderWorldClock.esm.js","sources":["../../../src/homePageComponents/HeaderWorldClock/HeaderWorldClock.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 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 label: string;\n value: string;\n dateTime: string;\n};\n\n/** @public */\nexport type ClockConfig = {\n label: string;\n timeZone: string;\n};\n\nfunction getTimes(\n clockConfigs: ClockConfig[],\n customTimeFormat?: Intl.DateTimeFormatOptions,\n) {\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 ...(customTimeFormat ?? 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 value = d.toLocaleTimeString(lang, options);\n const dateTime = d.toLocaleTimeString(lang, {\n timeZone: options.timeZone,\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n clocks.push({ label, value, dateTime });\n }\n\n return clocks;\n}\n\n/**\n * A component to display a configurable list of clocks for various time zones.\n *\n * @example\n * Here's a simple example:\n * ```\n * // This will give you a clock for the time zone that Stockholm is in\n * // you can add more than one but keep in mind space may be limited\n * const clockConfigs: ClockConfig[] = [\n * {\n * label: 'STO',\n * timeZone: 'Europe/Stockholm',\n * },\n * ];\n *\n * // Setting hour12 to false will make all the clocks show in the 24hr format\n * const timeFormat: Intl.DateTimeFormatOptions = {\n * hour: '2-digit',\n * minute: '2-digit',\n * hour12: false,\n * };\n *\n * // Here is the component in use:\n * <HeaderWorldClock\n * clockConfigs={clockConfigs}\n * customTimeFormat={timeFormat}\n * />\n * ```\n *\n * @public\n */\nexport const HeaderWorldClock = (props: {\n clockConfigs: ClockConfig[];\n customTimeFormat?: Intl.DateTimeFormatOptions;\n}) => {\n const { clockConfigs, customTimeFormat } = props;\n\n const defaultTimes: TimeObj[] = [];\n const [clocks, setTimes] = React.useState(defaultTimes);\n\n React.useEffect(() => {\n setTimes(getTimes(clockConfigs, customTimeFormat));\n\n const intervalId = setInterval(() => {\n setTimes(getTimes(clockConfigs, customTimeFormat));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [clockConfigs, customTimeFormat]);\n\n if (clocks.length !== 0) {\n return (\n <>\n {clocks.map(clock => (\n <HeaderLabel\n key={clock.label}\n label={clock.label}\n value={<time dateTime={clock.dateTime}>{clock.value}</time>}\n />\n ))}\n </>\n );\n }\n return null;\n};\n"],"names":[],"mappings":"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"}
@@ -14,7 +14,6 @@ const Content = ({
14
14
  noStarredEntitiesMessage,
15
15
  groupByKind
16
16
  }) => {
17
- var _a, _b;
18
17
  const catalogApi = useApi(catalogApiRef);
19
18
  const { starredEntities, toggleStarredEntity } = useStarredEntities();
20
19
  const [activeTab, setActiveTab] = React.useState(0);
@@ -38,7 +37,7 @@ const Content = ({
38
37
  return /* @__PURE__ */ React.createElement(Progress, null);
39
38
  }
40
39
  const groupedEntities = {};
41
- (_a = entities.value) == null ? void 0 : _a.forEach((entity) => {
40
+ entities.value?.forEach((entity) => {
42
41
  const kind = entity.kind;
43
42
  if (!groupedEntities[kind]) {
44
43
  groupedEntities[kind] = [];
@@ -46,13 +45,10 @@ const Content = ({
46
45
  groupedEntities[kind].push(entity);
47
46
  });
48
47
  const groupByKindEntries = Object.entries(groupedEntities);
49
- return entities.error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, { error: entities.error }) : /* @__PURE__ */ React.createElement("div", null, !groupByKind && /* @__PURE__ */ React.createElement(List, null, (_b = entities.value) == null ? void 0 : _b.sort(
50
- (a, b) => {
51
- var _a2, _b2;
52
- return ((_a2 = a.metadata.title) != null ? _a2 : a.metadata.name).localeCompare(
53
- (_b2 = b.metadata.title) != null ? _b2 : b.metadata.name
54
- );
55
- }
48
+ return entities.error ? /* @__PURE__ */ React.createElement(ResponseErrorPanel, { error: entities.error }) : /* @__PURE__ */ React.createElement("div", null, !groupByKind && /* @__PURE__ */ React.createElement(List, null, entities.value?.sort(
49
+ (a, b) => (a.metadata.title ?? a.metadata.name).localeCompare(
50
+ b.metadata.title ?? b.metadata.name
51
+ )
56
52
  ).map((entity) => /* @__PURE__ */ React.createElement(
57
53
  StarredEntityListItem,
58
54
  {
@@ -70,13 +66,10 @@ const Content = ({
70
66
  "aria-label": "entity-tabs"
71
67
  },
72
68
  groupByKindEntries.map(([kind]) => /* @__PURE__ */ React.createElement(Tab, { key: kind, label: kind }))
73
- ), groupByKind && groupByKindEntries.map(([kind, entitiesByKind], index) => /* @__PURE__ */ React.createElement("div", { key: kind, hidden: groupByKind && activeTab !== index }, /* @__PURE__ */ React.createElement(List, null, entitiesByKind == null ? void 0 : entitiesByKind.sort(
74
- (a, b) => {
75
- var _a2, _b2;
76
- return ((_a2 = a.metadata.title) != null ? _a2 : a.metadata.name).localeCompare(
77
- (_b2 = b.metadata.title) != null ? _b2 : b.metadata.name
78
- );
79
- }
69
+ ), groupByKind && groupByKindEntries.map(([kind, entitiesByKind], index) => /* @__PURE__ */ React.createElement("div", { key: kind, hidden: groupByKind && activeTab !== index }, /* @__PURE__ */ React.createElement(List, null, entitiesByKind?.sort(
70
+ (a, b) => (a.metadata.title ?? a.metadata.name).localeCompare(
71
+ b.metadata.title ?? b.metadata.name
72
+ )
80
73
  ).map((entity) => /* @__PURE__ */ React.createElement(
81
74
  StarredEntityListItem,
82
75
  {
@@ -1 +1 @@
1
- {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/StarredEntities/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 catalogApiRef,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport List from '@material-ui/core/List';\nimport Typography from '@material-ui/core/Typography';\nimport Tabs from '@material-ui/core/Tabs';\nimport Tab from '@material-ui/core/Tab';\nimport React from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem';\n\n/**\n * A component to display a list of starred entities for the user.\n *\n * @public\n */\n\nexport type StarredEntitiesProps = {\n noStarredEntitiesMessage?: React.ReactNode | undefined;\n groupByKind?: boolean;\n};\n\nexport const Content = ({\n noStarredEntitiesMessage,\n groupByKind,\n}: StarredEntitiesProps) => {\n const catalogApi = useApi(catalogApiRef);\n const { starredEntities, toggleStarredEntity } = useStarredEntities();\n const [activeTab, setActiveTab] = React.useState(0);\n\n // Grab starred entities from catalog to ensure they still exist and also retrieve display titles\n const entities = useAsync(async () => {\n if (!starredEntities.size) {\n return [];\n }\n\n return (\n await catalogApi.getEntitiesByRefs({\n entityRefs: [...starredEntities],\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n ],\n })\n ).items.filter((e): e is Entity => !!e);\n }, [catalogApi, starredEntities]);\n\n if (starredEntities.size === 0)\n return (\n <Typography variant=\"body1\">\n {noStarredEntitiesMessage ||\n 'Click the star beside an entity name to add it to this list!'}\n </Typography>\n );\n\n if (entities.loading) {\n return <Progress />;\n }\n\n const groupedEntities: { [kind: string]: Entity[] } = {};\n entities.value?.forEach(entity => {\n const kind = entity.kind;\n if (!groupedEntities[kind]) {\n groupedEntities[kind] = [];\n }\n groupedEntities[kind].push(entity);\n });\n\n const groupByKindEntries = Object.entries(groupedEntities);\n\n return entities.error ? (\n <ResponseErrorPanel error={entities.error} />\n ) : (\n <div>\n {!groupByKind && (\n <List>\n {entities.value\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n )}\n\n {groupByKind && (\n <Tabs\n value={activeTab}\n onChange={(_, newValue) => setActiveTab(newValue)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"entity-tabs\"\n >\n {groupByKindEntries.map(([kind]) => (\n <Tab key={kind} label={kind} />\n ))}\n </Tabs>\n )}\n\n {groupByKind &&\n groupByKindEntries.map(([kind, entitiesByKind], index) => (\n <div key={kind} hidden={groupByKind && activeTab !== index}>\n <List>\n {entitiesByKind\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n </div>\n ))}\n </div>\n );\n};\n"],"names":["_a","_b"],"mappings":"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"}
1
+ {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/StarredEntities/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 catalogApiRef,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport List from '@material-ui/core/List';\nimport Typography from '@material-ui/core/Typography';\nimport Tabs from '@material-ui/core/Tabs';\nimport Tab from '@material-ui/core/Tab';\nimport React from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { StarredEntityListItem } from '../../components/StarredEntityListItem/StarredEntityListItem';\n\n/**\n * A component to display a list of starred entities for the user.\n *\n * @public\n */\n\nexport type StarredEntitiesProps = {\n noStarredEntitiesMessage?: React.ReactNode | undefined;\n groupByKind?: boolean;\n};\n\nexport const Content = ({\n noStarredEntitiesMessage,\n groupByKind,\n}: StarredEntitiesProps) => {\n const catalogApi = useApi(catalogApiRef);\n const { starredEntities, toggleStarredEntity } = useStarredEntities();\n const [activeTab, setActiveTab] = React.useState(0);\n\n // Grab starred entities from catalog to ensure they still exist and also retrieve display titles\n const entities = useAsync(async () => {\n if (!starredEntities.size) {\n return [];\n }\n\n return (\n await catalogApi.getEntitiesByRefs({\n entityRefs: [...starredEntities],\n fields: [\n 'kind',\n 'metadata.namespace',\n 'metadata.name',\n 'metadata.title',\n ],\n })\n ).items.filter((e): e is Entity => !!e);\n }, [catalogApi, starredEntities]);\n\n if (starredEntities.size === 0)\n return (\n <Typography variant=\"body1\">\n {noStarredEntitiesMessage ||\n 'Click the star beside an entity name to add it to this list!'}\n </Typography>\n );\n\n if (entities.loading) {\n return <Progress />;\n }\n\n const groupedEntities: { [kind: string]: Entity[] } = {};\n entities.value?.forEach(entity => {\n const kind = entity.kind;\n if (!groupedEntities[kind]) {\n groupedEntities[kind] = [];\n }\n groupedEntities[kind].push(entity);\n });\n\n const groupByKindEntries = Object.entries(groupedEntities);\n\n return entities.error ? (\n <ResponseErrorPanel error={entities.error} />\n ) : (\n <div>\n {!groupByKind && (\n <List>\n {entities.value\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n )}\n\n {groupByKind && (\n <Tabs\n value={activeTab}\n onChange={(_, newValue) => setActiveTab(newValue)}\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"entity-tabs\"\n >\n {groupByKindEntries.map(([kind]) => (\n <Tab key={kind} label={kind} />\n ))}\n </Tabs>\n )}\n\n {groupByKind &&\n groupByKindEntries.map(([kind, entitiesByKind], index) => (\n <div key={kind} hidden={groupByKind && activeTab !== index}>\n <List>\n {entitiesByKind\n ?.sort((a, b) =>\n (a.metadata.title ?? a.metadata.name).localeCompare(\n b.metadata.title ?? b.metadata.name,\n ),\n )\n .map(entity => (\n <StarredEntityListItem\n key={stringifyEntityRef(entity)}\n entity={entity}\n onToggleStarredEntity={toggleStarredEntity}\n />\n ))}\n </List>\n </div>\n ))}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -34,10 +34,9 @@ const useStyles = makeStyles((theme) => ({
34
34
  }
35
35
  }));
36
36
  const Content = (props) => {
37
- var _a;
38
37
  const classes = useStyles();
39
38
  const toolkit = useToolkit();
40
- const tools = (_a = toolkit == null ? void 0 : toolkit.tools) != null ? _a : props.tools;
39
+ const tools = toolkit?.tools ?? props.tools;
41
40
  return /* @__PURE__ */ React.createElement(List, { className: classes.toolkit }, tools.map((tool) => /* @__PURE__ */ React.createElement(Link, { key: tool.url, to: tool.url, className: classes.tool }, /* @__PURE__ */ React.createElement(ListItemIcon, { className: classes.icon }, tool.icon), /* @__PURE__ */ React.createElement(
42
41
  ListItemText,
43
42
  {
@@ -1 +1 @@
1
- {"version":3,"file":"Content.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 List from '@material-ui/core/List';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React from 'react';\nimport { useToolkit, Tool } from './Context';\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 width: '72px',\n fontSize: '0.9em',\n lineHeight: '1.25',\n overflowWrap: 'break-word',\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\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 const toolkit = useToolkit();\n const tools = toolkit?.tools ?? props.tools;\n\n return (\n <List className={classes.toolkit}>\n {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\n/**\n * Props for Toolkit Content component.\n *\n * @public\n */\nexport type ToolkitContentProps = {\n tools: Tool[];\n};\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,MAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,GACb;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,MAAQ,EAAA,KAAA,CAAM,OAAQ,CAAA,GAAA,EAAK,CAAC,CAAA;AAAA,GAC9B;AAAA,EACA,KAAO,EAAA;AAAA,IACL,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,KAAO,EAAA,MAAA;AAAA,IACP,QAAU,EAAA,OAAA;AAAA,IACV,UAAY,EAAA,MAAA;AAAA,IACZ,YAAc,EAAA,YAAA;AAAA,IACd,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAA;AAAA,GAC5B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA,MAAA;AAAA,IACR,YAAc,EAAA,MAAA;AAAA,IACd,cAAgB,EAAA,QAAA;AAAA,IAChB,UAAY,EAAA,QAAA;AAAA,IACZ,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,GAC5C;AACF,CAAE,CAAA,CAAA,CAAA;AAOW,MAAA,OAAA,GAAU,CAAC,KAA+B,KAAA;AAzDvD,EAAA,IAAA,EAAA,CAAA;AA0DE,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,UAAU,UAAW,EAAA,CAAA;AAC3B,EAAA,MAAM,KAAQ,GAAA,CAAA,EAAA,GAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,KAAT,KAAA,IAAA,GAAA,EAAA,GAAkB,KAAM,CAAA,KAAA,CAAA;AAEtC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,OAAA,EAAA,EACtB,KAAM,CAAA,GAAA,CAAI,CAAC,IAAA,qBACT,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,GAAK,EAAA,IAAA,CAAK,GAAK,EAAA,EAAA,EAAI,IAAK,CAAA,GAAA,EAAK,SAAW,EAAA,OAAA,CAAQ,IACpD,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,IAAA,EAAA,EAAO,IAAK,CAAA,IAAK,CAClD,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,wBAA0B,EAAA,EAAE,SAAW,EAAA,OAAA,CAAQ,KAAM,EAAA;AAAA,MACrD,WAAW,IAAK,CAAA,KAAA;AAAA,KAAA;AAAA,GAEpB,CACD,CACH,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Content.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 List from '@material-ui/core/List';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport React from 'react';\nimport { useToolkit, Tool } from './Context';\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 width: '72px',\n fontSize: '0.9em',\n lineHeight: '1.25',\n overflowWrap: 'break-word',\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\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 const toolkit = useToolkit();\n const tools = toolkit?.tools ?? props.tools;\n\n return (\n <List className={classes.toolkit}>\n {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\n/**\n * Props for Toolkit Content component.\n *\n * @public\n */\nexport type ToolkitContentProps = {\n tools: Tool[];\n};\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,OAAS,EAAA;AAAA,IACP,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,MAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,GACb;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,MAAQ,EAAA,KAAA,CAAM,OAAQ,CAAA,GAAA,EAAK,CAAC,CAAA;AAAA,GAC9B;AAAA,EACA,KAAO,EAAA;AAAA,IACL,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,KAAO,EAAA,MAAA;AAAA,IACP,QAAU,EAAA,OAAA;AAAA,IACV,UAAY,EAAA,MAAA;AAAA,IACZ,YAAc,EAAA,YAAA;AAAA,IACd,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,SAAA;AAAA,GAC5B;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA,MAAA;AAAA,IACR,YAAc,EAAA,MAAA;AAAA,IACd,cAAgB,EAAA,QAAA;AAAA,IAChB,UAAY,EAAA,QAAA;AAAA,IACZ,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,GAC5C;AACF,CAAE,CAAA,CAAA,CAAA;AAOW,MAAA,OAAA,GAAU,CAAC,KAA+B,KAAA;AACrD,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,UAAU,UAAW,EAAA,CAAA;AAC3B,EAAM,MAAA,KAAA,GAAQ,OAAS,EAAA,KAAA,IAAS,KAAM,CAAA,KAAA,CAAA;AAEtC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,OAAA,EAAA,EACtB,KAAM,CAAA,GAAA,CAAI,CAAC,IAAA,qBACT,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,GAAK,EAAA,IAAA,CAAK,GAAK,EAAA,EAAA,EAAI,IAAK,CAAA,GAAA,EAAK,SAAW,EAAA,OAAA,CAAQ,IACpD,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,YAAa,EAAA,EAAA,SAAA,EAAW,OAAQ,CAAA,IAAA,EAAA,EAAO,IAAK,CAAA,IAAK,CAClD,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,wBAA0B,EAAA,EAAE,SAAW,EAAA,OAAA,CAAQ,KAAM,EAAA;AAAA,MACrD,WAAW,IAAK,CAAA,KAAA;AAAA,KAAA;AAAA,GAEpB,CACD,CACH,CAAA,CAAA;AAEJ;;;;"}
@@ -33,23 +33,22 @@ const Content = ({
33
33
  const config = useApi(configApiRef);
34
34
  const visitsApi = useApi(visitsApiRef);
35
35
  const { loading: reqLoading } = useAsync(async () => {
36
- var _a, _b;
37
36
  if (!visits && !loading && kind === "recent") {
38
37
  const filterBy = createFilterByQueryParamFromConfig(
39
- (_a = config.getOptionalConfigArray("home.recentVisits.filterBy")) != null ? _a : []
38
+ config.getOptionalConfigArray("home.recentVisits.filterBy") ?? []
40
39
  );
41
40
  return await visitsApi.list({
42
- limit: numVisitsTotal != null ? numVisitsTotal : 8,
41
+ limit: numVisitsTotal ?? 8,
43
42
  orderBy: [{ field: "timestamp", direction: "desc" }],
44
43
  ...filterBy && { filterBy }
45
44
  }).then(setVisits);
46
45
  }
47
46
  if (!visits && !loading && kind === "top") {
48
47
  const filterBy = createFilterByQueryParamFromConfig(
49
- (_b = config.getOptionalConfigArray("home.topVisits.filterBy")) != null ? _b : []
48
+ config.getOptionalConfigArray("home.topVisits.filterBy") ?? []
50
49
  );
51
50
  return await visitsApi.list({
52
- limit: numVisitsTotal != null ? numVisitsTotal : 8,
51
+ limit: numVisitsTotal ?? 8,
53
52
  orderBy: [{ field: "hits", direction: "desc" }],
54
53
  ...filterBy && { filterBy }
55
54
  }).then(setVisits);
@@ -1 +1 @@
1
- {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/VisitedByType/Content.tsx"],"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 React, { useEffect } from 'react';\nimport { createFilterByQueryParamFromConfig } from '../../api/config';\nimport { VisitedByType } from './VisitedByType';\nimport { Visit, visitsApiRef } from '../../api';\nimport { ContextValueOnly, useContext } from './Context';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\n\n/** @public */\nexport type VisitedByTypeKind = 'recent' | 'top';\n\n/** @public */\nexport type VisitedByTypeProps = {\n visits?: Array<Visit>;\n numVisitsOpen?: number;\n numVisitsTotal?: number;\n loading?: boolean;\n kind: VisitedByTypeKind;\n};\n\n/**\n * Display recently visited pages for the homepage\n * @public\n */\nexport const Content = ({\n visits,\n numVisitsOpen,\n numVisitsTotal,\n loading,\n kind,\n}: VisitedByTypeProps) => {\n const { setContext, setVisits, setLoading } = useContext();\n // Allows behavior override from properties\n useEffect(() => {\n const context: Partial<ContextValueOnly> = {};\n context.kind = kind;\n if (visits) {\n context.visits = visits;\n context.loading = false;\n } else if (loading) {\n context.loading = loading;\n }\n if (numVisitsOpen) context.numVisitsOpen = numVisitsOpen;\n if (numVisitsTotal) context.numVisitsTotal = numVisitsTotal;\n setContext(state => ({ ...state, ...context }));\n }, [setContext, kind, visits, loading, numVisitsOpen, numVisitsTotal]);\n\n const config = useApi(configApiRef);\n // Fetches data from visitsApi in case visits and loading are not provided\n const visitsApi = useApi(visitsApiRef);\n const { loading: reqLoading } = useAsync(async () => {\n if (!visits && !loading && kind === 'recent') {\n const filterBy = createFilterByQueryParamFromConfig(\n config.getOptionalConfigArray('home.recentVisits.filterBy') ?? [],\n );\n return await visitsApi\n .list({\n limit: numVisitsTotal ?? 8,\n orderBy: [{ field: 'timestamp', direction: 'desc' }],\n ...(filterBy && { filterBy }),\n })\n .then(setVisits);\n }\n if (!visits && !loading && kind === 'top') {\n const filterBy = createFilterByQueryParamFromConfig(\n config.getOptionalConfigArray('home.topVisits.filterBy') ?? [],\n );\n return await visitsApi\n .list({\n limit: numVisitsTotal ?? 8,\n orderBy: [{ field: 'hits', direction: 'desc' }],\n ...(filterBy && { filterBy }),\n })\n .then(setVisits);\n }\n return undefined;\n }, [visitsApi, visits, loading, setVisits]);\n useEffect(() => {\n if (!loading) {\n setLoading(reqLoading);\n }\n }, [loading, setLoading, reqLoading]);\n\n return <VisitedByType />;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/VisitedByType/Content.tsx"],"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 React, { useEffect } from 'react';\nimport { createFilterByQueryParamFromConfig } from '../../api/config';\nimport { VisitedByType } from './VisitedByType';\nimport { Visit, visitsApiRef } from '../../api';\nimport { ContextValueOnly, useContext } from './Context';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\n\n/** @public */\nexport type VisitedByTypeKind = 'recent' | 'top';\n\n/** @public */\nexport type VisitedByTypeProps = {\n visits?: Array<Visit>;\n numVisitsOpen?: number;\n numVisitsTotal?: number;\n loading?: boolean;\n kind: VisitedByTypeKind;\n};\n\n/**\n * Display recently visited pages for the homepage\n * @public\n */\nexport const Content = ({\n visits,\n numVisitsOpen,\n numVisitsTotal,\n loading,\n kind,\n}: VisitedByTypeProps) => {\n const { setContext, setVisits, setLoading } = useContext();\n // Allows behavior override from properties\n useEffect(() => {\n const context: Partial<ContextValueOnly> = {};\n context.kind = kind;\n if (visits) {\n context.visits = visits;\n context.loading = false;\n } else if (loading) {\n context.loading = loading;\n }\n if (numVisitsOpen) context.numVisitsOpen = numVisitsOpen;\n if (numVisitsTotal) context.numVisitsTotal = numVisitsTotal;\n setContext(state => ({ ...state, ...context }));\n }, [setContext, kind, visits, loading, numVisitsOpen, numVisitsTotal]);\n\n const config = useApi(configApiRef);\n // Fetches data from visitsApi in case visits and loading are not provided\n const visitsApi = useApi(visitsApiRef);\n const { loading: reqLoading } = useAsync(async () => {\n if (!visits && !loading && kind === 'recent') {\n const filterBy = createFilterByQueryParamFromConfig(\n config.getOptionalConfigArray('home.recentVisits.filterBy') ?? [],\n );\n return await visitsApi\n .list({\n limit: numVisitsTotal ?? 8,\n orderBy: [{ field: 'timestamp', direction: 'desc' }],\n ...(filterBy && { filterBy }),\n })\n .then(setVisits);\n }\n if (!visits && !loading && kind === 'top') {\n const filterBy = createFilterByQueryParamFromConfig(\n config.getOptionalConfigArray('home.topVisits.filterBy') ?? [],\n );\n return await visitsApi\n .list({\n limit: numVisitsTotal ?? 8,\n orderBy: [{ field: 'hits', direction: 'desc' }],\n ...(filterBy && { filterBy }),\n })\n .then(setVisits);\n }\n return undefined;\n }, [visitsApi, visits, loading, setVisits]);\n useEffect(() => {\n if (!loading) {\n setLoading(reqLoading);\n }\n }, [loading, setLoading, reqLoading]);\n\n return <VisitedByType />;\n};\n"],"names":[],"mappings":";;;;;;;;;AAwCO,MAAM,UAAU,CAAC;AAAA,EACtB,MAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,SAAW,EAAA,UAAA,KAAe,UAAW,EAAA,CAAA;AAEzD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAqC,EAAC,CAAA;AAC5C,IAAA,OAAA,CAAQ,IAAO,GAAA,IAAA,CAAA;AACf,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,OAAA,CAAQ,MAAS,GAAA,MAAA,CAAA;AACjB,MAAA,OAAA,CAAQ,OAAU,GAAA,KAAA,CAAA;AAAA,eACT,OAAS,EAAA;AAClB,MAAA,OAAA,CAAQ,OAAU,GAAA,OAAA,CAAA;AAAA,KACpB;AACA,IAAI,IAAA,aAAA;AAAe,MAAA,OAAA,CAAQ,aAAgB,GAAA,aAAA,CAAA;AAC3C,IAAI,IAAA,cAAA;AAAgB,MAAA,OAAA,CAAQ,cAAiB,GAAA,cAAA,CAAA;AAC7C,IAAA,UAAA,CAAW,YAAU,EAAE,GAAG,KAAO,EAAA,GAAG,SAAU,CAAA,CAAA,CAAA;AAAA,GAChD,EAAG,CAAC,UAAY,EAAA,IAAA,EAAM,QAAQ,OAAS,EAAA,aAAA,EAAe,cAAc,CAAC,CAAA,CAAA;AAErE,EAAM,MAAA,MAAA,GAAS,OAAO,YAAY,CAAA,CAAA;AAElC,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA,CAAA;AACrC,EAAA,MAAM,EAAE,OAAA,EAAS,UAAW,EAAA,GAAI,SAAS,YAAY;AACnD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,IAAW,SAAS,QAAU,EAAA;AAC5C,MAAA,MAAM,QAAW,GAAA,kCAAA;AAAA,QACf,MAAO,CAAA,sBAAA,CAAuB,4BAA4B,CAAA,IAAK,EAAC;AAAA,OAClE,CAAA;AACA,MAAO,OAAA,MAAM,UACV,IAAK,CAAA;AAAA,QACJ,OAAO,cAAkB,IAAA,CAAA;AAAA,QACzB,SAAS,CAAC,EAAE,OAAO,WAAa,EAAA,SAAA,EAAW,QAAQ,CAAA;AAAA,QACnD,GAAI,QAAY,IAAA,EAAE,QAAS,EAAA;AAAA,OAC5B,CACA,CAAA,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,KACnB;AACA,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,IAAW,SAAS,KAAO,EAAA;AACzC,MAAA,MAAM,QAAW,GAAA,kCAAA;AAAA,QACf,MAAO,CAAA,sBAAA,CAAuB,yBAAyB,CAAA,IAAK,EAAC;AAAA,OAC/D,CAAA;AACA,MAAO,OAAA,MAAM,UACV,IAAK,CAAA;AAAA,QACJ,OAAO,cAAkB,IAAA,CAAA;AAAA,QACzB,SAAS,CAAC,EAAE,OAAO,MAAQ,EAAA,SAAA,EAAW,QAAQ,CAAA;AAAA,QAC9C,GAAI,QAAY,IAAA,EAAE,QAAS,EAAA;AAAA,OAC5B,CACA,CAAA,IAAA,CAAK,SAAS,CAAA,CAAA;AAAA,KACnB;AACA,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,KACN,CAAC,SAAA,EAAW,MAAQ,EAAA,OAAA,EAAS,SAAS,CAAC,CAAA,CAAA;AAC1C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAS,EAAA;AACZ,MAAA,UAAA,CAAW,UAAU,CAAA,CAAA;AAAA,KACvB;AAAA,GACC,EAAA,CAAC,OAAS,EAAA,UAAA,EAAY,UAAU,CAAC,CAAA,CAAA;AAEpC,EAAA,2CAAQ,aAAc,EAAA,IAAA,CAAA,CAAA;AACxB;;;;"}
@@ -20,7 +20,7 @@ const WelcomeTitle = ({ language }) => {
20
20
  });
21
21
  }
22
22
  }, [error, alertApi]);
23
- return /* @__PURE__ */ React.createElement(Tooltip, { title: greeting.language }, /* @__PURE__ */ React.createElement(Typography, { component: "span", variant: "inherit" }, `${greeting.greeting}${(profile == null ? void 0 : profile.displayName) ? `, ${profile == null ? void 0 : profile.displayName}` : ""}!`));
23
+ return /* @__PURE__ */ React.createElement(Tooltip, { title: greeting.language }, /* @__PURE__ */ React.createElement(Typography, { component: "span", variant: "inherit" }, `${greeting.greeting}${profile?.displayName ? `, ${profile?.displayName}` : ""}!`));
24
24
  };
25
25
 
26
26
  export { WelcomeTitle };
@@ -1 +1 @@
1
- {"version":3,"file":"WelcomeTitle.esm.js","sources":["../../../src/homePageComponents/WelcomeTitle/WelcomeTitle.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 {\n alertApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport React, { useEffect, useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { getTimeBasedGreeting } from './timeUtil';\n\n/** @public */\nexport type WelcomeTitleLanguageProps = {\n language?: string[];\n};\n\nexport const WelcomeTitle = ({ language }: WelcomeTitleLanguageProps) => {\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const greeting = useMemo(() => getTimeBasedGreeting(language), [language]);\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 <Typography component=\"span\" variant=\"inherit\">{`${greeting.greeting}${\n profile?.displayName ? `, ${profile?.displayName}` : ''\n }!`}</Typography>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA+BO,MAAM,YAAe,GAAA,CAAC,EAAE,QAAA,EAA0C,KAAA;AACvE,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA,CAAA;AACzC,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA,CAAA;AACnC,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM,oBAAA,CAAqB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA,CAAA;AAEzE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAAS,MACzC,YAAY,cAAe,EAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,OAAA,EAAS,iCAAiC,KAAK,CAAA,CAAA;AAAA,QAC/C,QAAU,EAAA,OAAA;AAAA,OACX,CAAA,CAAA;AAAA,KACH;AAAA,GACC,EAAA,CAAC,KAAO,EAAA,QAAQ,CAAC,CAAA,CAAA;AAEpB,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,KAAO,EAAA,QAAA,CAAS,4BACtB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAU,EAAA,MAAA,EAAO,OAAQ,EAAA,SAAA,EAAA,EAAW,GAAG,QAAS,CAAA,QAAQ,CAClE,EAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,WAAc,IAAA,CAAA,EAAA,EAAK,mCAAS,WAAW,CAAA,CAAA,GAAK,EACvD,CAAA,CAAA,CAAI,CACN,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"WelcomeTitle.esm.js","sources":["../../../src/homePageComponents/WelcomeTitle/WelcomeTitle.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 {\n alertApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport React, { useEffect, useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { getTimeBasedGreeting } from './timeUtil';\n\n/** @public */\nexport type WelcomeTitleLanguageProps = {\n language?: string[];\n};\n\nexport const WelcomeTitle = ({ language }: WelcomeTitleLanguageProps) => {\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const greeting = useMemo(() => getTimeBasedGreeting(language), [language]);\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 <Typography component=\"span\" variant=\"inherit\">{`${greeting.greeting}${\n profile?.displayName ? `, ${profile?.displayName}` : ''\n }!`}</Typography>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA+BO,MAAM,YAAe,GAAA,CAAC,EAAE,QAAA,EAA0C,KAAA;AACvE,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA,CAAA;AACzC,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA,CAAA;AACnC,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM,oBAAA,CAAqB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA,CAAA;AAEzE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAAS,MACzC,YAAY,cAAe,EAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,OAAA,EAAS,iCAAiC,KAAK,CAAA,CAAA;AAAA,QAC/C,QAAU,EAAA,OAAA;AAAA,OACX,CAAA,CAAA;AAAA,KACH;AAAA,GACC,EAAA,CAAC,KAAO,EAAA,QAAQ,CAAC,CAAA,CAAA;AAEpB,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,KAAO,EAAA,QAAA,CAAS,4BACtB,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAU,EAAA,MAAA,EAAO,OAAQ,EAAA,SAAA,EAAA,EAAW,GAAG,QAAS,CAAA,QAAQ,CAClE,EAAA,OAAA,EAAS,WAAc,GAAA,CAAA,EAAA,EAAK,SAAS,WAAW,CAAA,CAAA,GAAK,EACvD,CAAA,CAAA,CAAI,CACN,CAAA,CAAA;AAEJ;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
- "version": "0.7.4",
3
+ "version": "0.7.5-next.1",
4
4
  "description": "A Backstage plugin that helps you build a home page",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin"
@@ -53,14 +53,14 @@
53
53
  "@backstage/catalog-client": "^1.6.5",
54
54
  "@backstage/catalog-model": "^1.5.0",
55
55
  "@backstage/config": "^1.2.0",
56
- "@backstage/core-app-api": "^1.12.5",
57
- "@backstage/core-compat-api": "^0.2.5",
58
- "@backstage/core-components": "^0.14.7",
59
- "@backstage/core-plugin-api": "^1.9.2",
60
- "@backstage/frontend-plugin-api": "^0.6.5",
61
- "@backstage/plugin-catalog-react": "^1.12.0",
62
- "@backstage/plugin-home-react": "^0.1.13",
63
- "@backstage/theme": "^0.5.4",
56
+ "@backstage/core-app-api": "^1.12.6-next.0",
57
+ "@backstage/core-compat-api": "^0.2.6-next.1",
58
+ "@backstage/core-components": "^0.14.8-next.1",
59
+ "@backstage/core-plugin-api": "^1.9.3-next.0",
60
+ "@backstage/frontend-plugin-api": "^0.6.6-next.1",
61
+ "@backstage/plugin-catalog-react": "^1.12.1-next.1",
62
+ "@backstage/plugin-home-react": "^0.1.14-next.1",
63
+ "@backstage/theme": "^0.5.6-next.0",
64
64
  "@material-ui/core": "^4.12.2",
65
65
  "@material-ui/icons": "^4.9.1",
66
66
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -77,9 +77,9 @@
77
77
  "zod": "^3.22.4"
78
78
  },
79
79
  "devDependencies": {
80
- "@backstage/cli": "^0.26.5",
81
- "@backstage/dev-utils": "^1.0.32",
82
- "@backstage/test-utils": "^1.5.5",
80
+ "@backstage/cli": "^0.26.7-next.2",
81
+ "@backstage/dev-utils": "^1.0.33-next.1",
82
+ "@backstage/test-utils": "^1.5.6-next.1",
83
83
  "@testing-library/dom": "^10.0.0",
84
84
  "@testing-library/jest-dom": "^6.0.0",
85
85
  "@testing-library/react": "^15.0.0",