@drodil/backstage-plugin-qeta 0.1.9 → 0.1.10

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/README.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  Welcome to the qeta plugin!
4
4
 
5
+ Qeta allows you to add Q&A section to your Backstage application.
6
+ This plugin requires that you also install
7
+ [@drodil/backstage-plugin-qeta-backend](https://www.npmjs.com/package/@drodil/backstage-plugin-qeta-backend)
8
+ plugin.
9
+
5
10
  ## Adding to your application
6
11
 
7
12
  Add the plugin to your frontend app:
@@ -5,9 +5,10 @@ import { useNavigate, useParams, Route } from 'react-router-dom';
5
5
  import { Routes } from 'react-router';
6
6
  import MDEditor from '@uiw/react-md-editor';
7
7
  import { useApi } from '@backstage/core-plugin-api';
8
- import { q as qetaApiRef } from './index-6811972d.esm.js';
8
+ import { q as qetaApiRef } from './index-cc3d4ce3.esm.js';
9
9
  import { Autocomplete, Skeleton, Pagination } from '@material-ui/lab';
10
10
  import { useAsync } from 'react-use';
11
+ import { useForm, Controller } from 'react-hook-form';
11
12
  import ArrowDownward from '@material-ui/icons/ArrowDownward';
12
13
  import ArrowUpward from '@material-ui/icons/ArrowUpward';
13
14
  import Check from '@material-ui/icons/Check';
@@ -39,78 +40,121 @@ const useStyles = makeStyles((theme) => {
39
40
  },
40
41
  questionListPagination: {
41
42
  marginTop: theme.spacing(2)
43
+ },
44
+ postButton: {
45
+ marginTop: theme.spacing(1),
46
+ marginBottom: theme.spacing(1)
42
47
  }
43
48
  };
44
49
  });
45
50
 
46
51
  const AskPage = () => {
47
52
  const navigate = useNavigate();
48
- const [question, setQuestion] = React.useState("");
49
- const [title, setTitle] = React.useState("");
50
53
  const [error, setError] = React.useState(false);
51
- const [tags, setTags] = React.useState([]);
52
54
  const [availableTags, setAvailableTags] = React.useState([]);
53
55
  const qetaApi = useApi(qetaApiRef);
54
56
  const styles = useStyles();
55
- const postQuestion = () => {
56
- qetaApi.postQuestion({ title, content: question, tags }).then((q) => {
57
+ const {
58
+ register,
59
+ handleSubmit,
60
+ control,
61
+ reset,
62
+ formState: { errors }
63
+ } = useForm();
64
+ const postQuestion = (data) => {
65
+ qetaApi.postQuestion(data).then((q) => {
57
66
  if (!q || !q.id) {
58
67
  setError(true);
59
68
  return;
60
69
  }
70
+ reset();
61
71
  navigate(`/qeta/questions/${q.id}`);
62
72
  }).catch((_e) => setError(true));
63
73
  };
64
74
  useEffect(() => {
65
75
  qetaApi.getTags().then((data) => setAvailableTags(data));
66
76
  }, [qetaApi]);
67
- return /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, { title: "Ask question" }), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 3, direction: "column" }, error && /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not post question" }), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(InfoCard, null, /* @__PURE__ */ React.createElement("form", null, /* @__PURE__ */ React.createElement(
77
+ return /* @__PURE__ */ React.createElement(Content, null, /* @__PURE__ */ React.createElement(ContentHeader, { title: "Ask question" }), /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 3, direction: "column" }, error && /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not post question" }), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(InfoCard, null, /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit(postQuestion) }, /* @__PURE__ */ React.createElement(
68
78
  TextField,
69
79
  {
70
80
  label: "Title",
71
81
  required: true,
72
82
  fullWidth: true,
83
+ error: "title" in errors,
73
84
  margin: "normal",
74
- title,
75
- onChange: (e) => setTitle(e.target.value),
76
85
  variant: "outlined",
77
- helperText: "Write good title for your question that people can understand"
86
+ helperText: "Write good title for your question that people can understand",
87
+ ...register("title", { required: true, maxLength: 255 })
78
88
  }
79
89
  ), /* @__PURE__ */ React.createElement(
80
- MDEditor,
90
+ Controller,
81
91
  {
82
- value: question,
83
- className: styles.markdownEditor,
84
- onChange: (v) => setQuestion(v),
85
- preview: "edit",
86
- height: 400
92
+ control,
93
+ defaultValue: "",
94
+ rules: {
95
+ required: true
96
+ },
97
+ render: ({ field: { onChange, value } }) => /* @__PURE__ */ React.createElement(
98
+ MDEditor,
99
+ {
100
+ className: styles.markdownEditor,
101
+ preview: "edit",
102
+ height: 400,
103
+ extraCommands: [],
104
+ value,
105
+ style: {
106
+ borderColor: "content" in errors ? "red" : void 0
107
+ },
108
+ onChange,
109
+ textareaProps: {
110
+ placeholder: "Your question"
111
+ }
112
+ }
113
+ ),
114
+ name: "content"
87
115
  }
88
116
  ), /* @__PURE__ */ React.createElement(
89
- Autocomplete,
117
+ Controller,
90
118
  {
91
- multiple: true,
92
- id: "tags-standard",
93
- options: availableTags,
94
- defaultValue: tags,
95
- onChange: (_e, inputTags) => {
96
- if (inputTags.length < 5) {
97
- setTags(inputTags);
98
- }
99
- },
100
- freeSolo: true,
101
- renderInput: (params) => /* @__PURE__ */ React.createElement(
102
- TextField,
119
+ control,
120
+ defaultValue: [],
121
+ render: ({ field: { onChange, value } }) => /* @__PURE__ */ React.createElement(
122
+ Autocomplete,
103
123
  {
104
- ...params,
105
- variant: "outlined",
106
- margin: "normal",
107
- label: "Tags",
108
- placeholder: "Type or select tags",
109
- helperText: "Add up to 5 tags to categorize your question"
124
+ multiple: true,
125
+ id: "tags-standard",
126
+ value,
127
+ options: availableTags,
128
+ freeSolo: true,
129
+ onChange: (_e, newValue) => {
130
+ if (!value || value.length < 5) {
131
+ onChange(newValue);
132
+ }
133
+ },
134
+ renderInput: (params) => /* @__PURE__ */ React.createElement(
135
+ TextField,
136
+ {
137
+ ...params,
138
+ variant: "outlined",
139
+ margin: "normal",
140
+ label: "Tags",
141
+ placeholder: "Type or select tags",
142
+ helperText: "Add up to 5 tags to categorize your question"
143
+ }
144
+ )
110
145
  }
111
- )
146
+ ),
147
+ name: "tags"
112
148
  }
113
- ), /* @__PURE__ */ React.createElement(Button, { variant: "contained", onClick: postQuestion }, "Post"))))));
149
+ ), /* @__PURE__ */ React.createElement(
150
+ Button,
151
+ {
152
+ type: "submit",
153
+ variant: "contained",
154
+ className: styles.postButton
155
+ },
156
+ "Post"
157
+ ))))));
114
158
  };
115
159
 
