@drodil/backstage-plugin-qeta 1.2.2 → 1.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.
@@ -1,9 +1,9 @@
1
- import { createRouteRef, createApiRef, createPlugin, createApiFactory, configApiRef, fetchApiRef, createRoutableExtension, useApi } from '@backstage/core-plugin-api';
1
+ import { createRouteRef, createApiRef, createPlugin, createApiFactory, configApiRef, fetchApiRef, createRoutableExtension, useApi, identityApiRef } from '@backstage/core-plugin-api';
2
2
  import { CustomErrorBase } from '@backstage/errors';
3
3
  import omitBy from 'lodash/omitBy';
4
4
  import isEmpty from 'lodash/isEmpty';
5
5
  import { useAsync } from 'react-use';
6
- import { makeStyles, Box, Grid, FormGroup, FormLabel, FormControlLabel, Checkbox, FormControl, RadioGroup, Radio, useTheme, Card, CardContent, Typography, Link, Chip, Button, Divider, Collapse, TextField } from '@material-ui/core';
6
+ import { makeStyles, Box, Grid, FormGroup, FormLabel, FormControlLabel, Checkbox, FormControl, RadioGroup, Radio, useTheme, Card, CardContent, Typography, Link, Chip, Button, Divider, Tooltip, Select, MenuItem, Collapse, TextField } from '@material-ui/core';
7
7
  import { catalogApiRef } from '@backstage/plugin-catalog-react';
8
8
  import React, { useEffect } from 'react';
9
9
  import { WarningPanel, MarkdownContent } from '@backstage/core-components';
@@ -14,8 +14,10 @@ import HelpOutline from '@material-ui/icons/HelpOutline';
14
14
  import FilterList from '@material-ui/icons/FilterList';
15
15
  import { useSearchParams, useNavigate } from 'react-router-dom';
16
16
  import { useForm, Controller } from 'react-hook-form';
17
- import 'react-mde/lib/styles/css/react-mde-all.css';
18
17
  import ReactMde from 'react-mde';
18
+ import 'react-mde/lib/styles/css/react-mde.css';
19
+ import 'react-mde/lib/styles/css/react-mde-editor.css';
20
+ import 'react-mde/lib/styles/css/react-mde-toolbar.css';
19
21
  import { compact } from 'lodash';
20
22
 
