@drodil/backstage-plugin-qeta-react 3.51.1 → 3.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AIAnswerCard/AIAnswerCard.esm.js +1 -1
- package/dist/components/AnswersContainer/AnswerList.esm.js +13 -34
- package/dist/components/AnswersContainer/AnswerList.esm.js.map +1 -1
- package/dist/components/AnswersContainer/AnswersContainer.esm.js +24 -29
- package/dist/components/AnswersContainer/AnswersContainer.esm.js.map +1 -1
- package/dist/components/Badges/UserBadges.esm.js +1 -1
- package/dist/components/CollectionsGrid/CollectionsGrid.esm.js +21 -19
- package/dist/components/CollectionsGrid/CollectionsGrid.esm.js.map +1 -1
- package/dist/components/CollectionsGrid/CollectionsGridContent.esm.js +26 -6
- package/dist/components/CollectionsGrid/CollectionsGridContent.esm.js.map +1 -1
- package/dist/components/EntitiesGrid/EntitiesGrid.esm.js +20 -17
- package/dist/components/EntitiesGrid/EntitiesGrid.esm.js.map +1 -1
- package/dist/components/EntitiesGrid/EntitiesGridContent.esm.js +24 -4
- package/dist/components/EntitiesGrid/EntitiesGridContent.esm.js.map +1 -1
- package/dist/components/FollowedLists/FollowedEntitiesList.esm.js +1 -1
- package/dist/components/FollowedLists/FollowedTagsList.esm.js +1 -1
- package/dist/components/FollowedLists/FollowedUsersList.esm.js +1 -1
- package/dist/components/HomePageCards/ImpactCard.esm.js +40 -4
- package/dist/components/HomePageCards/ImpactCard.esm.js.map +1 -1
- package/dist/components/HomePageCards/PostsCard.esm.js +1 -1
- package/dist/components/LeftMenu/LeftMenu.esm.js +35 -40
- package/dist/components/LeftMenu/LeftMenu.esm.js.map +1 -1
- package/dist/components/Links/Links.esm.js +1 -1
- package/dist/components/PostHighlightList/PostHighlightList.esm.js +1 -1
- package/dist/components/PostsContainer/PostList.esm.js +15 -30
- package/dist/components/PostsContainer/PostList.esm.js.map +1 -1
- package/dist/components/PostsContainer/PostsContainer.esm.js +8 -12
- package/dist/components/PostsContainer/PostsContainer.esm.js.map +1 -1
- package/dist/components/PostsGrid/PostsGrid.esm.js +8 -12
- package/dist/components/PostsGrid/PostsGrid.esm.js.map +1 -1
- package/dist/components/PostsGrid/PostsGridContent.esm.js +14 -30
- package/dist/components/PostsGrid/PostsGridContent.esm.js.map +1 -1
- package/dist/components/SuggestionsCard/SuggestionsCard.esm.js +35 -5
- package/dist/components/SuggestionsCard/SuggestionsCard.esm.js.map +1 -1
- package/dist/components/TagsAndEntities/EntityChip.esm.js +1 -1
- package/dist/components/TagsAndEntities/TagChip.esm.js +1 -1
- package/dist/components/TagsAndEntities/UserChip.esm.js +1 -1
- package/dist/components/TagsGrid/TagsGrid.esm.js +20 -17
- package/dist/components/TagsGrid/TagsGrid.esm.js.map +1 -1
- package/dist/components/TagsGrid/TagsGridContent.esm.js +40 -12
- package/dist/components/TagsGrid/TagsGridContent.esm.js.map +1 -1
- package/dist/components/TemplateList/TemplateForm.esm.js +1 -1
- package/dist/components/TemplateList/TemplateList.esm.js +1 -1
- package/dist/components/Timeline/Timeline.esm.js +83 -0
- package/dist/components/Timeline/Timeline.esm.js.map +1 -0
- package/dist/components/Timeline/TimelineItem.esm.js +162 -0
- package/dist/components/Timeline/TimelineItem.esm.js.map +1 -0
- package/dist/components/UsersGrid/UsersGrid.esm.js +24 -13
- package/dist/components/UsersGrid/UsersGrid.esm.js.map +1 -1
- package/dist/components/UsersGrid/UsersGridContent.esm.js +24 -4
- package/dist/components/UsersGrid/UsersGridContent.esm.js.map +1 -1
- package/dist/hooks/useGridPageSize.esm.js +55 -0
- package/dist/hooks/useGridPageSize.esm.js.map +1 -0
- package/dist/hooks/usePaginatedPosts.esm.js +22 -5
- package/dist/hooks/usePaginatedPosts.esm.js.map +1 -1
- package/dist/index.d.ts +63 -31
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/translation.esm.js +32 -5
- package/dist/translation.esm.js.map +1 -1
- package/package.json +3 -2
- package/dist/components/QetaPagination/QetaPagination.esm.js +0 -69
- package/dist/components/QetaPagination/QetaPagination.esm.js.map +0 -1
|
@@ -13,8 +13,8 @@ import 'react-use/lib/useAsync';
|
|
|
13
13
|
import '@backstage/plugin-permission-react';
|
|
14
14
|
import '@drodil/backstage-plugin-qeta-common';
|
|
15
15
|
import '@backstage/plugin-permission-common';
|
|
16
|
+
import { useGridPageSize } from '../../hooks/useGridPageSize.esm.js';
|
|
16
17
|
import useDebounce from 'react-use/lib/useDebounce';
|
|
17
|
-
import { QetaPagination } from '../QetaPagination/QetaPagination.esm.js';
|
|
18
18
|
import { EntitiesGridContent } from './EntitiesGridContent.esm.js';
|
|
19
19
|
import { QetaGridHeader } from '../Utility/QetaGridHeader.esm.js';
|
|
20
20
|
import { FilterPanel } from '../FilterPanel/FilterPanel.esm.js';
|
|
@@ -23,8 +23,7 @@ import FilterList from '@material-ui/icons/FilterList';
|
|
|
23
23
|
const EXPANDED_LOCAL_STORAGE_KEY = "qeta-entities-filters-expanded";
|
|
24
24
|
const EntitiesGrid = () => {
|
|
25
25
|
const [page, setPage] = useState(1);
|
|
26
|
-
const
|
|
27
|
-
const [entitiesPerPage, setEntitiesPerPage] = useState(25);
|
|
26
|
+
const entitiesPerPage = useGridPageSize("entities", 24);
|
|
28
27
|
const [searchQuery, setSearchQuery] = useState("");
|
|
29
28
|
const [showFilterPanel, setShowFilterPanel] = useState(
|
|
30
29
|
localStorage.getItem(EXPANDED_LOCAL_STORAGE_KEY) === "true"
|
|
@@ -34,6 +33,9 @@ const EntitiesGrid = () => {
|
|
|
34
33
|
orderBy: "postsCount",
|
|
35
34
|
searchQuery: ""
|
|
36
35
|
});
|
|
36
|
+
const [entities, setEntities] = useState([]);
|
|
37
|
+
const [hasMore, setHasMore] = useState(true);
|
|
38
|
+
const [total, setTotal] = useState(0);
|
|
37
39
|
useEffect(() => {
|
|
38
40
|
localStorage.setItem(
|
|
39
41
|
EXPANDED_LOCAL_STORAGE_KEY,
|
|
@@ -43,6 +45,7 @@ const EntitiesGrid = () => {
|
|
|
43
45
|
const onFilterChange = (changes) => {
|
|
44
46
|
const changesArray = Array.isArray(changes) ? changes : [changes];
|
|
45
47
|
setPage(1);
|
|
48
|
+
setEntities([]);
|
|
46
49
|
setFilters((prev) => {
|
|
47
50
|
const newValue = { ...prev };
|
|
48
51
|
for (const { key, value } of changesArray) {
|
|
@@ -66,6 +69,7 @@ const EntitiesGrid = () => {
|
|
|
66
69
|
);
|
|
67
70
|
const onSearchQueryChange = (val) => {
|
|
68
71
|
setPage(1);
|
|
72
|
+
setEntities([]);
|
|
69
73
|
setSearchQuery(val);
|
|
70
74
|
};
|
|
71
75
|
useDebounce(
|
|
@@ -79,9 +83,16 @@ const EntitiesGrid = () => {
|
|
|
79
83
|
);
|
|
80
84
|
useEffect(() => {
|
|
81
85
|
if (response) {
|
|
82
|
-
|
|
86
|
+
if (page === 1) {
|
|
87
|
+
setEntities(response.entities);
|
|
88
|
+
} else {
|
|
89
|
+
setEntities((prev) => [...prev, ...response.entities]);
|
|
90
|
+
}
|
|
91
|
+
setHasMore(response.entities.length >= entitiesPerPage);
|
|
92
|
+
setTotal(response.total);
|
|
83
93
|
}
|
|
84
|
-
}, [response, entitiesPerPage]);
|
|
94
|
+
}, [response, entitiesPerPage, page]);
|
|
95
|
+
const combinedResponse = response ? { ...response, entities, total } : void 0;
|
|
85
96
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
86
97
|
/* @__PURE__ */ jsx(
|
|
87
98
|
QetaGridHeader,
|
|
@@ -111,19 +122,11 @@ const EntitiesGrid = () => {
|
|
|
111
122
|
/* @__PURE__ */ jsx(
|
|
112
123
|
EntitiesGridContent,
|
|
113
124
|
{
|
|
114
|
-
response,
|
|
125
|
+
response: combinedResponse,
|
|
115
126
|
loading,
|
|
116
|
-
error
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
response && response?.total > 0 && /* @__PURE__ */ jsx(
|
|
120
|
-
QetaPagination,
|
|
121
|
-
{
|
|
122
|
-
pageSize: entitiesPerPage,
|
|
123
|
-
handlePageChange: (_e, p) => setPage(p),
|
|
124
|
-
handlePageSizeChange: (e) => setEntitiesPerPage(Number(e.target.value)),
|
|
125
|
-
page,
|
|
126
|
-
pageCount
|
|
127
|
+
error,
|
|
128
|
+
hasMore,
|
|
129
|
+
loadNextPage: () => setPage((prev) => prev + 1)
|
|
127
130
|
}
|
|
128
131
|
)
|
|
129
132
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntitiesGrid.esm.js","sources":["../../../src/components/EntitiesGrid/EntitiesGrid.tsx"],"sourcesContent":["import { Box } from '@material-ui/core';\nimport { useEffect, useState } from 'react';\nimport { useQetaApi } from '../../hooks';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport {
|
|
1
|
+
{"version":3,"file":"EntitiesGrid.esm.js","sources":["../../../src/components/EntitiesGrid/EntitiesGrid.tsx"],"sourcesContent":["import { Box } from '@material-ui/core';\nimport { useEffect, useState } from 'react';\nimport { useGridPageSize, useQetaApi } from '../../hooks';\nimport useDebounce from 'react-use/lib/useDebounce';\n\nimport { EntitiesGridContent } from './EntitiesGridContent';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { QetaGridHeader } from '../Utility/QetaGridHeader';\n\nimport { Change, EntityFilters, FilterPanel } from '../FilterPanel/FilterPanel';\nimport { Collapse, Button } from '@material-ui/core';\nimport FilterList from '@material-ui/icons/FilterList';\n\nconst EXPANDED_LOCAL_STORAGE_KEY = 'qeta-entities-filters-expanded';\n\nexport const EntitiesGrid = () => {\n const [page, setPage] = useState(1);\n const entitiesPerPage = useGridPageSize('entities', 24);\n const [searchQuery, setSearchQuery] = useState('');\n const [showFilterPanel, setShowFilterPanel] = useState(\n localStorage.getItem(EXPANDED_LOCAL_STORAGE_KEY) === 'true',\n );\n const [filters, setFilters] = useState<EntityFilters>({\n order: 'desc',\n orderBy: 'postsCount',\n searchQuery: '',\n });\n const [entities, setEntities] = useState<any[]>([]);\n const [hasMore, setHasMore] = useState(true);\n const [total, setTotal] = useState(0);\n\n useEffect(() => {\n localStorage.setItem(\n EXPANDED_LOCAL_STORAGE_KEY,\n showFilterPanel ? 'true' : 'false',\n );\n }, [showFilterPanel]);\n\n const onFilterChange = (\n changes: Change<EntityFilters> | Change<EntityFilters>[],\n ) => {\n const changesArray = Array.isArray(changes) ? changes : [changes];\n setPage(1);\n setEntities([]);\n setFilters(prev => {\n const newValue = { ...prev };\n for (const { key, value } of changesArray) {\n (newValue as any)[key] = value;\n }\n return newValue;\n });\n };\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api =>\n api.getEntities({\n limit: entitiesPerPage,\n offset: (page - 1) * entitiesPerPage,\n ...filters,\n }),\n [entitiesPerPage, page, filters],\n );\n\n const onSearchQueryChange = (val: string) => {\n setPage(1);\n setEntities([]);\n setSearchQuery(val);\n };\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 300,\n [searchQuery],\n );\n\n useEffect(() => {\n if (response) {\n if (page === 1) {\n setEntities(response.entities);\n } else {\n setEntities(prev => [...prev, ...response.entities]);\n }\n setHasMore(response.entities.length >= entitiesPerPage);\n setTotal(response.total);\n }\n }, [response, entitiesPerPage, page]);\n\n const combinedResponse = response\n ? { ...response, entities, total }\n : undefined;\n\n return (\n <Box>\n <QetaGridHeader\n title={\n response ? t('common.entities', { count: response?.total ?? 0 }) : ''\n }\n searchBarLabel={t('entitiesPage.search.label')}\n loading={loading}\n onSearch={onSearchQueryChange}\n buttons={\n <Button\n onClick={() => setShowFilterPanel(!showFilterPanel)}\n startIcon={<FilterList />}\n >\n {t('filterPanel.filterButton')}\n </Button>\n }\n />\n <Collapse in={showFilterPanel}>\n <FilterPanel<EntityFilters>\n onChange={onFilterChange}\n filters={filters}\n mode=\"entities\"\n />\n </Collapse>\n <EntitiesGridContent\n response={combinedResponse}\n loading={loading}\n error={error}\n hasMore={hasMore}\n loadNextPage={() => setPage(prev => prev + 1)}\n />\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { WarningPanel } from '@backstage/core-components';
|
|
3
3
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
4
4
|
import { qetaTranslationRef } from '../../translation.esm.js';
|
|
@@ -6,11 +6,21 @@ import { EntitiesGridItem } from './EntitiesGridItem.esm.js';
|
|
|
6
6
|
import { NoEntitiesCard } from './NoEntitiesCard.esm.js';
|
|
7
7
|
import { LoadingGrid } from '../LoadingGrid/LoadingGrid.esm.js';
|
|
8
8
|
import { Grid } from '@material-ui/core';
|
|
9
|
+
import { useInfiniteScroll } from 'infinite-scroll-hook';
|
|
9
10
|
|
|
10
11
|
const EntitiesGridContent = (props) => {
|
|
11
|
-
const { response, loading, error } = props;
|
|
12
|
+
const { response, loading, error, hasMore, loadNextPage } = props;
|
|
12
13
|
const { t } = useTranslationRef(qetaTranslationRef);
|
|
13
|
-
|
|
14
|
+
const { containerRef: sentryRef } = useInfiniteScroll({
|
|
15
|
+
shouldStop: !hasMore || !!error || loading,
|
|
16
|
+
onLoadMore: async () => {
|
|
17
|
+
if (loadNextPage) {
|
|
18
|
+
await loadNextPage();
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
offset: "800px"
|
|
22
|
+
});
|
|
23
|
+
if (loading && (!response || response.entities.length === 0)) {
|
|
14
24
|
return /* @__PURE__ */ jsx(LoadingGrid, {});
|
|
15
25
|
}
|
|
16
26
|
if (error || response === void 0) {
|
|
@@ -19,7 +29,17 @@ const EntitiesGridContent = (props) => {
|
|
|
19
29
|
if (!response?.entities || response.entities.length === 0) {
|
|
20
30
|
return /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(NoEntitiesCard, {}) });
|
|
21
31
|
}
|
|
22
|
-
return /* @__PURE__ */
|
|
32
|
+
return /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, alignItems: "stretch", children: [
|
|
33
|
+
response?.entities.map((entity) => /* @__PURE__ */ jsx(EntitiesGridItem, { entity }, entity.entityRef)),
|
|
34
|
+
/* @__PURE__ */ jsx(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
ref: sentryRef,
|
|
38
|
+
style: { width: "100%", marginTop: "10px", textAlign: "center" },
|
|
39
|
+
children: loading && /* @__PURE__ */ jsx(LoadingGrid, {})
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
] });
|
|
23
43
|
};
|
|
24
44
|
|
|
25
45
|
export { EntitiesGridContent };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntitiesGridContent.esm.js","sources":["../../../src/components/EntitiesGrid/EntitiesGridContent.tsx"],"sourcesContent":["import { EntitiesResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { WarningPanel } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { EntitiesGridItem } from './EntitiesGridItem';\nimport { NoEntitiesCard } from './NoEntitiesCard';\nimport { LoadingGrid } from '../LoadingGrid/LoadingGrid';\nimport { Grid } from '@material-ui/core';\n\nexport const EntitiesGridContent = (props: {\n loading: boolean;\n error: any;\n response?: EntitiesResponse;\n}) => {\n const { response, loading, error } = props;\n const { t } = useTranslationRef(qetaTranslationRef);\n\n if (loading) {\n return <LoadingGrid />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('entitiesPage.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n if (!response?.entities || response.entities.length === 0) {\n return (\n <Grid item xs={12}>\n <NoEntitiesCard />\n </Grid>\n );\n }\n\n return (\n <Grid container spacing={3} alignItems=\"stretch\">\n {response?.entities.map(entity => (\n <EntitiesGridItem entity={entity} key={entity.entityRef} />\n ))}\n </Grid>\n );\n};\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EntitiesGridContent.esm.js","sources":["../../../src/components/EntitiesGrid/EntitiesGridContent.tsx"],"sourcesContent":["import { EntitiesResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { WarningPanel } from '@backstage/core-components';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { EntitiesGridItem } from './EntitiesGridItem';\nimport { NoEntitiesCard } from './NoEntitiesCard';\nimport { LoadingGrid } from '../LoadingGrid/LoadingGrid';\nimport { Grid } from '@material-ui/core';\nimport { useInfiniteScroll } from 'infinite-scroll-hook';\n\nexport const EntitiesGridContent = (props: {\n loading: boolean;\n error: any;\n response?: EntitiesResponse;\n hasMore?: boolean;\n loadNextPage?: () => void;\n}) => {\n const { response, loading, error, hasMore, loadNextPage } = props;\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const { containerRef: sentryRef } = useInfiniteScroll({\n shouldStop: !hasMore || !!error || loading,\n onLoadMore: async () => {\n if (loadNextPage) {\n await loadNextPage();\n }\n },\n offset: '800px',\n }) as any;\n\n if (loading && (!response || response.entities.length === 0)) {\n return <LoadingGrid />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('entitiesPage.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n if (!response?.entities || response.entities.length === 0) {\n return (\n <Grid item xs={12}>\n <NoEntitiesCard />\n </Grid>\n );\n }\n\n return (\n <Grid container spacing={3} alignItems=\"stretch\">\n {response?.entities.map(entity => (\n <EntitiesGridItem entity={entity} key={entity.entityRef} />\n ))}\n <div\n ref={sentryRef}\n style={{ width: '100%', marginTop: '10px', textAlign: 'center' }}\n >\n {loading && <LoadingGrid />}\n </div>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAUa,MAAA,mBAAA,GAAsB,CAAC,KAM9B,KAAA;AACJ,EAAA,MAAM,EAAE,QAAU,EAAA,OAAA,EAAS,KAAO,EAAA,OAAA,EAAS,cAAiB,GAAA,KAAA;AAC5D,EAAA,MAAM,EAAE,CAAA,EAAM,GAAA,iBAAA,CAAkB,kBAAkB,CAAA;AAElD,EAAA,MAAM,EAAE,YAAA,EAAc,SAAU,EAAA,GAAI,iBAAkB,CAAA;AAAA,IACpD,UAAY,EAAA,CAAC,OAAW,IAAA,CAAC,CAAC,KAAS,IAAA,OAAA;AAAA,IACnC,YAAY,YAAY;AACtB,MAAA,IAAI,YAAc,EAAA;AAChB,QAAA,MAAM,YAAa,EAAA;AAAA;AACrB,KACF;AAAA,IACA,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,IAAI,YAAY,CAAC,QAAA,IAAY,QAAS,CAAA,QAAA,CAAS,WAAW,CAAI,CAAA,EAAA;AAC5D,IAAA,2BAAQ,WAAY,EAAA,EAAA,CAAA;AAAA;AAGtB,EAAI,IAAA,KAAA,IAAS,aAAa,KAAW,CAAA,EAAA;AACnC,IACE,uBAAA,GAAA,CAAC,gBAAa,QAAS,EAAA,OAAA,EAAQ,OAAO,CAAE,CAAA,2BAA2B,CAChE,EAAA,QAAA,EAAA,KAAA,EAAO,OACV,EAAA,CAAA;AAAA;AAIJ,EAAA,IAAI,CAAC,QAAU,EAAA,QAAA,IAAY,QAAS,CAAA,QAAA,CAAS,WAAW,CAAG,EAAA;AACzD,IACE,uBAAA,GAAA,CAAC,QAAK,IAAI,EAAA,IAAA,EAAC,IAAI,EACb,EAAA,QAAA,kBAAA,GAAA,CAAC,kBAAe,CAClB,EAAA,CAAA;AAAA;AAIJ,EAAA,4BACG,IAAK,EAAA,EAAA,SAAA,EAAS,MAAC,OAAS,EAAA,CAAA,EAAG,YAAW,SACpC,EAAA,QAAA,EAAA;AAAA,IAAU,QAAA,EAAA,QAAA,CAAS,IAAI,CACtB,MAAA,qBAAA,GAAA,CAAC,oBAAiB,MAAqB,EAAA,EAAA,MAAA,CAAO,SAAW,CAC1D,CAAA;AAAA,oBACD,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,SAAA;AAAA,QACL,OAAO,EAAE,KAAA,EAAO,QAAQ,SAAW,EAAA,MAAA,EAAQ,WAAW,QAAS,EAAA;AAAA,QAE9D,QAAA,EAAA,OAAA,wBAAY,WAAY,EAAA,EAAA;AAAA;AAAA;AAC3B,GACF,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -13,8 +13,8 @@ import 'react-use/lib/useAsync';
|
|
|
13
13
|
import '@backstage/plugin-permission-react';
|
|
14
14
|
import '@drodil/backstage-plugin-qeta-common';
|
|
15
15
|
import '@backstage/plugin-permission-common';
|
|
16
|
-
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
17
16
|
import { makeStyles, ListItem, Box, Tooltip, ListItemText } from '@material-ui/core';
|
|
17
|
+
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
18
18
|
import { Link } from 'react-router-dom';
|
|
19
19
|
import { entityRouteRef } from '../../routes.esm.js';
|
|
20
20
|
|
|
@@ -13,8 +13,8 @@ import 'react-use/lib/useAsync';
|
|
|
13
13
|
import '@backstage/plugin-permission-react';
|
|
14
14
|
import '@drodil/backstage-plugin-qeta-common';
|
|
15
15
|
import '@backstage/plugin-permission-common';
|
|
16
|
-
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
17
16
|
import { makeStyles, ListItem, Box, Tooltip, ListItemText } from '@material-ui/core';
|
|
17
|
+
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
18
18
|
import LocalOfferOutlined from '@material-ui/icons/LocalOfferOutlined';
|
|
19
19
|
import { Link } from 'react-router-dom';
|
|
20
20
|
import { tagRouteRef } from '../../routes.esm.js';
|
|
@@ -9,8 +9,8 @@ import 'react-use/lib/useAsync';
|
|
|
9
9
|
import '@backstage/plugin-permission-react';
|
|
10
10
|
import '@drodil/backstage-plugin-qeta-common';
|
|
11
11
|
import '@backstage/plugin-permission-common';
|
|
12
|
-
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
13
12
|
import { makeStyles, ListItem, Avatar, Tooltip, ListItemText } from '@material-ui/core';
|
|
13
|
+
import { RightListContainer, RightList } from '../Utility/RightList.esm.js';
|
|
14
14
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
15
15
|
import { qetaTranslationRef } from '../../translation.esm.js';
|
|
16
16
|
import { Link } from 'react-router-dom';
|
|
@@ -20,6 +20,11 @@ import HelpOutline from '@material-ui/icons/HelpOutline';
|
|
|
20
20
|
import QuestionAnswerIcon from '@material-ui/icons/QuestionAnswer';
|
|
21
21
|
import PeopleIcon from '@material-ui/icons/People';
|
|
22
22
|
import EmojiEvents from '@material-ui/icons/EmojiEvents';
|
|
23
|
+
import DescriptionIcon from '@material-ui/icons/Description';
|
|
24
|
+
import LinkIcon from '@material-ui/icons/Link';
|
|
25
|
+
import StarIcon from '@material-ui/icons/Star';
|
|
26
|
+
import CheckCircle from '@material-ui/icons/CheckCircle';
|
|
27
|
+
import TrendingUp from '@material-ui/icons/TrendingUp';
|
|
23
28
|
|
|
24
29
|
const ImpactCard = () => {
|
|
25
30
|
const { t } = useTranslationRef(qetaTranslationRef);
|
|
@@ -69,11 +74,12 @@ const ImpactCard = () => {
|
|
|
69
74
|
return num >= 1e3 ? numeral(num).format("0.0 a") : num;
|
|
70
75
|
};
|
|
71
76
|
const formattedImpact = formatNumber(impact.impact);
|
|
77
|
+
const totalContributions = stats.summary.totalQuestions + stats.summary.totalAnswers + stats.summary.totalArticles + stats.summary.totalLinks;
|
|
72
78
|
const statItems = [
|
|
73
79
|
{
|
|
74
|
-
icon: /* @__PURE__ */ jsx(
|
|
75
|
-
value: formatNumber(
|
|
76
|
-
label: t("impactCard.
|
|
80
|
+
icon: /* @__PURE__ */ jsx(TrendingUp, { fontSize: "small" }),
|
|
81
|
+
value: formatNumber(totalContributions),
|
|
82
|
+
label: t("impactCard.totalContributions")
|
|
77
83
|
},
|
|
78
84
|
{
|
|
79
85
|
icon: /* @__PURE__ */ jsx(HelpOutline, { fontSize: "small" }),
|
|
@@ -85,10 +91,40 @@ const ImpactCard = () => {
|
|
|
85
91
|
value: formatNumber(stats.summary.totalAnswers),
|
|
86
92
|
label: t("impactCard.answers")
|
|
87
93
|
},
|
|
94
|
+
{
|
|
95
|
+
icon: /* @__PURE__ */ jsx(DescriptionIcon, { fontSize: "small" }),
|
|
96
|
+
value: formatNumber(stats.summary.totalArticles),
|
|
97
|
+
label: t("impactCard.articles")
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
icon: /* @__PURE__ */ jsx(LinkIcon, { fontSize: "small" }),
|
|
101
|
+
value: formatNumber(stats.summary.totalLinks),
|
|
102
|
+
label: t("impactCard.links")
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
icon: /* @__PURE__ */ jsx(ThumbUp, { fontSize: "small" }),
|
|
106
|
+
value: formatNumber(stats.summary.totalVotes),
|
|
107
|
+
label: t("impactCard.votes")
|
|
108
|
+
},
|
|
88
109
|
{
|
|
89
110
|
icon: /* @__PURE__ */ jsx(PeopleIcon, { fontSize: "small" }),
|
|
90
111
|
value: formatNumber(stats.summary.totalFollowers),
|
|
91
112
|
label: t("impactCard.followers")
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
icon: /* @__PURE__ */ jsx(StarIcon, { fontSize: "small" }),
|
|
116
|
+
value: formatNumber(stats.summary.answerScore),
|
|
117
|
+
label: t("impactCard.answerScore")
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
icon: /* @__PURE__ */ jsx(StarIcon, { fontSize: "small" }),
|
|
121
|
+
value: formatNumber(stats.summary.postScore),
|
|
122
|
+
label: t("impactCard.postScore")
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { fontSize: "small" }),
|
|
126
|
+
value: formatNumber(stats.summary.correctAnswers),
|
|
127
|
+
label: t("impactCard.correctAnswers")
|
|
92
128
|
}
|
|
93
129
|
];
|
|
94
130
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -140,7 +176,7 @@ const ImpactCard = () => {
|
|
|
140
176
|
)
|
|
141
177
|
] }),
|
|
142
178
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
143
|
-
/* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(Grid, { container: true, spacing: 1, children: statItems.map((item, index) => /* @__PURE__ */ jsx(Grid, { item: true, xs:
|
|
179
|
+
/* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(Grid, { container: true, spacing: 1, children: statItems.map((item, index) => /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", color: "textSecondary", children: [
|
|
144
180
|
/* @__PURE__ */ jsx(Tooltip, { title: item.label, children: /* @__PURE__ */ jsx(Box, { display: "flex", alignItems: "center", children: item.icon }) }),
|
|
145
181
|
/* @__PURE__ */ jsx(Box, { ml: 1, children: /* @__PURE__ */ jsxs(Typography, { variant: "subtitle2", component: "span", children: [
|
|
146
182
|
item.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImpactCard.esm.js","sources":["../../../src/components/HomePageCards/ImpactCard.tsx"],"sourcesContent":["import numeral from 'numeral';\nimport { useIdentityApi, useQetaApi } from '../../hooks';\nimport {\n Box,\n Card,\n CardContent,\n Divider,\n Grid,\n Tooltip,\n Typography,\n useTheme,\n} from '@material-ui/core';\nimport { Alert, Skeleton } from '@material-ui/lab';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport {\n ImpactResponse,\n StatisticsResponse,\n UserStat,\n} from '@drodil/backstage-plugin-qeta-common';\nimport ThumbUp from '@material-ui/icons/ThumbUp';\nimport HelpOutline from '@material-ui/icons/HelpOutline';\nimport QuestionAnswer from '@material-ui/icons/QuestionAnswer';\nimport People from '@material-ui/icons/People';\nimport EmojiEvents from '@material-ui/icons/EmojiEvents';\n\nexport const ImpactCard = () => {\n const { t } = useTranslationRef(qetaTranslationRef);\n const theme = useTheme();\n const { value: user, loading: userLoading } = useIdentityApi(\n api => api.getBackstageIdentity(),\n [],\n );\n\n const {\n value: response,\n loading: statsLoading,\n error,\n } = useQetaApi<{\n impact: ImpactResponse;\n stats: StatisticsResponse<UserStat>;\n } | null>(\n async api => {\n if (!user) {\n return null;\n }\n const [impact, stats] = await Promise.all([\n api.getUserImpact(),\n api.getUserStats(user.userEntityRef),\n ]);\n return { impact, stats };\n },\n [user],\n );\n\n const loading = userLoading || statsLoading;\n\n const renderContent = () => {\n if (loading) {\n return (\n <Box p={2}>\n <Skeleton variant=\"text\" width=\"60%\" height={32} />\n <Skeleton variant=\"text\" width=\"40%\" height={48} />\n <Box mt={2}>\n <Divider />\n </Box>\n <Box mt={2}>\n <Grid container spacing={2}>\n {Array.from(new Array(4)).map((_, i) => (\n <Grid item xs={6} key={i}>\n <Skeleton variant=\"circle\" width={24} height={24} />\n <Skeleton variant=\"text\" width=\"80%\" />\n </Grid>\n ))}\n </Grid>\n </Box>\n </Box>\n );\n }\n\n if (error) {\n return <Alert severity=\"error\">{t('impactCard.error')}</Alert>;\n }\n\n if (!response) {\n return null;\n }\n\n const { impact, stats } = response;\n\n const formatNumber = (num: number) => {\n return num >= 1000 ? numeral(num).format('0.0 a') : num;\n };\n\n const formattedImpact = formatNumber(impact.impact);\n\n const statItems = [\n {\n icon: <ThumbUp fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalVotes),\n label: t('impactCard.votes'),\n },\n {\n icon: <HelpOutline fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalQuestions),\n label: t('impactCard.questions'),\n },\n {\n icon: <QuestionAnswer fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalAnswers),\n label: t('impactCard.answers'),\n },\n {\n icon: <People fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalFollowers),\n label: t('impactCard.followers'),\n },\n ];\n\n return (\n <>\n <Typography variant=\"h5\" component=\"h2\" gutterBottom>\n {t('impactCard.title')}\n </Typography>\n <Box display=\"flex\" alignItems=\"center\" mb={1}>\n <Typography\n variant=\"body1\"\n aria-label={`${formattedImpact} views`}\n style={{ fontWeight: 'bold', marginBottom: 0, fontSize: '32px' }}\n >\n {formattedImpact}\n </Typography>\n <Typography\n variant=\"body2\"\n component=\"span\"\n style={{ marginLeft: '0.5em', verticalAlign: 'middle' }}\n color=\"textSecondary\"\n >\n {t('impactCard.views')}\n </Typography>\n </Box>\n <Typography variant=\"body2\" color=\"textSecondary\" paragraph>\n {t('impactCard.contributions', {\n lastWeek: impact.lastWeekImpact.toString(10),\n })}\n </Typography>\n\n <Box display=\"flex\" alignItems=\"center\" mt={2} mb={2}>\n <EmojiEvents\n style={{ color: theme.palette.secondary.main, marginRight: '8px' }}\n />\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n style={{ fontWeight: 'bold' }}\n >\n {t('impactCard.reputation')}:{' '}\n <Box component=\"span\" style={{ fontSize: '1.1em' }}>\n {stats.summary.reputation || 0}\n </Box>\n </Typography>\n </Box>\n\n <Divider />\n\n <Box mt={2}>\n <Grid container spacing={1}>\n {statItems.map((item, index) => (\n <Grid item xs={6} key={index}>\n <Box display=\"flex\" alignItems=\"center\" color=\"textSecondary\">\n <Tooltip title={item.label}>\n <Box display=\"flex\" alignItems=\"center\">\n {item.icon}\n </Box>\n </Tooltip>\n <Box ml={1}>\n <Typography variant=\"subtitle2\" component=\"span\">\n {item.value} {item.label.toLowerCase()}\n </Typography>\n </Box>\n </Box>\n </Grid>\n ))}\n </Grid>\n </Box>\n </>\n );\n };\n\n return (\n <Box\n display={{ md: 'none', lg: 'block' }}\n style={{ marginBottom: '1em' }}\n role=\"region\"\n aria-label={t('impactCard.title')}\n >\n <Card elevation={2}>\n <CardContent>{renderContent()}</CardContent>\n </Card>\n </Box>\n );\n};\n"],"names":["QuestionAnswer","People"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ImpactCard.esm.js","sources":["../../../src/components/HomePageCards/ImpactCard.tsx"],"sourcesContent":["import numeral from 'numeral';\nimport { useIdentityApi, useQetaApi } from '../../hooks';\nimport {\n Box,\n Card,\n CardContent,\n Divider,\n Grid,\n Tooltip,\n Typography,\n useTheme,\n} from '@material-ui/core';\nimport { Alert, Skeleton } from '@material-ui/lab';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport {\n ImpactResponse,\n StatisticsResponse,\n UserStat,\n} from '@drodil/backstage-plugin-qeta-common';\nimport ThumbUp from '@material-ui/icons/ThumbUp';\nimport HelpOutline from '@material-ui/icons/HelpOutline';\nimport QuestionAnswer from '@material-ui/icons/QuestionAnswer';\nimport People from '@material-ui/icons/People';\nimport EmojiEvents from '@material-ui/icons/EmojiEvents';\nimport DescriptionIcon from '@material-ui/icons/Description';\nimport LinkIcon from '@material-ui/icons/Link';\nimport Star from '@material-ui/icons/Star';\nimport CheckCircle from '@material-ui/icons/CheckCircle';\nimport TrendingUp from '@material-ui/icons/TrendingUp';\n\nexport const ImpactCard = () => {\n const { t } = useTranslationRef(qetaTranslationRef);\n const theme = useTheme();\n const { value: user, loading: userLoading } = useIdentityApi(\n api => api.getBackstageIdentity(),\n [],\n );\n\n const {\n value: response,\n loading: statsLoading,\n error,\n } = useQetaApi<{\n impact: ImpactResponse;\n stats: StatisticsResponse<UserStat>;\n } | null>(\n async api => {\n if (!user) {\n return null;\n }\n const [impact, stats] = await Promise.all([\n api.getUserImpact(),\n api.getUserStats(user.userEntityRef),\n ]);\n return { impact, stats };\n },\n [user],\n );\n\n const loading = userLoading || statsLoading;\n\n const renderContent = () => {\n if (loading) {\n return (\n <Box p={2}>\n <Skeleton variant=\"text\" width=\"60%\" height={32} />\n <Skeleton variant=\"text\" width=\"40%\" height={48} />\n <Box mt={2}>\n <Divider />\n </Box>\n <Box mt={2}>\n <Grid container spacing={2}>\n {Array.from(new Array(4)).map((_, i) => (\n <Grid item xs={6} key={i}>\n <Skeleton variant=\"circle\" width={24} height={24} />\n <Skeleton variant=\"text\" width=\"80%\" />\n </Grid>\n ))}\n </Grid>\n </Box>\n </Box>\n );\n }\n\n if (error) {\n return <Alert severity=\"error\">{t('impactCard.error')}</Alert>;\n }\n\n if (!response) {\n return null;\n }\n\n const { impact, stats } = response;\n\n const formatNumber = (num: number) => {\n return num >= 1000 ? numeral(num).format('0.0 a') : num;\n };\n\n const formattedImpact = formatNumber(impact.impact);\n\n const totalContributions =\n stats.summary.totalQuestions +\n stats.summary.totalAnswers +\n stats.summary.totalArticles +\n stats.summary.totalLinks;\n\n const statItems = [\n {\n icon: <TrendingUp fontSize=\"small\" />,\n value: formatNumber(totalContributions),\n label: t('impactCard.totalContributions'),\n },\n {\n icon: <HelpOutline fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalQuestions),\n label: t('impactCard.questions'),\n },\n {\n icon: <QuestionAnswer fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalAnswers),\n label: t('impactCard.answers'),\n },\n {\n icon: <DescriptionIcon fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalArticles),\n label: t('impactCard.articles'),\n },\n {\n icon: <LinkIcon fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalLinks),\n label: t('impactCard.links'),\n },\n {\n icon: <ThumbUp fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalVotes),\n label: t('impactCard.votes'),\n },\n {\n icon: <People fontSize=\"small\" />,\n value: formatNumber(stats.summary.totalFollowers),\n label: t('impactCard.followers'),\n },\n {\n icon: <Star fontSize=\"small\" />,\n value: formatNumber(stats.summary.answerScore),\n label: t('impactCard.answerScore'),\n },\n {\n icon: <Star fontSize=\"small\" />,\n value: formatNumber(stats.summary.postScore),\n label: t('impactCard.postScore'),\n },\n {\n icon: <CheckCircle fontSize=\"small\" />,\n value: formatNumber(stats.summary.correctAnswers),\n label: t('impactCard.correctAnswers'),\n },\n ];\n\n return (\n <>\n <Typography variant=\"h5\" component=\"h2\" gutterBottom>\n {t('impactCard.title')}\n </Typography>\n <Box display=\"flex\" alignItems=\"center\" mb={1}>\n <Typography\n variant=\"body1\"\n aria-label={`${formattedImpact} views`}\n style={{ fontWeight: 'bold', marginBottom: 0, fontSize: '32px' }}\n >\n {formattedImpact}\n </Typography>\n <Typography\n variant=\"body2\"\n component=\"span\"\n style={{ marginLeft: '0.5em', verticalAlign: 'middle' }}\n color=\"textSecondary\"\n >\n {t('impactCard.views')}\n </Typography>\n </Box>\n <Typography variant=\"body2\" color=\"textSecondary\" paragraph>\n {t('impactCard.contributions', {\n lastWeek: impact.lastWeekImpact.toString(10),\n })}\n </Typography>\n\n <Box display=\"flex\" alignItems=\"center\" mt={2} mb={2}>\n <EmojiEvents\n style={{ color: theme.palette.secondary.main, marginRight: '8px' }}\n />\n <Typography\n variant=\"subtitle1\"\n component=\"span\"\n style={{ fontWeight: 'bold' }}\n >\n {t('impactCard.reputation')}:{' '}\n <Box component=\"span\" style={{ fontSize: '1.1em' }}>\n {stats.summary.reputation || 0}\n </Box>\n </Typography>\n </Box>\n\n <Divider />\n\n <Box mt={2}>\n <Grid container spacing={1}>\n {statItems.map((item, index) => (\n <Grid item xs={12} key={index}>\n <Box display=\"flex\" alignItems=\"center\" color=\"textSecondary\">\n <Tooltip title={item.label}>\n <Box display=\"flex\" alignItems=\"center\">\n {item.icon}\n </Box>\n </Tooltip>\n <Box ml={1}>\n <Typography variant=\"subtitle2\" component=\"span\">\n {item.value} {item.label.toLowerCase()}\n </Typography>\n </Box>\n </Box>\n </Grid>\n ))}\n </Grid>\n </Box>\n </>\n );\n };\n\n return (\n <Box\n display={{ md: 'none', lg: 'block' }}\n style={{ marginBottom: '1em' }}\n role=\"region\"\n aria-label={t('impactCard.title')}\n >\n <Card elevation={2}>\n <CardContent>{renderContent()}</CardContent>\n </Card>\n </Box>\n );\n};\n"],"names":["QuestionAnswer","People","Star"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ import '../../translation.esm.js';
|
|
|
13
13
|
import 'react-router-dom';
|
|
14
14
|
import { Card, CardHeader, Grid, Divider } from '@material-ui/core';
|
|
15
15
|
import '@material-ui/icons/Link';
|
|
16
|
-
import '
|
|
16
|
+
import 'infinite-scroll-hook';
|
|
17
17
|
import '@backstage/plugin-permission-react';
|
|
18
18
|
import '@backstage/plugin-permission-common';
|
|
19
19
|
import '@backstage/plugin-catalog-react';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { makeStyles, List,
|
|
2
|
+
import { makeStyles, List, ListItemIcon, Typography, Box, Tooltip, IconButton, MenuItem } from '@material-ui/core';
|
|
3
3
|
import { useRouteRef, useApp } from '@backstage/core-plugin-api';
|
|
4
4
|
import { useNavigate } from 'react-router-dom';
|
|
5
5
|
import { useLocation } from 'react-use';
|
|
@@ -45,13 +45,10 @@ const useStyles = makeStyles(
|
|
|
45
45
|
height: "100%"
|
|
46
46
|
},
|
|
47
47
|
leftMenuCompact: {
|
|
48
|
-
width: "
|
|
48
|
+
width: "70px",
|
|
49
49
|
overflowX: "hidden",
|
|
50
50
|
"& $sectionHeader": {
|
|
51
51
|
display: "none"
|
|
52
|
-
},
|
|
53
|
-
"& $divider": {
|
|
54
|
-
display: "none"
|
|
55
52
|
}
|
|
56
53
|
},
|
|
57
54
|
inPopup: {
|
|
@@ -60,22 +57,19 @@ const useStyles = makeStyles(
|
|
|
60
57
|
width: "auto"
|
|
61
58
|
},
|
|
62
59
|
outsidePopup: {
|
|
63
|
-
|
|
64
|
-
top: theme.spacing(2),
|
|
65
|
-
float: "right",
|
|
66
|
-
maxHeight: "calc(100vh - 100px)",
|
|
67
|
-
overflowY: "auto"
|
|
60
|
+
paddingRight: theme.spacing(2)
|
|
68
61
|
},
|
|
69
62
|
menuItem: {
|
|
70
|
-
margin: (props) => props.compact ? 0 : theme.spacing(0,
|
|
63
|
+
margin: (props) => props.compact ? 0 : theme.spacing(0, 1.5),
|
|
71
64
|
justifyContent: (props) => props.compact ? "center" : "flex-start",
|
|
72
|
-
padding: (props) => props.compact ? theme.spacing(1, 0) : theme.spacing(1,
|
|
65
|
+
padding: (props) => props.compact ? theme.spacing(1, 0) : theme.spacing(1, 0.5),
|
|
73
66
|
borderRadius: (props) => props.compact ? 0 : theme.shape.borderRadius,
|
|
74
67
|
transition: "all 0.2s ease-in-out",
|
|
75
68
|
color: theme.palette.text.primary,
|
|
76
69
|
display: "flex",
|
|
77
70
|
alignItems: "center",
|
|
78
71
|
minHeight: 48,
|
|
72
|
+
maxWidth: "80%",
|
|
79
73
|
"&:hover": {
|
|
80
74
|
backgroundColor: theme.palette.action.hover
|
|
81
75
|
}
|
|
@@ -110,7 +104,7 @@ const useStyles = makeStyles(
|
|
|
110
104
|
justifyContent: "center"
|
|
111
105
|
},
|
|
112
106
|
sectionHeader: {
|
|
113
|
-
padding: theme.spacing(0.5,
|
|
107
|
+
padding: theme.spacing(0.5, 2, 0.5, 2),
|
|
114
108
|
marginTop: theme.spacing(2),
|
|
115
109
|
color: theme.palette.text.secondary,
|
|
116
110
|
fontWeight: 600,
|
|
@@ -119,17 +113,13 @@ const useStyles = makeStyles(
|
|
|
119
113
|
letterSpacing: "0.5px",
|
|
120
114
|
whiteSpace: "nowrap"
|
|
121
115
|
},
|
|
122
|
-
divider: {
|
|
123
|
-
margin: theme.spacing(1, 2.5),
|
|
124
|
-
backgroundColor: theme.palette.divider
|
|
125
|
-
},
|
|
126
116
|
toggleButton: {
|
|
127
117
|
marginLeft: "auto",
|
|
128
|
-
marginRight: theme.spacing(
|
|
118
|
+
marginRight: theme.spacing(0),
|
|
129
119
|
marginBottom: theme.spacing(1)
|
|
130
120
|
},
|
|
131
121
|
label: {
|
|
132
|
-
marginLeft: theme.spacing(1
|
|
122
|
+
marginLeft: theme.spacing(1),
|
|
133
123
|
whiteSpace: "nowrap",
|
|
134
124
|
opacity: 1,
|
|
135
125
|
transition: "opacity 0.2s"
|
|
@@ -220,26 +210,8 @@ const LeftMenu = (props) => {
|
|
|
220
210
|
"aria-labelledby": "nested-list-subheader",
|
|
221
211
|
disablePadding: true,
|
|
222
212
|
children: [
|
|
223
|
-
!isPopup && /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: isCompact ? "center" : "flex-end", children: /* @__PURE__ */ jsx(
|
|
224
|
-
Tooltip,
|
|
225
|
-
{
|
|
226
|
-
title: isCompact ? t("leftMenu.expand") : t("leftMenu.collapse"),
|
|
227
|
-
placement: "right",
|
|
228
|
-
children: /* @__PURE__ */ jsx(
|
|
229
|
-
IconButton,
|
|
230
|
-
{
|
|
231
|
-
onClick: onToggle,
|
|
232
|
-
size: "small",
|
|
233
|
-
className: isCompact ? "" : styles.toggleButton,
|
|
234
|
-
style: { marginBottom: 0 },
|
|
235
|
-
children: isCompact ? /* @__PURE__ */ jsx(ChevronRightIcon, {}) : /* @__PURE__ */ jsx(MenuOpenIcon, {})
|
|
236
|
-
}
|
|
237
|
-
)
|
|
238
|
-
}
|
|
239
|
-
) }),
|
|
240
213
|
/* @__PURE__ */ jsx(CustomMenuItem, { route: rootRoute(), label: t("leftMenu.home"), children: /* @__PURE__ */ jsx(ListItemIcon, { className: styles.menuIcon, children: /* @__PURE__ */ jsx(HomeOutlined, { fontSize: "small" }) }) }),
|
|
241
214
|
/* @__PURE__ */ jsx("li", { style: { listStyle: "none" }, children: /* @__PURE__ */ jsx(Typography, { className: styles.sectionHeader, children: t("leftMenu.content") }) }),
|
|
242
|
-
/* @__PURE__ */ jsx(Divider, { className: styles.divider, component: "li" }),
|
|
243
215
|
/* @__PURE__ */ jsx(
|
|
244
216
|
CustomMenuItem,
|
|
245
217
|
{
|
|
@@ -294,7 +266,6 @@ const LeftMenu = (props) => {
|
|
|
294
266
|
}
|
|
295
267
|
),
|
|
296
268
|
/* @__PURE__ */ jsx("li", { style: { listStyle: "none" }, children: /* @__PURE__ */ jsx(Typography, { className: styles.sectionHeader, children: t("leftMenu.community") }) }),
|
|
297
|
-
/* @__PURE__ */ jsx(Divider, { className: styles.divider, component: "li" }),
|
|
298
269
|
/* @__PURE__ */ jsx(
|
|
299
270
|
CustomMenuItem,
|
|
300
271
|
{
|
|
@@ -323,7 +294,6 @@ const LeftMenu = (props) => {
|
|
|
323
294
|
),
|
|
324
295
|
(isModerator || canReview) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
325
296
|
/* @__PURE__ */ jsx("li", { style: { listStyle: "none" }, children: /* @__PURE__ */ jsx(Typography, { className: styles.sectionHeader, children: t("leftMenu.manage") }) }),
|
|
326
|
-
/* @__PURE__ */ jsx(Divider, { className: styles.divider, component: "li" }),
|
|
327
297
|
canReview && /* @__PURE__ */ jsx(CustomMenuItem, { route: reviewRoute(), label: t("leftMenu.review"), children: /* @__PURE__ */ jsx(ListItemIcon, { className: styles.menuIcon, children: /* @__PURE__ */ jsx(RateReviewOutlined, { fontSize: "small" }) }) }),
|
|
328
298
|
isModerator && /* @__PURE__ */ jsx(
|
|
329
299
|
CustomMenuItem,
|
|
@@ -333,7 +303,32 @@ const LeftMenu = (props) => {
|
|
|
333
303
|
children: /* @__PURE__ */ jsx(ListItemIcon, { className: styles.menuIcon, children: /* @__PURE__ */ jsx(SettingsOutlined, { fontSize: "small" }) })
|
|
334
304
|
}
|
|
335
305
|
)
|
|
336
|
-
] })
|
|
306
|
+
] }),
|
|
307
|
+
!isPopup && /* @__PURE__ */ jsx(
|
|
308
|
+
Box,
|
|
309
|
+
{
|
|
310
|
+
display: "flex",
|
|
311
|
+
justifyContent: isCompact ? "center" : "flex-start",
|
|
312
|
+
style: { marginTop: "auto" },
|
|
313
|
+
children: /* @__PURE__ */ jsx(
|
|
314
|
+
Tooltip,
|
|
315
|
+
{
|
|
316
|
+
title: isCompact ? t("leftMenu.expand") : t("leftMenu.collapse"),
|
|
317
|
+
placement: "right",
|
|
318
|
+
children: /* @__PURE__ */ jsx(
|
|
319
|
+
IconButton,
|
|
320
|
+
{
|
|
321
|
+
onClick: onToggle,
|
|
322
|
+
size: "small",
|
|
323
|
+
className: isCompact ? "" : styles.toggleButton,
|
|
324
|
+
style: { marginTop: 8, marginLeft: isCompact ? 0 : 18 },
|
|
325
|
+
children: isCompact ? /* @__PURE__ */ jsx(ChevronRightIcon, {}) : /* @__PURE__ */ jsx(MenuOpenIcon, {})
|
|
326
|
+
}
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
)
|
|
330
|
+
}
|
|
331
|
+
)
|
|
337
332
|
]
|
|
338
333
|
}
|
|
339
334
|
);
|