116
160
  const VoteButtons = (props) => {
@@ -225,30 +269,50 @@ const QuestionCard = (props) => {
225
269
 
226
270
  const AnswerForm = (props) => {
227
271
  const { question, onPost } = props;
228
- const [answer, setAnswer] = React.useState("");
229
272
  const [error, setError] = React.useState(false);
230
273
  const qetaApi = useApi(qetaApiRef);
231
274
  const styles = useStyles();
232
- const postAnswer = () => {
233
- qetaApi.postAnswer({ questionId: question.id, answer }).then((a) => {
275
+ const {
276
+ handleSubmit,
277
+ control,
278
+ formState: { errors },
279
+ reset
280
+ } = useForm();
281
+ const postAnswer = (data) => {
282
+ qetaApi.postAnswer({ questionId: question.id, answer: data.answer }).then((a) => {
234
283
  if (!a || !("id" in a)) {
235
284
  setError(true);
236
285
  return;
237
286
  }
287
+ reset();
238
288
  onPost(a);
239
- setAnswer("");
240
289
  }).catch((_e) => setError(true));
241
290
  };
242
- return /* @__PURE__ */ React.createElement("form", null, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, "Your answer"), error && /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not post answer" }), /* @__PURE__ */ React.createElement(
243
- MDEditor,
291
+ return /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit(postAnswer) }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, "Your answer"), error && /* @__PURE__ */ React.createElement(WarningPanel, { severity: "error", title: "Could not post answer" }), /* @__PURE__ */ React.createElement(
292
+ Controller,
244
293
  {
245
- value: answer,
246
- className: styles.markdownEditor,
247
- onChange: (v) => setAnswer(v),
248
- preview: "edit",
249
- height: 200
294
+ control,
295
+ defaultValue: "",
296
+ rules: {
297
+ required: true
298
+ },
299
+ render: ({ field: { onChange, value } }) => /* @__PURE__ */ React.createElement(
300
+ MDEditor,
301
+ {
302
+ className: styles.markdownEditor,
303
+ preview: "edit",
304
+ height: 200,
305
+ extraCommands: [],
306
+ value,
307
+ style: {
308
+ borderColor: "answer" in errors ? "red" : void 0
309
+ },
310
+ onChange
311
+ }
312
+ ),
313
+ name: "answer"
250
314
  }
251
- ), /* @__PURE__ */ React.createElement(Button, { variant: "contained", onClick: postAnswer }, "Post"));
315
+ ), /* @__PURE__ */ React.createElement(Button, { variant: "contained", type: "submit", className: styles.postButton }, "Post"));
252
316
  };
253
317
 
254
318
  const AnswerCard = (props) => {
@@ -286,8 +350,8 @@ const QuestionPage = () => {
286
350
  },
287
351
  /* @__PURE__ */ React.createElement(Button, { href: "/qeta" }, "Back to questions"),
288
352
  /* @__PURE__ */ React.createElement(Button, { variant: "contained", href: "/qeta/ask" }, "Ask question")
289
- ), /* @__PURE__ */ React.createElement(QuestionCard, { question }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, question.answersCount + newAnswers.length, " answers"), ((_a = question.answers) != null ? _a : []).concat(newAnswers).map((a) => {
290
- return /* @__PURE__ */ React.createElement(Box, { key: a.id, sx: { mb: 1 } }, /* @__PURE__ */ React.createElement(AnswerCard, { answer: a, question }), /* @__PURE__ */ React.createElement(Divider, null));
353
+ ), /* @__PURE__ */ React.createElement(QuestionCard, { question }), /* @__PURE__ */ React.createElement(Box, { sx: { mt: 3, mb: 2 } }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, question.answersCount + newAnswers.length, " answers")), ((_a = question.answers) != null ? _a : []).concat(newAnswers).map((a) => {
354
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { key: a.id, sx: { mb: 1 } }, /* @__PURE__ */ React.createElement(AnswerCard, { answer: a, question })), /* @__PURE__ */ React.createElement(Divider, null));
291
355
  }), /* @__PURE__ */ React.createElement(Divider, null), /* @__PURE__ */ React.createElement(AnswerForm, { question, onPost: onAnswerPost }));
292
356
  };
293
357
 
@@ -392,4 +456,4 @@ const HomePageContent = () => {
392
456
  const HomePage = () => /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "Q&A" }, /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Lifecycle", value: "Alpha" })), /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, { path: "/", element: /* @__PURE__ */ React.createElement(HomePageContent, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/ask", element: /* @__PURE__ */ React.createElement(AskPage, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/questions/:id", element: /* @__PURE__ */ React.createElement(QuestionPage, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/tags/:tag", element: /* @__PURE__ */ React.createElement(TagPage, null) }), /* @__PURE__ */ React.createElement(Route, { path: "/users/*", element: /* @__PURE__ */ React.createElement(UserPage, null) })));
393
457
 
394
458
  export { HomePage };
