@drodil/backstage-plugin-qeta-react 3.3.0 → 3.4.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 (207) hide show
  1. package/dist/components/AnswerCard/AnswerCard.esm.js +6 -1
  2. package/dist/components/AnswerCard/AnswerCard.esm.js.map +1 -1
  3. package/dist/components/AnswerForm/AnswerForm.esm.js +5 -1
  4. package/dist/components/AnswerForm/AnswerForm.esm.js.map +1 -1
  5. package/dist/components/AnswersContainer/AnswerList.esm.js +16 -38
  6. package/dist/components/AnswersContainer/AnswerList.esm.js.map +1 -1
  7. package/dist/components/AnswersContainer/AnswerListItem.esm.js +6 -1
  8. package/dist/components/AnswersContainer/AnswerListItem.esm.js.map +1 -1
  9. package/dist/components/AnswersContainer/AnswersContainer.esm.js +5 -1
  10. package/dist/components/AnswersContainer/AnswersContainer.esm.js.map +1 -1
  11. package/dist/components/ArticleContent/ArticleButtons.esm.js +6 -1
  12. package/dist/components/ArticleContent/ArticleButtons.esm.js.map +1 -1
  13. package/dist/components/ArticleContent/ArticleContent.esm.js +7 -1
  14. package/dist/components/ArticleContent/ArticleContent.esm.js.map +1 -1
  15. package/dist/components/AuthorBox/AuthorBox.esm.js +7 -1
  16. package/dist/components/AuthorBox/AuthorBox.esm.js.map +1 -1
  17. package/dist/components/Buttons/AddToCollectionButton.esm.js +4 -1
  18. package/dist/components/Buttons/AddToCollectionButton.esm.js.map +1 -1
  19. package/dist/components/Buttons/AskQuestionButton.esm.js +5 -1
  20. package/dist/components/Buttons/AskQuestionButton.esm.js.map +1 -1
  21. package/dist/components/Buttons/BackToArticlesButton.esm.js +5 -1
  22. package/dist/components/Buttons/BackToArticlesButton.esm.js.map +1 -1
  23. package/dist/components/Buttons/BackToCollectionsButton.esm.js +5 -1
  24. package/dist/components/Buttons/BackToCollectionsButton.esm.js.map +1 -1
  25. package/dist/components/Buttons/BackToQuestionsButton.esm.js +5 -1
  26. package/dist/components/Buttons/BackToQuestionsButton.esm.js.map +1 -1
  27. package/dist/components/Buttons/CollectionFollowButton.esm.js +40 -0
  28. package/dist/components/Buttons/CollectionFollowButton.esm.js.map +1 -0
  29. package/dist/components/Buttons/CreateCollectionButton.esm.js +5 -1
  30. package/dist/components/Buttons/CreateCollectionButton.esm.js.map +1 -1
  31. package/dist/components/Buttons/EntityFollowButton.esm.js +7 -1
  32. package/dist/components/Buttons/EntityFollowButton.esm.js.map +1 -1
  33. package/dist/components/Buttons/FavoriteButton.esm.js +4 -1
  34. package/dist/components/Buttons/FavoriteButton.esm.js.map +1 -1
  35. package/dist/components/Buttons/LinkButton.esm.js +6 -1
  36. package/dist/components/Buttons/LinkButton.esm.js.map +1 -1
  37. package/dist/components/Buttons/TagFollowButton.esm.js +7 -1
  38. package/dist/components/Buttons/TagFollowButton.esm.js.map +1 -1
  39. package/dist/components/Buttons/UserFollowButton.esm.js +7 -1
  40. package/dist/components/Buttons/UserFollowButton.esm.js.map +1 -1
  41. package/dist/components/Buttons/VoteButtons.esm.js +2 -2
  42. package/dist/components/Buttons/VoteButtons.esm.js.map +1 -1
  43. package/dist/components/Buttons/WriteArticleButton.esm.js +5 -1
  44. package/dist/components/Buttons/WriteArticleButton.esm.js.map +1 -1
  45. package/dist/components/CollectionCard/CollectionCard.esm.js +7 -3
  46. package/dist/components/CollectionCard/CollectionCard.esm.js.map +1 -1
  47. package/dist/components/CollectionForm/CollectionForm.esm.js +5 -1
  48. package/dist/components/CollectionForm/CollectionForm.esm.js.map +1 -1
  49. package/dist/components/CollectionsGrid/CollectionsGrid.esm.js +61 -14
  50. package/dist/components/CollectionsGrid/CollectionsGrid.esm.js.map +1 -1
  51. package/dist/components/CollectionsGrid/CollectionsGridContent.esm.js +13 -27
  52. package/dist/components/CollectionsGrid/CollectionsGridContent.esm.js.map +1 -1
  53. package/dist/components/CollectionsGrid/CollectionsGridItem.esm.js +28 -19
  54. package/dist/components/CollectionsGrid/CollectionsGridItem.esm.js.map +1 -1
  55. package/dist/components/CollectionsGrid/NoCollectionsCard.esm.js +25 -0
  56. package/dist/components/CollectionsGrid/NoCollectionsCard.esm.js.map +1 -0
  57. package/dist/components/CommentSection/CommentList.esm.js +4 -1
  58. package/dist/components/CommentSection/CommentList.esm.js.map +1 -1
  59. package/dist/components/CommentSection/CommentSection.esm.js +4 -1
  60. package/dist/components/CommentSection/CommentSection.esm.js.map +1 -1
  61. package/dist/components/DeleteModal/DeleteModal.esm.js +5 -1
  62. package/dist/components/DeleteModal/DeleteModal.esm.js.map +1 -1
  63. package/dist/components/EntitiesGrid/EntitiesGrid.esm.js +65 -22
  64. package/dist/components/EntitiesGrid/EntitiesGrid.esm.js.map +1 -1
  65. package/dist/components/EntitiesGrid/EntitiesGridContent.esm.js +31 -0
  66. package/dist/components/EntitiesGrid/EntitiesGridContent.esm.js.map +1 -0
  67. package/dist/components/EntitiesGrid/EntitiesGridItem.esm.js +6 -1
  68. package/dist/components/EntitiesGrid/EntitiesGridItem.esm.js.map +1 -1
  69. package/dist/components/EntitiesGrid/NoEntitiesCard.esm.js +25 -0
  70. package/dist/components/EntitiesGrid/NoEntitiesCard.esm.js.map +1 -0
  71. package/dist/components/FilterPanel/DateRangeFilter.esm.js +6 -1
  72. package/dist/components/FilterPanel/DateRangeFilter.esm.js.map +1 -1
  73. package/dist/components/FilterPanel/FilterPanel.esm.js +9 -5
  74. package/dist/components/FilterPanel/FilterPanel.esm.js.map +1 -1
  75. package/dist/components/FollowedLists/FollowedCollectionsList.esm.js +49 -0
  76. package/dist/components/FollowedLists/FollowedCollectionsList.esm.js.map +1 -0
  77. package/dist/components/FollowedLists/FollowedEntitiesList.esm.js +7 -1
  78. package/dist/components/FollowedLists/FollowedEntitiesList.esm.js.map +1 -1
  79. package/dist/components/FollowedLists/FollowedTagsList.esm.js +7 -1
  80. package/dist/components/FollowedLists/FollowedTagsList.esm.js.map +1 -1
  81. package/dist/components/HeaderImageInput/HeaderImageInput.esm.js +5 -1
  82. package/dist/components/HeaderImageInput/HeaderImageInput.esm.js.map +1 -1
  83. package/dist/components/HomePageCards/ImpactCard.esm.js +6 -1
  84. package/dist/components/HomePageCards/ImpactCard.esm.js.map +1 -1
  85. package/dist/components/HomePageCards/PostsCard.esm.js +8 -3
  86. package/dist/components/HomePageCards/PostsCard.esm.js.map +1 -1
  87. package/dist/components/LeftMenu/LeftMenu.esm.js +11 -3
  88. package/dist/components/LeftMenu/LeftMenu.esm.js.map +1 -1
  89. package/dist/components/Links/Links.esm.js +5 -1
  90. package/dist/components/Links/Links.esm.js.map +1 -1
  91. package/dist/components/MarkdownEditor/MarkdownEditor.esm.js.map +1 -1
  92. package/dist/components/MarkdownRenderer/MarkdownRenderer.esm.js +1 -1
  93. package/dist/components/MarkdownRenderer/MarkdownRenderer.esm.js.map +1 -1
  94. package/dist/components/PostAnonymouslyCheckbox/PostAnonymouslyCheckbox.esm.js +6 -1
  95. package/dist/components/PostAnonymouslyCheckbox/PostAnonymouslyCheckbox.esm.js.map +1 -1
  96. package/dist/components/PostForm/EntitiesInput.esm.js +5 -1
  97. package/dist/components/PostForm/EntitiesInput.esm.js.map +1 -1
  98. package/dist/components/PostForm/PostForm.esm.js +42 -5
  99. package/dist/components/PostForm/PostForm.esm.js.map +1 -1
  100. package/dist/components/PostForm/TagInput.esm.js +5 -2
  101. package/dist/components/PostForm/TagInput.esm.js.map +1 -1
  102. package/dist/components/PostHighlightList/PostHighlightList.esm.js +5 -1
  103. package/dist/components/PostHighlightList/PostHighlightList.esm.js.map +1 -1
  104. package/dist/components/PostsContainer/NoPostsCard.esm.js +6 -1
  105. package/dist/components/PostsContainer/NoPostsCard.esm.js.map +1 -1
  106. package/dist/components/PostsContainer/PostList.esm.js +16 -38
  107. package/dist/components/PostsContainer/PostList.esm.js.map +1 -1
  108. package/dist/components/PostsContainer/PostListItem.esm.js +6 -1
  109. package/dist/components/PostsContainer/PostListItem.esm.js.map +1 -1
  110. package/dist/components/PostsContainer/PostsContainer.esm.js +6 -2
  111. package/dist/components/PostsContainer/PostsContainer.esm.js.map +1 -1
  112. package/dist/components/PostsGrid/PostsGrid.esm.js +11 -3
  113. package/dist/components/PostsGrid/PostsGrid.esm.js.map +1 -1
  114. package/dist/components/PostsGrid/PostsGridContent.esm.js +23 -12
  115. package/dist/components/PostsGrid/PostsGridContent.esm.js.map +1 -1
  116. package/dist/components/PostsGrid/PostsGridItem.esm.js +6 -1
  117. package/dist/components/PostsGrid/PostsGridItem.esm.js.map +1 -1
  118. package/dist/components/QetaPagination/QetaPagination.esm.js +55 -0
  119. package/dist/components/QetaPagination/QetaPagination.esm.js.map +1 -0
  120. package/dist/components/QuestionCard/QuestionCard.esm.js +5 -1
  121. package/dist/components/QuestionCard/QuestionCard.esm.js.map +1 -1
  122. package/dist/components/QuestionsTable/QuestionsTable.esm.js +6 -1
  123. package/dist/components/QuestionsTable/QuestionsTable.esm.js.map +1 -1
  124. package/dist/components/SelectTemplateList/SelectTemplateList.esm.js +48 -0
  125. package/dist/components/SelectTemplateList/SelectTemplateList.esm.js.map +1 -0
  126. package/dist/components/StatsChart/StatsChart.esm.js +37 -13
  127. package/dist/components/StatsChart/StatsChart.esm.js.map +1 -1
  128. package/dist/components/StatsChart/util.esm.js +9 -0
  129. package/dist/components/StatsChart/util.esm.js.map +1 -0
  130. package/dist/components/SummaryStatsGrid/SummaryStatsGrid.esm.js +25 -1
  131. package/dist/components/SummaryStatsGrid/SummaryStatsGrid.esm.js.map +1 -1
  132. package/dist/components/TagsAndEntities/CollectionChip.esm.js +85 -0
  133. package/dist/components/TagsAndEntities/CollectionChip.esm.js.map +1 -0
  134. package/dist/components/TagsAndEntities/EntityChip.esm.js +5 -1
  135. package/dist/components/TagsAndEntities/EntityChip.esm.js.map +1 -1
  136. package/dist/components/TagsAndEntities/TagChip.esm.js +5 -1
  137. package/dist/components/TagsAndEntities/TagChip.esm.js.map +1 -1
  138. package/dist/components/TagsAndEntities/TagsAndEntities.esm.js +3 -0
  139. package/dist/components/TagsAndEntities/TagsAndEntities.esm.js.map +1 -1
  140. package/dist/components/TagsGrid/EditTagModal.esm.js +4 -1
  141. package/dist/components/TagsGrid/EditTagModal.esm.js.map +1 -1
  142. package/dist/components/TagsGrid/NoTagsCard.esm.js +25 -0
  143. package/dist/components/TagsGrid/NoTagsCard.esm.js.map +1 -0
  144. package/dist/components/TagsGrid/TagGridItem.esm.js +6 -1
  145. package/dist/components/TagsGrid/TagGridItem.esm.js.map +1 -1
  146. package/dist/components/TagsGrid/TagsGrid.esm.js +68 -22
  147. package/dist/components/TagsGrid/TagsGrid.esm.js.map +1 -1
  148. package/dist/components/TagsGrid/TagsGridContent.esm.js +31 -0
  149. package/dist/components/TagsGrid/TagsGridContent.esm.js.map +1 -0
  150. package/dist/components/TemplateList/TemplateForm.esm.js +207 -0
  151. package/dist/components/TemplateList/TemplateForm.esm.js.map +1 -0
  152. package/dist/components/TemplateList/TemplateList.esm.js +105 -0
  153. package/dist/components/TemplateList/TemplateList.esm.js.map +1 -0
  154. package/dist/components/TopRankingUsersCard/TopRankingUsersCard.esm.js +6 -1
  155. package/dist/components/TopRankingUsersCard/TopRankingUsersCard.esm.js.map +1 -1
  156. package/dist/components/UsersGrid/NoUsersCard.esm.js +25 -0
  157. package/dist/components/UsersGrid/NoUsersCard.esm.js.map +1 -0
  158. package/dist/components/UsersGrid/UsersGrid.esm.js +53 -19
  159. package/dist/components/UsersGrid/UsersGrid.esm.js.map +1 -1
  160. package/dist/components/UsersGrid/UsersGridContent.esm.js +31 -0
  161. package/dist/components/UsersGrid/UsersGridContent.esm.js.map +1 -0
  162. package/dist/components/UsersGrid/UsersGridItem.esm.js +7 -1
  163. package/dist/components/UsersGrid/UsersGridItem.esm.js.map +1 -1
  164. package/dist/hooks/useBasePath.esm.js +12 -0
  165. package/dist/hooks/useBasePath.esm.js.map +1 -0
  166. package/dist/hooks/useBaseUrl.esm.js +13 -0
  167. package/dist/hooks/useBaseUrl.esm.js.map +1 -0
  168. package/dist/hooks/useCollectionsFollow.esm.js +59 -0
  169. package/dist/hooks/useCollectionsFollow.esm.js.map +1 -0
  170. package/dist/hooks/useEntityAuthor.esm.js +90 -0
  171. package/dist/hooks/useEntityAuthor.esm.js.map +1 -0
  172. package/dist/hooks/useEntityFollow.esm.js +49 -0
  173. package/dist/hooks/useEntityFollow.esm.js.map +1 -0
  174. package/dist/hooks/useEntityQueryParameter.esm.js +14 -0
  175. package/dist/hooks/useEntityQueryParameter.esm.js.map +1 -0
  176. package/dist/hooks/useFormStyles.esm.js +26 -0
  177. package/dist/hooks/useFormStyles.esm.js.map +1 -0
  178. package/dist/hooks/useIdentityApi.esm.js +12 -0
  179. package/dist/hooks/useIdentityApi.esm.js.map +1 -0
  180. package/dist/hooks/useIsDarkTheme.esm.js +12 -0
  181. package/dist/hooks/useIsDarkTheme.esm.js.map +1 -0
  182. package/dist/hooks/useIsModerator.esm.js +23 -0
  183. package/dist/hooks/useIsModerator.esm.js.map +1 -0
  184. package/dist/hooks/usePaginatedPosts.esm.js +176 -0
  185. package/dist/hooks/usePaginatedPosts.esm.js.map +1 -0
  186. package/dist/hooks/useQetaApi.esm.js +13 -0
  187. package/dist/hooks/useQetaApi.esm.js.map +1 -0
  188. package/dist/hooks/useStyles.esm.js +141 -0
  189. package/dist/hooks/useStyles.esm.js.map +1 -0
  190. package/dist/hooks/useTagsFollow.esm.js +53 -0
  191. package/dist/hooks/useTagsFollow.esm.js.map +1 -0
  192. package/dist/hooks/useTranslation.esm.js +9 -0
  193. package/dist/hooks/useTranslation.esm.js.map +1 -0
  194. package/dist/hooks/useUserFollow.esm.js +53 -0
  195. package/dist/hooks/useUserFollow.esm.js.map +1 -0
  196. package/dist/hooks/useVoting.esm.js +140 -0
  197. package/dist/hooks/useVoting.esm.js.map +1 -0
  198. package/dist/index.d.ts +402 -306
  199. package/dist/index.esm.js +14 -2
  200. package/dist/index.esm.js.map +1 -1
  201. package/dist/routes.esm.js +6 -1
  202. package/dist/routes.esm.js.map +1 -1
  203. package/dist/translation.esm.js +63 -4
  204. package/dist/translation.esm.js.map +1 -1
  205. package/package.json +5 -2
  206. package/dist/utils/hooks.esm.js +0 -701
  207. package/dist/utils/hooks.esm.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ import { Card, CardContent, Grid, Typography } from '@material-ui/core';
