@drodil/backstage-plugin-qeta 2.2.1 → 2.3.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.
- package/dist/api/QetaClient.esm.js +434 -0
- package/dist/api/QetaClient.esm.js.map +1 -0
- package/dist/components/AskAnonymouslyCheckbox/AskAnonymouslyCheckbox.esm.js +32 -0
- package/dist/components/AskAnonymouslyCheckbox/AskAnonymouslyCheckbox.esm.js.map +1 -0
- package/dist/components/AskForm/AskForm.esm.js +218 -0
- package/dist/components/AskForm/AskForm.esm.js.map +1 -0
- package/dist/components/AskForm/EntitiesInput.esm.js +98 -0
- package/dist/components/AskForm/EntitiesInput.esm.js.map +1 -0
- package/dist/components/AskForm/TagInput.esm.js +86 -0
- package/dist/components/AskForm/TagInput.esm.js.map +1 -0
- package/dist/components/AskPage/AskPage.esm.js +38 -0
- package/dist/components/AskPage/AskPage.esm.js.map +1 -0
- package/dist/components/Buttons/AskQuestionButton.esm.js +43 -0
- package/dist/components/Buttons/AskQuestionButton.esm.js.map +1 -0
- package/dist/components/Buttons/BackToQuestionsButton.esm.js +38 -0
- package/dist/components/Buttons/BackToQuestionsButton.esm.js.map +1 -0
- package/dist/components/CommentSection/CommentList.esm.js +47 -0
- package/dist/components/CommentSection/CommentList.esm.js.map +1 -0
- package/dist/components/CommentSection/CommentSection.esm.js +97 -0
- package/dist/components/CommentSection/CommentSection.esm.js.map +1 -0
- package/dist/components/DeleteModal/DeleteModal.esm.js +77 -0
- package/dist/components/DeleteModal/DeleteModal.esm.js.map +1 -0
- package/dist/components/FavoritePage/FavoritePage.esm.js +13 -0
- package/dist/components/FavoritePage/FavoritePage.esm.js.map +1 -0
- package/dist/components/HomePage/HomePage.esm.js +144 -0
- package/dist/components/HomePage/HomePage.esm.js.map +1 -0
- package/dist/components/HomePage/index.esm.js +2 -0
- package/dist/components/HomePage/index.esm.js.map +1 -0
- package/dist/components/Links/Links.esm.js +31 -0
- package/dist/components/Links/Links.esm.js.map +1 -0
- package/dist/components/MarkdownEditor/MarkdownEditor.esm.js +80 -0
- package/dist/components/MarkdownEditor/MarkdownEditor.esm.js.map +1 -0
- package/dist/components/QuestionHighlightList/QuestionHighlightList.esm.js +61 -0
- package/dist/components/QuestionHighlightList/QuestionHighlightList.esm.js.map +1 -0
- package/dist/components/QuestionPage/AnswerCard.esm.js +101 -0
- package/dist/components/QuestionPage/AnswerCard.esm.js.map +1 -0
- package/dist/components/QuestionPage/AnswerForm.esm.js +130 -0
- package/dist/components/QuestionPage/AnswerForm.esm.js.map +1 -0
- package/dist/components/QuestionPage/AuthorBox.esm.js +25 -0
- package/dist/components/QuestionPage/AuthorBox.esm.js.map +1 -0
- package/dist/components/QuestionPage/EntityChip.esm.js +26 -0
- package/dist/components/QuestionPage/EntityChip.esm.js.map +1 -0
- package/dist/components/QuestionPage/FavoriteButton.esm.js +43 -0
- package/dist/components/QuestionPage/FavoriteButton.esm.js.map +1 -0
- package/dist/components/QuestionPage/LinkButton.esm.js +32 -0
- package/dist/components/QuestionPage/LinkButton.esm.js.map +1 -0
- package/dist/components/QuestionPage/QuestionCard.esm.js +103 -0
- package/dist/components/QuestionPage/QuestionCard.esm.js.map +1 -0
- package/dist/components/QuestionPage/QuestionPage.esm.js +131 -0
- package/dist/components/QuestionPage/QuestionPage.esm.js.map +1 -0
- package/dist/components/QuestionPage/TagsAndEntities.esm.js +44 -0
- package/dist/components/QuestionPage/TagsAndEntities.esm.js.map +1 -0
- package/dist/components/QuestionPage/VoteButtons.esm.js +146 -0
- package/dist/components/QuestionPage/VoteButtons.esm.js.map +1 -0
- package/dist/components/QuestionTableCard/Content.esm.js +9 -0
- package/dist/components/QuestionTableCard/Content.esm.js.map +1 -0
- package/dist/components/QuestionTableCard/QuestionTableRow.esm.js +21 -0
- package/dist/components/QuestionTableCard/QuestionTableRow.esm.js.map +1 -0
- package/dist/components/QuestionTableCard/QuestionsTable.esm.js +130 -0
- package/dist/components/QuestionTableCard/QuestionsTable.esm.js.map +1 -0
- package/dist/components/QuestionTableCard/index.esm.js +3 -0
- package/dist/components/QuestionTableCard/index.esm.js.map +1 -0
- package/dist/components/QuestionsContainer/FilterPanel.esm.js +230 -0
- package/dist/components/QuestionsContainer/FilterPanel.esm.js.map +1 -0
- package/dist/components/QuestionsContainer/NoQuestionsCard.esm.js +46 -0
- package/dist/components/QuestionsContainer/NoQuestionsCard.esm.js.map +1 -0
- package/dist/components/QuestionsContainer/QuestionList.esm.js +102 -0
- package/dist/components/QuestionsContainer/QuestionList.esm.js.map +1 -0
- package/dist/components/QuestionsContainer/QuestionListItem.esm.js +119 -0
- package/dist/components/QuestionsContainer/QuestionListItem.esm.js.map +1 -0
- package/dist/components/QuestionsContainer/QuestionsContainer.esm.js +231 -0
- package/dist/components/QuestionsContainer/QuestionsContainer.esm.js.map +1 -0
- package/dist/components/RelativeTimeWithTooltip/RelativeTimeWithTooltip.esm.js +22 -0
- package/dist/components/RelativeTimeWithTooltip/RelativeTimeWithTooltip.esm.js.map +1 -0
- package/dist/components/Statistics/StatisticsPage.esm.js +13 -0
- package/dist/components/Statistics/StatisticsPage.esm.js.map +1 -0
- package/dist/components/Statistics/TopRankingUsersCard.esm.js +163 -0
- package/dist/components/Statistics/TopRankingUsersCard.esm.js.map +1 -0
- package/dist/components/Statistics/TrophyIcon.esm.js +19 -0
- package/dist/components/Statistics/TrophyIcon.esm.js.map +1 -0
- package/dist/components/Statistics/styles.esm.js +23 -0
- package/dist/components/Statistics/styles.esm.js.map +1 -0
- package/dist/components/TagPage/TagPage.esm.js +16 -0
- package/dist/components/TagPage/TagPage.esm.js.map +1 -0
- package/dist/components/TagPage/TagsContainer.esm.js +63 -0
- package/dist/components/TagPage/TagsContainer.esm.js.map +1 -0
- package/dist/components/UserPage/UserPage.esm.js +24 -0
- package/dist/components/UserPage/UserPage.esm.js.map +1 -0
- package/dist/index.esm.js +9 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +60 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/utils/hooks.esm.js +283 -0
- package/dist/utils/hooks.esm.js.map +1 -0
- package/dist/utils/utils.esm.js +31 -0
- package/dist/utils/utils.esm.js.map +1 -0
- package/package.json +15 -15
- package/dist/esm/index-CuD-iIx9.esm.js +0 -2408
- package/dist/esm/index-CuD-iIx9.esm.js.map +0 -1
- package/dist/esm/index-Djg6aEGn.esm.js +0 -33
- package/dist/esm/index-Djg6aEGn.esm.js.map +0 -1
- package/dist/esm/index-Z9_0Lp_9.esm.js +0 -1120
- package/dist/esm/index-Z9_0Lp_9.esm.js.map +0 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { useQetaApi } from '../../utils/hooks.esm.js';
|
|
2
|
+
import { Box, Typography, Grid, TextField, Button, Collapse } from '@material-ui/core';
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
|
+
import useDebounce from 'react-use/lib/useDebounce';
|
|
5
|
+
import { filterKeys, FilterPanel } from './FilterPanel.esm.js';
|
|
6
|
+
import { QuestionList } from './QuestionList.esm.js';
|
|
7
|
+
import FilterList from '@material-ui/icons/FilterList';
|
|
8
|
+
import { useSearchParams } from 'react-router-dom';
|
|
9
|
+
import { AskQuestionButton } from '../Buttons/AskQuestionButton.esm.js';
|
|
10
|
+
import { EntityRefLink } from '@backstage/plugin-catalog-react';
|
|
11
|
+
import { useAnalytics } from '@backstage/core-plugin-api';
|
|
12
|
+
import { filterTags } from '@drodil/backstage-plugin-qeta-common';
|
|
13
|
+
|
|
14
|
+
const QuestionsContainer = (props) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const {
|
|
17
|
+
tags,
|
|
18
|
+
author,
|
|
19
|
+
entity,
|
|
20
|
+
showFilters,
|
|
21
|
+
showTitle,
|
|
22
|
+
title,
|
|
23
|
+
favorite,
|
|
24
|
+
showAskButton,
|
|
25
|
+
showNoQuestionsBtn
|
|
26
|
+
} = props;
|
|
27
|
+
const analytics = useAnalytics();
|
|
28
|
+
const [page, setPage] = React.useState(1);
|
|
29
|
+
const [questionsPerPage, setQuestionsPerPage] = React.useState(10);
|
|
30
|
+
const [showFilterPanel, setShowFilterPanel] = React.useState(false);
|
|
31
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
32
|
+
const [searchQuery, setSearchQuery] = React.useState("");
|
|
33
|
+
const [filters, setFilters] = React.useState({
|
|
34
|
+
order: "desc",
|
|
35
|
+
orderBy: "created",
|
|
36
|
+
noAnswers: "false",
|
|
37
|
+
noCorrectAnswer: "false",
|
|
38
|
+
noVotes: "false",
|
|
39
|
+
searchQuery: "",
|
|
40
|
+
entity: entity != null ? entity : "",
|
|
41
|
+
tags: tags != null ? tags : []
|
|
42
|
+
});
|
|
43
|
+
const onPageChange = (value) => {
|
|
44
|
+
setPage(value);
|
|
45
|
+
setSearchParams((prev) => {
|
|
46
|
+
const newValue = prev;
|
|
47
|
+
newValue.set("page", String(value));
|
|
48
|
+
return newValue;
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const onFilterChange = (key, value) => {
|
|
52
|
+
if (filters[key] === value) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setPage(1);
|
|
56
|
+
setFilters({ ...filters, ...{ [key]: value } });
|
|
57
|
+
setSearchParams((prev) => {
|
|
58
|
+
const newValue = prev;
|
|
59
|
+
if (!value || value === "false") {
|
|
60
|
+
newValue.delete(key);
|
|
61
|
+
} else if (Array.isArray(value)) {
|
|
62
|
+
if (value.length === 0) {
|
|
63
|
+
newValue.delete(key);
|
|
64
|
+
} else {
|
|
65
|
+
newValue.set(key, value.join(","));
|
|
66
|
+
}
|
|
67
|
+
} else if (value.length > 0) {
|
|
68
|
+
newValue.set(key, value);
|
|
69
|
+
} else {
|
|
70
|
+
newValue.delete(key);
|
|
71
|
+
}
|
|
72
|
+
return newValue;
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const onSearchQueryChange = (event) => {
|
|
76
|
+
onPageChange(1);
|
|
77
|
+
if (event.target.value) {
|
|
78
|
+
analytics.captureEvent("qeta_search", event.target.value);
|
|
79
|
+
}
|
|
80
|
+
setSearchQuery(event.target.value);
|
|
81
|
+
};
|
|
82
|
+
useDebounce(
|
|
83
|
+
() => {
|
|
84
|
+
if (filters.searchQuery !== searchQuery) {
|
|
85
|
+
setFilters({ ...filters, searchQuery });
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
400,
|
|
89
|
+
[searchQuery]
|
|
90
|
+
);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
let filtersApplied = false;
|
|
93
|
+
searchParams.forEach((value, key) => {
|
|
94
|
+
var _a2;
|
|
95
|
+
try {
|
|
96
|
+
if (key === "page") {
|
|
97
|
+
const pv = Number.parseInt(value, 10);
|
|
98
|
+
if (pv > 0) {
|
|
99
|
+
setPage(pv);
|
|
100
|
+
} else {
|
|
101
|
+
setPage(1);
|
|
102
|
+
}
|
|
103
|
+
} else if (key === "questionsPerPage") {
|
|
104
|
+
const qpp = Number.parseInt(value, 10);
|
|
105
|
+
if (qpp > 0)
|
|
106
|
+
setQuestionsPerPage(qpp);
|
|
107
|
+
} else if (filterKeys.includes(key)) {
|
|
108
|
+
filtersApplied = true;
|
|
109
|
+
if (key === "tags") {
|
|
110
|
+
filters.tags = (_a2 = filterTags(value)) != null ? _a2 : [];
|
|
111
|
+
} else {
|
|
112
|
+
filters[key] = value;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (_e) {
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
setFilters(filters);
|
|
119
|
+
if (filtersApplied) {
|
|
120
|
+
setShowFilterPanel(true);
|
|
121
|
+
}
|
|
122
|
+
}, [searchParams, filters]);
|
|
123
|
+
const {
|
|
124
|
+
value: response,
|
|
125
|
+
loading,
|
|
126
|
+
error
|
|
127
|
+
} = useQetaApi(
|
|
128
|
+
(api) => {
|
|
129
|
+
return api.getQuestions({
|
|
130
|
+
limit: questionsPerPage,
|
|
131
|
+
offset: (page - 1) * questionsPerPage,
|
|
132
|
+
includeEntities: true,
|
|
133
|
+
author,
|
|
134
|
+
favorite,
|
|
135
|
+
...filters
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
[page, filters, questionsPerPage]
|
|
139
|
+
);
|
|
140
|
+
const onPageSizeChange = (value) => {
|
|
141
|
+
if (response) {
|
|
142
|
+
let newPage = page;
|
|
143
|
+
while (newPage * value > response.total) {
|
|
144
|
+
newPage -= 1;
|
|
145
|
+
}
|
|
146
|
+
onPageChange(Math.max(1, newPage));
|
|
147
|
+
}
|
|
148
|
+
setQuestionsPerPage(value);
|
|
149
|
+
setSearchParams((prev) => {
|
|
150
|
+
const newValue = prev;
|
|
151
|
+
newValue.set("questionsPerPage", String(value));
|
|
152
|
+
return newValue;
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
let shownTitle = title;
|
|
156
|
+
let link = void 0;
|
|
157
|
+
if (author) {
|
|
158
|
+
shownTitle = `Questions by `;
|
|
159
|
+
link = /* @__PURE__ */ React.createElement(EntityRefLink, { entityRef: author, hideIcon: true, defaultKind: "user" });
|
|
160
|
+
} else if (entity) {
|
|
161
|
+
shownTitle = `Questions about `;
|
|
162
|
+
link = /* @__PURE__ */ React.createElement(EntityRefLink, { entityRef: entity });
|
|
163
|
+
} else if (tags) {
|
|
164
|
+
shownTitle = `Questions tagged with [${tags.join(", ")}]`;
|
|
165
|
+
} else if (favorite) {
|
|
166
|
+
shownTitle = "Your favorite questions";
|
|
167
|
+
}
|
|
168
|
+
return /* @__PURE__ */ React.createElement(Box, { className: "qetaQuestionsContainer" }, showTitle && /* @__PURE__ */ React.createElement(
|
|
169
|
+
Typography,
|
|
170
|
+
{
|
|
171
|
+
variant: "h5",
|
|
172
|
+
className: "qetaQuestionsContainerTitle",
|
|
173
|
+
style: { marginBottom: "1.5rem" }
|
|
174
|
+
},
|
|
175
|
+
shownTitle,
|
|
176
|
+
link
|
|
177
|
+
), /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, md: 4 }, /* @__PURE__ */ React.createElement(
|
|
178
|
+
TextField,
|
|
179
|
+
{
|
|
180
|
+
id: "search-bar",
|
|
181
|
+
fullWidth: true,
|
|
182
|
+
onChange: onSearchQueryChange,
|
|
183
|
+
label: "Search for questions",
|
|
184
|
+
className: "qetaQuestionsContainerSearchInput",
|
|
185
|
+
variant: "outlined",
|
|
186
|
+
placeholder: "Search...",
|
|
187
|
+
size: "small",
|
|
188
|
+
style: { marginBottom: "5px" }
|
|
189
|
+
}
|
|
190
|
+
)), showAskButton && /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(
|
|
191
|
+
AskQuestionButton,
|
|
192
|
+
{
|
|
193
|
+
entity: entity != null ? entity : filters.entity,
|
|
194
|
+
entityPage: entity !== void 0,
|
|
195
|
+
tags
|
|
196
|
+
}
|
|
197
|
+
))), /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(
|
|
198
|
+
Typography,
|
|
199
|
+
{
|
|
200
|
+
variant: "h6",
|
|
201
|
+
className: "qetaQuestionsContainerQuestionCount"
|
|
202
|
+
},
|
|
203
|
+
`${(_a = response == null ? void 0 : response.total) != null ? _a : 0} ${(response == null ? void 0 : response.total) === 1 ? "question" : "questions"}`
|
|
204
|
+
)), (showFilters != null ? showFilters : true) && /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(
|
|
205
|
+
Button,
|
|
206
|
+
{
|
|
207
|
+
onClick: () => setShowFilterPanel(!showFilterPanel),
|
|
208
|
+
className: "qetaQuestionsContainerFilterPanelBtn",
|
|
209
|
+
startIcon: /* @__PURE__ */ React.createElement(FilterList, null)
|
|
210
|
+
},
|
|
211
|
+
"Filter"
|
|
212
|
+
))), (showFilters != null ? showFilters : true) && /* @__PURE__ */ React.createElement(Collapse, { in: showFilterPanel }, /* @__PURE__ */ React.createElement(FilterPanel, { onChange: onFilterChange, filters })), /* @__PURE__ */ React.createElement(
|
|
213
|
+
QuestionList,
|
|
214
|
+
{
|
|
215
|
+
loading,
|
|
216
|
+
error,
|
|
217
|
+
response,
|
|
218
|
+
onPageChange,
|
|
219
|
+
onPageSizeChange,
|
|
220
|
+
entity,
|
|
221
|
+
page,
|
|
222
|
+
pageSize: questionsPerPage,
|
|
223
|
+
showNoQuestionsBtn,
|
|
224
|
+
entityPage: entity !== void 0,
|
|
225
|
+
tags
|
|
226
|
+
}
|
|
227
|
+
));
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export { QuestionsContainer };
|
|
231
|
+
//# sourceMappingURL=QuestionsContainer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuestionsContainer.esm.js","sources":["../../../src/components/QuestionsContainer/QuestionsContainer.tsx"],"sourcesContent":["import { useQetaApi } from '../../utils/hooks';\nimport {\n Box,\n Button,\n Collapse,\n Grid,\n TextField,\n Typography,\n} from '@material-ui/core';\n\nimport React, { useEffect } from 'react';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { FilterKey, filterKeys, FilterPanel, Filters } from './FilterPanel';\nimport { QuestionList } from './QuestionList';\nimport FilterList from '@material-ui/icons/FilterList';\nimport { useSearchParams } from 'react-router-dom';\nimport { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { useAnalytics } from '@backstage/core-plugin-api';\nimport { filterTags } from '@drodil/backstage-plugin-qeta-common';\n\nexport interface QuestionsContainerProps {\n tags?: string[];\n author?: string;\n entity?: string;\n showFilters?: boolean;\n showTitle?: boolean;\n title?: string;\n favorite?: boolean;\n showAskButton?: boolean;\n showNoQuestionsBtn?: boolean;\n}\n\nexport const QuestionsContainer = (props: QuestionsContainerProps) => {\n const {\n tags,\n author,\n entity,\n showFilters,\n showTitle,\n title,\n favorite,\n showAskButton,\n showNoQuestionsBtn,\n } = props;\n const analytics = useAnalytics();\n const [page, setPage] = React.useState(1);\n const [questionsPerPage, setQuestionsPerPage] = React.useState(10);\n const [showFilterPanel, setShowFilterPanel] = React.useState(false);\n const [searchParams, setSearchParams] = useSearchParams();\n const [searchQuery, setSearchQuery] = React.useState('');\n const [filters, setFilters] = React.useState<Filters>({\n order: 'desc',\n orderBy: 'created',\n noAnswers: 'false',\n noCorrectAnswer: 'false',\n noVotes: 'false',\n searchQuery: '',\n entity: entity ?? '',\n tags: tags ?? [],\n });\n\n const onPageChange = (value: number) => {\n setPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('page', String(value));\n return newValue;\n });\n };\n\n const onFilterChange = (key: FilterKey, value: string | string[]) => {\n if (filters[key] === value) {\n return;\n }\n\n setPage(1);\n setFilters({ ...filters, ...{ [key]: value } });\n setSearchParams(prev => {\n const newValue = prev;\n if (!value || value === 'false') {\n newValue.delete(key);\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n newValue.delete(key);\n } else {\n newValue.set(key, value.join(','));\n }\n } else if (value.length > 0) {\n newValue.set(key, value);\n } else {\n newValue.delete(key);\n }\n return newValue;\n });\n };\n\n const onSearchQueryChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n onPageChange(1);\n if (event.target.value) {\n analytics.captureEvent('qeta_search', event.target.value);\n }\n setSearchQuery(event.target.value);\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 let filtersApplied = false;\n searchParams.forEach((value, key) => {\n try {\n if (key === 'page') {\n const pv = Number.parseInt(value, 10);\n if (pv > 0) {\n setPage(pv);\n } else {\n setPage(1);\n }\n } else if (key === 'questionsPerPage') {\n const qpp = Number.parseInt(value, 10);\n if (qpp > 0) setQuestionsPerPage(qpp);\n } else if (filterKeys.includes(key as FilterKey)) {\n filtersApplied = true;\n if (key === 'tags') {\n filters.tags = filterTags(value) ?? [];\n } else {\n (filters as any)[key] = value;\n }\n }\n } catch (_e) {\n // NOOP\n }\n });\n setFilters(filters);\n if (filtersApplied) {\n setShowFilterPanel(true);\n }\n }, [searchParams, filters]);\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api => {\n return api.getQuestions({\n limit: questionsPerPage,\n offset: (page - 1) * questionsPerPage,\n includeEntities: true,\n author,\n favorite,\n ...filters,\n });\n },\n [page, filters, questionsPerPage],\n );\n\n const onPageSizeChange = (value: number) => {\n if (response) {\n let newPage = page;\n while (newPage * value > response.total) {\n newPage -= 1;\n }\n onPageChange(Math.max(1, newPage));\n }\n setQuestionsPerPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('questionsPerPage', String(value));\n return newValue;\n });\n };\n\n let shownTitle = title;\n let link = undefined;\n if (author) {\n shownTitle = `Questions by `;\n link = <EntityRefLink entityRef={author} hideIcon defaultKind=\"user\" />;\n } else if (entity) {\n shownTitle = `Questions about `;\n link = <EntityRefLink entityRef={entity} />;\n } else if (tags) {\n shownTitle = `Questions tagged with [${tags.join(', ')}]`;\n } else if (favorite) {\n shownTitle = 'Your favorite questions';\n }\n\n return (\n <Box className=\"qetaQuestionsContainer\">\n {showTitle && (\n <Typography\n variant=\"h5\"\n className=\"qetaQuestionsContainerTitle\"\n style={{ marginBottom: '1.5rem' }}\n >\n {shownTitle}\n {link}\n </Typography>\n )}\n <Grid container justifyContent=\"space-between\">\n <Grid item xs={12} md={4}>\n <TextField\n id=\"search-bar\"\n fullWidth\n onChange={onSearchQueryChange}\n label=\"Search for questions\"\n className=\"qetaQuestionsContainerSearchInput\"\n variant=\"outlined\"\n placeholder=\"Search...\"\n size=\"small\"\n style={{ marginBottom: '5px' }}\n />\n </Grid>\n {showAskButton && (\n <Grid item>\n <AskQuestionButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n </Grid>\n )}\n </Grid>\n <Grid container justifyContent=\"space-between\">\n <Grid item>\n <Typography\n variant=\"h6\"\n className=\"qetaQuestionsContainerQuestionCount\"\n >{`${response?.total ?? 0} ${\n response?.total === 1 ? 'question' : 'questions'\n }`}</Typography>\n </Grid>\n {(showFilters ?? true) && (\n <Grid item>\n <Button\n onClick={() => setShowFilterPanel(!showFilterPanel)}\n className=\"qetaQuestionsContainerFilterPanelBtn\"\n startIcon={<FilterList />}\n >\n Filter\n </Button>\n </Grid>\n )}\n </Grid>\n {(showFilters ?? true) && (\n <Collapse in={showFilterPanel}>\n <FilterPanel onChange={onFilterChange} filters={filters} />\n </Collapse>\n )}\n\n <QuestionList\n loading={loading}\n error={error}\n response={response}\n onPageChange={onPageChange}\n onPageSizeChange={onPageSizeChange}\n entity={entity}\n page={page}\n pageSize={questionsPerPage}\n showNoQuestionsBtn={showNoQuestionsBtn}\n entityPage={entity !== undefined}\n tags={tags}\n />\n </Box>\n );\n};\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Tooltip } from '@material-ui/core';
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
import RelativeTime from 'react-relative-time';
|
|
4
|
+
|
|
5
|
+
const RelativeTimeWithTooltip = (props) => {
|
|
6
|
+
const { value } = props;
|
|
7
|
+
let date = value;
|
|
8
|
+
const [updates, setUpdates] = React.useState(1);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const interval = setInterval(() => {
|
|
11
|
+
setUpdates(updates === 1 ? 0 : 1);
|
|
12
|
+
}, 3e4);
|
|
13
|
+
return () => clearInterval(interval);
|
|
14
|
+
}, [updates, setUpdates]);
|
|
15
|
+
if (typeof date === "string" || date instanceof String) {
|
|
16
|
+
date = new Date(date);
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ React.createElement(Tooltip, { title: date.toLocaleString(navigator.languages) }, /* @__PURE__ */ React.createElement(RelativeTime, { value: date }));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { RelativeTimeWithTooltip };
|
|
22
|
+
//# sourceMappingURL=RelativeTimeWithTooltip.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RelativeTimeWithTooltip.esm.js","sources":["../../../src/components/RelativeTimeWithTooltip/RelativeTimeWithTooltip.tsx"],"sourcesContent":["import { Tooltip } from '@material-ui/core';\nimport React, { useEffect } from 'react';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\n\nexport const RelativeTimeWithTooltip = (props: { value: Date | string }) => {\n const { value } = props;\n let date = value;\n const [updates, setUpdates] = React.useState(1);\n\n useEffect(() => {\n const interval = setInterval(() => {\n setUpdates(updates === 1 ? 0 : 1);\n }, 30000);\n return () => clearInterval(interval);\n }, [updates, setUpdates]);\n\n if (typeof date === 'string' || date instanceof String) {\n date = new Date(date);\n }\n\n return (\n <Tooltip title={date.toLocaleString(navigator.languages)}>\n <RelativeTime value={date} />\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;AAKa,MAAA,uBAAA,GAA0B,CAAC,KAAoC,KAAA;AAC1E,EAAM,MAAA,EAAE,OAAU,GAAA,KAAA,CAAA;AAClB,EAAA,IAAI,IAAO,GAAA,KAAA,CAAA;AACX,EAAA,MAAM,CAAC,OAAS,EAAA,UAAU,CAAI,GAAA,KAAA,CAAM,SAAS,CAAC,CAAA,CAAA;AAE9C,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,QAAA,GAAW,YAAY,MAAM;AACjC,MAAW,UAAA,CAAA,OAAA,KAAY,CAAI,GAAA,CAAA,GAAI,CAAC,CAAA,CAAA;AAAA,OAC/B,GAAK,CAAA,CAAA;AACR,IAAO,OAAA,MAAM,cAAc,QAAQ,CAAA,CAAA;AAAA,GAClC,EAAA,CAAC,OAAS,EAAA,UAAU,CAAC,CAAA,CAAA;AAExB,EAAA,IAAI,OAAO,IAAA,KAAS,QAAY,IAAA,IAAA,YAAgB,MAAQ,EAAA;AACtD,IAAO,IAAA,GAAA,IAAI,KAAK,IAAI,CAAA,CAAA;AAAA,GACtB;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,KAAO,EAAA,IAAA,CAAK,cAAe,CAAA,SAAA,CAAU,SAAS,CAAA,EAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,IAAA,EAAM,CAC7B,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Content, ContentHeader } from '@backstage/core-components';
|
|
3
|
+
import { AskQuestionButton } from '../Buttons/AskQuestionButton.esm.js';
|
|
4
|
+
import { Container } from '@material-ui/core';
|
|
5
|
+
import { TopRankingUsers } from './TopRankingUsersCard.esm.js';
|
|
6
|
+
import { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton.esm.js';
|
|
7
|
+
|
|
8
|
+
const StatisticsPage = () => {
|
|
9
|
+
return /* @__PURE__ */ React.createElement(Content, { className: "qetaStatisticsPage" }, /* @__PURE__ */ React.createElement(Container, { maxWidth: "lg" }, /* @__PURE__ */ React.createElement(ContentHeader, { title: "Statistics" }, /* @__PURE__ */ React.createElement(BackToQuestionsButton, null), /* @__PURE__ */ React.createElement(AskQuestionButton, null)), /* @__PURE__ */ React.createElement(TopRankingUsers, { limit: 10 })));
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { StatisticsPage };
|
|
13
|
+
//# sourceMappingURL=StatisticsPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatisticsPage.esm.js","sources":["../../../src/components/Statistics/StatisticsPage.tsx"],"sourcesContent":["import React from 'react';\nimport { Content, ContentHeader } from '@backstage/core-components';\nimport { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { Container } from '@material-ui/core';\nimport { TopRankingUsers } from './TopRankingUsersCard';\nimport { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton';\n\nexport const StatisticsPage = () => {\n return (\n <Content className=\"qetaStatisticsPage\">\n <Container maxWidth=\"lg\">\n <ContentHeader title=\"Statistics\">\n <BackToQuestionsButton />\n <AskQuestionButton />\n </ContentHeader>\n <TopRankingUsers limit={10} />\n </Container>\n </Content>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAOO,MAAM,iBAAiB,MAAM;AAClC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAU,oBACjB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAU,QAAS,EAAA,IAAA,EAAA,kBACjB,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA,EAAc,KAAM,EAAA,YAAA,EAAA,sCAClB,qBAAsB,EAAA,IAAA,CAAA,kBACtB,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,IAAkB,CACrB,CAAA,sCACC,eAAgB,EAAA,EAAA,KAAA,EAAO,EAAI,EAAA,CAC9B,CACF,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { WarningPanel, CardTab, TabbedCard, Progress } from '@backstage/core-components';
|
|
3
|
+
import { ListItem, ListItemAvatar, Avatar, ListItemText, Typography, List } from '@material-ui/core';
|
|
4
|
+
import { useQetaApi } from '../../utils/hooks.esm.js';
|
|
5
|
+
import { TrophyIcon } from './TrophyIcon.esm.js';
|
|
6
|
+
import { useStyles } from './styles.esm.js';
|
|
7
|
+
import { UserLink } from '../Links/Links.esm.js';
|
|
8
|
+
|
|
9
|
+
const DefaultRankingIcons = /* @__PURE__ */ new Map([
|
|
10
|
+
[
|
|
11
|
+
1,
|
|
12
|
+
/* @__PURE__ */ React.createElement(
|
|
13
|
+
TrophyIcon,
|
|
14
|
+
{
|
|
15
|
+
style: { color: "#DAA520", height: "2.2rem", width: "2.2rem" }
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
2,
|
|
21
|
+
/* @__PURE__ */ React.createElement(
|
|
22
|
+
TrophyIcon,
|
|
23
|
+
{
|
|
24
|
+
style: { color: "#C0C0C0", height: "2.1rem", width: "2.1rem" }
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
3,
|
|
30
|
+
/* @__PURE__ */ React.createElement(TrophyIcon, { style: { color: "#B87333", height: "2rem", width: "2rem" } })
|
|
31
|
+
]
|
|
32
|
+
]);
|
|
33
|
+
const DefaultUserIcon = /* @__PURE__ */ React.createElement(TrophyIcon, { style: { height: "2rem", width: "2rem" } });
|
|
34
|
+
const getOrdinal = (n) => {
|
|
35
|
+
if (n % 10 === 1 && n % 100 !== 11) {
|
|
36
|
+
return `${n}st`;
|
|
37
|
+
} else if (n % 10 === 2 && n % 100 !== 12) {
|
|
38
|
+
return `${n}nd`;
|
|
39
|
+
} else if (n % 10 === 3 && n % 100 !== 13) {
|
|
40
|
+
return `${n}rd`;
|
|
41
|
+
}
|
|
42
|
+
return `${n}th`;
|
|
43
|
+
};
|
|
44
|
+
const RankingRow = (props) => {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
const classes = useStyles();
|
|
47
|
+
const userRef = props.userRef;
|
|
48
|
+
const ordinalPosition = (props == null ? void 0 : props.position) ? getOrdinal(props == null ? void 0 : props.position) : "";
|
|
49
|
+
const userIcon = ((_a = props.rankingIcon) == null ? void 0 : _a.userRankingIcon) ? (_b = props.rankingIcon) == null ? void 0 : _b.userRankingIcon : DefaultUserIcon;
|
|
50
|
+
const topRankingIcon = props.rankingIcon ? props.rankingIcon.iconsByRanking.get(Number(props == null ? void 0 : props.position)) : DefaultRankingIcons.get(Number(props == null ? void 0 : props.position)) || DefaultUserIcon;
|
|
51
|
+
const rankingIcon = (props == null ? void 0 : props.position) > 3 ? userIcon : topRankingIcon;
|
|
52
|
+
return /* @__PURE__ */ React.createElement(ListItem, { className: "qetaRankingCardRow" }, /* @__PURE__ */ React.createElement(ListItemAvatar, null, /* @__PURE__ */ React.createElement(Avatar, { className: classes.trophyIcon }, rankingIcon)), /* @__PURE__ */ React.createElement(
|
|
53
|
+
ListItemText,
|
|
54
|
+
{
|
|
55
|
+
disableTypography: true,
|
|
56
|
+
style: {
|
|
57
|
+
display: "flex",
|
|
58
|
+
justifyContent: "center"
|
|
59
|
+
},
|
|
60
|
+
primary: /* @__PURE__ */ React.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ React.createElement(
|
|
61
|
+
Typography,
|
|
62
|
+
{
|
|
63
|
+
style: { marginRight: "10px", fontWeight: 400 },
|
|
64
|
+
variant: "subtitle1"
|
|
65
|
+
},
|
|
66
|
+
`${ordinalPosition}`
|
|
67
|
+
), /* @__PURE__ */ React.createElement(UserLink, { entityRef: userRef != null ? userRef : "" }))
|
|
68
|
+
}
|
|
69
|
+
), /* @__PURE__ */ React.createElement("div", { className: classes.votesText }, /* @__PURE__ */ React.createElement(Typography, { variant: "subtitle1" }, props == null ? void 0 : props.total, " ", props.unit)));
|
|
70
|
+
};
|
|
71
|
+
const RankingCard = (props) => {
|
|
72
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
73
|
+
const rankingStats = props.limit ? (_a = props.statistic) == null ? void 0 : _a.ranking.slice(0, props.limit) : (_b = props.statistic) == null ? void 0 : _b.ranking;
|
|
74
|
+
return /* @__PURE__ */ React.createElement("div", { style: { display: "block" }, className: "qetaRankingCard" }, /* @__PURE__ */ React.createElement("span", { className: "qetaRankingCardDescription" }, props.description), /* @__PURE__ */ React.createElement(List, { className: "qetaRankingCardList" }, rankingStats == null ? void 0 : rankingStats.map((authorStats) => {
|
|
75
|
+
return /* @__PURE__ */ React.createElement(
|
|
76
|
+
RankingRow,
|
|
77
|
+
{
|
|
78
|
+
total: authorStats.total || 0,
|
|
79
|
+
position: authorStats.position || 0,
|
|
80
|
+
userRef: authorStats.author,
|
|
81
|
+
unit: props.unit
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}), !(rankingStats == null ? void 0 : rankingStats.some(
|
|
85
|
+
(authorStats) => {
|
|
86
|
+
var _a2, _b2;
|
|
87
|
+
return authorStats.author === ((_b2 = (_a2 = props.statistic) == null ? void 0 : _a2.loggedUser) == null ? void 0 : _b2.author);
|
|
88
|
+
}
|
|
89
|
+
)) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("hr", null), /* @__PURE__ */ React.createElement(
|
|
90
|
+
RankingRow,
|
|
91
|
+
{
|
|
92
|
+
total: ((_d = (_c = props.statistic) == null ? void 0 : _c.loggedUser) == null ? void 0 : _d.total) || 0,
|
|
93
|
+
position: ((_f = (_e = props.statistic) == null ? void 0 : _e.loggedUser) == null ? void 0 : _f.position) || 0,
|
|
94
|
+
userRef: (_h = (_g = props.statistic) == null ? void 0 : _g.loggedUser) == null ? void 0 : _h.author,
|
|
95
|
+
unit: props.unit
|
|
96
|
+
}
|
|
97
|
+
))));
|
|
98
|
+
};
|
|
99
|
+
const TopRankingUsers = (props) => {
|
|
100
|
+
const {
|
|
101
|
+
value: topStatistics,
|
|
102
|
+
loading,
|
|
103
|
+
error
|
|
104
|
+
} = useQetaApi(
|
|
105
|
+
(api) => api.getTopStatisticsHomepage({
|
|
106
|
+
options: { limit: 50 }
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
const tabData = [
|
|
110
|
+
{
|
|
111
|
+
title: "Most questions",
|
|
112
|
+
description: "People who have posted most questions",
|
|
113
|
+
unit: "questions"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
title: "Most answers",
|
|
117
|
+
description: "People who have answered most questions",
|
|
118
|
+
unit: "answers"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
title: "Top Upvoted Questions",
|
|
122
|
+
description: "People who have the highest rated questions",
|
|
123
|
+
unit: "votes"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
title: "Top Upvoted Answers",
|
|
127
|
+
description: "People who have the highest rated answers",
|
|
128
|
+
unit: "votes"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
title: "Top Upvoted Correct Answers",
|
|
132
|
+
description: "People who have the highest rated correct answers",
|
|
133
|
+
unit: "votes"
|
|
134
|
+
}
|
|
135
|
+
];
|
|
136
|
+
if ((error || topStatistics === void 0) && !loading) {
|
|
137
|
+
return /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not load statistics." }, error == null ? void 0 : error.message);
|
|
138
|
+
}
|
|
139
|
+
let content;
|
|
140
|
+
if (loading) {
|
|
141
|
+
content = [
|
|
142
|
+
/* @__PURE__ */ React.createElement(CardTab, null, /* @__PURE__ */ React.createElement(Progress, null))
|
|
143
|
+
];
|
|
144
|
+
} else if (topStatistics && topStatistics.length > 0) {
|
|
145
|
+
content = topStatistics == null ? void 0 : topStatistics.map((stats, index) => {
|
|
146
|
+
return /* @__PURE__ */ React.createElement(CardTab, { label: tabData[index].title }, /* @__PURE__ */ React.createElement(
|
|
147
|
+
RankingCard,
|
|
148
|
+
{
|
|
149
|
+
description: tabData[index].description,
|
|
150
|
+
limit: props.limit,
|
|
151
|
+
statistic: stats,
|
|
152
|
+
unit: tabData[index].unit
|
|
153
|
+
}
|
|
154
|
+
));
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
content = [/* @__PURE__ */ React.createElement(CardTab, null, "No statistics available")];
|
|
158
|
+
}
|
|
159
|
+
return /* @__PURE__ */ React.createElement(TabbedCard, { title: props.title || "Ranking Q&A \u{1F3C6}" }, content);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export { RankingCard, RankingRow, TopRankingUsers };
|
|
163
|
+
//# sourceMappingURL=TopRankingUsersCard.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TopRankingUsersCard.esm.js","sources":["../../../src/components/Statistics/TopRankingUsersCard.tsx"],"sourcesContent":["import React, { ReactElement, ReactNode } from 'react';\nimport {\n CardTab,\n Progress,\n TabbedCard,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n Avatar,\n List,\n ListItem,\n ListItemAvatar,\n ListItemText,\n Typography,\n} from '@material-ui/core';\nimport { StatisticResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { useQetaApi } from '../../utils/hooks';\nimport { TrophyIcon } from './TrophyIcon';\nimport { useStyles } from './styles';\nimport { UserLink } from '../Links/Links';\n\ntype RankingIcon = {\n iconsByRanking: Map<number, ReactNode>;\n userRankingIcon: ReactNode;\n};\n\nconst DefaultRankingIcons = new Map<number, ReactNode>([\n [\n 1,\n <TrophyIcon\n style={{ color: '#DAA520', height: '2.2rem', width: '2.2rem' }}\n />,\n ],\n [\n 2,\n <TrophyIcon\n style={{ color: '#C0C0C0', height: '2.1rem', width: '2.1rem' }}\n />,\n ],\n [\n 3,\n <TrophyIcon style={{ color: '#B87333', height: '2rem', width: '2rem' }} />,\n ],\n]);\n\nconst DefaultUserIcon = (\n <TrophyIcon style={{ height: '2rem', width: '2rem' }} />\n);\n\nconst getOrdinal = (n: number) => {\n if (n % 10 === 1 && n % 100 !== 11) {\n return `${n}st`;\n } else if (n % 10 === 2 && n % 100 !== 12) {\n return `${n}nd`;\n } else if (n % 10 === 3 && n % 100 !== 13) {\n return `${n}rd`;\n }\n\n return `${n}th`;\n};\n\nexport const RankingRow = (props: {\n userRef?: string;\n total: number;\n position: number;\n rankingIcon?: RankingIcon;\n unit: string;\n}) => {\n const classes = useStyles();\n const userRef = props.userRef;\n\n const ordinalPosition = props?.position ? getOrdinal(props?.position) : '';\n\n const userIcon = props.rankingIcon?.userRankingIcon\n ? props.rankingIcon?.userRankingIcon\n : DefaultUserIcon;\n\n const topRankingIcon = props.rankingIcon\n ? props.rankingIcon.iconsByRanking.get(Number(props?.position))\n : DefaultRankingIcons.get(Number(props?.position)) || DefaultUserIcon;\n\n const rankingIcon = props?.position > 3 ? userIcon : topRankingIcon;\n\n return (\n <ListItem className=\"qetaRankingCardRow\">\n <ListItemAvatar>\n <Avatar className={classes.trophyIcon}>{rankingIcon}</Avatar>\n </ListItemAvatar>\n\n <ListItemText\n disableTypography\n style={{\n display: 'flex',\n justifyContent: 'center',\n }}\n primary={\n <div style={{ display: 'flex' }}>\n <Typography\n style={{ marginRight: '10px', fontWeight: 400 }}\n variant=\"subtitle1\"\n >{`${ordinalPosition}`}</Typography>\n <UserLink entityRef={userRef ?? ''} />\n </div>\n }\n />\n\n <div className={classes.votesText}>\n <Typography variant=\"subtitle1\">\n {props?.total} {props.unit}\n </Typography>\n </div>\n </ListItem>\n );\n};\n\nexport const RankingCard = (props: {\n limit?: number;\n description: string;\n statistic?: StatisticResponse;\n unit: string;\n}) => {\n const rankingStats = props.limit\n ? props.statistic?.ranking.slice(0, props.limit)\n : props.statistic?.ranking;\n\n return (\n <div style={{ display: 'block' }} className=\"qetaRankingCard\">\n <span className=\"qetaRankingCardDescription\">{props.description}</span>\n <List className=\"qetaRankingCardList\">\n {rankingStats?.map(authorStats => {\n return (\n <RankingRow\n total={authorStats.total || 0}\n position={authorStats.position || 0}\n userRef={authorStats.author}\n unit={props.unit}\n />\n );\n })}\n {!rankingStats?.some(\n authorStats =>\n authorStats.author === props.statistic?.loggedUser?.author,\n ) && (\n <>\n <hr />\n <RankingRow\n total={props.statistic?.loggedUser?.total || 0}\n position={props.statistic?.loggedUser?.position || 0}\n userRef={props.statistic?.loggedUser?.author}\n unit={props.unit}\n />\n </>\n )}\n </List>\n </div>\n );\n};\n\nexport const TopRankingUsers = (props: {\n title?: string;\n hideTitle?: boolean;\n limit?: number;\n}) => {\n const {\n value: topStatistics,\n loading,\n error,\n } = useQetaApi(api =>\n api.getTopStatisticsHomepage({\n options: { limit: 50 },\n }),\n );\n\n const tabData = [\n {\n title: 'Most questions',\n description: 'People who have posted most questions',\n unit: 'questions',\n },\n {\n title: 'Most answers',\n description: 'People who have answered most questions',\n unit: 'answers',\n },\n {\n title: 'Top Upvoted Questions',\n description: 'People who have the highest rated questions',\n unit: 'votes',\n },\n {\n title: 'Top Upvoted Answers',\n description: 'People who have the highest rated answers',\n unit: 'votes',\n },\n {\n title: 'Top Upvoted Correct Answers',\n description: 'People who have the highest rated correct answers',\n unit: 'votes',\n },\n ];\n\n if ((error || topStatistics === undefined) && !loading) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load statistics.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n let content: ReactElement[];\n\n if (loading) {\n content = [\n <CardTab>\n <Progress />\n </CardTab>,\n ];\n } else if (topStatistics && topStatistics.length > 0) {\n content = topStatistics?.map((stats, index) => {\n return (\n <CardTab label={tabData[index].title}>\n <RankingCard\n description={tabData[index].description}\n limit={props.limit}\n statistic={stats}\n unit={tabData[index].unit}\n />\n </CardTab>\n );\n });\n } else {\n content = [<CardTab>No statistics available</CardTab>];\n }\n\n return (\n <TabbedCard title={props.title || 'Ranking Q&A 🏆'}>{content}</TabbedCard>\n );\n};\n"],"names":["_a","_b"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SvgIcon } from '@material-ui/core';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
const TrophyIcon = (props) => /* @__PURE__ */ React.createElement(SvgIcon, { ...props, viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement(
|
|
5
|
+
"path",
|
|
6
|
+
{
|
|
7
|
+
id: "secondary",
|
|
8
|
+
d: "M17,12a1,1,0,0,1,0-2,3,3,0,0,0,3-3V6H17.17a1,1,0,0,1,0-2H20a2,2,0,0,1,2,2V7A5,5,0,0,1,17,12ZM8,11a1,1,0,0,0-1-1A3,3,0,0,1,4,7V6H6.74a1,1,0,0,0,0-2H4A2,2,0,0,0,2,6V7a5,5,0,0,0,5,5A1,1,0,0,0,8,11Zm5,10V16.18a1,1,0,0,0-2,0V21a1,1,0,0,0,2,0Z"
|
|
9
|
+
}
|
|
10
|
+
), /* @__PURE__ */ React.createElement(
|
|
11
|
+
"path",
|
|
12
|
+
{
|
|
13
|
+
id: "primary",
|
|
14
|
+
d: "M16,22H8a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2ZM17,2H7A1,1,0,0,0,6,3V9.57a7.75,7.75,0,0,0,4.89,7.22A3,3,0,0,0,12,17a3.13,3.13,0,0,0,1.12-.21A7.76,7.76,0,0,0,18,9.57V3A1,1,0,0,0,17,2Z"
|
|
15
|
+
}
|
|
16
|
+
));
|
|
17
|
+
|
|
18
|
+
export { TrophyIcon };
|
|
19
|
+
//# sourceMappingURL=TrophyIcon.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrophyIcon.esm.js","sources":["../../../src/components/Statistics/TrophyIcon.tsx"],"sourcesContent":["import { SvgIcon, SvgIconProps } from '@material-ui/core';\n\nimport React from 'react';\n\nexport const TrophyIcon = (props: SvgIconProps) => (\n <SvgIcon {...props} viewBox=\"0 0 24 24\">\n <path\n id=\"secondary\"\n d=\"M17,12a1,1,0,0,1,0-2,3,3,0,0,0,3-3V6H17.17a1,1,0,0,1,0-2H20a2,2,0,0,1,2,2V7A5,5,0,0,1,17,12ZM8,11a1,1,0,0,0-1-1A3,3,0,0,1,4,7V6H6.74a1,1,0,0,0,0-2H4A2,2,0,0,0,2,6V7a5,5,0,0,0,5,5A1,1,0,0,0,8,11Zm5,10V16.18a1,1,0,0,0-2,0V21a1,1,0,0,0,2,0Z\"\n />\n <path\n id=\"primary\"\n d=\"M16,22H8a1,1,0,0,1,0-2h8a1,1,0,0,1,0,2ZM17,2H7A1,1,0,0,0,6,3V9.57a7.75,7.75,0,0,0,4.89,7.22A3,3,0,0,0,12,17a3.13,3.13,0,0,0,1.12-.21A7.76,7.76,0,0,0,18,9.57V3A1,1,0,0,0,17,2Z\"\n />\n </SvgIcon>\n);\n"],"names":[],"mappings":";;;AAIa,MAAA,UAAA,GAAa,CAAC,KACzB,qBAAA,KAAA,CAAA,aAAA,CAAC,WAAS,GAAG,KAAA,EAAO,SAAQ,WAC1B,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,EAAC,MAAA;AAAA,EAAA;AAAA,IACC,EAAG,EAAA,WAAA;AAAA,IACH,CAAE,EAAA,+OAAA;AAAA,GAAA;AACJ,CACA,kBAAA,KAAA,CAAA,aAAA;AAAA,EAAC,MAAA;AAAA,EAAA;AAAA,IACC,EAAG,EAAA,SAAA;AAAA,IACH,CAAE,EAAA,gLAAA;AAAA,GAAA;AACJ,CACF;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { makeStyles } from '@material-ui/core';
|
|
2
|
+
|
|
3
|
+
const useStyles = makeStyles((theme) => {
|
|
4
|
+
return {
|
|
5
|
+
trophyIcon: {
|
|
6
|
+
backgroundColor: "initial",
|
|
7
|
+
color: theme.palette.text.primary,
|
|
8
|
+
borderRadius: "50%",
|
|
9
|
+
boxSizing: "border-box",
|
|
10
|
+
padding: "1rem",
|
|
11
|
+
height: 100,
|
|
12
|
+
width: 100
|
|
13
|
+
},
|
|
14
|
+
votesText: {
|
|
15
|
+
display: "grid",
|
|
16
|
+
placeItems: "center",
|
|
17
|
+
marginLeft: "16px"
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export { useStyles };
|
|
23
|
+
//# sourceMappingURL=styles.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.esm.js","sources":["../../../src/components/Statistics/styles.ts"],"sourcesContent":["import { makeStyles } from '@material-ui/core';\n\nexport const useStyles = makeStyles(theme => {\n return {\n trophyIcon: {\n backgroundColor: 'initial',\n color: theme.palette.text.primary,\n borderRadius: '50%',\n boxSizing: 'border-box',\n padding: '1rem',\n height: 100,\n width: 100,\n },\n votesText: {\n display: 'grid',\n placeItems: 'center',\n marginLeft: '16px',\n },\n };\n});\n"],"names":[],"mappings":";;AAEa,MAAA,SAAA,GAAY,WAAW,CAAS,KAAA,KAAA;AAC3C,EAAO,OAAA;AAAA,IACL,UAAY,EAAA;AAAA,MACV,eAAiB,EAAA,SAAA;AAAA,MACjB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,IAAK,CAAA,OAAA;AAAA,MAC1B,YAAc,EAAA,KAAA;AAAA,MACd,SAAW,EAAA,YAAA;AAAA,MACX,OAAS,EAAA,MAAA;AAAA,MACT,MAAQ,EAAA,GAAA;AAAA,MACR,KAAO,EAAA,GAAA;AAAA,KACT;AAAA,IACA,SAAW,EAAA;AAAA,MACT,OAAS,EAAA,MAAA;AAAA,MACT,UAAY,EAAA,QAAA;AAAA,MACZ,UAAY,EAAA,MAAA;AAAA,KACd;AAAA,GACF,CAAA;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Content, ContentHeader } from '@backstage/core-components';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { QuestionsContainer } from '../QuestionsContainer/QuestionsContainer.esm.js';
|
|
5
|
+
import { TagsContainer } from './TagsContainer.esm.js';
|
|
6
|
+
import { AskQuestionButton } from '../Buttons/AskQuestionButton.esm.js';
|
|
7
|
+
import { Container } from '@material-ui/core';
|
|
8
|
+
import { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton.esm.js';
|
|
9
|
+
|
|
10
|
+
const TagPage = () => {
|
|
11
|
+
const { tag } = useParams();
|
|
12
|
+
return /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(Container, { maxWidth: "lg" }, /* @__PURE__ */ React.createElement(ContentHeader, { title: tag ? `Questions tagged [${tag}]` : "Tags" }, /* @__PURE__ */ React.createElement(BackToQuestionsButton, null), /* @__PURE__ */ React.createElement(AskQuestionButton, { tags: tag ? [tag] : void 0 })), tag ? /* @__PURE__ */ React.createElement(QuestionsContainer, { tags: [tag != null ? tag : ""] }) : /* @__PURE__ */ React.createElement(TagsContainer, null)));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { TagPage };
|
|
16
|
+
//# sourceMappingURL=TagPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagPage.esm.js","sources":["../../../src/components/TagPage/TagPage.tsx"],"sourcesContent":["import React from 'react';\nimport { Content, ContentHeader } from '@backstage/core-components';\nimport { useParams } from 'react-router-dom';\nimport { QuestionsContainer } from '../QuestionsContainer/QuestionsContainer';\nimport { TagsContainer } from './TagsContainer';\nimport { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { Container } from '@material-ui/core';\nimport { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton';\n\nexport const TagPage = () => {\n const { tag } = useParams();\n return (\n <Content>\n <Container maxWidth=\"lg\">\n <ContentHeader title={tag ? `Questions tagged [${tag}]` : 'Tags'}>\n <BackToQuestionsButton />\n <AskQuestionButton tags={tag ? [tag] : undefined} />\n </ContentHeader>\n {tag ? <QuestionsContainer tags={[tag ?? '']} /> : <TagsContainer />}\n </Container>\n </Content>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AASO,MAAM,UAAU,MAAM;AAC3B,EAAM,MAAA,EAAE,GAAI,EAAA,GAAI,SAAU,EAAA,CAAA;AAC1B,EAAA,2CACG,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,SAAU,EAAA,EAAA,QAAA,EAAS,wBACjB,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA,EAAc,KAAO,EAAA,GAAA,GAAM,qBAAqB,GAAG,CAAA,CAAA,CAAA,GAAM,0BACvD,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA,IAAsB,mBACtB,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,IAAM,EAAA,GAAA,GAAM,CAAC,GAAG,CAAA,GAAI,QAAW,CACpD,CAAA,EACC,sBAAO,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA,EAAmB,IAAM,EAAA,CAAC,oBAAO,EAAE,CAAA,EAAG,oBAAM,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA,IAAc,CACpE,CACF,CAAA,CAAA;AAEJ;;;;"}
|