395
- //# sourceMappingURL=index-913c01cf.esm.js.map
459
+ //# sourceMappingURL=index-2de4ebb7.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-2de4ebb7.esm.js","sources":["../../src/utils/hooks.ts","../../src/components/AskPage/AskPage.tsx","../../src/components/QuestionPage/VoteButtons.tsx","../../src/components/QuestionPage/QuestionCard.tsx","../../src/components/QuestionPage/AnswerForm.tsx","../../src/components/QuestionPage/AnswerCard.tsx","../../src/components/QuestionPage/QuestionPage.tsx","../../src/components/HomePage/QuestionList/QuestionListItem.tsx","../../src/components/HomePage/QuestionList/QuestionList.tsx","../../src/components/TagPage/TagPage.tsx","../../src/components/UserPage/UserPage.tsx","../../src/components/HomePage/HomePage.tsx"],"sourcesContent":["import { QetaApi, qetaApiRef } from '../api';\nimport { useAsync } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core';\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 const useStyles = makeStyles(theme => {\n return {\n markdownEditor: {\n backgroundColor: 'initial',\n boxShadow: 'none',\n color: theme.palette.text.primary,\n border: `1px solid ${theme.palette.grey[600]}`,\n '& .w-md-editor-toolbar': {\n backgroundColor: 'initial',\n },\n },\n questionCardVote: {\n textAlign: 'center',\n marginRight: '20px',\n },\n questionListPagination: {\n marginTop: theme.spacing(2),\n },\n postButton: {\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n },\n };\n});\n","import {\n Content,\n ContentHeader,\n InfoCard,\n WarningPanel,\n} from '@backstage/core-components';\nimport { Button, Grid, TextField } from '@material-ui/core';\nimport MDEditor from '@uiw/react-md-editor';\nimport React, { useEffect } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef, QuestionRequest } from '../../api';\nimport { useNavigate } from 'react-router-dom';\nimport { Autocomplete } from '@material-ui/lab';\nimport { useStyles } from '../../utils/hooks';\nimport { Controller, useForm } from 'react-hook-form';\n\nexport const AskPage = () => {\n const navigate = useNavigate();\n const [error, setError] = React.useState(false);\n const [availableTags, setAvailableTags] = React.useState<string[]>([]);\n const qetaApi = useApi(qetaApiRef);\n const styles = useStyles();\n const {\n register,\n handleSubmit,\n control,\n reset,\n formState: { errors },\n } = useForm<QuestionRequest>();\n\n const postQuestion = (data: QuestionRequest) => {\n qetaApi\n .postQuestion(data)\n .then(q => {\n if (!q || !q.id) {\n setError(true);\n return;\n }\n reset();\n navigate(`/qeta/questions/${q.id}`);\n })\n .catch(_e => setError(true));\n };\n\n useEffect(() => {\n qetaApi.getTags().then(data => setAvailableTags(data));\n }, [qetaApi]);\n\n return (\n <Content>\n <ContentHeader title=\"Ask question\" />\n <Grid container spacing={3} direction=\"column\">\n {error && (\n <WarningPanel severity=\"error\" title=\"Could not post question\" />\n )}\n <Grid item>\n <InfoCard>\n <form onSubmit={handleSubmit(postQuestion)}>\n <TextField\n label=\"Title\"\n required\n fullWidth\n error={'title' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n helperText=\"Write good title for your question that people can understand\"\n {...register('title', { required: true, maxLength: 255 })}\n />\n <Controller\n control={control}\n defaultValue=\"\"\n rules={{\n required: true,\n }}\n render={({ field: { onChange, value } }) => (\n <MDEditor\n className={styles.markdownEditor}\n preview=\"edit\"\n height={400}\n extraCommands={[]}\n value={value}\n style={{\n borderColor: 'content' in errors ? 'red' : undefined,\n }}\n onChange={onChange}\n textareaProps={{\n placeholder: 'Your question',\n }}\n />\n )}\n name=\"content\"\n />\n <Controller\n control={control}\n defaultValue={[]}\n render={({ field: { onChange, value } }) => (\n <Autocomplete\n multiple\n id=\"tags-standard\"\n value={value}\n options={availableTags}\n freeSolo\n onChange={(_e, newValue) => {\n if (!value || value.length < 5) {\n onChange(newValue);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label=\"Tags\"\n placeholder=\"Type or select tags\"\n helperText=\"Add up to 5 tags to categorize your question\"\n />\n )}\n />\n )}\n name=\"tags\"\n />\n <Button\n type=\"submit\"\n variant=\"contained\"\n className={styles.postButton}\n >\n Post\n </Button>\n </form>\n </InfoCard>\n </Grid>\n </Grid>\n </Content>\n );\n};\n","import { AnswerResponse, qetaApiRef, QuestionResponse } from '../../api';\nimport { Box, IconButton, Tooltip, Typography } from '@material-ui/core';\nimport ArrowDownward from '@material-ui/icons/ArrowDownward';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport Check from '@material-ui/icons/Check';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\n\nexport const VoteButtons = (props: {\n entity: QuestionResponse | AnswerResponse;\n question?: QuestionResponse;\n}) => {\n const [ownVote, setOwnVote] = React.useState(props.entity.ownVote ?? 0);\n const isCorrectAnswer =\n 'questionId' in props.entity ? props.entity.correct : false;\n const [correct, setCorrect] = React.useState(isCorrectAnswer);\n const [entity, setEntity] = React.useState<QuestionResponse | AnswerResponse>(\n props.entity,\n );\n const qetaApi = useApi(qetaApiRef);\n\n const voteUp = () => {\n if ('title' in entity) {\n qetaApi.voteQuestionUp(entity.id).then(response => {\n setOwnVote(1);\n setEntity(response);\n });\n } else if ('questionId' in entity) {\n qetaApi.voteAnswerUp(entity.questionId, entity.id).then(response => {\n setOwnVote(1);\n setEntity(response);\n });\n }\n };\n\n const voteDown = () => {\n if ('title' in entity) {\n qetaApi.voteQuestionDown(entity.id).then(response => {\n setOwnVote(-1);\n setEntity(response);\n });\n } else if ('questionId' in entity) {\n qetaApi.voteAnswerDown(entity.questionId, entity.id).then(response => {\n setOwnVote(-1);\n setEntity(response);\n });\n }\n };\n\n const toggleCorrectAnswer = () => {\n if (!('questionId' in entity)) {\n return;\n }\n if (correct) {\n qetaApi\n .markAnswerIncorrect(entity.questionId, entity.id)\n .then(response => {\n if (response) {\n setCorrect(false);\n }\n });\n } else {\n qetaApi.markAnswerCorrect(entity.questionId, entity.id).then(response => {\n setCorrect(response);\n });\n }\n };\n\n return (\n <React.Fragment>\n <Tooltip\n title={\n props.entity.own\n ? 'You cannot vote your own post'\n : 'This answer is good'\n }\n >\n <IconButton\n aria-label=\"vote up\"\n color={ownVote > 0 ? 'primary' : 'default'}\n disabled={props.entity.own ?? false}\n size=\"small\"\n onClick={voteUp}\n >\n <ArrowUpward />\n </IconButton>\n </Tooltip>\n <Typography variant=\"h6\">{entity.score}</Typography>\n <Tooltip\n title={\n props.entity.own\n ? 'You cannot vote your own post'\n : 'This answer is not good'\n }\n >\n <IconButton\n aria-label=\"vote down\"\n color={ownVote < 0 ? 'primary' : 'default'}\n disabled={props.entity.own ?? false}\n size=\"small\"\n onClick={voteDown}\n >\n <ArrowDownward />\n </IconButton>\n </Tooltip>\n {'correct' in props.entity && props.question?.own && (\n <Box>\n <Tooltip title=\"Mark answer as correct\">\n <IconButton\n aria-label=\"mark correct\"\n color={correct ? 'primary' : 'default'}\n size=\"small\"\n onClick={toggleCorrectAnswer}\n >\n <Check />\n </IconButton>\n </Tooltip>\n </Box>\n )}\n </React.Fragment>\n );\n};\n","import { QuestionResponse } from '../../api';\nimport {\n Box,\n Card,\n CardContent,\n Chip,\n Grid,\n Link,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { VoteButtons } from './VoteButtons';\nimport { useStyles } from '../../utils/hooks';\n\nexport const QuestionCard = (props: { question: QuestionResponse }) => {\n const { question } = props;\n const styles = useStyles();\n\n return (\n <Card variant=\"outlined\">\n <CardContent>\n <Grid container spacing={0}>\n <Grid item className={styles.questionCardVote}>\n <VoteButtons entity={question} />\n </Grid>\n <Grid item>\n <Typography variant=\"body1\" gutterBottom>\n <MarkdownContent content={question.content} dialect=\"gfm\" />\n </Typography>\n {question.tags &&\n question.tags.map(tag => (\n <Chip\n label={tag}\n size=\"small\"\n component=\"a\"\n href={`/qeta/tags/${tag}`}\n clickable\n />\n ))}\n <Box>\n By{' '}\n <Link href={`/qeta/users/${question.author}`}>\n {question.author}\n </Link>\n </Box>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n );\n};\n","import { WarningPanel } from '@backstage/core-components';\nimport { Button, Typography } from '@material-ui/core';\nimport MDEditor from '@uiw/react-md-editor';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n AnswerRequest,\n AnswerResponse,\n qetaApiRef,\n QuestionResponse,\n} from '../../api';\nimport { useStyles } from '../../utils/hooks';\nimport { Controller, useForm } from 'react-hook-form';\n\nexport const AnswerForm = (props: {\n question: QuestionResponse;\n onPost: (answer: AnswerResponse) => void;\n}) => {\n const { question, onPost } = props;\n const [error, setError] = React.useState(false);\n const qetaApi = useApi(qetaApiRef);\n const styles = useStyles();\n\n const {\n handleSubmit,\n control,\n formState: { errors },\n reset,\n } = useForm<AnswerRequest>();\n\n const postAnswer = (data: AnswerRequest) => {\n qetaApi\n .postAnswer({ questionId: question.id, answer: data.answer })\n .then(a => {\n if (!a || !('id' in a)) {\n setError(true);\n return;\n }\n reset();\n onPost(a);\n })\n .catch(_e => setError(true));\n };\n\n return (\n <form onSubmit={handleSubmit(postAnswer)}>\n <Typography variant=\"h6\">Your answer</Typography>\n {error && <WarningPanel severity=\"error\" title=\"Could not post answer\" />}\n <Controller\n control={control}\n defaultValue=\"\"\n rules={{\n required: true,\n }}\n render={({ field: { onChange, value } }) => (\n <MDEditor\n className={styles.markdownEditor}\n preview=\"edit\"\n height={200}\n extraCommands={[]}\n value={value}\n style={{\n borderColor: 'answer' in errors ? 'red' : undefined,\n }}\n onChange={onChange}\n />\n )}\n name=\"answer\"\n />\n <Button variant=\"contained\" type=\"submit\" className={styles.postButton}>\n Post\n </Button>\n </form>\n );\n};\n","import { AnswerResponse, QuestionResponse } from '../../api';\nimport {\n Box,\n Card,\n CardContent,\n Grid,\n Link,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { VoteButtons } from './VoteButtons';\nimport { useStyles } from '../../utils/hooks';\n\nexport const AnswerCard = (props: {\n answer: AnswerResponse;\n question: QuestionResponse;\n}) => {\n const { answer, question } = props;\n const styles = useStyles();\n\n return (\n <Card id={`a${answer.id}`}>\n <CardContent>\n <Grid container spacing={0}>\n <Grid item className={styles.questionCardVote}>\n <VoteButtons entity={answer} question={question} />\n </Grid>\n <Grid item>\n <Typography variant=\"body1\" gutterBottom>\n <MarkdownContent content={answer.content} dialect=\"gfm\" />\n </Typography>\n <Box>\n By{' '}\n <Link href={`/qeta/users/${answer.author}`}>{answer.author}</Link>\n </Box>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n );\n};\n","import React from 'react';\nimport { Box, Button, Divider, Typography } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport {\n Content,\n ContentHeader,\n WarningPanel,\n} from '@backstage/core-components';\nimport { useQetaApi } from '../../utils/hooks';\nimport { QuestionCard } from './QuestionCard';\nimport { AnswerResponse, QuestionResponse } from '../../api';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { AnswerForm } from './AnswerForm';\nimport { AnswerCard } from './AnswerCard';\nimport { Skeleton } from '@material-ui/lab';\n\nexport const QuestionPage = () => {\n const { id } = useParams();\n const [newAnswers, setNewAnswers] = React.useState<AnswerResponse[]>([]);\n\n const {\n value: question,\n loading,\n error,\n } = useQetaApi(api => api.getQuestion(id), [id]);\n\n const onAnswerPost = (answer: AnswerResponse) => {\n setNewAnswers(newAnswers.concat([answer]));\n };\n\n const getDescription = (q: QuestionResponse) => {\n return (\n <span>\n Asked{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\" sx={{ mr: 2 }}>\n <RelativeTime value={q.created} />\n </Box>\n {q.updated && (\n <React.Fragment>\n Updated{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\">\n <RelativeTime value={q.created} />\n </Box>\n </React.Fragment>\n )}\n Viewed{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\">\n {q.views} times\n </Box>\n </span>\n );\n };\n\n if (loading) {\n return <Skeleton variant=\"rect\" height={200} />;\n }\n\n if (error || question === undefined) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load question.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n return (\n <Content>\n <ContentHeader\n title={question.title}\n // @ts-ignore\n description={getDescription(question)}\n >\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionCard question={question} />\n <Box sx={{ mt: 3, mb: 2 }}>\n <Typography variant=\"h6\">\n {question.answersCount + newAnswers.length} answers\n </Typography>\n </Box>\n {(question.answers ?? []).concat(newAnswers).map(a => {\n return (\n <>\n <Box key={a.id} sx={{ mb: 1 }}>\n <AnswerCard answer={a} question={question} />\n </Box>\n <Divider />\n </>\n );\n })}\n <Divider />\n <AnswerForm question={question} onPost={onAnswerPost} />\n </Content>\n );\n};\n","import { QuestionResponse } from '../../../api';\nimport { Card, CardContent, Chip, Link, Typography } from '@material-ui/core';\nimport React from 'react';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\n\nexport const QuestionListItem = (props: { question: QuestionResponse }) => {\n const { question } = props;\n return (\n <Card>\n <CardContent>\n <Typography gutterBottom variant=\"h5\" component=\"div\">\n <Link href={`/qeta/questions/${question.id}`}>{question.title}</Link>\n </Typography>\n {question.tags &&\n question.tags.map(tag => (\n <Chip\n label={tag}\n size=\"small\"\n component=\"a\"\n href={`/qeta/tags/${tag}`}\n clickable\n />\n ))}\n <Typography variant=\"body2\" display=\"block\">\n By{' '}\n <Link href={`/qeta/users/${question.author}`}>{question.author}</Link>{' '}\n <RelativeTime\n value={question.created}\n titleFormat=\"YYYY/MM/DD HH:mm\"\n />\n </Typography>\n <Typography variant=\"caption\" display=\"inline\" gutterBottom>\n Score: {question.score} {' | '}\n </Typography>\n <Typography\n variant=\"caption\"\n color={question.correctAnswer ? 'secondary' : 'initial'}\n display=\"inline\"\n gutterBottom\n >\n Answers: {question.answersCount}\n </Typography>\n <Typography variant=\"caption\" display=\"inline\" gutterBottom>\n {' | '} Views: {question.views}\n </Typography>\n </CardContent>\n </Card>\n );\n};\n","import { useQetaApi, useStyles } from '../../../utils/hooks';\nimport { WarningPanel } from '@backstage/core-components';\nimport { Box, Divider, Grid } from '@material-ui/core';\nimport React from 'react';\nimport { QuestionListItem } from './QuestionListItem';\nimport { Pagination, Skeleton } from '@material-ui/lab';\n\nexport const QuestionList = (props: { tags?: string[]; author?: string }) => {\n const { tags, author } = props;\n const [page, setPage] = React.useState(1);\n const pageSize = 10;\n const offset = (page - 1) * pageSize;\n const styles = useStyles();\n\n const handleChange = (_event: React.ChangeEvent<unknown>, value: number) => {\n setPage(value);\n };\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api => api.getQuestions({ limit: pageSize, offset, tags, author }),\n [page, offset],\n );\n\n if (loading) {\n return <Skeleton variant=\"rect\" height={200} />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load questions.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n if (response.questions.length === 0) {\n return <Box>No questions found</Box>;\n }\n\n const pageCount =\n response.total < pageSize ? 1 : Math.ceil(response.total / pageSize);\n\n return (\n <Box>\n <Grid container spacing={2}>\n {response.questions.map(question => {\n return (\n <Grid item xs={12} key={question.id}>\n <QuestionListItem question={question} />\n <Divider />\n </Grid>\n );\n })}\n </Grid>\n <Grid\n container\n spacing={0}\n className={styles.questionListPagination}\n direction=\"column\"\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Pagination\n page={page}\n onChange={handleChange}\n count={pageCount}\n size=\"large\"\n variant=\"outlined\"\n showFirstButton\n showLastButton\n />\n </Grid>\n </Box>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport { Content, ContentHeader } from '@backstage/core-components';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { QuestionList } from '../HomePage/QuestionList';\n\nexport const TagPage = () => {\n const { tag } = useParams();\n return (\n <Content>\n <ContentHeader title={`Questions tagged [${tag}]`}>\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList tags={[tag ?? '']} />\n </Content>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport { Content, ContentHeader } from '@backstage/core-components';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { QuestionList } from '../HomePage/QuestionList';\n\nexport const UserPage = () => {\n const identity = useParams()['*'] ?? 'unknown';\n return (\n <Content>\n <ContentHeader title={`Questions by [${identity}]`}>\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList author={identity ?? ''} />\n </Content>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport {\n Content,\n ContentHeader,\n Header,\n HeaderLabel,\n Page,\n} from '@backstage/core-components';\nimport { Route } from 'react-router-dom';\nimport { Routes } from 'react-router';\nimport { AskPage } from '../AskPage';\nimport { QuestionPage } from '../QuestionPage/QuestionPage';\nimport { QuestionList } from './QuestionList/QuestionList';\nimport { TagPage } from '../TagPage/TagPage';\nimport { UserPage } from '../UserPage/UserPage';\n\nexport const HomePageContent = () => {\n return (\n <Content>\n <ContentHeader title=\"All questions\">\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList />\n </Content>\n );\n};\n\nexport const HomePage = () => (\n <Page themeId=\"tool\">\n <Header title=\"Q&A\">\n <HeaderLabel label=\"Lifecycle\" value=\"Alpha\" />\n </Header>\n <Routes>\n <Route path=\"/\" element={<HomePageContent />} />\n <Route path=\"/ask\" element={<AskPage />} />\n <Route path=\"/questions/:id\" element={<QuestionPage />} />\n <Route path=\"/tags/:tag\" element={<TagPage />} />\n <Route path=\"/users/*\" element={<UserPage />} />\n </Routes>\n </Page>\n);\n"],"names":[],"mappings":"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"}
@@ -173,10 +173,10 @@ const qetaPlugin = createPlugin({
173
173
  const QetaPage = qetaPlugin.provide(
174
174
  createRoutableExtension({
175
175
  name: "QetaPage",
176
- component: () => import('./index-913c01cf.esm.js').then((m) => m.HomePage),
176
+ component: () => import('./index-2de4ebb7.esm.js').then((m) => m.HomePage),
177
177
  mountPoint: rootRouteRef
178
178
  })
179
179
  );
180
180
 
181
181
  export { QetaPage as Q, qetaPlugin as a, qetaApiRef as q };
182
- //# sourceMappingURL=index-6811972d.esm.js.map
182
+ //# sourceMappingURL=index-cc3d4ce3.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-6811972d.esm.js","sources":["../../src/routes.ts","../../src/api/QetaClient.ts","../../src/plugin.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'qeta',\n});\n","import { GetQuestionsOptions, QetaApi } from './QetaApi';\nimport { ConfigApi, createApiRef, FetchApi } from '@backstage/core-plugin-api';\nimport { CustomErrorBase } from '@backstage/errors';\nimport {\n AnswerRequest,\n AnswerResponse,\n AnswerResponseBody,\n QuestionRequest,\n QuestionResponse,\n QuestionResponseBody,\n QuestionsResponse,\n QuestionsResponseBody,\n} from './types';\nimport omitBy from 'lodash/omitBy';\nimport isEmpty from 'lodash/isEmpty';\n\nexport const qetaApiRef = createApiRef<QetaApi>({\n id: 'plugin.qeta.service',\n});\n\nexport class QetaError extends CustomErrorBase {\n public errors: null | undefined | any[];\n\n constructor(message: string, errors: null | undefined | any[]) {\n super(message);\n\n this.errors = errors;\n }\n}\n\nexport class QetaClient implements QetaApi {\n private readonly baseUrl: string;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { configApi: ConfigApi; fetchApi: FetchApi }) {\n this.fetchApi = options.fetchApi;\n this.baseUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async getQuestions(options: GetQuestionsOptions): Promise<QuestionsResponse> {\n const query = new URLSearchParams(\n omitBy(options as any, isEmpty),\n ).toString();\n\n let url = `${this.baseUrl}/api/qeta/questions`;\n if (query) {\n url += `?${query}`;\n }\n\n const response = await this.fetchApi.fetch(url);\n\n const data = (await response.json()) as QuestionsResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async postQuestion(question: QuestionRequest): Promise<QuestionResponse> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions`,\n {\n method: 'POST',\n body: JSON.stringify(question),\n headers: { 'Content-Type': 'application/json' },\n },\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async getQuestion(id?: string): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async getTags(): Promise<string[]> {\n const response = await this.fetchApi.fetch(`${this.baseUrl}/api/qeta/tags`);\n return (await response.json()) as string[];\n }\n\n async voteQuestionUp(id: number): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}/upvote`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteQuestionDown(id: number): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}/downvote`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async postAnswer(answer: AnswerRequest): Promise<AnswerResponseBody> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${answer.questionId}/answers`,\n {\n method: 'POST',\n body: JSON.stringify({ answer: answer.answer }),\n headers: { 'Content-Type': 'application/json' },\n },\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteAnswerUp(questionId: number, id: number): Promise<AnswerResponse> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/upvote`,\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteAnswerDown(\n questionId: number,\n id: number,\n ): Promise<AnswerResponse> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/downvote`,\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async markAnswerCorrect(questionId: number, id: number): Promise<boolean> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/correct`,\n );\n const data = await response;\n return data.ok;\n }\n\n async markAnswerIncorrect(questionId: number, id: number): Promise<boolean> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/incorrect`,\n );\n const data = await response;\n return data.ok;\n }\n}\n","import {\n configApiRef,\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { qetaApiRef, QetaClient } from './api';\n\nexport const qetaPlugin = createPlugin({\n id: 'qeta',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: qetaApiRef,\n deps: { configApi: configApiRef, fetchApi: fetchApiRef },\n factory: ({ configApi, fetchApi }) =>\n new QetaClient({ configApi, fetchApi }),\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: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index-cc3d4ce3.esm.js","sources":["../../src/routes.ts","../../src/api/QetaClient.ts","../../src/plugin.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'qeta',\n});\n","import { GetQuestionsOptions, QetaApi } from './QetaApi';\nimport { ConfigApi, createApiRef, FetchApi } from '@backstage/core-plugin-api';\nimport { CustomErrorBase } from '@backstage/errors';\nimport {\n AnswerRequest,\n AnswerResponse,\n AnswerResponseBody,\n QuestionRequest,\n QuestionResponse,\n QuestionResponseBody,\n QuestionsResponse,\n QuestionsResponseBody,\n} from './types';\nimport omitBy from 'lodash/omitBy';\nimport isEmpty from 'lodash/isEmpty';\n\nexport const qetaApiRef = createApiRef<QetaApi>({\n id: 'plugin.qeta.service',\n});\n\nexport class QetaError extends CustomErrorBase {\n public errors: null | undefined | any[];\n\n constructor(message: string, errors: null | undefined | any[]) {\n super(message);\n\n this.errors = errors;\n }\n}\n\nexport class QetaClient implements QetaApi {\n private readonly baseUrl: string;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { configApi: ConfigApi; fetchApi: FetchApi }) {\n this.fetchApi = options.fetchApi;\n this.baseUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async getQuestions(options: GetQuestionsOptions): Promise<QuestionsResponse> {\n const query = new URLSearchParams(\n omitBy(options as any, isEmpty),\n ).toString();\n\n let url = `${this.baseUrl}/api/qeta/questions`;\n if (query) {\n url += `?${query}`;\n }\n\n const response = await this.fetchApi.fetch(url);\n\n const data = (await response.json()) as QuestionsResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async postQuestion(question: QuestionRequest): Promise<QuestionResponse> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions`,\n {\n method: 'POST',\n body: JSON.stringify(question),\n headers: { 'Content-Type': 'application/json' },\n },\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async getQuestion(id?: string): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async getTags(): Promise<string[]> {\n const response = await this.fetchApi.fetch(`${this.baseUrl}/api/qeta/tags`);\n return (await response.json()) as string[];\n }\n\n async voteQuestionUp(id: number): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}/upvote`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteQuestionDown(id: number): Promise<QuestionResponse> {\n if (!id) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}/downvote`,\n );\n const data = (await response.json()) as QuestionResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async postAnswer(answer: AnswerRequest): Promise<AnswerResponseBody> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${answer.questionId}/answers`,\n {\n method: 'POST',\n body: JSON.stringify({ answer: answer.answer }),\n headers: { 'Content-Type': 'application/json' },\n },\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteAnswerUp(questionId: number, id: number): Promise<AnswerResponse> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/upvote`,\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async voteAnswerDown(\n questionId: number,\n id: number,\n ): Promise<AnswerResponse> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/downvote`,\n );\n const data = (await response.json()) as AnswerResponseBody;\n\n if ('errors' in data) {\n throw new QetaError('Failed to fetch', data.errors);\n }\n\n return data;\n }\n\n async markAnswerCorrect(questionId: number, id: number): Promise<boolean> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/correct`,\n );\n const data = await response;\n return data.ok;\n }\n\n async markAnswerIncorrect(questionId: number, id: number): Promise<boolean> {\n if (!id || !questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}/answers/${id}/incorrect`,\n );\n const data = await response;\n return data.ok;\n }\n}\n","import {\n configApiRef,\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { qetaApiRef, QetaClient } from './api';\n\nexport const qetaPlugin = createPlugin({\n id: 'qeta',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: qetaApiRef,\n deps: { configApi: configApiRef, fetchApi: fetchApiRef },\n factory: ({ configApi, fetchApi }) =>\n new QetaClient({ configApi, fetchApi }),\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: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Q as QetaPage, a as qetaPlugin } from './esm/index-6811972d.esm.js';
1
+ export { Q as QetaPage, a as qetaPlugin } from './esm/index-cc3d4ce3.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
3
  import '@backstage/errors';
4
4
  import 'lodash/omitBy';
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "frontend",
8
8
  "backstage.io"
9
9
  ],
10
- "version": "0.1.9",
10
+ "version": "0.1.10",
11
11
  "main": "dist/index.esm.js",
12
12
  "types": "dist/index.d.ts",
13
13
  "prepublishOnly": "yarn tsc && yarn build",
@@ -38,9 +38,9 @@
38
38
  "postpack": "backstage-cli package postpack"
39
39
  },
