@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,63 @@
|
|
|
1
|
+
import { Grid, TextField, IconButton, Typography, Chip, Avatar } from '@material-ui/core';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useQetaApi } from '../../utils/hooks.esm.js';
|
|
4
|
+
import { Progress, WarningPanel } from '@backstage/core-components';
|
|
5
|
+
import { useRouteRef } from '@backstage/core-plugin-api';
|
|
6
|
+
import { tagRouteRef } from '@drodil/backstage-plugin-qeta-react';
|
|
7
|
+
|
|
8
|
+
const TagsContainer = () => {
|
|
9
|
+
const [searchQuery, setSearchQuery] = React.useState("");
|
|
10
|
+
const tagRoute = useRouteRef(tagRouteRef);
|
|
11
|
+
const {
|
|
12
|
+
value: response,
|
|
13
|
+
loading,
|
|
14
|
+
error
|
|
15
|
+
} = useQetaApi((api) => api.getTags(), []);
|
|
16
|
+
if (loading) {
|
|
17
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
18
|
+
}
|
|
19
|
+
if (error || response === void 0) {
|
|
20
|
+
return /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not load tags." }, error == null ? void 0 : error.message);
|
|
21
|
+
}
|
|
22
|
+
const filterData = (query, data) => {
|
|
23
|
+
if (!query) {
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
return data.filter((t) => t.tag.toLowerCase().includes(query));
|
|
27
|
+
};
|
|
28
|
+
const tags = filterData(searchQuery, response);
|
|
29
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true, className: "qetaTagsContainer" }, /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
|
|
30
|
+
TextField,
|
|
31
|
+
{
|
|
32
|
+
id: "search-bar",
|
|
33
|
+
className: "text qetaTagsContainerSearchInput",
|
|
34
|
+
onChange: (event) => setSearchQuery(event.target.value),
|
|
35
|
+
label: "Search tag",
|
|
36
|
+
variant: "outlined",
|
|
37
|
+
placeholder: "Search...",
|
|
38
|
+
size: "small"
|
|
39
|
+
}
|
|
40
|
+
), /* @__PURE__ */ React.createElement(IconButton, { type: "submit", "aria-label": "search" })), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(
|
|
41
|
+
Typography,
|
|
42
|
+
{
|
|
43
|
+
variant: "h6",
|
|
44
|
+
className: "qetaTagsContainerTitle"
|
|
45
|
+
},
|
|
46
|
+
`Showing ${tags.length} tags`
|
|
47
|
+
)), /* @__PURE__ */ React.createElement(Grid, { item: true }, tags.map((tag) => /* @__PURE__ */ React.createElement(
|
|
48
|
+
Chip,
|
|
49
|
+
{
|
|
50
|
+
key: tag.tag,
|
|
51
|
+
variant: "outlined",
|
|
52
|
+
avatar: /* @__PURE__ */ React.createElement(Avatar, null, tag.questionsCount),
|
|
53
|
+
label: tag.tag,
|
|
54
|
+
className: "qetaTagsContainerChip",
|
|
55
|
+
component: "a",
|
|
56
|
+
clickable: true,
|
|
57
|
+
href: tagRoute({ tag: tag.tag })
|
|
58
|
+
}
|
|
59
|
+
))));
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export { TagsContainer };
|
|
63
|
+
//# sourceMappingURL=TagsContainer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagsContainer.esm.js","sources":["../../../src/components/TagPage/TagsContainer.tsx"],"sourcesContent":["import {\n Avatar,\n Chip,\n Grid,\n IconButton,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useQetaApi } from '../../utils/hooks';\nimport { Progress, WarningPanel } from '@backstage/core-components';\nimport { TagResponse } from '@drodil/backstage-plugin-qeta-common';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { tagRouteRef } from '@drodil/backstage-plugin-qeta-react';\n\nexport const TagsContainer = () => {\n const [searchQuery, setSearchQuery] = React.useState('');\n const tagRoute = useRouteRef(tagRouteRef);\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(api => api.getTags(), []);\n\n if (loading) {\n return <Progress />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load tags.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n const filterData = (query: string, data: TagResponse[]) => {\n if (!query) {\n return data;\n }\n return data.filter(t => t.tag.toLowerCase().includes(query));\n };\n\n const tags = filterData(searchQuery, response);\n\n return (\n <Grid container className=\"qetaTagsContainer\">\n <Grid item xs={12}>\n <TextField\n id=\"search-bar\"\n className=\"text qetaTagsContainerSearchInput\"\n onChange={(\n event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,\n ) => setSearchQuery(event.target.value)}\n label=\"Search tag\"\n variant=\"outlined\"\n placeholder=\"Search...\"\n size=\"small\"\n />\n <IconButton type=\"submit\" aria-label=\"search\" />\n </Grid>\n <Grid item xs={12}>\n <Typography\n variant=\"h6\"\n className=\"qetaTagsContainerTitle\"\n >{`Showing ${tags.length} tags`}</Typography>\n </Grid>\n <Grid item>\n {tags.map(tag => (\n <Chip\n key={tag.tag}\n variant=\"outlined\"\n avatar={<Avatar>{tag.questionsCount}</Avatar>}\n label={tag.tag}\n className=\"qetaTagsContainerChip\"\n component=\"a\"\n clickable\n href={tagRoute({ tag: tag.tag })}\n />\n ))}\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
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 { AskQuestionButton } from '../Buttons/AskQuestionButton.esm.js';
|
|
6
|
+
import { Container } from '@material-ui/core';
|
|
7
|
+
import { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton.esm.js';
|
|
8
|
+
import { useEntityPresentation } from '@backstage/plugin-catalog-react';
|
|
9
|
+
|
|
10
|
+
const UserPage = () => {
|
|
11
|
+
var _a;
|
|
12
|
+
const identity = (_a = useParams()["*"]) != null ? _a : "unknown";
|
|
13
|
+
const presentation = useEntityPresentation(identity);
|
|
14
|
+
return /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(Container, { maxWidth: "lg" }, /* @__PURE__ */ React.createElement(ContentHeader, { title: `Questions by ${presentation.primaryTitle}` }, /* @__PURE__ */ React.createElement(BackToQuestionsButton, null), /* @__PURE__ */ React.createElement(AskQuestionButton, null)), /* @__PURE__ */ React.createElement(
|
|
15
|
+
QuestionsContainer,
|
|
16
|
+
{
|
|
17
|
+
author: identity != null ? identity : "",
|
|
18
|
+
showNoQuestionsBtn: false
|
|
19
|
+
}
|
|
20
|
+
)));
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { UserPage };
|
|
24
|
+
//# sourceMappingURL=UserPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserPage.esm.js","sources":["../../../src/components/UserPage/UserPage.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 { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { Container } from '@material-ui/core';\nimport { BackToQuestionsButton } from '../Buttons/BackToQuestionsButton';\nimport { useEntityPresentation } from '@backstage/plugin-catalog-react';\n\nexport const UserPage = () => {\n const identity = useParams()['*'] ?? 'unknown';\n const presentation = useEntityPresentation(identity);\n return (\n <Content>\n <Container maxWidth=\"lg\">\n <ContentHeader title={`Questions by ${presentation.primaryTitle}`}>\n <BackToQuestionsButton />\n <AskQuestionButton />\n </ContentHeader>\n <QuestionsContainer\n author={identity ?? ''}\n showNoQuestionsBtn={false}\n />\n </Container>\n </Content>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AASO,MAAM,WAAW,MAAM;AAT9B,EAAA,IAAA,EAAA,CAAA;AAUE,EAAA,MAAM,QAAW,GAAA,CAAA,EAAA,GAAA,SAAA,EAAY,CAAA,GAAG,MAAf,IAAoB,GAAA,EAAA,GAAA,SAAA,CAAA;AACrC,EAAM,MAAA,YAAA,GAAe,sBAAsB,QAAQ,CAAA,CAAA;AACnD,EAAA,2CACG,OACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,aAAU,QAAS,EAAA,IAAA,EAAA,sCACjB,aAAc,EAAA,EAAA,KAAA,EAAO,gBAAgB,YAAa,CAAA,YAAY,sBAC5D,KAAA,CAAA,aAAA,CAAA,qBAAA,EAAA,IAAsB,mBACtB,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,IAAkB,CACrB,CACA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,kBAAA;AAAA,IAAA;AAAA,MACC,QAAQ,QAAY,IAAA,IAAA,GAAA,QAAA,GAAA,EAAA;AAAA,MACpB,kBAAoB,EAAA,KAAA;AAAA,KAAA;AAAA,GAExB,CACF,CAAA,CAAA;AAEJ;;;;"}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,33 +1,10 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import '@backstage/plugin-catalog-react';
|
|
11
|
-
import 'lodash';
|
|
12
|
-
import 'react-router-dom';
|
|
13
|
-
import 'react';
|
|
14
|
-
import 'react-use/lib/useDebounce';
|
|
15
|
-
import '@material-ui/lab';
|
|
16
|
-
import '@backstage/catalog-model';
|
|
17
|
-
import '@backstage/core-components';
|
|
18
|
-
import 'dompurify';
|
|
19
|
-
import 'react-relative-time';
|
|
20
|
-
import '@backstage/plugin-signals-react';
|
|
21
|
-
import '@material-ui/icons/HelpOutline';
|
|
22
|
-
import '@material-ui/icons/FilterList';
|
|
23
|
-
import '@backstage/plugin-permission-react';
|
|
24
|
-
import '@drodil/backstage-plugin-qeta-common';
|
|
25
|
-
import 'react-hook-form';
|
|
26
|
-
import 'react-mde';
|
|
27
|
-
import 'react-mde/lib/styles/css/react-mde.css';
|
|
28
|
-
import 'react-mde/lib/styles/css/react-mde-editor.css';
|
|
29
|
-
import 'react-mde/lib/styles/css/react-mde-toolbar.css';
|
|
30
|
-
import 'file-type';
|
|
31
|
-
import '@material-ui/icons/Refresh';
|
|
32
|
-
import '@material-ui/icons/HomeOutlined';
|
|
1
|
+
export { QetaPage, QuestionTableCard, qetaPlugin } from './plugin.esm.js';
|
|
2
|
+
export { QuestionsContainer } from './components/QuestionsContainer/QuestionsContainer.esm.js';
|
|
3
|
+
export { AskForm } from './components/AskForm/AskForm.esm.js';
|
|
4
|
+
export { Content } from './components/QuestionTableCard/Content.esm.js';
|
|
5
|
+
export { QuestionsTable } from './components/QuestionTableCard/QuestionsTable.esm.js';
|
|
6
|
+
export { RankingCard, RankingRow, TopRankingUsers } from './components/Statistics/TopRankingUsersCard.esm.js';
|
|
7
|
+
export { TrophyIcon } from './components/Statistics/TrophyIcon.esm.js';
|
|
8
|
+
export { StatisticsPage } from './components/Statistics/StatisticsPage.esm.js';
|
|
9
|
+
export { QetaClient, qetaApiRef } from './api/QetaClient.esm.js';
|
|
33
10
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createPlugin, createApiFactory, fetchApiRef, discoveryApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { createCardExtension } from '@backstage/plugin-home-react';
|
|
3
|
+
import { qetaApiRef, QetaClient } from './api/QetaClient.esm.js';
|
|
4
|
+
import { qetaRouteRef } from '@drodil/backstage-plugin-qeta-react';
|
|
5
|
+
|
|
6
|
+
const qetaPlugin = createPlugin({
|
|
7
|
+
id: "qeta",
|
|
8
|
+
routes: {
|
|
9
|
+
root: qetaRouteRef
|
|
10
|
+
},
|
|
11
|
+
apis: [
|
|
12
|
+
createApiFactory({
|
|
13
|
+
api: qetaApiRef,
|
|
14
|
+
deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },
|
|
15
|
+
factory: ({ fetchApi, discoveryApi }) => new QetaClient({ fetchApi, discoveryApi })
|
|
16
|
+
})
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
const QetaPage = qetaPlugin.provide(
|
|
20
|
+
createRoutableExtension({
|
|
21
|
+
name: "QetaPage",
|
|
22
|
+
component: () => import('./components/HomePage/index.esm.js').then((m) => m.HomePage),
|
|
23
|
+
mountPoint: qetaRouteRef
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
const QuestionTableCard = qetaPlugin.provide(
|
|
27
|
+
createCardExtension({
|
|
28
|
+
name: "QuestionsTableCard",
|
|
29
|
+
title: "Q&A",
|
|
30
|
+
description: "Shows Q&A questions",
|
|
31
|
+
components: () => import('./components/QuestionTableCard/index.esm.js'),
|
|
32
|
+
layout: {
|
|
33
|
+
height: { minRows: 6 },
|
|
34
|
+
width: { minColumns: 6 }
|
|
35
|
+
},
|
|
36
|
+
settings: {
|
|
37
|
+
schema: {
|
|
38
|
+
title: "Q&A",
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
rowsPerPage: {
|
|
42
|
+
title: "Rows per page",
|
|
43
|
+
type: "number",
|
|
44
|
+
enum: [5, 10, 20, 30, 40, 50],
|
|
45
|
+
default: 10
|
|
46
|
+
},
|
|
47
|
+
quickFilter: {
|
|
48
|
+
title: "Default filter",
|
|
49
|
+
type: "string",
|
|
50
|
+
enum: ["latest", "favorites", "most_viewed"],
|
|
51
|
+
default: "latest"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
export { QetaPage, QuestionTableCard, qetaPlugin };
|
|
60
|
+
//# sourceMappingURL=plugin.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport { createCardExtension } from '@backstage/plugin-home-react';\nimport { qetaApiRef, QetaClient } from './api';\nimport { qetaRouteRef } from '@drodil/backstage-plugin-qeta-react';\n\nexport const qetaPlugin = createPlugin({\n id: 'qeta',\n routes: {\n root: qetaRouteRef,\n },\n apis: [\n createApiFactory({\n api: qetaApiRef,\n deps: { fetchApi: fetchApiRef, discoveryApi: discoveryApiRef },\n factory: ({ fetchApi, discoveryApi }) =>\n new QetaClient({ fetchApi, discoveryApi }),\n }),\n ],\n});\n\nexport const QetaPage = qetaPlugin.provide(\n createRoutableExtension({\n name: 'QetaPage',\n component: () => import('./components/HomePage').then(m => m.HomePage),\n mountPoint: qetaRouteRef,\n }),\n);\n\nexport const QuestionTableCard = qetaPlugin.provide(\n createCardExtension<{ rowsPerPage?: number; quickFilter?: string }>({\n name: 'QuestionsTableCard',\n title: 'Q&A',\n description: 'Shows Q&A questions',\n components: () => import('./components/QuestionTableCard'),\n layout: {\n height: { minRows: 6 },\n width: { minColumns: 6 },\n },\n settings: {\n schema: {\n title: 'Q&A',\n type: 'object',\n properties: {\n rowsPerPage: {\n title: 'Rows per page',\n type: 'number',\n enum: [5, 10, 20, 30, 40, 50],\n default: 10,\n },\n quickFilter: {\n title: 'Default filter',\n type: 'string',\n enum: ['latest', 'favorites', 'most_viewed'],\n default: 'latest',\n },\n },\n },\n },\n }),\n);\n"],"names":[],"mappings":";;;;;AAWO,MAAM,aAAa,YAAa,CAAA;AAAA,EACrC,EAAI,EAAA,MAAA;AAAA,EACJ,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,UAAA;AAAA,MACL,IAAM,EAAA,EAAE,QAAU,EAAA,WAAA,EAAa,cAAc,eAAgB,EAAA;AAAA,MAC7D,OAAA,EAAS,CAAC,EAAE,QAAU,EAAA,YAAA,EACpB,KAAA,IAAI,UAAW,CAAA,EAAE,QAAU,EAAA,YAAA,EAAc,CAAA;AAAA,KAC5C,CAAA;AAAA,GACH;AACF,CAAC,EAAA;AAEM,MAAM,WAAW,UAAW,CAAA,OAAA;AAAA,EACjC,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,UAAA;AAAA,IACN,SAAA,EAAW,MAAM,OAAO,oCAAuB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,QAAQ,CAAA;AAAA,IACrE,UAAY,EAAA,YAAA;AAAA,GACb,CAAA;AACH,EAAA;AAEO,MAAM,oBAAoB,UAAW,CAAA,OAAA;AAAA,EAC1C,mBAAoE,CAAA;AAAA,IAClE,IAAM,EAAA,oBAAA;AAAA,IACN,KAAO,EAAA,KAAA;AAAA,IACP,WAAa,EAAA,qBAAA;AAAA,IACb,UAAA,EAAY,MAAM,OAAO,6CAAgC,CAAA;AAAA,IACzD,MAAQ,EAAA;AAAA,MACN,MAAA,EAAQ,EAAE,OAAA,EAAS,CAAE,EAAA;AAAA,MACrB,KAAA,EAAO,EAAE,UAAA,EAAY,CAAE,EAAA;AAAA,KACzB;AAAA,IACA,QAAU,EAAA;AAAA,MACR,MAAQ,EAAA;AAAA,QACN,KAAO,EAAA,KAAA;AAAA,QACP,IAAM,EAAA,QAAA;AAAA,QACN,UAAY,EAAA;AAAA,UACV,WAAa,EAAA;AAAA,YACX,KAAO,EAAA,eAAA;AAAA,YACP,IAAM,EAAA,QAAA;AAAA,YACN,MAAM,CAAC,CAAA,EAAG,IAAI,EAAI,EAAA,EAAA,EAAI,IAAI,EAAE,CAAA;AAAA,YAC5B,OAAS,EAAA,EAAA;AAAA,WACX;AAAA,UACA,WAAa,EAAA;AAAA,YACX,KAAO,EAAA,gBAAA;AAAA,YACP,IAAM,EAAA,QAAA;AAAA,YACN,IAAM,EAAA,CAAC,QAAU,EAAA,WAAA,EAAa,aAAa,CAAA;AAAA,YAC3C,OAAS,EAAA,QAAA;AAAA,WACX;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,GACD,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { qetaApiRef } from '../api/QetaClient.esm.js';
|
|
2
|
+
import useAsync from 'react-use/lib/useAsync';
|
|
3
|
+
import { useApi, identityApiRef, configApiRef } from '@backstage/core-plugin-api';
|
|
4
|
+
import { makeStyles } from '@material-ui/core';
|
|
5
|
+
import { catalogApiRef, useEntityPresentation } from '@backstage/plugin-catalog-react';
|
|
6
|
+
import { trimEnd } from 'lodash';
|
|
7
|
+
import { useSearchParams } from 'react-router-dom';
|
|
8
|
+
import React, { useEffect } from 'react';
|
|
9
|
+
|
|
10
|
+
function useQetaApi(f, deps = []) {
|
|
11
|
+
const qetaApi = useApi(qetaApiRef);
|
|
12
|
+
return useAsync(async () => {
|
|
13
|
+
return await f(qetaApi);
|
|
14
|
+
}, deps);
|
|
15
|
+
}
|
|
16
|
+
function useIdentityApi(f, deps = []) {
|
|
17
|
+
const identityApi = useApi(identityApiRef);
|
|
18
|
+
return useAsync(async () => {
|
|
19
|
+
return await f(identityApi);
|
|
20
|
+
}, deps);
|
|
21
|
+
}
|
|
22
|
+
function useEntityQueryParameter(entity) {
|
|
23
|
+
const [searchParams] = useSearchParams();
|
|
24
|
+
const [entityRef, setEntityRef] = React.useState(entity);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
setEntityRef((_a = searchParams.get("entity")) != null ? _a : void 0);
|
|
28
|
+
}, [searchParams, setEntityRef]);
|
|
29
|
+
return entityRef;
|
|
30
|
+
}
|
|
31
|
+
const useStyles = makeStyles((theme) => {
|
|
32
|
+
return {
|
|
33
|
+
markdownEditor: {
|
|
34
|
+
backgroundColor: "initial",
|
|
35
|
+
color: theme.palette.text.primary,
|
|
36
|
+
border: `1px solid ${theme.palette.action.disabled}`,
|
|
37
|
+
borderRadius: theme.shape.borderRadius,
|
|
38
|
+
"&:hover": {
|
|
39
|
+
borderColor: theme.palette.action.active
|
|
40
|
+
},
|
|
41
|
+
"&:focus-within": {
|
|
42
|
+
borderColor: theme.palette.primary.main
|
|
43
|
+
},
|
|
44
|
+
"& .mde-header": {
|
|
45
|
+
backgroundColor: "initial",
|
|
46
|
+
color: theme.palette.text.primary,
|
|
47
|
+
borderBottom: `1px solid ${theme.palette.action.selected}`,
|
|
48
|
+
"& .mde-tabs button, .mde-header-item > button": {
|
|
49
|
+
color: `${theme.palette.text.primary} !important`
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"& .mde-preview-content": {
|
|
53
|
+
padding: "10px"
|
|
54
|
+
},
|
|
55
|
+
"& .mde-text, .mde-preview": {
|
|
56
|
+
fontSize: theme.typography.body1.fontSize,
|
|
57
|
+
fontFamily: theme.typography.body1.fontFamily,
|
|
58
|
+
lineHeight: theme.typography.body1.lineHeight
|
|
59
|
+
},
|
|
60
|
+
"& .mde-text": {
|
|
61
|
+
backgroundColor: "initial",
|
|
62
|
+
color: theme.palette.text.primary,
|
|
63
|
+
outline: "none"
|
|
64
|
+
},
|
|
65
|
+
"& .image-tip": {
|
|
66
|
+
color: theme.palette.text.primary,
|
|
67
|
+
backgroundColor: "initial"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
markdownEditorError: {
|
|
71
|
+
border: `1px solid ${theme.palette.error.main} !important`
|
|
72
|
+
},
|
|
73
|
+
markdownContent: {
|
|
74
|
+
"& *": {
|
|
75
|
+
wordBreak: "break-word"
|
|
76
|
+
},
|
|
77
|
+
"&.inline": {
|
|
78
|
+
display: "inline-block"
|
|
79
|
+
},
|
|
80
|
+
"& > :first-child": {
|
|
81
|
+
marginTop: "0px !important"
|
|
82
|
+
},
|
|
83
|
+
"& > :last-child": {
|
|
84
|
+
marginBottom: "0px !important"
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
successColor: {
|
|
88
|
+
color: theme.palette.success.main
|
|
89
|
+
},
|
|
90
|
+
questionDivider: {
|
|
91
|
+
marginTop: theme.spacing(2),
|
|
92
|
+
marginBottom: theme.spacing(2)
|
|
93
|
+
},
|
|
94
|
+
questionCard: {
|
|
95
|
+
marginBottom: theme.spacing(1),
|
|
96
|
+
position: "relative"
|
|
97
|
+
},
|
|
98
|
+
questionCardVote: {
|
|
99
|
+
textAlign: "center",
|
|
100
|
+
width: "32px",
|
|
101
|
+
marginRight: "26px",
|
|
102
|
+
display: "inline-block",
|
|
103
|
+
verticalAlign: "top"
|
|
104
|
+
},
|
|
105
|
+
questionCardContent: {
|
|
106
|
+
display: "inline-block",
|
|
107
|
+
width: "calc(100% - 70px)",
|
|
108
|
+
minHeight: "160px"
|
|
109
|
+
},
|
|
110
|
+
questionListItemStats: {
|
|
111
|
+
width: "80px",
|
|
112
|
+
textAlign: "right",
|
|
113
|
+
marginRight: "26px",
|
|
114
|
+
display: "inline-block",
|
|
115
|
+
verticalAlign: "top",
|
|
116
|
+
paddingTop: "10px"
|
|
117
|
+
},
|
|
118
|
+
questionListItemContent: {
|
|
119
|
+
display: "inline-block",
|
|
120
|
+
width: "calc(100% - 120px)"
|
|
121
|
+
},
|
|
122
|
+
questionListItemAuthor: {
|
|
123
|
+
display: "inline",
|
|
124
|
+
float: "right"
|
|
125
|
+
},
|
|
126
|
+
questionListItemAvatar: {
|
|
127
|
+
display: "inline-flex",
|
|
128
|
+
marginRight: "0.25rem",
|
|
129
|
+
fontSize: "1rem",
|
|
130
|
+
maxWidth: "1rem",
|
|
131
|
+
maxHeight: "1rem"
|
|
132
|
+
},
|
|
133
|
+
answerCardContent: {
|
|
134
|
+
display: "inline-block",
|
|
135
|
+
width: "calc(100% - 70px)"
|
|
136
|
+
},
|
|
137
|
+
questionCardAuthor: {
|
|
138
|
+
padding: theme.spacing(1),
|
|
139
|
+
float: "right",
|
|
140
|
+
maxWidth: "200px",
|
|
141
|
+
border: `1px solid ${theme.palette.action.selected}`,
|
|
142
|
+
"& .avatar": {
|
|
143
|
+
width: theme.spacing(3),
|
|
144
|
+
height: theme.spacing(3),
|
|
145
|
+
fontSize: "1rem"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
questionListPagination: {
|
|
149
|
+
marginTop: theme.spacing(2)
|
|
150
|
+
},
|
|
151
|
+
postButton: {
|
|
152
|
+
marginTop: theme.spacing(1),
|
|
153
|
+
marginBottom: theme.spacing(1)
|
|
154
|
+
},
|
|
155
|
+
questionsPerPageInput: {
|
|
156
|
+
paddingTop: "10px"
|
|
157
|
+
},
|
|
158
|
+
questionsPerPage: {
|
|
159
|
+
marginRight: theme.spacing(3)
|
|
160
|
+
},
|
|
161
|
+
questionHighlightList: {
|
|
162
|
+
width: "100%",
|
|
163
|
+
border: `1px solid ${theme.palette.action.selected}`,
|
|
164
|
+
borderRadius: theme.shape.borderRadius,
|
|
165
|
+
"&:not(:first-child)": {
|
|
166
|
+
marginTop: theme.spacing(2)
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
filterPanel: {
|
|
170
|
+
border: `1px solid ${theme.palette.action.selected}`,
|
|
171
|
+
borderRadius: theme.shape.borderRadius,
|
|
172
|
+
padding: theme.spacing(3)
|
|
173
|
+
},
|
|
174
|
+
questionCardMetadata: {
|
|
175
|
+
marginTop: theme.spacing(3)
|
|
176
|
+
},
|
|
177
|
+
marginRight: {
|
|
178
|
+
marginRight: theme.spacing(1)
|
|
179
|
+
},
|
|
180
|
+
questionCardActions: {
|
|
181
|
+
marginTop: theme.spacing(2),
|
|
182
|
+
"& a": {
|
|
183
|
+
marginRight: theme.spacing(1)
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
noPadding: {
|
|
187
|
+
padding: `0 !important`
|
|
188
|
+
},
|
|
189
|
+
menuIcon: {
|
|
190
|
+
minWidth: "26px"
|
|
191
|
+
},
|
|
192
|
+
deleteModal: {
|
|
193
|
+
position: "absolute",
|
|
194
|
+
top: "20%",
|
|
195
|
+
left: "50%",
|
|
196
|
+
transform: "translate(-50%, -50%)",
|
|
197
|
+
width: 400,
|
|
198
|
+
backgroundColor: theme.palette.background.default,
|
|
199
|
+
border: `1px solid ${theme.palette.action.selected}`,
|
|
200
|
+
borderRadius: theme.shape.borderRadius,
|
|
201
|
+
padding: theme.spacing(2),
|
|
202
|
+
"& button": {
|
|
203
|
+
marginTop: theme.spacing(2),
|
|
204
|
+
float: "right"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
authorLink: {
|
|
208
|
+
textOverflow: "ellipsis",
|
|
209
|
+
overflow: "hidden",
|
|
210
|
+
whiteSpace: "nowrap"
|
|
211
|
+
},
|
|
212
|
+
highlight: {
|
|
213
|
+
animation: "$highlight 2s"
|
|
214
|
+
},
|
|
215
|
+
"@keyframes highlight": {
|
|
216
|
+
"0%": {
|
|
217
|
+
boxShadow: `0px 0px 0px 3px ${theme.palette.secondary.light}`
|
|
218
|
+
},
|
|
219
|
+
"100%": {
|
|
220
|
+
boxShadow: "none"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
});
|
|
225
|
+
const useBaseUrl = () => {
|
|
226
|
+
try {
|
|
227
|
+
const config = useApi(configApiRef);
|
|
228
|
+
return config.getOptionalString("app.baseUrl");
|
|
229
|
+
} catch {
|
|
230
|
+
return void 0;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const useBasePath = () => {
|
|
234
|
+
var _a;
|
|
235
|
+
const base = "http://sample.dev";
|
|
236
|
+
const url = (_a = useBaseUrl()) != null ? _a : "/";
|
|
237
|
+
const { pathname } = new URL(url, base);
|
|
238
|
+
return trimEnd(pathname, "/");
|
|
239
|
+
};
|
|
240
|
+
const useEntityAuthor = (entity) => {
|
|
241
|
+
var _a;
|
|
242
|
+
const catalogApi = useApi(catalogApiRef);
|
|
243
|
+
const identityApi = useApi(identityApiRef);
|
|
244
|
+
const [name, setName] = React.useState(void 0);
|
|
245
|
+
const [user, setUser] = React.useState(null);
|
|
246
|
+
const [initials, setInitials] = React.useState(null);
|
|
247
|
+
const [currentUser, setCurrentUser] = React.useState(null);
|
|
248
|
+
const anonymous = (_a = entity.anonymous) != null ? _a : false;
|
|
249
|
+
let author = entity.author;
|
|
250
|
+
if (!author.startsWith("user:")) {
|
|
251
|
+
author = `user:${author}`;
|
|
252
|
+
}
|
|
253
|
+
const { primaryTitle: userName } = useEntityPresentation(author);
|
|
254
|
+
useEffect(() => {
|
|
255
|
+
if (!anonymous) {
|
|
256
|
+
catalogApi.getEntityByRef(entity.author).catch((_) => setUser(null)).then((data) => data ? setUser(data) : setUser(null));
|
|
257
|
+
}
|
|
258
|
+
}, [catalogApi, entity, anonymous]);
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
identityApi.getBackstageIdentity().then((res) => {
|
|
261
|
+
var _a2;
|
|
262
|
+
setCurrentUser((_a2 = res.userEntityRef) != null ? _a2 : "user:default/guest");
|
|
263
|
+
});
|
|
264
|
+
}, [identityApi]);
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
let displayName = userName;
|
|
267
|
+
if (entity.author === currentUser) {
|
|
268
|
+
displayName = "You";
|
|
269
|
+
if (anonymous) {
|
|
270
|
+
displayName += " (anonymous)";
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
setName(displayName);
|
|
274
|
+
}, [entity.author, anonymous, currentUser, userName]);
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
const init = (name != null ? name : "").split(" ").map((p) => p[0]).join("").substring(0, 2).toUpperCase();
|
|
277
|
+
setInitials(init);
|
|
278
|
+
}, [name]);
|
|
279
|
+
return { name, initials, user };
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
export { useBasePath, useBaseUrl, useEntityAuthor, useEntityQueryParameter, useIdentityApi, useQetaApi, useStyles };
|
|
283
|
+
//# sourceMappingURL=hooks.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.esm.js","sources":["../../src/utils/hooks.ts"],"sourcesContent":["import { QetaApi, qetaApiRef } from '../api';\nimport useAsync from 'react-use/lib/useAsync';\nimport {\n configApiRef,\n IdentityApi,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport {\n catalogApiRef,\n useEntityPresentation,\n} from '@backstage/plugin-catalog-react';\nimport { trimEnd } from 'lodash';\nimport { useSearchParams } from 'react-router-dom';\nimport React, { useEffect } from 'react';\nimport { UserEntity } from '@backstage/catalog-model';\nimport {\n AnswerResponse,\n QuestionResponse,\n} from '@drodil/backstage-plugin-qeta-common';\n\nexport function useQetaApi<T>(\n f: (api: QetaApi) => Promise<T>,\n deps: any[] = [],\n) {\n const qetaApi = useApi(qetaApiRef);\n\n return useAsync(async () => {\n return await f(qetaApi);\n }, deps);\n}\n\nexport function useCatalogApi<T>(\n f: (api: CatalogApi) => Promise<T>,\n deps: any[] = [],\n) {\n const catalogApi = useApi(catalogApiRef);\n\n return useAsync(async () => {\n return await f(catalogApi);\n }, deps);\n}\n\nexport function useIdentityApi<T>(\n f: (api: IdentityApi) => Promise<T>,\n deps: any[] = [],\n) {\n const identityApi = useApi(identityApiRef);\n\n return useAsync(async () => {\n return await f(identityApi);\n }, deps);\n}\n\nexport function useEntityQueryParameter(entity?: string) {\n const [searchParams] = useSearchParams();\n const [entityRef, setEntityRef] = React.useState<string | undefined>(entity);\n\n useEffect(() => {\n setEntityRef(searchParams.get('entity') ?? undefined);\n }, [searchParams, setEntityRef]);\n\n return entityRef;\n}\n\nexport const useStyles = makeStyles(theme => {\n return {\n markdownEditor: {\n backgroundColor: 'initial',\n color: theme.palette.text.primary,\n border: `1px solid ${theme.palette.action.disabled}`,\n borderRadius: theme.shape.borderRadius,\n '&:hover': {\n borderColor: theme.palette.action.active,\n },\n '&:focus-within': {\n borderColor: theme.palette.primary.main,\n },\n '& .mde-header': {\n backgroundColor: 'initial',\n color: theme.palette.text.primary,\n borderBottom: `1px solid ${theme.palette.action.selected}`,\n '& .mde-tabs button, .mde-header-item > button': {\n color: `${theme.palette.text.primary} !important`,\n },\n },\n '& .mde-preview-content': {\n padding: '10px',\n },\n '& .mde-text, .mde-preview': {\n fontSize: theme.typography.body1.fontSize,\n fontFamily: theme.typography.body1.fontFamily,\n lineHeight: theme.typography.body1.lineHeight,\n },\n '& .mde-text': {\n backgroundColor: 'initial',\n color: theme.palette.text.primary,\n outline: 'none',\n },\n '& .image-tip': {\n color: theme.palette.text.primary,\n backgroundColor: 'initial',\n },\n },\n markdownEditorError: {\n border: `1px solid ${theme.palette.error.main} !important`,\n },\n markdownContent: {\n '& *': {\n wordBreak: 'break-word',\n },\n '&.inline': {\n display: 'inline-block',\n },\n '& > :first-child': {\n marginTop: '0px !important',\n },\n '& > :last-child': {\n marginBottom: '0px !important',\n },\n },\n successColor: {\n color: theme.palette.success.main,\n },\n questionDivider: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(2),\n },\n questionCard: {\n marginBottom: theme.spacing(1),\n position: 'relative',\n },\n questionCardVote: {\n textAlign: 'center',\n width: '32px',\n marginRight: '26px',\n display: 'inline-block',\n verticalAlign: 'top',\n },\n questionCardContent: {\n display: 'inline-block',\n width: 'calc(100% - 70px)',\n minHeight: '160px',\n },\n questionListItemStats: {\n width: '80px',\n textAlign: 'right',\n marginRight: '26px',\n display: 'inline-block',\n verticalAlign: 'top',\n paddingTop: '10px',\n },\n questionListItemContent: {\n display: 'inline-block',\n width: 'calc(100% - 120px)',\n },\n questionListItemAuthor: {\n display: 'inline',\n float: 'right',\n },\n questionListItemAvatar: {\n display: 'inline-flex',\n marginRight: '0.25rem',\n fontSize: '1rem',\n maxWidth: '1rem',\n maxHeight: '1rem',\n },\n answerCardContent: {\n display: 'inline-block',\n width: 'calc(100% - 70px)',\n },\n questionCardAuthor: {\n padding: theme.spacing(1),\n float: 'right',\n maxWidth: '200px',\n border: `1px solid ${theme.palette.action.selected}`,\n '& .avatar': {\n width: theme.spacing(3),\n height: theme.spacing(3),\n fontSize: '1rem',\n },\n },\n questionListPagination: {\n marginTop: theme.spacing(2),\n },\n postButton: {\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n },\n questionsPerPageInput: {\n paddingTop: '10px',\n },\n questionsPerPage: {\n marginRight: theme.spacing(3),\n },\n questionHighlightList: {\n width: '100%',\n border: `1px solid ${theme.palette.action.selected}`,\n borderRadius: theme.shape.borderRadius,\n '&:not(:first-child)': {\n marginTop: theme.spacing(2),\n },\n },\n filterPanel: {\n border: `1px solid ${theme.palette.action.selected}`,\n borderRadius: theme.shape.borderRadius,\n padding: theme.spacing(3),\n },\n questionCardMetadata: {\n marginTop: theme.spacing(3),\n },\n marginRight: {\n marginRight: theme.spacing(1),\n },\n questionCardActions: {\n marginTop: theme.spacing(2),\n '& a': {\n marginRight: theme.spacing(1),\n },\n },\n noPadding: {\n padding: `0 !important`,\n },\n menuIcon: {\n minWidth: '26px',\n },\n deleteModal: {\n position: 'absolute',\n top: '20%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: 400,\n backgroundColor: theme.palette.background.default,\n border: `1px solid ${theme.palette.action.selected}`,\n borderRadius: theme.shape.borderRadius,\n padding: theme.spacing(2),\n '& button': {\n marginTop: theme.spacing(2),\n float: 'right',\n },\n },\n authorLink: {\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n },\n highlight: {\n animation: '$highlight 2s',\n },\n '@keyframes highlight': {\n '0%': {\n boxShadow: `0px 0px 0px 3px ${theme.palette.secondary.light}`,\n },\n '100%': {\n boxShadow: 'none',\n },\n },\n };\n});\n\n// Url resolving logic from https://github.com/backstage/backstage/blob/master/packages/core-components/src/components/Link/Link.tsx\n\n/**\n * Returns the app base url that could be empty if the Config API is not properly implemented.\n * The only cases there would be no Config API are in tests and in storybook stories, and in those cases, it's unlikely that callers would rely on this subpath behavior.\n */\nexport const useBaseUrl = () => {\n try {\n const config = useApi(configApiRef);\n return config.getOptionalString('app.baseUrl');\n } catch {\n return undefined;\n }\n};\n\nexport const useBasePath = () => {\n // baseUrl can be specified as just a path\n const base = 'http://sample.dev';\n const url = useBaseUrl() ?? '/';\n const { pathname } = new URL(url, base);\n return trimEnd(pathname, '/');\n};\n\nexport const useEntityAuthor = (entity: QuestionResponse | AnswerResponse) => {\n const catalogApi = useApi(catalogApiRef);\n const identityApi = useApi(identityApiRef);\n const [name, setName] = React.useState<string | undefined>(undefined);\n const [user, setUser] = React.useState<UserEntity | null>(null);\n const [initials, setInitials] = React.useState<string | null>(null);\n const [currentUser, setCurrentUser] = React.useState<string | null>(null);\n const anonymous = entity.anonymous ?? false;\n let author = entity.author;\n if (!author.startsWith('user:')) {\n author = `user:${author}`;\n }\n\n const { primaryTitle: userName } = useEntityPresentation(author);\n\n useEffect(() => {\n if (!anonymous) {\n catalogApi\n .getEntityByRef(entity.author)\n .catch(_ => setUser(null))\n .then(data => (data ? setUser(data as UserEntity) : setUser(null)));\n }\n }, [catalogApi, entity, anonymous]);\n\n useEffect(() => {\n identityApi.getBackstageIdentity().then(res => {\n setCurrentUser(res.userEntityRef ?? 'user:default/guest');\n });\n }, [identityApi]);\n\n useEffect(() => {\n let displayName = userName;\n if (entity.author === currentUser) {\n displayName = 'You';\n if (anonymous) {\n displayName += ' (anonymous)';\n }\n }\n setName(displayName);\n }, [entity.author, anonymous, currentUser, userName]);\n\n useEffect(() => {\n const init = (name ?? '')\n .split(' ')\n .map(p => p[0])\n .join('')\n .substring(0, 2)\n .toUpperCase();\n setInitials(init);\n }, [name]);\n\n return { name, initials, user };\n};\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
|
|
3
|
+
const formatEntityName = (username) => {
|
|
4
|
+
if (!username) {
|
|
5
|
+
return "";
|
|
6
|
+
}
|
|
7
|
+
const plainName = username.split(/[/:]+/).pop();
|
|
8
|
+
return plainName == null ? void 0 : plainName.split(/[_.-]+/).map((a) => a.charAt(0).toUpperCase() + a.slice(1)).join(" ");
|
|
9
|
+
};
|
|
10
|
+
const getEntityTitle = (entity) => {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const stringified = stringifyEntityRef(entity);
|
|
13
|
+
return (_b = formatEntityName((_a = entity.metadata.title) != null ? _a : stringified)) != null ? _b : stringified;
|
|
14
|
+
};
|
|
15
|
+
const truncate = (str, n) => {
|
|
16
|
+
return str.length > n ? `${str.slice(0, n - 1)}...` : str;
|
|
17
|
+
};
|
|
18
|
+
const removeMarkdownFormatting = (text) => {
|
|
19
|
+
let fixed = text.replace(/^(-\s*?|\*\s*?|_\s*?){3,}\s*/gm, "");
|
|
20
|
+
fixed = text.replace(/<[^>]*>/g, "");
|
|
21
|
+
fixed = fixed.replace(/```[\s\S]*?```/g, (match) => {
|
|
22
|
+
return match.replace(/(^```[a-z]*\n)|(```$)/g, "").trim();
|
|
23
|
+
});
|
|
24
|
+
fixed = fixed.replace(/`{1,2}([^`]*)`{1,2}/g, "$1");
|
|
25
|
+
fixed = fixed.replace(/(?:\*\*|__)([^\n*]+)(?:\*\*|__)/g, "$1").replace(/(?:\*|_)([^\n*]+)(?:\*|_)/g, "$1").replace(/(?:~~)([^~]+)(?:~~)/g, "$1").replace(/^[>\t]{0,3}>+\s?/gm, "").replace(/\[\^.+?\](: .*?$)?/g, "").replace(/^([ \t]*)([*\-+]|\d+\.)\s+/gm, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/^#{1,6}[ \t]+/gm, "").replace(/^[=-]{2,}\s*$/g, "").replace(/(?:\r\n|\r|\n)/g, " ").replace(/(^\s+|\s+$)/g, "");
|
|
26
|
+
fixed = fixed.replace(/<[^>]*>/g, "");
|
|
27
|
+
return fixed;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { formatEntityName, getEntityTitle, removeMarkdownFormatting, truncate };
|
|
31
|
+
//# sourceMappingURL=utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.esm.js","sources":["../../src/utils/utils.ts"],"sourcesContent":["import { Entity, stringifyEntityRef } from '@backstage/catalog-model';\n\nexport const formatEntityName = (username?: string) => {\n if (!username) {\n return '';\n }\n const plainName = username.split(/[/:]+/).pop();\n return plainName\n ?.split(/[_.-]+/)\n .map(a => a.charAt(0).toUpperCase() + a.slice(1))\n .join(' ');\n};\n\nexport const getEntityTitle = (entity: Entity): string => {\n const stringified = stringifyEntityRef(entity);\n return formatEntityName(entity.metadata.title ?? stringified) ?? stringified;\n};\n\nexport const truncate = (str: string, n: number): string => {\n return str.length > n ? `${str.slice(0, n - 1)}...` : str;\n};\n\n// Covers many common but not all cases of markdown formatting\nexport const removeMarkdownFormatting = (text: string): string => {\n // Remove horizontal rules\n let fixed = text.replace(/^(-\\s*?|\\*\\s*?|_\\s*?){3,}\\s*/gm, '');\n\n // Remove HTML tags\n fixed = text.replace(/<[^>]*>/g, '');\n\n // Handle code blocks defined with a language\n fixed = fixed.replace(/```[\\s\\S]*?```/g, match => {\n return match.replace(/(^```[a-z]*\\n)|(```$)/g, '').trim();\n });\n\n // Handle inline code blocks and code blocks defined using ```\n fixed = fixed.replace(/`{1,2}([^`]*)`{1,2}/g, '$1');\n\n // Remove other markdown formatting\n fixed = fixed\n .replace(/(?:\\*\\*|__)([^\\n*]+)(?:\\*\\*|__)/g, '$1') // Bold\n .replace(/(?:\\*|_)([^\\n*]+)(?:\\*|_)/g, '$1') // Italic\n .replace(/(?:~~)([^~]+)(?:~~)/g, '$1') // Strikethrough\n .replace(/^[>\\t]{0,3}>+\\s?/gm, '') // Blockquotes\n .replace(/\\[\\^.+?\\](: .*?$)?/g, '') // Footnotes\n .replace(/^([ \\t]*)([*\\-+]|\\d+\\.)\\s+/gm, '') // Lists\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // Images\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // Links\n .replace(/^#{1,6}[ \\t]+/gm, '') // Headers\n .replace(/^[=-]{2,}\\s*$/g, '') // Setex style headers\n .replace(/(?:\\r\\n|\\r|\\n)/g, ' ') // Newlines\n .replace(/(^\\s+|\\s+$)/g, ''); // Trimming leading and trailing spaces\n\n // Remove remaining HTML tags\n fixed = fixed.replace(/<[^>]*>/g, '');\n\n return fixed;\n};\n"],"names":[],"mappings":";;AAEa,MAAA,gBAAA,GAAmB,CAAC,QAAsB,KAAA;AACrD,EAAA,IAAI,CAAC,QAAU,EAAA;AACb,IAAO,OAAA,EAAA,CAAA;AAAA,GACT;AACA,EAAA,MAAM,SAAY,GAAA,QAAA,CAAS,KAAM,CAAA,OAAO,EAAE,GAAI,EAAA,CAAA;AAC9C,EAAA,OAAO,SACH,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAA,KAAA,CAAM,QACP,CAAA,CAAA,GAAA,CAAI,OAAK,CAAE,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,aAAgB,GAAA,CAAA,CAAE,KAAM,CAAA,CAAC,GAC9C,IAAK,CAAA,GAAA,CAAA,CAAA;AACV,EAAA;AAEa,MAAA,cAAA,GAAiB,CAAC,MAA2B,KAAA;AAb1D,EAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAcE,EAAM,MAAA,WAAA,GAAc,mBAAmB,MAAM,CAAA,CAAA;AAC7C,EAAA,OAAA,CAAO,uBAAiB,EAAO,GAAA,MAAA,CAAA,QAAA,CAAS,UAAhB,IAAyB,GAAA,EAAA,GAAA,WAAW,MAArD,IAA0D,GAAA,EAAA,GAAA,WAAA,CAAA;AACnE,EAAA;AAEa,MAAA,QAAA,GAAW,CAAC,GAAA,EAAa,CAAsB,KAAA;AAC1D,EAAO,OAAA,GAAA,CAAI,MAAS,GAAA,CAAA,GAAI,CAAG,EAAA,GAAA,CAAI,MAAM,CAAG,EAAA,CAAA,GAAI,CAAC,CAAC,CAAQ,GAAA,CAAA,GAAA,GAAA,CAAA;AACxD,EAAA;AAGa,MAAA,wBAAA,GAA2B,CAAC,IAAyB,KAAA;AAEhE,EAAA,IAAI,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,gCAAA,EAAkC,EAAE,CAAA,CAAA;AAG7D,EAAQ,KAAA,GAAA,IAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,EAAE,CAAA,CAAA;AAGnC,EAAQ,KAAA,GAAA,KAAA,CAAM,OAAQ,CAAA,iBAAA,EAAmB,CAAS,KAAA,KAAA;AAChD,IAAA,OAAO,KAAM,CAAA,OAAA,CAAQ,wBAA0B,EAAA,EAAE,EAAE,IAAK,EAAA,CAAA;AAAA,GACzD,CAAA,CAAA;AAGD,EAAQ,KAAA,GAAA,KAAA,CAAM,OAAQ,CAAA,sBAAA,EAAwB,IAAI,CAAA,CAAA;AAGlD,EAAQ,KAAA,GAAA,KAAA,CACL,QAAQ,kCAAoC,EAAA,IAAI,EAChD,OAAQ,CAAA,4BAAA,EAA8B,IAAI,CAC1C,CAAA,OAAA,CAAQ,wBAAwB,IAAI,CAAA,CACpC,QAAQ,oBAAsB,EAAA,EAAE,EAChC,OAAQ,CAAA,qBAAA,EAAuB,EAAE,CAAA,CACjC,OAAQ,CAAA,8BAAA,EAAgC,EAAE,CAC1C,CAAA,OAAA,CAAQ,2BAA2B,IAAI,CAAA,CACvC,QAAQ,wBAA0B,EAAA,IAAI,CACtC,CAAA,OAAA,CAAQ,iBAAmB,EAAA,EAAE,EAC7B,OAAQ,CAAA,gBAAA,EAAkB,EAAE,CAC5B,CAAA,OAAA,CAAQ,mBAAmB,GAAG,CAAA,CAC9B,OAAQ,CAAA,cAAA,EAAgB,EAAE,CAAA,CAAA;AAG7B,EAAQ,KAAA,GAAA,KAAA,CAAM,OAAQ,CAAA,UAAA,EAAY,EAAE,CAAA,CAAA;AAEpC,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
|