2
+ import React from 'react';
3
+ import '@backstage/core-plugin-api';
4
+ import '../../api.esm.js';
5
+ import 'react-use';
6
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
7
+ import '../../hooks/useStyles.esm.js';
8
+ import 'react-use/lib/useAsync';
9
+
10
+ const NoUsersCard = () => {
11
+ const { t } = useTranslation();
12
+ return /* @__PURE__ */ React.createElement(Card, { style: { marginTop: "2rem" } }, /* @__PURE__ */ React.createElement(CardContent, null, /* @__PURE__ */ React.createElement(
13
+ Grid,
14
+ {
15
+ container: true,
16
+ justifyContent: "center",
17
+ alignItems: "center",
18
+ direction: "column"
19
+ },
20
+ /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, t(`usersPage.users`, { count: 0 })))
21
+ )));
22
+ };
23
+
24
+ export { NoUsersCard };
25
+ //# sourceMappingURL=NoUsersCard.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoUsersCard.esm.js","sources":["../../../src/components/UsersGrid/NoUsersCard.tsx"],"sourcesContent":["import { Card, CardContent, Grid, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { useTranslation } from '../../hooks';\n\nexport const NoUsersCard = () => {\n const { t } = useTranslation();\n\n return (\n <Card style={{ marginTop: '2rem' }}>\n <CardContent>\n <Grid\n container\n justifyContent=\"center\"\n alignItems=\"center\"\n direction=\"column\"\n >\n <Grid item>\n <Typography variant=\"h6\">\n {t(`usersPage.users`, { count: 0 })}\n </Typography>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAIO,MAAM,cAAc,MAAM;AAC/B,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA,CAAA;AAE7B,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,KAAO,EAAA,EAAE,WAAW,MAAO,EAAA,EAAA,sCAC9B,WACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,SAAS,EAAA,IAAA;AAAA,MACT,cAAe,EAAA,QAAA;AAAA,MACf,UAAW,EAAA,QAAA;AAAA,MACX,SAAU,EAAA,QAAA;AAAA,KAAA;AAAA,oBAET,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,sCACP,UAAW,EAAA,EAAA,OAAA,EAAQ,IACjB,EAAA,EAAA,CAAA,CAAE,mBAAmB,EAAE,KAAA,EAAO,CAAE,EAAC,CACpC,CACF,CAAA;AAAA,GAEJ,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -1,30 +1,55 @@
1
- import { Grid, TextField, IconButton, Typography } from '@material-ui/core';
2
- import React from 'react';
3
- import { useTranslation, useQetaApi } from '../../utils/hooks.esm.js';
4
- import { Progress, WarningPanel } from '@backstage/core-components';
5
- import { UsersGridItem } from './UsersGridItem.esm.js';
1
+ import { Grid, TextField, IconButton } from '@material-ui/core';
2
+ import React, { useEffect } from 'react';
3
+ import { useQetaApi } from '../../hooks/useQetaApi.esm.js';
4
+ import '@backstage/core-plugin-api';
5
+ import '../../api.esm.js';
6
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
7
+ import '../../hooks/useStyles.esm.js';
8
+ import 'react-use/lib/useAsync';
9
+ import { QetaPagination } from '../QetaPagination/QetaPagination.esm.js';
10
+ import { UsersGridContent } from './UsersGridContent.esm.js';
11
+ import useDebounce from 'react-use/lib/useDebounce';
12
+ import { NoUsersCard } from './NoUsersCard.esm.js';
6
13
 