40
40
  "dependencies": {
41
- "@backstage/core-components": "^0.12.0",
42
- "@backstage/core-plugin-api": "^1.1.0",
43
- "@backstage/errors": "^1.1.3",
41
+ "@backstage/core-components": "^0.12.1",
42
+ "@backstage/core-plugin-api": "^1.2.0",
43
+ "@backstage/errors": "^1.1.4",
44
44
  "@backstage/theme": "^0.2.16",
45
45
  "@material-ui/core": "^4.9.13",
46
46
  "@material-ui/icons": "^4.11.3",
@@ -49,6 +49,7 @@
49
49
  "ajv": "^8.11.0",
50
50
  "ajv-formats": "^2.1.1",
51
51
  "lodash": "^4.17.21",
52
+ "react-hook-form": "^7.41.0",
52
53
  "react-relative-time": "^0.0.7",
53
54
  "react-router": "^6.5.0",
54
55
  "react-router-dom": "^6.5.0",
@@ -58,10 +59,10 @@
58
59
  "react": "^16.13.1 || ^17.0.0"
59
60
  },
60
61
  "devDependencies": {
61
- "@backstage/cli": "^0.21.0",
62
- "@backstage/core-app-api": "^1.2.0",
63
- "@backstage/dev-utils": "^1.0.8",
64
- "@backstage/test-utils": "^1.2.2",
62
+ "@backstage/cli": "^0.22.0",
63
+ "@backstage/core-app-api": "^1.3.0",
64
+ "@backstage/dev-utils": "^1.0.9",
65
+ "@backstage/test-utils": "^1.2.3",
65
66
  "@testing-library/jest-dom": "^5.10.1",
66
67
  "@testing-library/react": "^12.1.3",
67
68
  "@testing-library/user-event": "^14.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-913c01cf.esm.js","sources":["../../src/utils/hooks.ts","../../src/components/AskPage/AskPage.tsx","../../src/components/QuestionPage/VoteButtons.tsx","../../src/components/QuestionPage/QuestionCard.tsx","../../src/components/QuestionPage/AnswerForm.tsx","../../src/components/QuestionPage/AnswerCard.tsx","../../src/components/QuestionPage/QuestionPage.tsx","../../src/components/HomePage/QuestionList/QuestionListItem.tsx","../../src/components/HomePage/QuestionList/QuestionList.tsx","../../src/components/TagPage/TagPage.tsx","../../src/components/UserPage/UserPage.tsx","../../src/components/HomePage/HomePage.tsx"],"sourcesContent":["import { QetaApi, qetaApiRef } from '../api';\nimport { useAsync } from 'react-use';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { makeStyles } from '@material-ui/core';\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 const useStyles = makeStyles(theme => {\n return {\n markdownEditor: {\n backgroundColor: 'initial',\n boxShadow: 'none',\n color: theme.palette.text.primary,\n border: `1px solid ${theme.palette.grey[600]}`,\n '& .w-md-editor-toolbar': {\n backgroundColor: 'initial',\n },\n },\n questionCardVote: {\n textAlign: 'center',\n marginRight: '20px',\n },\n questionListPagination: {\n marginTop: theme.spacing(2),\n },\n };\n});\n","import {\n Content,\n ContentHeader,\n InfoCard,\n WarningPanel,\n} from '@backstage/core-components';\nimport { Button, Grid, TextField } from '@material-ui/core';\nimport MDEditor from '@uiw/react-md-editor';\nimport React, { useEffect } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useNavigate } from 'react-router-dom';\nimport { Autocomplete } from '@material-ui/lab';\nimport { useStyles } from '../../utils/hooks';\n\nexport const AskPage = () => {\n const navigate = useNavigate();\n const [question, setQuestion] = React.useState('');\n const [title, setTitle] = React.useState('');\n const [error, setError] = React.useState(false);\n const [tags, setTags] = React.useState<string[]>([]);\n const [availableTags, setAvailableTags] = React.useState<string[]>([]);\n const qetaApi = useApi(qetaApiRef);\n const styles = useStyles();\n\n const postQuestion = () => {\n qetaApi\n .postQuestion({ title, content: question, tags })\n .then(q => {\n if (!q || !q.id) {\n setError(true);\n return;\n }\n navigate(`/qeta/questions/${q.id}`);\n })\n .catch(_e => setError(true));\n };\n\n useEffect(() => {\n qetaApi.getTags().then(data => setAvailableTags(data));\n }, [qetaApi]);\n\n return (\n <Content>\n <ContentHeader title=\"Ask question\" />\n <Grid container spacing={3} direction=\"column\">\n {error && (\n <WarningPanel severity=\"error\" title=\"Could not post question\" />\n )}\n <Grid item>\n <InfoCard>\n <form>\n <TextField\n label=\"Title\"\n required\n fullWidth\n margin=\"normal\"\n title={title}\n onChange={e => setTitle(e.target.value)}\n variant=\"outlined\"\n helperText=\"Write good title for your question that people can understand\"\n />\n <MDEditor\n value={question}\n className={styles.markdownEditor}\n onChange={v => setQuestion(v as string)}\n preview=\"edit\"\n height={400}\n />\n <Autocomplete\n multiple\n id=\"tags-standard\"\n options={availableTags}\n defaultValue={tags}\n onChange={(_e, inputTags) => {\n if (inputTags.length < 5) {\n setTags(inputTags);\n }\n }}\n freeSolo\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label=\"Tags\"\n placeholder=\"Type or select tags\"\n helperText=\"Add up to 5 tags to categorize your question\"\n />\n )}\n />\n <Button variant=\"contained\" onClick={postQuestion}>\n Post\n </Button>\n </form>\n </InfoCard>\n </Grid>\n </Grid>\n </Content>\n );\n};\n","import { AnswerResponse, qetaApiRef, QuestionResponse } from '../../api';\nimport { Box, IconButton, Tooltip, Typography } from '@material-ui/core';\nimport ArrowDownward from '@material-ui/icons/ArrowDownward';\nimport ArrowUpward from '@material-ui/icons/ArrowUpward';\nimport Check from '@material-ui/icons/Check';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\n\nexport const VoteButtons = (props: {\n entity: QuestionResponse | AnswerResponse;\n question?: QuestionResponse;\n}) => {\n const [ownVote, setOwnVote] = React.useState(props.entity.ownVote ?? 0);\n const isCorrectAnswer =\n 'questionId' in props.entity ? props.entity.correct : false;\n const [correct, setCorrect] = React.useState(isCorrectAnswer);\n const [entity, setEntity] = React.useState<QuestionResponse | AnswerResponse>(\n props.entity,\n );\n const qetaApi = useApi(qetaApiRef);\n\n const voteUp = () => {\n if ('title' in entity) {\n qetaApi.voteQuestionUp(entity.id).then(response => {\n setOwnVote(1);\n setEntity(response);\n });\n } else if ('questionId' in entity) {\n qetaApi.voteAnswerUp(entity.questionId, entity.id).then(response => {\n setOwnVote(1);\n setEntity(response);\n });\n }\n };\n\n const voteDown = () => {\n if ('title' in entity) {\n qetaApi.voteQuestionDown(entity.id).then(response => {\n setOwnVote(-1);\n setEntity(response);\n });\n } else if ('questionId' in entity) {\n qetaApi.voteAnswerDown(entity.questionId, entity.id).then(response => {\n setOwnVote(-1);\n setEntity(response);\n });\n }\n };\n\n const toggleCorrectAnswer = () => {\n if (!('questionId' in entity)) {\n return;\n }\n if (correct) {\n qetaApi\n .markAnswerIncorrect(entity.questionId, entity.id)\n .then(response => {\n if (response) {\n setCorrect(false);\n }\n });\n } else {\n qetaApi.markAnswerCorrect(entity.questionId, entity.id).then(response => {\n setCorrect(response);\n });\n }\n };\n\n return (\n <React.Fragment>\n <Tooltip\n title={\n props.entity.own\n ? 'You cannot vote your own post'\n : 'This answer is good'\n }\n >\n <IconButton\n aria-label=\"vote up\"\n color={ownVote > 0 ? 'primary' : 'default'}\n disabled={props.entity.own ?? false}\n size=\"small\"\n onClick={voteUp}\n >\n <ArrowUpward />\n </IconButton>\n </Tooltip>\n <Typography variant=\"h6\">{entity.score}</Typography>\n <Tooltip\n title={\n props.entity.own\n ? 'You cannot vote your own post'\n : 'This answer is not good'\n }\n >\n <IconButton\n aria-label=\"vote down\"\n color={ownVote < 0 ? 'primary' : 'default'}\n disabled={props.entity.own ?? false}\n size=\"small\"\n onClick={voteDown}\n >\n <ArrowDownward />\n </IconButton>\n </Tooltip>\n {'correct' in props.entity && props.question?.own && (\n <Box>\n <Tooltip title=\"Mark answer as correct\">\n <IconButton\n aria-label=\"mark correct\"\n color={correct ? 'primary' : 'default'}\n size=\"small\"\n onClick={toggleCorrectAnswer}\n >\n <Check />\n </IconButton>\n </Tooltip>\n </Box>\n )}\n </React.Fragment>\n );\n};\n","import { QuestionResponse } from '../../api';\nimport {\n Box,\n Card,\n CardContent,\n Chip,\n Grid,\n Link,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { VoteButtons } from './VoteButtons';\nimport { useStyles } from '../../utils/hooks';\n\nexport const QuestionCard = (props: { question: QuestionResponse }) => {\n const { question } = props;\n const styles = useStyles();\n\n return (\n <Card variant=\"outlined\">\n <CardContent>\n <Grid container spacing={0}>\n <Grid item className={styles.questionCardVote}>\n <VoteButtons entity={question} />\n </Grid>\n <Grid item>\n <Typography variant=\"body1\" gutterBottom>\n <MarkdownContent content={question.content} dialect=\"gfm\" />\n </Typography>\n {question.tags &&\n question.tags.map(tag => (\n <Chip\n label={tag}\n size=\"small\"\n component=\"a\"\n href={`/qeta/tags/${tag}`}\n clickable\n />\n ))}\n <Box>\n By{' '}\n <Link href={`/qeta/users/${question.author}`}>\n {question.author}\n </Link>\n </Box>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n );\n};\n","import { WarningPanel } from '@backstage/core-components';\nimport { Button, Typography } from '@material-ui/core';\nimport MDEditor from '@uiw/react-md-editor';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { AnswerResponse, qetaApiRef, QuestionResponse } from '../../api';\nimport { useStyles } from '../../utils/hooks';\n\nexport const AnswerForm = (props: {\n question: QuestionResponse;\n onPost: (answer: AnswerResponse) => void;\n}) => {\n const { question, onPost } = props;\n const [answer, setAnswer] = React.useState('');\n const [error, setError] = React.useState(false);\n const qetaApi = useApi(qetaApiRef);\n const styles = useStyles();\n\n const postAnswer = () => {\n qetaApi\n .postAnswer({ questionId: question.id, answer })\n .then(a => {\n if (!a || !('id' in a)) {\n setError(true);\n return;\n }\n onPost(a);\n setAnswer('');\n })\n .catch(_e => setError(true));\n };\n\n return (\n <form>\n <Typography variant=\"h6\">Your answer</Typography>\n {error && <WarningPanel severity=\"error\" title=\"Could not post answer\" />}\n <MDEditor\n value={answer}\n className={styles.markdownEditor}\n onChange={v => setAnswer(v as string)}\n preview=\"edit\"\n height={200}\n />\n <Button variant=\"contained\" onClick={postAnswer}>\n Post\n </Button>\n </form>\n );\n};\n","import { AnswerResponse, QuestionResponse } from '../../api';\nimport {\n Box,\n Card,\n CardContent,\n Grid,\n Link,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { VoteButtons } from './VoteButtons';\nimport { useStyles } from '../../utils/hooks';\n\nexport const AnswerCard = (props: {\n answer: AnswerResponse;\n question: QuestionResponse;\n}) => {\n const { answer, question } = props;\n const styles = useStyles();\n\n return (\n <Card id={`a${answer.id}`}>\n <CardContent>\n <Grid container spacing={0}>\n <Grid item className={styles.questionCardVote}>\n <VoteButtons entity={answer} question={question} />\n </Grid>\n <Grid item>\n <Typography variant=\"body1\" gutterBottom>\n <MarkdownContent content={answer.content} dialect=\"gfm\" />\n </Typography>\n <Box>\n By{' '}\n <Link href={`/qeta/users/${answer.author}`}>{answer.author}</Link>\n </Box>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n );\n};\n","import React from 'react';\nimport { Box, Button, Divider, Typography } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport {\n Content,\n ContentHeader,\n WarningPanel,\n} from '@backstage/core-components';\nimport { useQetaApi } from '../../utils/hooks';\nimport { QuestionCard } from './QuestionCard';\nimport { AnswerResponse, QuestionResponse } from '../../api';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { AnswerForm } from './AnswerForm';\nimport { AnswerCard } from './AnswerCard';\nimport { Skeleton } from '@material-ui/lab';\n\nexport const QuestionPage = () => {\n const { id } = useParams();\n const [newAnswers, setNewAnswers] = React.useState<AnswerResponse[]>([]);\n\n const {\n value: question,\n loading,\n error,\n } = useQetaApi(api => api.getQuestion(id), [id]);\n\n const onAnswerPost = (answer: AnswerResponse) => {\n setNewAnswers(newAnswers.concat([answer]));\n };\n\n const getDescription = (q: QuestionResponse) => {\n return (\n <span>\n Asked{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\" sx={{ mr: 2 }}>\n <RelativeTime value={q.created} />\n </Box>\n {q.updated && (\n <React.Fragment>\n Updated{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\">\n <RelativeTime value={q.created} />\n </Box>\n </React.Fragment>\n )}\n Viewed{' '}\n <Box fontWeight=\"fontWeightMedium\" display=\"inline\">\n {q.views} times\n </Box>\n </span>\n );\n };\n\n if (loading) {\n return <Skeleton variant=\"rect\" height={200} />;\n }\n\n if (error || question === undefined) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load question.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n return (\n <Content>\n <ContentHeader\n title={question.title}\n // @ts-ignore\n description={getDescription(question)}\n >\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionCard question={question} />\n <Typography variant=\"h6\">\n {question.answersCount + newAnswers.length} answers\n </Typography>\n {(question.answers ?? []).concat(newAnswers).map(a => {\n return (\n <Box key={a.id} sx={{ mb: 1 }}>\n <AnswerCard answer={a} question={question} />\n <Divider />\n </Box>\n );\n })}\n <Divider />\n <AnswerForm question={question} onPost={onAnswerPost} />\n </Content>\n );\n};\n","import { QuestionResponse } from '../../../api';\nimport { Card, CardContent, Chip, Link, Typography } from '@material-ui/core';\nimport React from 'react';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\n\nexport const QuestionListItem = (props: { question: QuestionResponse }) => {\n const { question } = props;\n return (\n <Card>\n <CardContent>\n <Typography gutterBottom variant=\"h5\" component=\"div\">\n <Link href={`/qeta/questions/${question.id}`}>{question.title}</Link>\n </Typography>\n {question.tags &&\n question.tags.map(tag => (\n <Chip\n label={tag}\n size=\"small\"\n component=\"a\"\n href={`/qeta/tags/${tag}`}\n clickable\n />\n ))}\n <Typography variant=\"body2\" display=\"block\">\n By{' '}\n <Link href={`/qeta/users/${question.author}`}>{question.author}</Link>{' '}\n <RelativeTime\n value={question.created}\n titleFormat=\"YYYY/MM/DD HH:mm\"\n />\n </Typography>\n <Typography variant=\"caption\" display=\"inline\" gutterBottom>\n Score: {question.score} {' | '}\n </Typography>\n <Typography\n variant=\"caption\"\n color={question.correctAnswer ? 'secondary' : 'initial'}\n display=\"inline\"\n gutterBottom\n >\n Answers: {question.answersCount}\n </Typography>\n <Typography variant=\"caption\" display=\"inline\" gutterBottom>\n {' | '} Views: {question.views}\n </Typography>\n </CardContent>\n </Card>\n );\n};\n","import { useQetaApi, useStyles } from '../../../utils/hooks';\nimport { WarningPanel } from '@backstage/core-components';\nimport { Box, Divider, Grid } from '@material-ui/core';\nimport React from 'react';\nimport { QuestionListItem } from './QuestionListItem';\nimport { Pagination, Skeleton } from '@material-ui/lab';\n\nexport const QuestionList = (props: { tags?: string[]; author?: string }) => {\n const { tags, author } = props;\n const [page, setPage] = React.useState(1);\n const pageSize = 10;\n const offset = (page - 1) * pageSize;\n const styles = useStyles();\n\n const handleChange = (_event: React.ChangeEvent<unknown>, value: number) => {\n setPage(value);\n };\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api => api.getQuestions({ limit: pageSize, offset, tags, author }),\n [page, offset],\n );\n\n if (loading) {\n return <Skeleton variant=\"rect\" height={200} />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title=\"Could not load questions.\">\n {error?.message}\n </WarningPanel>\n );\n }\n\n if (response.questions.length === 0) {\n return <Box>No questions found</Box>;\n }\n\n const pageCount =\n response.total < pageSize ? 1 : Math.ceil(response.total / pageSize);\n\n return (\n <Box>\n <Grid container spacing={2}>\n {response.questions.map(question => {\n return (\n <Grid item xs={12} key={question.id}>\n <QuestionListItem question={question} />\n <Divider />\n </Grid>\n );\n })}\n </Grid>\n <Grid\n container\n spacing={0}\n className={styles.questionListPagination}\n direction=\"column\"\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Pagination\n page={page}\n onChange={handleChange}\n count={pageCount}\n size=\"large\"\n variant=\"outlined\"\n showFirstButton\n showLastButton\n />\n </Grid>\n </Box>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport { Content, ContentHeader } from '@backstage/core-components';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { QuestionList } from '../HomePage/QuestionList';\n\nexport const TagPage = () => {\n const { tag } = useParams();\n return (\n <Content>\n <ContentHeader title={`Questions tagged [${tag}]`}>\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList tags={[tag ?? '']} />\n </Content>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport { useParams } from 'react-router-dom';\nimport { Content, ContentHeader } from '@backstage/core-components';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { QuestionList } from '../HomePage/QuestionList';\n\nexport const UserPage = () => {\n const identity = useParams()['*'] ?? 'unknown';\n return (\n <Content>\n <ContentHeader title={`Questions by [${identity}]`}>\n <Button href=\"/qeta\">Back to questions</Button>\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList author={identity ?? ''} />\n </Content>\n );\n};\n","import React from 'react';\nimport { Button } from '@material-ui/core';\nimport {\n Content,\n ContentHeader,\n Header,\n HeaderLabel,\n Page,\n} from '@backstage/core-components';\nimport { Route } from 'react-router-dom';\nimport { Routes } from 'react-router';\nimport { AskPage } from '../AskPage';\nimport { QuestionPage } from '../QuestionPage/QuestionPage';\nimport { QuestionList } from './QuestionList/QuestionList';\nimport { TagPage } from '../TagPage/TagPage';\nimport { UserPage } from '../UserPage/UserPage';\n\nexport const HomePageContent = () => {\n return (\n <Content>\n <ContentHeader title=\"All questions\">\n <Button variant=\"contained\" href=\"/qeta/ask\">\n Ask question\n </Button>\n </ContentHeader>\n <QuestionList />\n </Content>\n );\n};\n\nexport const HomePage = () => (\n <Page themeId=\"tool\">\n <Header title=\"Q&A\">\n <HeaderLabel label=\"Lifecycle\" value=\"Alpha\" />\n </Header>\n <Routes>\n <Route path=\"/\" element={<HomePageContent />} />\n <Route path=\"/ask\" element={<AskPage />} />\n <Route path=\"/questions/:id\" element={<QuestionPage />} />\n <Route path=\"/tags/:tag\" element={<TagPage />} />\n <Route path=\"/users/*\" element={<UserPage />} />\n </Routes>\n </Page>\n);\n"],"names":[],"mappings":"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"}