21
23
  const rootRouteRef = createRouteRef({
@@ -36,17 +38,6 @@ class QetaClient {
36
38
  this.fetchApi = options.fetchApi;
37
39
  this.baseUrl = options.configApi.getString("backend.baseUrl");
38
40
  }
39
- getQueryParameters(params) {
40
- const asStrings = Object.fromEntries(
41
- Object.entries(params).map(([k, v]) => {
42
- if (!v) {
43
- return [k, ""];
44
- }
45
- return [k, `${v}`];
46
- })
47
- );
48
- return new URLSearchParams(omitBy(asStrings, isEmpty));
49
- }
50
41
  async getQuestions(options) {
51
42
  const query = this.getQueryParameters(options).toString();
52
43
  let url = `${this.baseUrl}/api/qeta/questions`;
@@ -131,6 +122,32 @@ class QetaClient {
131
122
  }
132
123
  return data;
133
124
  }
125
+ async favoriteQuestion(id) {
126
+ if (!id) {
127
+ throw new QetaError("Invalid id provided", void 0);
128
+ }
129
+ const response = await this.fetchApi.fetch(
130
+ `${this.baseUrl}/api/qeta/questions/${id}/favorite`
131
+ );
132
+ const data = await response.json();
133
+ if ("errors" in data) {
134
+ throw new QetaError("Failed to fetch", data.errors);
135
+ }
136
+ return data;
137
+ }
138
+ async unfavoriteQuestion(id) {
139
+ if (!id) {
140
+ throw new QetaError("Invalid id provided", void 0);
141
+ }
142
+ const response = await this.fetchApi.fetch(
143
+ `${this.baseUrl}/api/qeta/questions/${id}/unfavorite`
144
+ );
145
+ const data = await response.json();
146
+ if ("errors" in data) {
147
+ throw new QetaError("Failed to fetch", data.errors);
148
+ }
149
+ return data;
150
+ }
134
151
  async postAnswer(answer) {
135
152
  const response = await this.fetchApi.fetch(
136
153
  `${this.baseUrl}/api/qeta/questions/${answer.questionId}/answers`,
@@ -261,6 +278,17 @@ class QetaClient {
261
278
  }
262
279
  return data;
263
280
  }
281
+ getQueryParameters(params) {
282
+ const asStrings = Object.fromEntries(
283
+ Object.entries(params).map(([k, v]) => {
284
+ if (!v) {
285
+ return [k, ""];
286
+ }
287
+ return [k, `${v}`];
288
+ })
289
+ );
290
+ return new URLSearchParams(omitBy(asStrings, isEmpty));
291
+ }
264
292
  }
265
293
 
266
294
  const qetaPlugin = createPlugin({
@@ -279,7 +307,7 @@ const qetaPlugin = createPlugin({
279
307
  const QetaPage = qetaPlugin.provide(
280
308
  createRoutableExtension({
281
309
  name: "QetaPage",
282
- component: () => import('./index-9a18f5f5.esm.js').then((m) => m.HomePage),
310
+ component: () => import('./index-92b6a51f.esm.js').then((m) => m.HomePage),
283
311
  mountPoint: rootRouteRef
284
312
  })
285
313
  );
@@ -290,6 +318,12 @@ function useQetaApi(f, deps = []) {
290
318
  return await f(qetaApi);
291
319
  }, deps);
292
320
  }
321
+ function useIdentityApi(f, deps = []) {
322
+ const identityApi = useApi(identityApiRef);
323
+ return useAsync(async () => {
324
+ return await f(identityApi);
325
+ }, deps);
326
+ }
293
327
  const useStyles = makeStyles((theme) => {
294
328
  return {
295
329
  markdownEditor: {
@@ -311,6 +345,14 @@ const useStyles = makeStyles((theme) => {
311
345
  color: `${theme.palette.text.primary} !important`
312
346
  }
313
347
  },
348
+ "& .mde-preview-content": {
349
+ padding: "0 10px 0px 10px"
350
+ },
351
+ "& .mde-text, .mde-preview": {
352
+ fontSize: theme.typography.body1.fontSize,
353
+ fontFamily: theme.typography.body1.fontFamily,
354
+ lineHeight: theme.typography.body1.lineHeight
355
+ },
314
356
  "& .mde-text": {
315
357
  backgroundColor: "initial",
316
358
  color: theme.palette.text.primary,
@@ -320,6 +362,11 @@ const useStyles = makeStyles((theme) => {
320
362
  markdownEditorError: {
321
363
  border: `1px solid ${theme.palette.error.main} !important`
322
364
  },
365
+ markdownContent: {
366
+ "& h1, h2, h3, h4, h5, h6": {
367
+ marginTop: 0
368
+ }
369
+ },
323
370
  successColor: {
324
371
  color: theme.palette.success.main
325
372
  },
@@ -344,6 +391,12 @@ const useStyles = makeStyles((theme) => {
344
391
  marginTop: theme.spacing(1),
345
392
  marginBottom: theme.spacing(1)
346
393
  },
394
+ questionsPerPageInput: {
395
+ paddingTop: "10px"
396
+ },
397
+ questionsPerPage: {
398
+ marginRight: theme.spacing(3)
399
+ },
347
400
  questionHighlightList: {
348
401
  width: "100%",
349
402
  border: `1px solid ${theme.palette.action.selected}`,
@@ -370,6 +423,9 @@ const useStyles = makeStyles((theme) => {
370
423
  marginRight: theme.spacing(1)
371
424
  }
372
425
  },
426
+ menuIcon: {
427
+ minWidth: "26px"
428
+ },
373
429
  deleteModal: {
374
430
  position: "absolute",
375
431
  top: "20%",
@@ -531,12 +587,22 @@ const QuestionListItem = (props) => {
531
587
  };
532
588
 
533
589
  const QuestionList = (props) => {
534
- const { loading, error, response, onPageChange, entity, page } = props;
535
- const pageSize = 10;
590
+ const {
591
+ loading,
592
+ error,
593
+ response,
594
+ onPageChange,
595
+ entity,
596
+ page,
597
+ onPageSizeChange
598
+ } = props;
536
599
  const styles = useStyles();
537
- const handleChange = (_event, value) => {
600
+ const handlePageChange = (_event, value) => {
538
601
  onPageChange(value);
539
602
  };
603
+ const handlePageSizeChange = (event) => {
604
+ onPageSizeChange(Number.parseInt(event.target.value, 10));
605
+ };
540
606
  if (loading) {
541
607
  return /* @__PURE__ */ React.createElement(Skeleton, { variant: "rect", height: 200 });
542
608
  }
@@ -557,13 +623,15 @@ const QuestionList = (props) => {
557
623
  Button,
558
624
  {
559
625
  href: entity ? `/qeta/ask?entity=${entity}` : "/qeta/ask",
560
- startIcon: /* @__PURE__ */ React.createElement(HelpOutline, null)
626
+ startIcon: /* @__PURE__ */ React.createElement(HelpOutline, null),
627
+ color: "primary",
628
+ variant: "outlined"
561
629
  },
562
630
  "Go ahead and ask one!"
563
631
  ))
564
632
  );
565
633
  }
566
- const pageCount = response.total < pageSize ? 1 : Math.ceil(response.total / pageSize);
634
+ const pageCount = response.total < props.pageSize ? 1 : Math.ceil(response.total / props.pageSize);
567
635
  return /* @__PURE__ */ React.createElement(Box, { sx: { mt: 2 } }, /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 2 }, response.questions.map((question) => {
568
636
  return /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12, key: question.id }, /* @__PURE__ */ React.createElement(QuestionListItem, { question }), /* @__PURE__ */ React.createElement(Divider, null));
569
637
  })), /* @__PURE__ */ React.createElement(
@@ -572,15 +640,28 @@ const QuestionList = (props) => {
572
640
  container: true,
573
641
  spacing: 0,
574
642
  className: styles.questionListPagination,
575
- direction: "column",
576
643
  alignItems: "center",
577
- justifyContent: "center"
644
+ justifyContent: "space-between"
578
645
  },
646
+ /* @__PURE__ */ React.createElement(Tooltip, { title: "Questions per page", arrow: true }, /* @__PURE__ */ React.createElement(FormControl, { variant: "filled" }, /* @__PURE__ */ React.createElement(
647
+ Select,
648
+ {
649
+ value: props.pageSize,
650
+ onChange: handlePageSizeChange,
651
+ className: styles.questionsPerPage,
652
+ inputProps: { className: styles.questionsPerPageInput }
653
+ },
654
+ /* @__PURE__ */ React.createElement(MenuItem, { value: 5 }, "5"),
655
+ /* @__PURE__ */ React.createElement(MenuItem, { value: 10 }, "10"),
656
+ /* @__PURE__ */ React.createElement(MenuItem, { value: 25 }, "25"),
657
+ /* @__PURE__ */ React.createElement(MenuItem, { value: 50 }, "50"),
658
+ /* @__PURE__ */ React.createElement(MenuItem, { value: 100 }, "100")
659
+ ))),
579
660
  /* @__PURE__ */ React.createElement(
580
661
  Pagination,
581
662
  {
582
663
  page,
583
- onChange: handleChange,
664
+ onChange: handlePageChange,
584
665
  count: pageCount,
585
666
  size: "large",
586
667
  variant: "outlined",
@@ -593,8 +674,9 @@ const QuestionList = (props) => {
593
674
 
594
675
  const QuestionsContainer = (props) => {
595
676
  var _a;
596
- const { tags, author, entity, showFilters, showTitle, title } = props;
677
+ const { tags, author, entity, showFilters, showTitle, title, favorite } = props;
597
678
  const [page, setPage] = React.useState(1);
679
+ const [questionsPerPage, setQuestionsPerPage] = React.useState(10);
598
680
  const [showFilterPanel, setShowFilterPanel] = React.useState(false);
599
681
  const [searchParams, setSearchParams] = useSearchParams();
600
682
  const [filters, setFilters] = React.useState({
@@ -604,8 +686,6 @@ const QuestionsContainer = (props) => {
604
686
  noCorrectAnswer: "false",
605
687
  noVotes: "false"
606
688
  });
607
- const pageSize = 10;
608
- const offset = (page - 1) * pageSize;
609
689
  const onPageChange = (value) => {
610
690
  setPage(value);
611
691
  setSearchParams((prev) => {
@@ -626,11 +706,23 @@ const QuestionsContainer = (props) => {
626
706
  useEffect(() => {
627
707
  let filtersApplied = false;
628
708
  searchParams.forEach((value, key) => {
629
- if (key === "page") {
630
- setPage(Number.parseInt(value, 10));
631
- } else if (key in filterKeys) {
632
- filtersApplied = true;
633
- filters[key] = value;
709
+ try {
710
+ if (key === "page") {
711
+ const pv = Number.parseInt(value, 10);
712
+ if (pv > 0) {
713
+ setPage(pv);
714
+ } else {
715
+ setPage(1);
716
+ }
717
+ } else if (key === "questionsPerPage") {
718
+ const qpp = Number.parseInt(value, 10);
719
+ if (qpp > 0)
720
+ setQuestionsPerPage(qpp);
721
+ } else if (key in filterKeys) {
722
+ filtersApplied = true;
723
+ filters[key] = value;
724
+ }
725
+ } catch (_e) {
634
726
  }
635
727
  });
636
728
  setFilters(filters);
@@ -644,15 +736,31 @@ const QuestionsContainer = (props) => {
644
736
  error
645
737
  } = useQetaApi(
646
738
  (api) => api.getQuestions({
647
- limit: pageSize,
648
- offset,
739
+ limit: questionsPerPage,
740
+ offset: (page - 1) * questionsPerPage,
649
741
  tags,
650
742
  entity,
651
743
  author,
744
+ favorite,
652
745
  ...filters
653
746
  }),
654
- [page, offset, filters]
747
+ [page, filters, questionsPerPage]
655
748
  );
749
+ const onPageSizeChange = (value) => {
750
+ if (response) {
751
+ let newPage = page;
752
+ while (newPage * value > response.total) {
753
+ newPage -= 1;
754
+ }
755
+ onPageChange(Math.max(1, newPage));
756
+ }
757
+ setQuestionsPerPage(value);
758
+ setSearchParams((prev) => {
759
+ const newValue = prev;
760
+ newValue.set("questionsPerPage", String(value));
761
+ return newValue;
762
+ });
763
+ };
656
764
  let shownTitle = title;
657
765
  if (author) {
658
766
  shownTitle = `Questions by ${formatEntityName(author)}`;
@@ -660,6 +768,8 @@ const QuestionsContainer = (props) => {
660
768
  shownTitle = `Questions about ${formatEntityName(entity)}`;
661
769
  } else if (tags) {
662
770
  shownTitle = `Questions tagged with [${tags.join(", ")}]`;
771
+ } else if (favorite) {
772
+ shownTitle = "Your favorite questions";
663
773
  }
664
774
  return /* @__PURE__ */ React.createElement(Box, null, showTitle && /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, shownTitle), /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, `${(_a = response == null ? void 0 : response.total) != null ? _a : 0} questions`)), (showFilters != null ? showFilters : true) && /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(
665
775
  Button,
@@ -675,8 +785,10 @@ const QuestionsContainer = (props) => {
675
785
  error,
676
786
  response,
677
787
  onPageChange,
788
+ onPageSizeChange,
678
789
  entity,
679
- page
790
+ page,
791
+ pageSize: questionsPerPage
680
792
  }
681
793
  ));
682
794
  };
@@ -699,9 +811,23 @@ const MarkdownEditor = (props) => {
699
811
  selectedTab,
700
812
  onTabChange: setSelectedTab,
701
813
  minEditorHeight: height,
702
- minPreviewHeight: height,
703
- childProps: { textArea: { required: true, placeholder } },
704
- generateMarkdownPreview: (content) => Promise.resolve(/* @__PURE__ */ React.createElement(MarkdownContent, { content }))
814
+ minPreviewHeight: height - 10,
815
+ childProps: {
816
+ textArea: {
817
+ required: true,
818
+ placeholder
819
+ }
820
+ },
821
+ generateMarkdownPreview: (content) => Promise.resolve(
822
+ /* @__PURE__ */ React.createElement(
823
+ MarkdownContent,
824
+ {
825
+ content,
826
+ dialect: "gfm",
827
+ className: styles.markdownContent
828
+ }
829
+ )
830
+ )
705
831
  }
706
832
  );
707
833
  };
@@ -943,8 +1069,17 @@ const AskForm = (props) => {
943
1069
  ),
944
1070
  name: "entities"
945
1071
  }
946
- ), /* @__PURE__ */ React.createElement(Button, { type: "submit", variant: "contained", className: styles.postButton }, id ? "Save" : "Post"));
1072
+ ), /* @__PURE__ */ React.createElement(
1073
+ Button,
1074
+ {
1075
+ color: "primary",
1076
+ type: "submit",
1077
+ variant: "contained",
1078
+ className: styles.postButton
1079
+ },
1080
+ id ? "Save" : "Post"
1081
+ ));
947
1082
  };
948
1083
 
949
- export { AskForm as A, MarkdownEditor as M, QuestionsContainer as Q, getEntityUrl as a, useQetaApi as b, qetaPlugin as c, QetaPage as d, QetaClient as e, formatEntityName as f, getEntityTitle as g, qetaApiRef as q, useStyles as u };
950
- //# sourceMappingURL=index-074b9dc0.esm.js.map
1084
+ export { AskForm as A, MarkdownEditor as M, QuestionsContainer as Q, getEntityUrl as a, useQetaApi as b, useIdentityApi as c, qetaPlugin as d, QetaPage as e, formatEntityName as f, getEntityTitle as g, QetaClient as h, qetaApiRef as q, useStyles as u };
1085
+ //# sourceMappingURL=index-4ddf1732.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-4ddf1732.esm.js","sources":["../../src/routes.ts","../../src/api/QetaClient.ts","../../src/plugin.ts","../../src/utils/hooks.ts","../../src/components/QuestionsContainer/FilterPanel.tsx","../../src/utils/utils.ts","../../src/components/QuestionsContainer/QuestionListItem.tsx","../../src/components/QuestionsContainer/QuestionList.tsx","../../src/components/QuestionsContainer/QuestionsContainer.tsx","../../src/components/MarkdownEditor/MarkdownEditor.tsx","../../src/components/AskForm/AskForm.tsx"],"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 TagResponse,\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 = this.getQueryParameters(options).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 getQuestionsList(type: string): Promise<QuestionsResponse> {\n const query = new URLSearchParams({ limit: '7' }).toString();\n\n let url = `${this.baseUrl}/api/qeta/questions/list/${type}`;\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<TagResponse[]> {\n const response = await this.fetchApi.fetch(`${this.baseUrl}/api/qeta/tags`);\n return (await response.json()) as TagResponse[];\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 favoriteQuestion(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}/favorite`,\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 unfavoriteQuestion(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}/unfavorite`,\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 async deleteQuestion(questionId: number): Promise<boolean> {\n if (!questionId) {\n throw new QetaError('Invalid id provided', undefined);\n }\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${questionId}`,\n {\n method: 'DELETE',\n },\n );\n const data = await response;\n return data.ok;\n }\n\n async deleteAnswer(questionId: number, id: number): Promise<boolean> {\n if (!questionId || !id) {\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}`,\n {\n method: 'DELETE',\n },\n );\n const data = await response;\n return data.ok;\n }\n\n async updateQuestion(\n id: string,\n question: QuestionRequest,\n ): Promise<QuestionResponse> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${id}`,\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 update', data.errors);\n }\n\n return data;\n }\n\n async updateAnswer(\n id: number,\n answer: AnswerRequest,\n ): Promise<AnswerResponseBody> {\n const response = await this.fetchApi.fetch(\n `${this.baseUrl}/api/qeta/questions/${answer.questionId}/answers/${id}`,\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 getAnswer(\n questionId: string | number | undefined,\n id: string | number | undefined,\n ): Promise<AnswerResponseBody> {\n if (!questionId || !id) {\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}`,\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 private getQueryParameters(params: any): URLSearchParams {\n const asStrings = Object.fromEntries(\n Object.entries(params).map(([k, v]) => {\n if (!v) {\n return [k, ''];\n }\n return [k, `${v}`];\n }),\n );\n return new URLSearchParams(omitBy(asStrings, isEmpty));\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","import { QetaApi, qetaApiRef } from '../api';\nimport { useAsync } from 'react-use';\nimport {\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 { catalogApiRef } from '@backstage/plugin-catalog-react';\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 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: '0 10px 0px 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 },\n markdownEditorError: {\n border: `1px solid ${theme.palette.error.main} !important`,\n },\n markdownContent: {\n '& h1, h2, h3, h4, h5, h6': {\n marginTop: 0,\n },\n },\n successColor: {\n color: theme.palette.success.main,\n },\n questionCardVote: {\n textAlign: 'center',\n width: '50px',\n marginRight: '20px',\n display: 'inline-block',\n verticalAlign: 'top',\n },\n questionCardContent: {\n display: 'inline-block',\n width: 'calc(100% - 70px)',\n },\n questionCardAuthor: {\n textAlign: 'right',\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 width: '100%',\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 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 };\n});\n","import React from 'react';\nimport {\n Box,\n Checkbox,\n FormControl,\n FormControlLabel,\n FormGroup,\n FormLabel,\n Grid,\n Radio,\n RadioGroup,\n} from '@material-ui/core';\nimport { useStyles } from '../../utils/hooks';\n\nconst radioSelect = (value: string, label: string) => {\n return (\n <FormControlLabel\n value={value}\n control={<Radio size=\"small\" />}\n label={label}\n />\n );\n};\n\nexport const filterKeys = [\n 'orderBy',\n 'order',\n 'noAnswers',\n 'noCorrectAnswer',\n 'noVotes',\n] as const;\nexport type FilterKey = typeof filterKeys[number];\n\nexport interface FilterPanelProps {\n onChange: (key: FilterKey, value: string) => void;\n filters: Record<FilterKey, string>;\n}\n\nexport const FilterPanel = (props: FilterPanelProps) => {\n const { onChange, filters } = props;\n const styles = useStyles();\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n let value = event.target.value;\n if (event.target.type === 'checkbox') {\n value = event.target.checked ? 'true' : 'false';\n }\n onChange(event.target.name as FilterKey, value);\n };\n\n return (\n <Box className={styles.filterPanel}>\n <Grid container spacing={4}>\n <Grid item>\n <FormGroup>\n <FormLabel id=\"qeta-filter-order-by\">Filter</FormLabel>\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n name=\"noAnswers\"\n onChange={handleChange}\n checked={filters.noAnswers === 'true'}\n />\n }\n label=\"No answers\"\n />\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n name=\"noCorrectAnswer\"\n checked={filters.noCorrectAnswer === 'true'}\n onChange={handleChange}\n />\n }\n label=\"No correct answers\"\n />\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n name=\"noVotes\"\n checked={filters.noVotes === 'true'}\n onChange={handleChange}\n />\n }\n label=\"No votes\"\n />\n </FormGroup>\n </Grid>\n <Grid item>\n <FormControl>\n <FormLabel id=\"qeta-filter-order-by\">Order by</FormLabel>\n <RadioGroup\n aria-labelledby=\"qeta-filter-order-by\"\n name=\"orderBy\"\n value={filters.orderBy}\n onChange={handleChange}\n >\n {radioSelect('created', 'Created')}\n {radioSelect('views', 'Views')}\n {radioSelect('score', 'Score')}\n {radioSelect('answersCount', 'Answers')}\n </RadioGroup>\n </FormControl>\n </Grid>\n <Grid item>\n <FormControl>\n <FormLabel id=\"qeta-filter-order\">Order</FormLabel>\n <RadioGroup\n aria-labelledby=\"qeta-filter-order\"\n name=\"order\"\n value={filters.order}\n onChange={handleChange}\n >\n {radioSelect('desc', 'Descending')}\n {radioSelect('asc', 'Ascending')}\n </RadioGroup>\n </FormControl>\n </Grid>\n </Grid>\n </Box>\n );\n};\n","import { Entity, stringifyEntityRef } from '@backstage/catalog-model';\n\nexport const getEntityUrl = (entity: Entity) => {\n return `/catalog/${entity.metadata.namespace ?? 'default'}/${entity.kind}/${\n entity.metadata.name\n }`.toLowerCase();\n};\n\nexport const formatEntityName = (username: string) => {\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","import { QuestionResponse } from '../../api';\nimport {\n Card,\n CardContent,\n Chip,\n Link,\n Typography,\n useTheme,\n} from '@material-ui/core';\nimport React from 'react';\n// @ts-ignore\nimport RelativeTime from 'react-relative-time';\nimport { formatEntityName } from '../../utils/utils';\n\nexport const QuestionListItem = (props: { question: QuestionResponse }) => {\n const { question } = props;\n const theme = useTheme();\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 key={tag}\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}`}>\n {formatEntityName(question.author)}\n </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 style={{\n color: question.correctAnswer\n ? theme.palette.success.main\n : undefined,\n }}\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 { useStyles } from '../../utils/hooks';\nimport { WarningPanel } from '@backstage/core-components';\nimport {\n Box,\n Button,\n Divider,\n FormControl,\n Grid,\n MenuItem,\n Select,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { QuestionListItem } from './QuestionListItem';\nimport { Pagination, Skeleton } from '@material-ui/lab';\nimport { QuestionsResponse } from '../../api';\nimport HelpOutline from '@material-ui/icons/HelpOutline';\n\nexport const QuestionList = (props: {\n loading: boolean;\n error: any;\n response?: QuestionsResponse;\n onPageChange: (page: number) => void;\n onPageSizeChange: (size: number) => void;\n page: number;\n pageSize: number;\n entity?: string;\n}) => {\n const {\n loading,\n error,\n response,\n onPageChange,\n entity,\n page,\n onPageSizeChange,\n } = props;\n const styles = useStyles();\n\n const handlePageChange = (\n _event: React.ChangeEvent<unknown>,\n value: number,\n ) => {\n onPageChange(value);\n };\n\n const handlePageSizeChange = (\n event: React.ChangeEvent<{ value: unknown }>,\n ) => {\n onPageSizeChange(Number.parseInt(event.target.value as string, 10));\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 (\n <Grid\n container\n justifyContent=\"center\"\n alignItems=\"center\"\n direction=\"column\"\n >\n <Grid item>\n <Typography variant=\"h6\">No questions found</Typography>\n </Grid>\n <Grid item>\n <Button\n href={entity ? `/qeta/ask?entity=${entity}` : '/qeta/ask'}\n startIcon={<HelpOutline />}\n color=\"primary\"\n variant=\"outlined\"\n >\n Go ahead and ask one!\n </Button>\n </Grid>\n </Grid>\n );\n }\n\n const pageCount =\n response.total < props.pageSize\n ? 1\n : Math.ceil(response.total / props.pageSize);\n\n return (\n <Box sx={{ mt: 2 }}>\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 alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Tooltip title=\"Questions per page\" arrow>\n <FormControl variant=\"filled\">\n <Select\n value={props.pageSize}\n onChange={handlePageSizeChange}\n className={styles.questionsPerPage}\n inputProps={{ className: styles.questionsPerPageInput }}\n >\n <MenuItem value={5}>5</MenuItem>\n <MenuItem value={10}>10</MenuItem>\n <MenuItem value={25}>25</MenuItem>\n <MenuItem value={50}>50</MenuItem>\n <MenuItem value={100}>100</MenuItem>\n </Select>\n </FormControl>\n </Tooltip>\n <Pagination\n page={page}\n onChange={handlePageChange}\n count={pageCount}\n size=\"large\"\n variant=\"outlined\"\n showFirstButton\n showLastButton\n />\n </Grid>\n </Box>\n );\n};\n","import { useQetaApi } from '../../utils/hooks';\nimport { Box, Button, Collapse, Grid, Typography } from '@material-ui/core';\nimport React, { useEffect } from 'react';\nimport { FilterKey, filterKeys, FilterPanel } from './FilterPanel';\nimport { QuestionList } from './QuestionList';\nimport FilterList from '@material-ui/icons/FilterList';\nimport { useSearchParams } from 'react-router-dom';\nimport { formatEntityName } from '../../utils/utils';\n\nexport interface QuestionsContainerProps {\n tags?: string[];\n author?: string;\n entity?: string;\n showFilters?: boolean;\n showTitle?: boolean;\n title?: string;\n favorite?: boolean;\n}\nexport const QuestionsContainer = (props: QuestionsContainerProps) => {\n const { tags, author, entity, showFilters, showTitle, title, favorite } =\n props;\n const [page, setPage] = React.useState(1);\n const [questionsPerPage, setQuestionsPerPage] = React.useState(10);\n const [showFilterPanel, setShowFilterPanel] = React.useState(false);\n const [searchParams, setSearchParams] = useSearchParams();\n const [filters, setFilters] = React.useState({\n order: 'desc',\n orderBy: 'created',\n noAnswers: 'false',\n noCorrectAnswer: 'false',\n noVotes: 'false',\n });\n\n const onPageChange = (value: number) => {\n setPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('page', String(value));\n return newValue;\n });\n };\n\n const onFilterChange = (key: FilterKey, value: string) => {\n onPageChange(1);\n setFilters({ ...filters, ...{ [key]: value } });\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set(key, value);\n return newValue;\n });\n };\n\n useEffect(() => {\n let filtersApplied = false;\n searchParams.forEach((value, key) => {\n try {\n if (key === 'page') {\n const pv = Number.parseInt(value, 10);\n if (pv > 0) {\n setPage(pv);\n } else {\n setPage(1);\n }\n } else if (key === 'questionsPerPage') {\n const qpp = Number.parseInt(value, 10);\n if (qpp > 0) setQuestionsPerPage(qpp);\n } else if (key in filterKeys) {\n filtersApplied = true;\n filters[key as FilterKey] = value;\n }\n } catch (_e) {\n // NOOP\n }\n });\n setFilters(filters);\n if (filtersApplied) {\n setShowFilterPanel(true);\n }\n }, [searchParams, filters]);\n\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api =>\n api.getQuestions({\n limit: questionsPerPage,\n offset: (page - 1) * questionsPerPage,\n tags,\n entity,\n author,\n favorite,\n ...filters,\n }),\n [page, filters, questionsPerPage],\n );\n\n const onPageSizeChange = (value: number) => {\n if (response) {\n let newPage = page;\n while (newPage * value > response.total) {\n newPage -= 1;\n }\n onPageChange(Math.max(1, newPage));\n }\n setQuestionsPerPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('questionsPerPage', String(value));\n return newValue;\n });\n };\n\n let shownTitle = title;\n if (author) {\n shownTitle = `Questions by ${formatEntityName(author)}`;\n } else if (entity) {\n shownTitle = `Questions about ${formatEntityName(entity)}`;\n } else if (tags) {\n shownTitle = `Questions tagged with [${tags.join(', ')}]`;\n } else if (favorite) {\n shownTitle = 'Your favorite questions';\n }\n\n return (\n <Box>\n {showTitle && <Typography variant=\"h5\">{shownTitle}</Typography>}\n <Grid container justifyContent=\"space-between\">\n <Grid item>\n <Typography variant=\"h6\">{`${\n response?.total ?? 0\n } questions`}</Typography>\n </Grid>\n {(showFilters ?? true) && (\n <Grid item>\n <Button\n onClick={() => setShowFilterPanel(!showFilterPanel)}\n startIcon={<FilterList />}\n >\n Filter\n </Button>\n </Grid>\n )}\n </Grid>\n {(showFilters ?? true) && (\n <Collapse in={showFilterPanel}>\n <FilterPanel onChange={onFilterChange} filters={filters} />\n </Collapse>\n )}\n\n <QuestionList\n loading={loading}\n error={error}\n response={response}\n onPageChange={onPageChange}\n onPageSizeChange={onPageSizeChange}\n entity={entity}\n page={page}\n pageSize={questionsPerPage}\n />\n </Box>\n );\n};\n","import React from 'react';\nimport ReactMde from 'react-mde';\nimport { MarkdownContent } from '@backstage/core-components';\nimport 'react-mde/lib/styles/css/react-mde.css';\nimport 'react-mde/lib/styles/css/react-mde-editor.css';\nimport 'react-mde/lib/styles/css/react-mde-toolbar.css';\nimport { useStyles } from '../../utils/hooks';\n\nexport const MarkdownEditor = (props: {\n value: string;\n onChange: (value: string) => void;\n height: number;\n error?: boolean;\n placeholder?: string;\n}) => {\n const { value, onChange, height, error, placeholder } = props;\n const [selectedTab, setSelectedTab] = React.useState<'write' | 'preview'>(\n 'write',\n );\n const styles = useStyles();\n\n return (\n <ReactMde\n classes={{\n reactMde: styles.markdownEditor,\n textArea: error ? styles.markdownEditorError : undefined,\n }}\n value={value}\n onChange={onChange}\n selectedTab={selectedTab}\n onTabChange={setSelectedTab}\n minEditorHeight={height}\n minPreviewHeight={height - 10}\n childProps={{\n textArea: {\n required: true,\n placeholder,\n },\n }}\n generateMarkdownPreview={content =>\n Promise.resolve(\n <MarkdownContent\n content={content}\n dialect=\"gfm\"\n className={styles.markdownContent}\n />,\n )\n }\n />\n );\n};\n","import { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Button, TextField } from '@material-ui/core';\nimport { Alert, Autocomplete } from '@material-ui/lab';\nimport React, { useEffect } from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n QetaApi,\n qetaApiRef,\n QuestionRequest,\n QuestionResponse,\n} from '../../api';\nimport { useStyles } from '../../utils/hooks';\nimport { MarkdownEditor } from '../MarkdownEditor/MarkdownEditor';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { getEntityTitle } from '../../utils/utils';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { compact } from 'lodash';\n\ninterface QuestionForm {\n title: string;\n content: string;\n tags?: string[];\n entities?: Entity[];\n}\n\nconst formToRequest = (form: QuestionForm): QuestionRequest => {\n return {\n ...form,\n entities: form.entities?.map(stringifyEntityRef),\n };\n};\n\nconst getDefaultValues = (): QuestionForm => {\n return {\n title: '',\n content: '',\n tags: [],\n entities: [],\n };\n};\n\nconst getValues = async (\n api: QetaApi,\n catalogApi: CatalogApi,\n id?: string,\n): Promise<QuestionForm> => {\n if (!id) {\n return getDefaultValues();\n }\n\n const question = await api.getQuestion(id);\n const entities = question.entities\n ? await catalogApi.getEntitiesByRefs({\n entityRefs: question.entities,\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n ],\n })\n : [];\n return {\n title: question.title,\n content: question.content,\n tags: question.tags ?? [],\n entities: 'items' in entities ? compact(entities.items) : [],\n };\n};\n\nexport const AskForm = (props: {\n id?: string;\n entity?: string;\n onPost?: (question: QuestionResponse) => void;\n}) => {\n const { id, entity, onPost } = props;\n const navigate = useNavigate();\n const [entityRef, setEntityRef] = React.useState(entity);\n const [values, setValues] = React.useState(getDefaultValues());\n const [error, setError] = React.useState(false);\n const [availableTags, setAvailableTags] = React.useState<string[] | null>([]);\n const [searchParams, _setSearchParams] = useSearchParams();\n const [availableEntities, setAvailableEntities] = React.useState<\n Entity[] | null\n >([]);\n\n const qetaApi = useApi(qetaApiRef);\n const catalogApi = useApi(catalogApiRef);\n const configApi = useApi(configApiRef);\n const styles = useStyles();\n const {\n register,\n handleSubmit,\n control,\n reset,\n formState: { errors },\n } = useForm<QuestionForm>({\n values,\n defaultValues: getDefaultValues(),\n });\n\n const postQuestion = (data: QuestionForm) => {\n if (id) {\n qetaApi\n .updateQuestion(id, formToRequest(data))\n .then(q => {\n if (!q || !q.id) {\n setError(true);\n return;\n }\n reset();\n if (onPost) {\n onPost(q);\n } else {\n navigate(`/qeta/questions/${q.id}`);\n }\n })\n .catch(_e => setError(true));\n return;\n }\n qetaApi\n .postQuestion(formToRequest(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 if (!entityRef) {\n const e = searchParams.get('entity');\n if (e) {\n setEntityRef(e);\n }\n }\n }, [entityRef, searchParams]);\n\n useEffect(() => {\n if (id) {\n getValues(qetaApi, catalogApi, id).then(data => {\n setValues(data);\n });\n }\n }, [qetaApi, catalogApi, id]);\n\n useEffect(() => {\n if (entityRef) {\n catalogApi.getEntityByRef(entityRef).then(data => {\n if (data) {\n setValues(v => {\n return { ...v, entities: [data] };\n });\n setAvailableEntities([data]);\n }\n });\n }\n }, [catalogApi, entityRef]);\n\n useEffect(() => {\n reset(values);\n }, [values, reset]);\n\n useEffect(() => {\n qetaApi\n .getTags()\n .catch(_ => setAvailableTags(null))\n .then(data =>\n data\n ? setAvailableTags(data.map(tag => tag.tag))\n : setAvailableTags(null),\n );\n }, [qetaApi]);\n\n useEffect(() => {\n if (entityRef) {\n return;\n }\n let entityKinds = configApi.getOptionalStringArray('qeta.entityKinds');\n if (!entityKinds) {\n entityKinds = ['Component'];\n }\n\n catalogApi\n .getEntities({\n filter: { kind: entityKinds },\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n ],\n })\n .catch(_ => setAvailableEntities(null))\n .then(data =>\n data ? setAvailableEntities(data.items) : setAvailableEntities(null),\n );\n }, [catalogApi, entityRef, configApi]);\n\n return (\n <form onSubmit={handleSubmit(postQuestion)}>\n {error && <Alert severity=\"error\">Could not post question</Alert>}\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 {\n // @ts-ignore\n ...register('title', { required: true, maxLength: 255 })\n }\n />\n <Controller\n control={control}\n rules={{\n required: true,\n }}\n render={({ field: { onChange, value } }) => (\n <MarkdownEditor\n value={value}\n onChange={onChange}\n height={400}\n error={'content' in errors}\n placeholder=\"Your question\"\n />\n )}\n name=\"content\"\n />\n {availableTags && (\n <Controller\n control={control}\n render={({ field: { onChange, value } }) => (\n <Autocomplete\n multiple\n id=\"tags-select\"\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 )}\n {availableEntities && (\n <Controller\n control={control}\n render={({ field: { onChange, value } }) => (\n <Autocomplete\n multiple\n hidden={!!entityRef}\n value={value}\n id=\"entities-select\"\n options={availableEntities}\n getOptionLabel={getEntityTitle}\n getOptionSelected={(o, v) =>\n stringifyEntityRef(o) === stringifyEntityRef(v)\n }\n onChange={(_e, newValue) => {\n if (!value || value.length < 3) {\n onChange(newValue);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label=\"Entities\"\n placeholder=\"Type or select entities\"\n helperText=\"Add up to 3 entities this question relates to\"\n />\n )}\n />\n )}\n name=\"entities\"\n />\n )}\n <Button\n color=\"primary\"\n type=\"submit\"\n variant=\"contained\"\n className={styles.postButton}\n >\n {id ? 'Save' : 'Post'}\n </Button>\n </form>\n );\n};\n"],"names":[],"mappings":"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"}