7
14
  const UsersGrid = () => {
15
+ const [page, setPage] = React.useState(1);
16
+ const [pageCount, setPageCount] = React.useState(1);
17
+ const [entitiesPerPage, setEntitiesPerPage] = React.useState(25);
8
18
  const [searchQuery, setSearchQuery] = React.useState("");
19
+ const [filters, setFilters] = React.useState({
20
+ order: "desc",
21
+ searchQuery: ""
22
+ });
9
23
  const { t } = useTranslation();
10
24
  const {
11
25
  value: response,
12
26
  loading,
13
27
  error
14
- } = useQetaApi((api) => api.getUsers(), []);
15
- if (loading) {
16
- return /* @__PURE__ */ React.createElement(Progress, null);
17
- }
18
- if (error || response === void 0) {
19
- return /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: t("usersPage.errorLoading") }, error?.message);
20
- }
21
- const filterData = (query, data) => {
22
- if (!query) {
23
- return data;
28
+ } = useQetaApi(
29
+ (api) => api.getUsers({
30
+ limit: entitiesPerPage,
31
+ offset: (page - 1) * entitiesPerPage,
32
+ ...filters
33
+ }),
34
+ [entitiesPerPage, page, filters]
35
+ );
36
+ useDebounce(
37
+ () => {
38
+ if (filters.searchQuery !== searchQuery) {
39
+ setFilters({ ...filters, searchQuery });
40
+ }
41
+ },
42
+ 400,
43
+ [searchQuery]
44
+ );
45
+ useEffect(() => {
46
+ if (response) {
47
+ setPageCount(Math.ceil(response.total / entitiesPerPage));
24
48
  }
25
- return data.filter((entity) => entity.userRef.toLowerCase().includes(query));
26
- };
27
- const entities = filterData(searchQuery, response);
49
+ }, [response, entitiesPerPage]);
50
+ if (!response?.users || response.users.length === 0) {
51
+ return /* @__PURE__ */ React.createElement(NoUsersCard, null);
52
+ }
28
53
  return /* @__PURE__ */ React.createElement(Grid, { container: true, className: "qetaUsersContainer" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
29
54
  TextField,
30
55
  {
@@ -36,7 +61,16 @@ const UsersGrid = () => {
36
61
  placeholder: t("usersPage.search.placeholder"),
37
62
  size: "small"
38
63
  }
39
- ), /* @__PURE__ */ React.createElement(IconButton, { type: "submit", "aria-label": "search" })), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: "qetaUsersContainerTitle" }, t("usersPage.users", { count: entities.length }))), /* @__PURE__ */ React.createElement(Grid, { container: true, item: true, xs: 12, alignItems: "stretch" }, entities.map((entity) => /* @__PURE__ */ React.createElement(UsersGridItem, { user: entity, key: entity.userRef }))));
64
+ ), /* @__PURE__ */ React.createElement(IconButton, { type: "submit", "aria-label": "search" })), /* @__PURE__ */ React.createElement(UsersGridContent, { response, loading, error }), /* @__PURE__ */ React.createElement(
65
+ QetaPagination,
66
+ {
67
+ pageSize: entitiesPerPage,
68
+ handlePageChange: (_e, p) => setPage(p),
69
+ handlePageSizeChange: (e) => setEntitiesPerPage(Number(e.target.value)),
70
+ page,
71
+ pageCount
72
+ }
73
+ ));
40
74
  };
41
75
 
42
76
  export { UsersGrid };
@@ -1 +1 @@
1
- {"version":3,"file":"UsersGrid.esm.js","sources":["../../../src/components/UsersGrid/UsersGrid.tsx"],"sourcesContent":["import { Grid, IconButton, TextField, Typography } from '@material-ui/core';\nimport React from 'react';\nimport { useQetaApi, useTranslation } from '../../utils/hooks';\nimport { Progress, WarningPanel } from '@backstage/core-components';\nimport { UserResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { UsersGridItem } from './UsersGridItem';\n\nexport const UsersGrid = () => {\n const [searchQuery, setSearchQuery] = React.useState('');\n const { t } = useTranslation();\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(api => api.getUsers(), []);\n\n if (loading) {\n return <Progress />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('usersPage.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n const filterData = (query: string, data: UserResponse[]) => {\n if (!query) {\n return data;\n }\n return data.filter(entity => entity.userRef.toLowerCase().includes(query));\n };\n\n const entities = filterData(searchQuery, response);\n\n return (\n <Grid container className=\"qetaUsersContainer\">\n <Grid item xs={12}>\n <TextField\n id=\"search-bar\"\n className=\"text qetaUsersContainerSearchInput\"\n onChange={(\n event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,\n ) => setSearchQuery(event.target.value)}\n label={t('usersPage.search.label')}\n variant=\"outlined\"\n placeholder={t('usersPage.search.placeholder')}\n size=\"small\"\n />\n <IconButton type=\"submit\" aria-label=\"search\" />\n </Grid>\n <Grid item xs={12}>\n <Typography variant=\"h6\" className=\"qetaUsersContainerTitle\">\n {t('usersPage.users', { count: entities.length })}\n </Typography>\n </Grid>\n <Grid container item xs={12} alignItems=\"stretch\">\n {entities.map(entity => (\n <UsersGridItem user={entity} key={entity.userRef} />\n ))}\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;AAOO,MAAM,YAAY,MAAM;AAC7B,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,KAAA,CAAM,SAAS,EAAE,CAAA,CAAA;AACvD,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA,CAAA;AAE7B,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,QAAA;AAAA,IACP,OAAA;AAAA,IACA,KAAA;AAAA,MACE,UAAW,CAAA,CAAA,GAAA,KAAO,IAAI,QAAS,EAAA,EAAG,EAAE,CAAA,CAAA;AAExC,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,GACnB;AAEA,EAAI,IAAA,KAAA,IAAS,aAAa,KAAW,CAAA,EAAA;AACnC,IACE,uBAAA,KAAA,CAAA,aAAA,CAAC,gBAAa,QAAS,EAAA,OAAA,EAAQ,OAAO,CAAE,CAAA,wBAAwB,CAC7D,EAAA,EAAA,KAAA,EAAO,OACV,CAAA,CAAA;AAAA,GAEJ;AAEA,EAAM,MAAA,UAAA,GAAa,CAAC,KAAA,EAAe,IAAyB,KAAA;AAC1D,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AACA,IAAO,OAAA,IAAA,CAAK,OAAO,CAAU,MAAA,KAAA,MAAA,CAAO,QAAQ,WAAY,EAAA,CAAE,QAAS,CAAA,KAAK,CAAC,CAAA,CAAA;AAAA,GAC3E,CAAA;AAEA,EAAM,MAAA,QAAA,GAAW,UAAW,CAAA,WAAA,EAAa,QAAQ,CAAA,CAAA;AAEjD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAS,IAAC,EAAA,SAAA,EAAU,oBACxB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,EACb,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,EAAG,EAAA,YAAA;AAAA,MACH,SAAU,EAAA,oCAAA;AAAA,MACV,UAAU,CACR,KAAA,KACG,cAAe,CAAA,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,MACtC,KAAA,EAAO,EAAE,wBAAwB,CAAA;AAAA,MACjC,OAAQ,EAAA,UAAA;AAAA,MACR,WAAA,EAAa,EAAE,8BAA8B,CAAA;AAAA,MAC7C,IAAK,EAAA,OAAA;AAAA,KAAA;AAAA,GACP,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,IAAK,EAAA,QAAA,EAAS,cAAW,QAAS,EAAA,CAChD,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,MAAC,EAAI,EAAA,EAAA,EAAA,kBACZ,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,IAAA,EAAK,WAAU,yBAChC,EAAA,EAAA,CAAA,CAAE,iBAAmB,EAAA,EAAE,KAAO,EAAA,QAAA,CAAS,QAAQ,CAClD,CACF,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,WAAS,IAAC,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,EAAI,EAAA,UAAA,EAAW,aACrC,QAAS,CAAA,GAAA,CAAI,CACZ,MAAA,qBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,IAAA,EAAM,MAAQ,EAAA,GAAA,EAAK,MAAO,CAAA,OAAA,EAAS,CACnD,CACH,CACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"UsersGrid.esm.js","sources":["../../../src/components/UsersGrid/UsersGrid.tsx"],"sourcesContent":["import { Grid, IconButton, TextField } from '@material-ui/core';\nimport React, { useEffect } from 'react';\nimport { useQetaApi, useTranslation } from '../../hooks';\nimport { QetaPagination } from '../QetaPagination/QetaPagination';\nimport { UsersGridContent } from './UsersGridContent';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { NoUsersCard } from './NoUsersCard';\n\ntype EntityFilters = {\n order: 'asc' | 'desc';\n orderBy?: 'userRef';\n searchQuery: string;\n};\n\nexport const UsersGrid = () => {\n const [page, setPage] = React.useState(1);\n const [pageCount, setPageCount] = React.useState(1);\n const [entitiesPerPage, setEntitiesPerPage] = React.useState(25);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [filters, setFilters] = React.useState<EntityFilters>({\n order: 'desc',\n searchQuery: '',\n });\n const { t } = useTranslation();\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api =>\n api.getUsers({\n limit: entitiesPerPage,\n offset: (page - 1) * entitiesPerPage,\n ...filters,\n }),\n [entitiesPerPage, page, filters],\n );\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 400,\n [searchQuery],\n );\n\n useEffect(() => {\n if (response) {\n setPageCount(Math.ceil(response.total / entitiesPerPage));\n }\n }, [response, entitiesPerPage]);\n\n if (!response?.users || response.users.length === 0) {\n return <NoUsersCard />;\n }\n\n return (\n <Grid container className=\"qetaUsersContainer\">\n <Grid item xs={12}>\n <TextField\n id=\"search-bar\"\n className=\"text qetaUsersContainerSearchInput\"\n onChange={(\n event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,\n ) => setSearchQuery(event.target.value)}\n label={t('usersPage.search.label')}\n variant=\"outlined\"\n placeholder={t('usersPage.search.placeholder')}\n size=\"small\"\n />\n <IconButton type=\"submit\" aria-label=\"search\" />\n </Grid>\n <UsersGridContent response={response} loading={loading} error={error} />\n <QetaPagination\n pageSize={entitiesPerPage}\n handlePageChange={(_e, p) => setPage(p)}\n handlePageSizeChange={e => setEntitiesPerPage(Number(e.target.value))}\n page={page}\n pageCount={pageCount}\n />\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { Grid, Typography } from '@material-ui/core';
2
+ import React, { useState, useEffect } from 'react';
3
+ import { Progress, WarningPanel } from '@backstage/core-components';
4
+ import '@backstage/core-plugin-api';
5
+ import '../../api.esm.js';
6
+ import 'react-use';
7
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
8
+ import '../../hooks/useStyles.esm.js';
9
+ import 'react-use/lib/useAsync';
10
+ import { UsersGridItem } from './UsersGridItem.esm.js';
11
+
12
+ const UsersGridContent = (props) => {
13
+ const { response, loading, error } = props;
14
+ const { t } = useTranslation();
15
+ const [initialLoad, setInitialLoad] = useState(true);
16
+ useEffect(() => {
17
+ if (!initialLoad) {
18
+ setInitialLoad(false);
19
+ }
20
+ }, [initialLoad, loading]);
21
+ if (loading && initialLoad) {
22
+ return /* @__PURE__ */ React.createElement(Progress, null);
23
+ }
24
+ if (error || response === void 0) {
25
+ return /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: t("tagPage.errorLoading") }, error?.message);
26
+ }
27
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6", className: "qetaUsersContainerTitle" }, t("usersPage.users", { count: response.total }))), /* @__PURE__ */ React.createElement(Grid, { container: true, item: true, xs: 12, alignItems: "stretch" }, response.users.map((entity) => /* @__PURE__ */ React.createElement(UsersGridItem, { user: entity, key: entity.userRef }))));
28
+ };
29
+
30
+ export { UsersGridContent };
31
+ //# sourceMappingURL=UsersGridContent.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsersGridContent.esm.js","sources":["../../../src/components/UsersGrid/UsersGridContent.tsx"],"sourcesContent":["import { Grid, Typography } from '@material-ui/core';\nimport React, { useEffect, useState } from 'react';\nimport { UsersResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { Progress, WarningPanel } from '@backstage/core-components';\nimport { useTranslation } from '../../hooks';\nimport { UsersGridItem } from './UsersGridItem';\n\nexport const UsersGridContent = (props: {\n loading: boolean;\n error: any;\n response?: UsersResponse;\n}) => {\n const { response, loading, error } = props;\n const { t } = useTranslation();\n const [initialLoad, setInitialLoad] = useState(true);\n\n useEffect(() => {\n if (!initialLoad) {\n setInitialLoad(false);\n }\n }, [initialLoad, loading]);\n\n if (loading && initialLoad) {\n return <Progress />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('tagPage.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n return (\n <>\n <Grid item xs={12}>\n <Typography variant=\"h6\" className=\"qetaUsersContainerTitle\">\n {t('usersPage.users', { count: response.total })}\n </Typography>\n </Grid>\n <Grid container item xs={12} alignItems=\"stretch\">\n {response.users.map(entity => (\n <UsersGridItem user={entity} key={entity.userRef} />\n ))}\n </Grid>\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAOa,MAAA,gBAAA,GAAmB,CAAC,KAI3B,KAAA;AACJ,EAAA,MAAM,EAAE,QAAA,EAAU,OAAS,EAAA,KAAA,EAAU,GAAA,KAAA,CAAA;AACrC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA,CAAA;AAC7B,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,IAAI,CAAA,CAAA;AAEnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AAAA,KACtB;AAAA,GACC,EAAA,CAAC,WAAa,EAAA,OAAO,CAAC,CAAA,CAAA;AAEzB,EAAA,IAAI,WAAW,WAAa,EAAA;AAC1B,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA,CAAA;AAAA,GACnB;AAEA,EAAI,IAAA,KAAA,IAAS,aAAa,KAAW,CAAA,EAAA;AACnC,IACE,uBAAA,KAAA,CAAA,aAAA,CAAC,gBAAa,QAAS,EAAA,OAAA,EAAQ,OAAO,CAAE,CAAA,sBAAsB,CAC3D,EAAA,EAAA,KAAA,EAAO,OACV,CAAA,CAAA;AAAA,GAEJ;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,sCACG,IAAK,EAAA,EAAA,IAAA,EAAI,MAAC,EAAI,EAAA,EAAA,EAAA,sCACZ,UAAW,EAAA,EAAA,OAAA,EAAQ,MAAK,SAAU,EAAA,yBAAA,EAAA,EAChC,EAAE,iBAAmB,EAAA,EAAE,OAAO,QAAS,CAAA,KAAA,EAAO,CACjD,CACF,CAAA,sCACC,IAAK,EAAA,EAAA,SAAA,EAAS,MAAC,IAAI,EAAA,IAAA,EAAC,IAAI,EAAI,EAAA,UAAA,EAAW,aACrC,QAAS,CAAA,KAAA,CAAM,IAAI,CAClB,MAAA,qBAAA,KAAA,CAAA,aAAA,CAAC,iBAAc,IAAM,EAAA,MAAA,EAAQ,KAAK,MAAO,CAAA,OAAA,EAAS,CACnD,CACH,CACF,CAAA,CAAA;AAEJ;;;;"}
@@ -2,10 +2,16 @@ import { Grid, Card, CardActionArea, CardHeader, Avatar, CardContent, Typography
2
2
  import React from 'react';
3
3
  import { useRouteRef } from '@backstage/core-plugin-api';
4
4
  import { useNavigate } from 'react-router-dom';
5
- import { useTranslation, useEntityAuthor, useUserFollow, useIdentityApi } from '../../utils/hooks.esm.js';
6
5
  import { useEntityPresentation } from '@backstage/plugin-catalog-react';
7
6
  import { userRouteRef } from '../../routes.esm.js';
8
7
  import { parseEntityRef } from '@backstage/catalog-model';
8
+ import '../../api.esm.js';
9
+ import 'react-use';
10
+ import { useTranslation } from '../../hooks/useTranslation.esm.js';
11
+ import { useUserFollow } from '../../hooks/useUserFollow.esm.js';
12
+ import '../../hooks/useStyles.esm.js';
13
+ import { useIdentityApi } from '../../hooks/useIdentityApi.esm.js';
14
+ import { useEntityAuthor } from '../../hooks/useEntityAuthor.esm.js';
9
15
 
10
16
  const UsersGridItem = (props) => {
11
17
  const { user } = props;
@@ -1 +1 @@
1
- {"version":3,"file":"UsersGridItem.esm.js","sources":["../../../src/components/UsersGrid/UsersGridItem.tsx"],"sourcesContent":["import { UserResponse } from '@drodil/backstage-plugin-qeta-common';\nimport {\n Avatar,\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useNavigate } from 'react-router-dom';\nimport { useIdentityApi, useTranslation } from '../../utils';\nimport { useEntityAuthor, useUserFollow } from '../../utils/hooks';\nimport { useEntityPresentation } from '@backstage/plugin-catalog-react';\nimport { userRouteRef } from '../../routes';\nimport { parseEntityRef } from '@backstage/catalog-model';\n\nexport const UsersGridItem = (props: { user: UserResponse }) => {\n const { user } = props;\n const userRoute = useRouteRef(userRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const compound = parseEntityRef(user.userRef);\n const { primaryTitle, Icon } = useEntityPresentation(compound);\n const { name, initials, user: userEntity } = useEntityAuthor(user);\n const users = useUserFollow();\n const {\n value: currentUser,\n loading: loadingUser,\n error: userError,\n } = useIdentityApi(api => api.getBackstageIdentity(), []);\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea\n onClick={() => navigate(`${userRoute()}/${user.userRef}`)}\n >\n <CardHeader\n title={primaryTitle}\n avatar={\n Icon ? (\n <Avatar\n src={userEntity?.spec?.profile?.picture}\n className=\"avatar\"\n alt={name}\n variant=\"rounded\"\n >\n {initials}\n </Avatar>\n ) : null\n }\n />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', {\n count: user.totalQuestions,\n itemType: 'question',\n })}\n {' · '}\n {t('common.answers', {\n count: user.totalAnswers,\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalArticles,\n itemType: 'article',\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalComments,\n itemType: 'comment',\n })}\n {' · '}\n {t('common.votes', {\n count: user.totalVotes,\n })}\n {' · '}\n {t('common.viewsShort', {\n count: user.totalViews,\n })}\n </Typography>\n </CardContent>\n </CardActionArea>\n {!loadingUser &&\n !userError &&\n currentUser?.userEntityRef !== user.userRef && (\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('userButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={\n users.isFollowingUser(user.userRef)\n ? 'secondary'\n : 'primary'\n }\n onClick={() => {\n if (users.isFollowingUser(user.userRef)) {\n users.unfollowUser(user.userRef);\n } else {\n users.followUser(user.userRef);\n }\n }}\n >\n {users.isFollowingUser(user.userRef)\n ? t('userButton.unfollow')\n : t('userButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n </Grid>\n </CardActions>\n )}\n </Card>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UsersGridItem.esm.js","sources":["../../../src/components/UsersGrid/UsersGridItem.tsx"],"sourcesContent":["import { UserResponse } from '@drodil/backstage-plugin-qeta-common';\nimport {\n Avatar,\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useNavigate } from 'react-router-dom';\nimport { useEntityPresentation } from '@backstage/plugin-catalog-react';\nimport { userRouteRef } from '../../routes';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { useIdentityApi, useTranslation, useUserFollow } from '../../hooks';\nimport { useEntityAuthor } from '../../hooks/useEntityAuthor';\n\nexport const UsersGridItem = (props: { user: UserResponse }) => {\n const { user } = props;\n const userRoute = useRouteRef(userRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const compound = parseEntityRef(user.userRef);\n const { primaryTitle, Icon } = useEntityPresentation(compound);\n const { name, initials, user: userEntity } = useEntityAuthor(user);\n const users = useUserFollow();\n const {\n value: currentUser,\n loading: loadingUser,\n error: userError,\n } = useIdentityApi(api => api.getBackstageIdentity(), []);\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea\n onClick={() => navigate(`${userRoute()}/${user.userRef}`)}\n >\n <CardHeader\n title={primaryTitle}\n avatar={\n Icon ? (\n <Avatar\n src={userEntity?.spec?.profile?.picture}\n className=\"avatar\"\n alt={name}\n variant=\"rounded\"\n >\n {initials}\n </Avatar>\n ) : null\n }\n />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', {\n count: user.totalQuestions,\n itemType: 'question',\n })}\n {' · '}\n {t('common.answers', {\n count: user.totalAnswers,\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalArticles,\n itemType: 'article',\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalComments,\n itemType: 'comment',\n })}\n {' · '}\n {t('common.votes', {\n count: user.totalVotes,\n })}\n {' · '}\n {t('common.viewsShort', {\n count: user.totalViews,\n })}\n </Typography>\n </CardContent>\n </CardActionArea>\n {!loadingUser &&\n !userError &&\n currentUser?.userEntityRef !== user.userRef && (\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('userButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={\n users.isFollowingUser(user.userRef)\n ? 'secondary'\n : 'primary'\n }\n onClick={() => {\n if (users.isFollowingUser(user.userRef)) {\n users.unfollowUser(user.userRef);\n } else {\n users.followUser(user.userRef);\n }\n }}\n >\n {users.isFollowingUser(user.userRef)\n ? t('userButton.unfollow')\n : t('userButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n </Grid>\n </CardActions>\n )}\n </Card>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { trimEnd } from 'lodash';
2
+ import { useBaseUrl } from './useBaseUrl.esm.js';
3
+
4
+ const useBasePath = () => {
5
+ const base = "http://sample.dev";
6
+ const url = useBaseUrl() ?? "/";
7
+ const { pathname } = new URL(url, base);
8
+ return trimEnd(pathname, "/");
9
+ };
10
+
11
+ export { useBasePath };
12
+ //# sourceMappingURL=useBasePath.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBasePath.esm.js","sources":["../../src/hooks/useBasePath.ts"],"sourcesContent":["import { trimEnd } from 'lodash';\nimport { useBaseUrl } from './useBaseUrl';\n\nexport const useBasePath = () => {\n // baseUrl can be specified as just a path\n const base = 'http://sample.dev';\n const url = useBaseUrl() ?? '/';\n const { pathname } = new URL(url, base);\n return trimEnd(pathname, '/');\n};\n"],"names":[],"mappings":";;;AAGO,MAAM,cAAc,MAAM;AAE/B,EAAA,MAAM,IAAO,GAAA,mBAAA,CAAA;AACb,EAAM,MAAA,GAAA,GAAM,YAAgB,IAAA,GAAA,CAAA;AAC5B,EAAA,MAAM,EAAE,QAAS,EAAA,GAAI,IAAI,GAAA,CAAI,KAAK,IAAI,CAAA,CAAA;AACtC,EAAO,OAAA,OAAA,CAAQ,UAAU,GAAG,CAAA,CAAA;AAC9B;;;;"}
@@ -0,0 +1,13 @@
1
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const useBaseUrl = () => {
4
+ try {
5
+ const config = useApi(configApiRef);
6
+ return config.getOptionalString("app.baseUrl");
7
+ } catch {
8
+ return void 0;
9
+ }
10
+ };
11
+
12
+ export { useBaseUrl };
13
+ //# sourceMappingURL=useBaseUrl.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBaseUrl.esm.js","sources":["../../src/hooks/useBaseUrl.ts"],"sourcesContent":["// Url resolving logic from https://github.com/backstage/backstage/blob/master/packages/core-components/src/components/Link/Link.tsx\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\n/**\n * Returns the app base url that could be empty if the Config API is not properly implemented.\n * The only cases there would be no Config API are in tests and in storybook stories, and in those cases, it's unlikely that callers would rely on this subpath behavior.\n */\nexport const useBaseUrl = () => {\n try {\n const config = useApi(configApiRef);\n return config.getOptionalString('app.baseUrl');\n } catch {\n return undefined;\n }\n};\n"],"names":[],"mappings":";;AAQO,MAAM,aAAa,MAAM;AAC9B,EAAI,IAAA;AACF,IAAM,MAAA,MAAA,GAAS,OAAO,YAAY,CAAA,CAAA;AAClC,IAAO,OAAA,MAAA,CAAO,kBAAkB,aAAa,CAAA,CAAA;AAAA,GACvC,CAAA,MAAA;AACN,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AACF;;;;"}
@@ -0,0 +1,59 @@
1
+ import React, { useEffect, useCallback } from 'react';
2
+ import { useApi } from '@backstage/core-plugin-api';
3
+ import { qetaApiRef } from '../api.esm.js';
4
+
5
+ let followedCollections = void 0;
6
+ const useCollectionsFollow = () => {
7
+ const [collections, setCollections] = React.useState(
8
+ followedCollections ?? []
9
+ );
10
+ const [loading, setLoading] = React.useState(
11
+ followedCollections === void 0
12
+ );
13
+ const qetaApi = useApi(qetaApiRef);
14
+ useEffect(() => {
15
+ if (followedCollections === void 0) {
16
+ qetaApi.getFollowedCollections().then((res) => {
17
+ followedCollections = res.collections;
18
+ setCollections(followedCollections);
19
+ setLoading(false);
20
+ });
21
+ } else {
22
+ setCollections(followedCollections);
23
+ }
24
+ }, [qetaApi]);
25
+ const followCollection = useCallback(
26
+ (collection) => {
27
+ qetaApi.followCollection(collection.id).then(() => {
28
+ setCollections((prev) => [...prev, collection]);
29
+ followedCollections?.push(collection);
30
+ });
31
+ },
32
+ [qetaApi]
33
+ );
34
+ const unfollowCollection = useCallback(
35
+ (collection) => {
36
+ qetaApi.unfollowCollection(collection.id).then(() => {
37
+ setCollections((prev) => prev.filter((t) => t.id !== collection.id));
38
+ followedCollections = followedCollections?.filter(
39
+ (t) => t.id !== collection.id
40
+ );
41
+ });
42
+ },
43
+ [qetaApi]
44
+ );
45
+ const isFollowingCollection = useCallback(
46
+ (collection) => Boolean(collections.find((t) => t.id === collection.id)),
47
+ [collections]
48
+ );
49
+ return {
50
+ collections,
51
+ followCollection,
52
+ unfollowCollection,
53
+ isFollowingCollection,
54
+ loading
55
+ };
56
+ };
57
+
58
+ export { useCollectionsFollow };
59
+ //# sourceMappingURL=useCollectionsFollow.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCollectionsFollow.esm.js","sources":["../../src/hooks/useCollectionsFollow.ts"],"sourcesContent":["import React, { useCallback, useEffect } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../api';\nimport { Collection } from '@drodil/backstage-plugin-qeta-common';\n\nlet followedCollections: Collection[] | undefined = undefined;\n\nexport const useCollectionsFollow = () => {\n const [collections, setCollections] = React.useState<Collection[]>(\n followedCollections ?? [],\n );\n const [loading, setLoading] = React.useState(\n followedCollections === undefined,\n );\n const qetaApi = useApi(qetaApiRef);\n\n useEffect(() => {\n if (followedCollections === undefined) {\n qetaApi.getFollowedCollections().then(res => {\n followedCollections = res.collections;\n setCollections(followedCollections);\n setLoading(false);\n });\n } else {\n setCollections(followedCollections);\n }\n }, [qetaApi]);\n\n const followCollection = useCallback(\n (collection: Collection) => {\n qetaApi.followCollection(collection.id).then(() => {\n setCollections(prev => [...prev, collection]);\n followedCollections?.push(collection);\n });\n },\n [qetaApi],\n );\n\n const unfollowCollection = useCallback(\n (collection: Collection) => {\n qetaApi.unfollowCollection(collection.id).then(() => {\n setCollections(prev => prev.filter(t => t.id !== collection.id));\n followedCollections = followedCollections?.filter(\n t => t.id !== collection.id,\n );\n });\n },\n [qetaApi],\n );\n\n const isFollowingCollection = useCallback(\n (collection: Collection) =>\n Boolean(collections.find(t => t.id === collection.id)),\n [collections],\n );\n return {\n collections,\n followCollection,\n unfollowCollection,\n isFollowingCollection,\n loading,\n };\n};\n"],"names":[],"mappings":";;;;AAKA,IAAI,mBAAgD,GAAA,KAAA,CAAA,CAAA;AAE7C,MAAM,uBAAuB,MAAM;AACxC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,KAAM,CAAA,QAAA;AAAA,IAC1C,uBAAuB,EAAC;AAAA,GAC1B,CAAA;AACA,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,KAAM,CAAA,QAAA;AAAA,IAClC,mBAAwB,KAAA,KAAA,CAAA;AAAA,GAC1B,CAAA;AACA,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,wBAAwB,KAAW,CAAA,EAAA;AACrC,MAAQ,OAAA,CAAA,sBAAA,EAAyB,CAAA,IAAA,CAAK,CAAO,GAAA,KAAA;AAC3C,QAAA,mBAAA,GAAsB,GAAI,CAAA,WAAA,CAAA;AAC1B,QAAA,cAAA,CAAe,mBAAmB,CAAA,CAAA;AAClC,QAAA,UAAA,CAAW,KAAK,CAAA,CAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACI,MAAA;AACL,MAAA,cAAA,CAAe,mBAAmB,CAAA,CAAA;AAAA,KACpC;AAAA,GACF,EAAG,CAAC,OAAO,CAAC,CAAA,CAAA;AAEZ,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,CAAC,UAA2B,KAAA;AAC1B,MAAA,OAAA,CAAQ,gBAAiB,CAAA,UAAA,CAAW,EAAE,CAAA,CAAE,KAAK,MAAM;AACjD,QAAA,cAAA,CAAe,CAAQ,IAAA,KAAA,CAAC,GAAG,IAAA,EAAM,UAAU,CAAC,CAAA,CAAA;AAC5C,QAAA,mBAAA,EAAqB,KAAK,UAAU,CAAA,CAAA;AAAA,OACrC,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA,IACzB,CAAC,UAA2B,KAAA;AAC1B,MAAA,OAAA,CAAQ,kBAAmB,CAAA,UAAA,CAAW,EAAE,CAAA,CAAE,KAAK,MAAM;AACnD,QAAe,cAAA,CAAA,CAAA,IAAA,KAAQ,KAAK,MAAO,CAAA,CAAA,CAAA,KAAK,EAAE,EAAO,KAAA,UAAA,CAAW,EAAE,CAAC,CAAA,CAAA;AAC/D,QAAA,mBAAA,GAAsB,mBAAqB,EAAA,MAAA;AAAA,UACzC,CAAA,CAAA,KAAK,CAAE,CAAA,EAAA,KAAO,UAAW,CAAA,EAAA;AAAA,SAC3B,CAAA;AAAA,OACD,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAA,MAAM,qBAAwB,GAAA,WAAA;AAAA,IAC5B,CAAC,UACC,KAAA,OAAA,CAAQ,WAAY,CAAA,IAAA,CAAK,OAAK,CAAE,CAAA,EAAA,KAAO,UAAW,CAAA,EAAE,CAAC,CAAA;AAAA,IACvD,CAAC,WAAW,CAAA;AAAA,GACd,CAAA;AACA,EAAO,OAAA;AAAA,IACL,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA,qBAAA;AAAA,IACA,OAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,90 @@
1
+ import DataLoader from 'dataloader';
2
+ import { useApi, identityApiRef } from '@backstage/core-plugin-api';
3
+ import { catalogApiRef, useEntityPresentation } from '@backstage/plugin-catalog-react';
4
+ import React, { useEffect } from 'react';
5
+
6
+ const userCache = /* @__PURE__ */ new Map();
7
+ const dataLoaderFactory = (catalogApi) => new DataLoader(
8
+ async (entityRefs) => {
9
+ const { items } = await catalogApi.getEntitiesByRefs({
10
+ fields: [
11
+ "kind",
12
+ "metadata.name",
13
+ "metadata.namespace",
14
+ "spec.profile.displayName",
15
+ "spec.profile.picture"
16
+ ],
17
+ entityRefs
18
+ });
19
+ entityRefs.forEach((entityRef, index) => {
20
+ userCache.set(entityRef, items[index]);
21
+ });
22
+ return items;
23
+ },
24
+ {
25
+ name: "EntityAuthorLoader",
26
+ cacheMap: /* @__PURE__ */ new Map(),
27
+ maxBatchSize: 100,
28
+ batchScheduleFn: (callback) => {
29
+ setTimeout(callback, 50);
30
+ }
31
+ }
32
+ );
33
+ const useEntityAuthor = (entity) => {
34
+ const catalogApi = useApi(catalogApiRef);
35
+ const identityApi = useApi(identityApiRef);
36
+ const [name, setName] = React.useState(void 0);
37
+ const [user, setUser] = React.useState(null);
38
+ const [initials, setInitials] = React.useState(null);
39
+ const [currentUser, setCurrentUser] = React.useState(null);
40
+ const anonymous = "anonymous" in entity ? entity.anonymous ?? false : false;
41
+ let author = (
42
+ // eslint-disable-next-line no-nested-ternary
43
+ "author" in entity ? entity.author : "userRef" in entity ? entity.userRef : entity.owner
44
+ );
45
+ if (!author.startsWith("user:")) {
46
+ author = `user:${author}`;
47
+ }
48
+ const { primaryTitle: userName } = useEntityPresentation(author);
49
+ useEffect(() => {
50
+ if (anonymous) {
51
+ return;
52
+ }
53
+ if (userCache.get(author)) {
54
+ setUser(userCache.get(author));
55
+ return;
56
+ }
57
+ dataLoaderFactory(catalogApi).load(author).then((data) => {
58
+ if (data) {
59
+ setUser(data);
60
+ } else {
61
+ setUser(null);
62
+ }
63
+ }).catch(() => {
64
+ setUser(null);
65
+ });
66
+ }, [catalogApi, author, anonymous]);
67
+ useEffect(() => {
68
+ identityApi.getBackstageIdentity().then((res) => {
69
+ setCurrentUser(res.userEntityRef ?? "user:default/guest");
70
+ });
71
+ }, [identityApi]);
72
+ useEffect(() => {
73
+ let displayName = userName;
74
+ if (author === currentUser) {
75
+ displayName = "You";
76
+ if (anonymous) {
77
+ displayName += " (anonymous)";
78
+ }
79
+ }
80
+ setName(displayName);
81
+ }, [author, anonymous, currentUser, userName]);
82
+ useEffect(() => {
83
+ const init = (name ?? "").split(" ").map((p) => p[0]).join("").substring(0, 2).toUpperCase();
84
+ setInitials(init);
85
+ }, [name]);
86
+ return { name, initials, user };
87
+ };
88
+
89
+ export { useEntityAuthor };
90
+ //# sourceMappingURL=useEntityAuthor.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEntityAuthor.esm.js","sources":["../../src/hooks/useEntityAuthor.ts"],"sourcesContent":["import { UserEntity } from '@backstage/catalog-model';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport DataLoader from 'dataloader';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n useEntityPresentation,\n} from '@backstage/plugin-catalog-react';\nimport React, { useEffect } from 'react';\nimport {\n AnswerResponse,\n CollectionResponse,\n PostResponse,\n UserResponse,\n} from '@drodil/backstage-plugin-qeta-common';\n\nconst userCache: Map<string, UserEntity> = new Map();\nconst dataLoaderFactory = (catalogApi: CatalogApi) =>\n new DataLoader(\n async (entityRefs: readonly string[]) => {\n const { items } = await catalogApi.getEntitiesByRefs({\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'spec.profile.displayName',\n 'spec.profile.picture',\n ],\n entityRefs: entityRefs as string[],\n });\n\n entityRefs.forEach((entityRef, index) => {\n userCache.set(entityRef, items[index] as UserEntity);\n });\n return items;\n },\n {\n name: 'EntityAuthorLoader',\n cacheMap: new Map(),\n maxBatchSize: 100,\n batchScheduleFn: callback => {\n setTimeout(callback, 50);\n },\n },\n );\n\nexport const useEntityAuthor = (\n entity: PostResponse | AnswerResponse | CollectionResponse | UserResponse,\n) => {\n const catalogApi = useApi(catalogApiRef);\n const identityApi = useApi(identityApiRef);\n const [name, setName] = React.useState<string | undefined>(undefined);\n const [user, setUser] = React.useState<UserEntity | null>(null);\n const [initials, setInitials] = React.useState<string | null>(null);\n const [currentUser, setCurrentUser] = React.useState<string | null>(null);\n const anonymous = 'anonymous' in entity ? entity.anonymous ?? false : false;\n let author =\n // eslint-disable-next-line no-nested-ternary\n 'author' in entity\n ? entity.author\n : 'userRef' in entity\n ? entity.userRef\n : entity.owner;\n if (!author.startsWith('user:')) {\n author = `user:${author}`;\n }\n\n const { primaryTitle: userName } = useEntityPresentation(author);\n\n useEffect(() => {\n if (anonymous) {\n return;\n }\n\n if (userCache.get(author)) {\n setUser(userCache.get(author) as UserEntity);\n return;\n }\n\n dataLoaderFactory(catalogApi)\n .load(author)\n .then(data => {\n if (data) {\n setUser(data as UserEntity);\n } else {\n setUser(null);\n }\n })\n .catch(() => {\n setUser(null);\n });\n }, [catalogApi, author, anonymous]);\n\n useEffect(() => {\n identityApi.getBackstageIdentity().then(res => {\n setCurrentUser(res.userEntityRef ?? 'user:default/guest');\n });\n }, [identityApi]);\n\n useEffect(() => {\n let displayName = userName;\n if (author === currentUser) {\n displayName = 'You';\n if (anonymous) {\n displayName += ' (anonymous)';\n }\n }\n setName(displayName);\n }, [author, anonymous, currentUser, userName]);\n\n useEffect(() => {\n const init = (name ?? '')\n .split(' ')\n .map(p => p[0])\n .join('')\n .substring(0, 2)\n .toUpperCase();\n setInitials(init);\n }, [name]);\n\n return { name, initials, user };\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import React, { useEffect, useCallback } from 'react';
2
+ import { useApi } from '@backstage/core-plugin-api';
3
+ import { qetaApiRef } from '../api.esm.js';
4
+
5
+ let followedEntities = void 0;
6
+ const useEntityFollow = () => {
7
+ const [entities, setEntities] = React.useState(
8
+ followedEntities ?? []
9
+ );
10
+ const [loading, setLoading] = React.useState(followedEntities === void 0);
11
+ const qetaApi = useApi(qetaApiRef);
12
+ useEffect(() => {
13
+ if (followedEntities === void 0) {
14
+ qetaApi.getFollowedEntities().then((res) => {
15
+ followedEntities = res.entityRefs;
16
+ setEntities(res.entityRefs);
17
+ setLoading(false);
18
+ });
19
+ } else {
20
+ setEntities(followedEntities);
21
+ }
22
+ }, [qetaApi]);
23
+ const followEntity = useCallback(
24
+ (entityRef) => {
25
+ qetaApi.followEntity(entityRef).then(() => {
26
+ setEntities((prev) => [...prev, entityRef]);
27
+ followedEntities?.push(entityRef);
28
+ });
29
+ },
30
+ [qetaApi]
31
+ );
32
+ const unfollowEntity = useCallback(
33
+ (entityRef) => {
34
+ qetaApi.unfollowEntity(entityRef).then(() => {
35
+ setEntities((prev) => prev.filter((t) => t !== entityRef));
36
+ followedEntities = followedEntities?.filter((t) => t !== entityRef);
37
+ });
38
+ },
39
+ [qetaApi]
40
+ );
41
+ const isFollowingEntity = useCallback(
42
+ (entityRef) => entities.includes(entityRef),
43
+ [entities]
44
+ );
45
+ return { entities, followEntity, unfollowEntity, isFollowingEntity, loading };
46
+ };
47
+
48
+ export { useEntityFollow };
49
+ //# sourceMappingURL=useEntityFollow.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEntityFollow.esm.js","sources":["../../src/hooks/useEntityFollow.ts"],"sourcesContent":["import React, { useCallback, useEffect } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../api';\n\nlet followedEntities: string[] | undefined = undefined;\n\nexport const useEntityFollow = () => {\n const [entities, setEntities] = React.useState<string[]>(\n followedEntities ?? [],\n );\n const [loading, setLoading] = React.useState(followedEntities === undefined);\n const qetaApi = useApi(qetaApiRef);\n\n useEffect(() => {\n if (followedEntities === undefined) {\n qetaApi.getFollowedEntities().then(res => {\n followedEntities = res.entityRefs;\n setEntities(res.entityRefs);\n setLoading(false);\n });\n } else {\n setEntities(followedEntities);\n }\n }, [qetaApi]);\n\n const followEntity = useCallback(\n (entityRef: string) => {\n qetaApi.followEntity(entityRef).then(() => {\n setEntities(prev => [...prev, entityRef]);\n followedEntities?.push(entityRef);\n });\n },\n [qetaApi],\n );\n\n const unfollowEntity = useCallback(\n (entityRef: string) => {\n qetaApi.unfollowEntity(entityRef).then(() => {\n setEntities(prev => prev.filter(t => t !== entityRef));\n followedEntities = followedEntities?.filter(t => t !== entityRef);\n });\n },\n [qetaApi],\n );\n\n const isFollowingEntity = useCallback(\n (entityRef: string) => entities.includes(entityRef),\n [entities],\n );\n return { entities, followEntity, unfollowEntity, isFollowingEntity, loading };\n};\n"],"names":[],"mappings":";;;;AAIA,IAAI,gBAAyC,GAAA,KAAA,CAAA,CAAA;AAEtC,MAAM,kBAAkB,MAAM;AACnC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,KAAM,CAAA,QAAA;AAAA,IACpC,oBAAoB,EAAC;AAAA,GACvB,CAAA;AACA,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,IAAI,KAAM,CAAA,QAAA,CAAS,qBAAqB,KAAS,CAAA,CAAA,CAAA;AAC3E,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,qBAAqB,KAAW,CAAA,EAAA;AAClC,MAAQ,OAAA,CAAA,mBAAA,EAAsB,CAAA,IAAA,CAAK,CAAO,GAAA,KAAA;AACxC,QAAA,gBAAA,GAAmB,GAAI,CAAA,UAAA,CAAA;AACvB,QAAA,WAAA,CAAY,IAAI,UAAU,CAAA,CAAA;AAC1B,QAAA,UAAA,CAAW,KAAK,CAAA,CAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACI,MAAA;AACL,MAAA,WAAA,CAAY,gBAAgB,CAAA,CAAA;AAAA,KAC9B;AAAA,GACF,EAAG,CAAC,OAAO,CAAC,CAAA,CAAA;AAEZ,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,SAAsB,KAAA;AACrB,MAAA,OAAA,CAAQ,YAAa,CAAA,SAAS,CAAE,CAAA,IAAA,CAAK,MAAM;AACzC,QAAA,WAAA,CAAY,CAAQ,IAAA,KAAA,CAAC,GAAG,IAAA,EAAM,SAAS,CAAC,CAAA,CAAA;AACxC,QAAA,gBAAA,EAAkB,KAAK,SAAS,CAAA,CAAA;AAAA,OACjC,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAA,MAAM,cAAiB,GAAA,WAAA;AAAA,IACrB,CAAC,SAAsB,KAAA;AACrB,MAAA,OAAA,CAAQ,cAAe,CAAA,SAAS,CAAE,CAAA,IAAA,CAAK,MAAM;AAC3C,QAAA,WAAA,CAAY,UAAQ,IAAK,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,KAAM,SAAS,CAAC,CAAA,CAAA;AACrD,QAAA,gBAAA,GAAmB,gBAAkB,EAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAA,KAAM,SAAS,CAAA,CAAA;AAAA,OACjE,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,SAAA,KAAsB,QAAS,CAAA,QAAA,CAAS,SAAS,CAAA;AAAA,IAClD,CAAC,QAAQ,CAAA;AAAA,GACX,CAAA;AACA,EAAA,OAAO,EAAE,QAAA,EAAU,YAAc,EAAA,cAAA,EAAgB,mBAAmB,OAAQ,EAAA,CAAA;AAC9E;;;;"}
@@ -0,0 +1,14 @@
1
+ import { useSearchParams } from 'react-router-dom';
2
+ import React, { useEffect } from 'react';
3
+
4
+ function useEntityQueryParameter(entity) {
5
+ const [searchParams] = useSearchParams();
6
+ const [entityRef, setEntityRef] = React.useState(entity);
7
+ useEffect(() => {
8
+ setEntityRef(searchParams.get("entity") ?? void 0);
9
+ }, [searchParams, setEntityRef]);
10
+ return entityRef;
11
+ }
12
+
13
+ export { useEntityQueryParameter };
14
+ //# sourceMappingURL=useEntityQueryParameter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEntityQueryParameter.esm.js","sources":["../../src/hooks/useEntityQueryParameter.ts"],"sourcesContent":["import { useSearchParams } from 'react-router-dom';\nimport React, { useEffect } from 'react';\n\nexport function useEntityQueryParameter(entity?: string) {\n const [searchParams] = useSearchParams();\n const [entityRef, setEntityRef] = React.useState<string | undefined>(entity);\n\n useEffect(() => {\n setEntityRef(searchParams.get('entity') ?? undefined);\n }, [searchParams, setEntityRef]);\n\n return entityRef;\n}\n"],"names":[],"mappings":";;;AAGO,SAAS,wBAAwB,MAAiB,EAAA;AACvD,EAAM,MAAA,CAAC,YAAY,CAAA,GAAI,eAAgB,EAAA,CAAA;AACvC,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,CAAI,GAAA,KAAA,CAAM,SAA6B,MAAM,CAAA,CAAA;AAE3E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,YAAA,CAAa,YAAa,CAAA,GAAA,CAAI,QAAQ,CAAA,IAAK,KAAS,CAAA,CAAA,CAAA;AAAA,GACnD,EAAA,CAAC,YAAc,EAAA,YAAY,CAAC,CAAA,CAAA;AAE/B,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,26 @@
1
+ import { makeStyles } from '@material-ui/core';
2
+
3
+ const useFormStyles = makeStyles(
4
+ (theme) => {
5
+ return {
6
+ headerImage: {
7
+ marginBottom: "1rem",
8
+ marginTop: "1rem",
9
+ height: "250px",
10
+ objectFit: "cover",
11
+ width: "100%",
12
+ border: `1px solid ${theme.palette.background.paper}`,
13
+ boxShadow: theme.shadows[1]
14
+ },
15
+ postButton: {
16
+ marginTop: theme.spacing(1),
17
+ marginBottom: theme.spacing(1)
18
+ },
19
+ form: {}
20
+ };
21
+ },
22
+ { name: "QetaForm" }
23
+ );
24
+
25
+ export { useFormStyles };
26
+ //# sourceMappingURL=useFormStyles.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormStyles.esm.js","sources":["../../src/hooks/useFormStyles.ts"],"sourcesContent":["import { makeStyles } from '@material-ui/core';\n\nexport type QetaFormClassKey = 'headerImage' | 'postButton' | 'postForm';\n\nexport const useFormStyles = makeStyles(\n theme => {\n return {\n headerImage: {\n marginBottom: '1rem',\n marginTop: '1rem',\n height: '250px',\n objectFit: 'cover',\n width: '100%',\n border: `1px solid ${theme.palette.background.paper}`,\n boxShadow: theme.shadows[1],\n },\n postButton: {\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n },\n form: {},\n };\n },\n { name: 'QetaForm' },\n);\n"],"names":[],"mappings":";;AAIO,MAAM,aAAgB,GAAA,UAAA;AAAA,EAC3B,CAAS,KAAA,KAAA;AACP,IAAO,OAAA;AAAA,MACL,WAAa,EAAA;AAAA,QACX,YAAc,EAAA,MAAA;AAAA,QACd,SAAW,EAAA,MAAA;AAAA,QACX,MAAQ,EAAA,OAAA;AAAA,QACR,SAAW,EAAA,OAAA;AAAA,QACX,KAAO,EAAA,MAAA;AAAA,QACP,MAAQ,EAAA,CAAA,UAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,WAAW,KAAK,CAAA,CAAA;AAAA,QACnD,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,OAC5B;AAAA,MACA,UAAY,EAAA;AAAA,QACV,SAAA,EAAW,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,QAC1B,YAAA,EAAc,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,OAC/B;AAAA,MACA,MAAM,EAAC;AAAA,KACT,CAAA;AAAA,GACF;AAAA,EACA,EAAE,MAAM,UAAW,EAAA;AACrB;;;;"}
@@ -0,0 +1,12 @@
1
+ import { useApi, identityApiRef } from '@backstage/core-plugin-api';
2
+ import useAsync from 'react-use/lib/useAsync';
3
+
4
+ function useIdentityApi(f, deps = []) {
5
+ const identityApi = useApi(identityApiRef);
6
+ return useAsync(async () => {
7
+ return await f(identityApi);
8
+ }, deps);
9
+ }
10
+
11
+ export { useIdentityApi };
12
+ //# sourceMappingURL=useIdentityApi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIdentityApi.esm.js","sources":["../../src/hooks/useIdentityApi.ts"],"sourcesContent":["import {\n IdentityApi,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\n\nexport function useIdentityApi<T>(\n f: (api: IdentityApi) => Promise<T>,\n deps: any[] = [],\n) {\n const identityApi = useApi(identityApiRef);\n\n return useAsync(async () => {\n return await f(identityApi);\n }, deps);\n}\n"],"names":[],"mappings":";;;AAOO,SAAS,cACd,CAAA,CAAA,EACA,IAAc,GAAA,EACd,EAAA;AACA,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA,CAAA;AAEzC,EAAA,OAAO,SAAS,YAAY;AAC1B,IAAO,OAAA,MAAM,EAAE,WAAW,CAAA,CAAA;AAAA,KACzB,IAAI,CAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,12 @@
1
+ import { useApi, appThemeApiRef } from '@backstage/core-plugin-api';
2
+ import { useMemo } from 'react';
3
+
4
+ function useIsDarkTheme() {
5
+ const appThemeApi = useApi(appThemeApiRef);
6
+ const themes = appThemeApi.getInstalledThemes();
7
+ const theme = useMemo(() => appThemeApi.getActiveThemeId(), [appThemeApi]);
8
+ return Boolean(themes.find((t) => t.id === theme)?.variant === "dark");
9
+ }
10
+
11
+ export { useIsDarkTheme };
12
+ //# sourceMappingURL=useIsDarkTheme.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsDarkTheme.esm.js","sources":["../../src/hooks/useIsDarkTheme.ts"],"sourcesContent":["import { appThemeApiRef, useApi } from '@backstage/core-plugin-api';\nimport { useMemo } from 'react';\n\nexport function useIsDarkTheme() {\n const appThemeApi = useApi(appThemeApiRef);\n const themes = appThemeApi.getInstalledThemes();\n const theme = useMemo(() => appThemeApi.getActiveThemeId(), [appThemeApi]);\n return Boolean(themes.find(t => t.id === theme)?.variant === 'dark');\n}\n"],"names":[],"mappings":";;;AAGO,SAAS,cAAiB,GAAA;AAC/B,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA,CAAA;AACzC,EAAM,MAAA,MAAA,GAAS,YAAY,kBAAmB,EAAA,CAAA;AAC9C,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM,WAAA,CAAY,kBAAoB,EAAA,CAAC,WAAW,CAAC,CAAA,CAAA;AACzE,EAAO,OAAA,OAAA,CAAQ,OAAO,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,EAAO,KAAA,KAAK,CAAG,EAAA,OAAA,KAAY,MAAM,CAAA,CAAA;AACrE;;;;"}