@drodil/backstage-plugin-qeta-react 3.14.0 → 3.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AnswersContainer/AnswerListItem.esm.js +70 -38
- package/dist/components/AnswersContainer/AnswerListItem.esm.js.map +1 -1
- package/dist/components/CollectionsGrid/CollectionsGrid.esm.js +4 -2
- package/dist/components/CollectionsGrid/CollectionsGrid.esm.js.map +1 -1
- package/dist/components/CollectionsGrid/CollectionsGridItem.esm.js +4 -1
- package/dist/components/CollectionsGrid/CollectionsGridItem.esm.js.map +1 -1
- package/dist/components/DeleteModal/DeleteModal.esm.js +24 -5
- package/dist/components/DeleteModal/DeleteModal.esm.js.map +1 -1
- package/dist/components/EntitiesGrid/EntitiesGridItem.esm.js +4 -1
- package/dist/components/EntitiesGrid/EntitiesGridItem.esm.js.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.esm.js +0 -1
- package/dist/components/FilterPanel/FilterPanel.esm.js.map +1 -1
- package/dist/components/LeftMenu/LeftMenuButton.esm.js +3 -1
- package/dist/components/LeftMenu/LeftMenuButton.esm.js.map +1 -1
- package/dist/components/PostForm/TagInput.esm.js +20 -22
- package/dist/components/PostForm/TagInput.esm.js.map +1 -1
- package/dist/components/PostsContainer/NoPostsCard.esm.js +2 -2
- package/dist/components/PostsContainer/NoPostsCard.esm.js.map +1 -1
- package/dist/components/PostsContainer/PostsContainer.esm.js +5 -3
- package/dist/components/PostsContainer/PostsContainer.esm.js.map +1 -1
- package/dist/components/PostsGrid/PostsGrid.esm.js +2 -1
- package/dist/components/PostsGrid/PostsGrid.esm.js.map +1 -1
- package/dist/components/TagsAndEntities/EntityChip.esm.js +7 -4
- package/dist/components/TagsAndEntities/EntityChip.esm.js.map +1 -1
- package/dist/components/TagsAndEntities/TagChip.esm.js +4 -1
- package/dist/components/TagsAndEntities/TagChip.esm.js.map +1 -1
- package/dist/components/TagsAndEntities/UserChip.esm.js +7 -4
- package/dist/components/TagsAndEntities/UserChip.esm.js.map +1 -1
- package/dist/components/TagsGrid/CreateTagModal.esm.js +92 -0
- package/dist/components/TagsGrid/CreateTagModal.esm.js.map +1 -0
- package/dist/components/TagsGrid/EditTagModal.esm.js +2 -1
- package/dist/components/TagsGrid/EditTagModal.esm.js.map +1 -1
- package/dist/components/TagsGrid/TagGridItem.esm.js +34 -2
- package/dist/components/TagsGrid/TagGridItem.esm.js.map +1 -1
- package/dist/components/TagsGrid/TagsGrid.esm.js +28 -4
- package/dist/components/TagsGrid/TagsGrid.esm.js.map +1 -1
- package/dist/components/UsersGrid/UsersGridItem.esm.js +4 -1
- package/dist/components/UsersGrid/UsersGridItem.esm.js.map +1 -1
- package/dist/components/Utility/ModalContent.esm.js +1 -1
- package/dist/components/Utility/ModalContent.esm.js.map +1 -1
- package/dist/index.d.ts +20 -6
- package/dist/translation.esm.js +12 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +2 -2
- package/dist/hooks/useBasePath.esm.js +0 -12
- package/dist/hooks/useBasePath.esm.js.map +0 -1
- package/dist/hooks/useBaseUrl.esm.js +0 -13
- package/dist/hooks/useBaseUrl.esm.js.map +0 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Modal, Backdrop, Typography, Grid, TextField, Button } from '@material-ui/core';
|
|
2
|
+
import { Alert } from '@material-ui/lab';
|
|
3
|
+
import React__default from 'react';
|
|
4
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
5
|
+
import { qetaApiRef } from '../../api.esm.js';
|
|
6
|
+
import 'react-use';
|
|
7
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
8
|
+
import '@backstage/catalog-model';
|
|
9
|
+
import 'dataloader';
|
|
10
|
+
import '@backstage/plugin-catalog-react';
|
|
11
|
+
import 'react-use/lib/useAsync';
|
|
12
|
+
import { ModalContent } from '../Utility/ModalContent.esm.js';
|
|
13
|
+
|
|
14
|
+
const CreateTagModal = (props) => {
|
|
15
|
+
const { open, onClose } = props;
|
|
16
|
+
const [tag, setTag] = React__default.useState("");
|
|
17
|
+
const [description, setDescription] = React__default.useState("");
|
|
18
|
+
const { t } = useTranslation();
|
|
19
|
+
const [error, setError] = React__default.useState(false);
|
|
20
|
+
const qetaApi = useApi(qetaApiRef);
|
|
21
|
+
const handleCreate = () => {
|
|
22
|
+
qetaApi.createTag(tag, description).then((ret) => {
|
|
23
|
+
if (ret) {
|
|
24
|
+
setTag("");
|
|
25
|
+
setDescription("");
|
|
26
|
+
onClose();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setError(true);
|
|
30
|
+
}).catch(() => {
|
|
31
|
+
setError(true);
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
35
|
+
Modal,
|
|
36
|
+
{
|
|
37
|
+
open,
|
|
38
|
+
onClose,
|
|
39
|
+
className: "qetaCreateTagModal",
|
|
40
|
+
"aria-labelledby": "modal-modal-title",
|
|
41
|
+
"aria-describedby": "modal-modal-description",
|
|
42
|
+
closeAfterTransition: true,
|
|
43
|
+
BackdropComponent: Backdrop,
|
|
44
|
+
BackdropProps: {
|
|
45
|
+
timeout: 500
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
/* @__PURE__ */ React__default.createElement(ModalContent, null, error && /* @__PURE__ */ React__default.createElement(Alert, { severity: "error" }, t("createTagModal.errorPosting")), /* @__PURE__ */ React__default.createElement(
|
|
49
|
+
Typography,
|
|
50
|
+
{
|
|
51
|
+
id: "modal-modal-title",
|
|
52
|
+
className: "qetaCreateTagModalTitle",
|
|
53
|
+
variant: "h6",
|
|
54
|
+
component: "h2",
|
|
55
|
+
style: { marginBottom: "1em" }
|
|
56
|
+
},
|
|
57
|
+
t("createTagModal.title")
|
|
58
|
+
), /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
|
|
59
|
+
TextField,
|
|
60
|
+
{
|
|
61
|
+
variant: "outlined",
|
|
62
|
+
label: t("createTagModal.tagInput"),
|
|
63
|
+
style: { width: "100%" },
|
|
64
|
+
required: true,
|
|
65
|
+
value: tag,
|
|
66
|
+
onChange: (e) => setTag(e.target.value)
|
|
67
|
+
}
|
|
68
|
+
)), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
|
|
69
|
+
TextField,
|
|
70
|
+
{
|
|
71
|
+
variant: "outlined",
|
|
72
|
+
label: t("createTagModal.description"),
|
|
73
|
+
multiline: true,
|
|
74
|
+
minRows: 10,
|
|
75
|
+
style: { width: "100%" },
|
|
76
|
+
value: description ?? "",
|
|
77
|
+
onChange: (e) => setDescription(e.target.value)
|
|
78
|
+
}
|
|
79
|
+
))), /* @__PURE__ */ React__default.createElement(
|
|
80
|
+
Button,
|
|
81
|
+
{
|
|
82
|
+
onClick: handleCreate,
|
|
83
|
+
className: "qetaCreateTagModalSaveBtn",
|
|
84
|
+
color: "secondary"
|
|
85
|
+
},
|
|
86
|
+
t("createTagModal.createButton")
|
|
87
|
+
), /* @__PURE__ */ React__default.createElement(Button, { onClick: onClose, className: "qetaCreateTagModalCancelBtn" }, t("createTagModal.cancelButton")))
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { CreateTagModal };
|
|
92
|
+
//# sourceMappingURL=CreateTagModal.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateTagModal.esm.js","sources":["../../../src/components/TagsGrid/CreateTagModal.tsx"],"sourcesContent":["import {\n Backdrop,\n Button,\n Grid,\n Modal,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslation } from '../../hooks';\nimport { ModalContent } from '../Utility/ModalContent';\n\nexport const CreateTagModal = (props: {\n open: boolean;\n onClose: () => void;\n}) => {\n const { open, onClose } = props;\n const [tag, setTag] = React.useState('');\n const [description, setDescription] = React.useState('');\n const { t } = useTranslation();\n const [error, setError] = React.useState(false);\n const qetaApi = useApi(qetaApiRef);\n\n const handleCreate = () => {\n qetaApi\n .createTag(tag, description)\n .then(ret => {\n if (ret) {\n setTag('');\n setDescription('');\n onClose();\n return;\n }\n setError(true);\n })\n .catch(() => {\n setError(true);\n });\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n className=\"qetaCreateTagModal\"\n aria-labelledby=\"modal-modal-title\"\n aria-describedby=\"modal-modal-description\"\n closeAfterTransition\n BackdropComponent={Backdrop}\n BackdropProps={{\n timeout: 500,\n }}\n >\n <ModalContent>\n {error && (\n <Alert severity=\"error\">{t('createTagModal.errorPosting')}</Alert>\n )}\n <Typography\n id=\"modal-modal-title\"\n className=\"qetaCreateTagModalTitle\"\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: '1em' }}\n >\n {t('createTagModal.title')}\n </Typography>\n <Grid container>\n <Grid item xs={12}>\n <TextField\n variant=\"outlined\"\n label={t('createTagModal.tagInput')}\n style={{ width: '100%' }}\n required\n value={tag}\n onChange={e => setTag(e.target.value)}\n />\n </Grid>\n <Grid item xs={12}>\n <TextField\n variant=\"outlined\"\n label={t('createTagModal.description')}\n multiline\n minRows={10}\n style={{ width: '100%' }}\n value={description ?? ''}\n onChange={e => setDescription(e.target.value)}\n />\n </Grid>\n </Grid>\n <Button\n onClick={handleCreate}\n className=\"qetaCreateTagModalSaveBtn\"\n color=\"secondary\"\n >\n {t('createTagModal.createButton')}\n </Button>\n <Button onClick={onClose} className=\"qetaCreateTagModalCancelBtn\">\n {t('createTagModal.cancelButton')}\n </Button>\n </ModalContent>\n </Modal>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -48,7 +48,8 @@ const EditTagModal = (props) => {
|
|
|
48
48
|
id: "modal-modal-title",
|
|
49
49
|
className: "qetaEditTagModalTitle",
|
|
50
50
|
variant: "h6",
|
|
51
|
-
component: "h2"
|
|
51
|
+
component: "h2",
|
|
52
|
+
style: { marginBottom: "1em" }
|
|
52
53
|
},
|
|
53
54
|
t("editTagModal.title", { tag: tag.tag })
|
|
54
55
|
), /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditTagModal.esm.js","sources":["../../../src/components/TagsGrid/EditTagModal.tsx"],"sourcesContent":["import { TagResponse } from '@drodil/backstage-plugin-qeta-common';\nimport {\n Backdrop,\n Button,\n Grid,\n Modal,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslation } from '../../hooks';\nimport { ModalContent } from '../Utility/ModalContent';\n\nexport const EditTagModal = (props: {\n tag: TagResponse;\n open: boolean;\n onClose: () => void;\n}) => {\n const { tag, open, onClose } = props;\n const [description, setDescription] = React.useState(tag.description);\n const { t } = useTranslation();\n const [error, setError] = React.useState(false);\n const qetaApi = useApi(qetaApiRef);\n\n const handleUpdate = () => {\n qetaApi\n .updateTag(tag.tag, description)\n .then(ret => {\n if (ret) {\n onClose();\n return;\n }\n setError(true);\n })\n .catch(() => {\n setError(true);\n });\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n className=\"qetaEditTagModal\"\n aria-labelledby=\"modal-modal-title\"\n aria-describedby=\"modal-modal-description\"\n closeAfterTransition\n BackdropComponent={Backdrop}\n BackdropProps={{\n timeout: 500,\n }}\n >\n <ModalContent>\n {error && (\n <Alert severity=\"error\">{t('editTagModal.errorPosting')}</Alert>\n )}\n <Typography\n id=\"modal-modal-title\"\n className=\"qetaEditTagModalTitle\"\n variant=\"h6\"\n component=\"h2\"\n >\n {t('editTagModal.title', { tag: tag.tag })}\n </Typography>\n <Grid container>\n <Grid item xs={12}>\n <TextField\n variant=\"outlined\"\n label={t('editTagModal.description')}\n multiline\n minRows={10}\n style={{ width: '100%' }}\n value={description ?? ''}\n onChange={e => setDescription(e.target.value)}\n />\n </Grid>\n </Grid>\n <Button\n onClick={handleUpdate}\n className=\"qetaEditTagModalSaveBtn\"\n color=\"secondary\"\n >\n {t('editTagModal.saveButton')}\n </Button>\n <Button onClick={onClose} className=\"qetaEditTagModalCancelBtn\">\n {t('editTagModal.cancelButton')}\n </Button>\n </ModalContent>\n </Modal>\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;;;;AAgBa,MAAA,YAAA,GAAe,CAAC,KAIvB,KAAA;AACJ,EAAA,MAAM,EAAE,GAAA,EAAK,IAAM,EAAA,OAAA,EAAY,GAAA,KAAA;AAC/B,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,IAAIA,cAAM,CAAA,QAAA,CAAS,IAAI,WAAW,CAAA;AACpE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAAA,cAAA,CAAM,SAAS,KAAK,CAAA;AAC9C,EAAM,MAAA,OAAA,GAAU,OAAO,UAAU,CAAA;AAEjC,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,OAAA,CACG,UAAU,GAAI,CAAA,GAAA,EAAK,WAAW,CAAA,CAC9B,KAAK,CAAO,GAAA,KAAA;AACX,MAAA,IAAI,GAAK,EAAA;AACP,QAAQ,OAAA,EAAA;AACR,QAAA;AAAA;AAEF,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,KACd,CACA,CAAA,KAAA,CAAM,MAAM;AACX,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,KACd,CAAA;AAAA,GACL;AAEA,EACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAU,EAAA,kBAAA;AAAA,MACV,iBAAgB,EAAA,mBAAA;AAAA,MAChB,kBAAiB,EAAA,yBAAA;AAAA,MACjB,oBAAoB,EAAA,IAAA;AAAA,MACpB,iBAAmB,EAAA,QAAA;AAAA,MACnB,aAAe,EAAA;AAAA,QACb,OAAS,EAAA;AAAA;AACX,KAAA;AAAA,oBAEAA,cAAA,CAAA,aAAA,CAAC,YACE,EAAA,IAAA,EAAA,KAAA,oBACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAM,UAAS,OAAS,EAAA,EAAA,CAAA,CAAE,2BAA2B,CAAE,CAE1D,kBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,EAAG,EAAA,mBAAA;AAAA,QACH,SAAU,EAAA,uBAAA;AAAA,QACV,OAAQ,EAAA,IAAA;AAAA,QACR,SAAU,EAAA;AAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"EditTagModal.esm.js","sources":["../../../src/components/TagsGrid/EditTagModal.tsx"],"sourcesContent":["import { TagResponse } from '@drodil/backstage-plugin-qeta-common';\nimport {\n Backdrop,\n Button,\n Grid,\n Modal,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslation } from '../../hooks';\nimport { ModalContent } from '../Utility/ModalContent';\n\nexport const EditTagModal = (props: {\n tag: TagResponse;\n open: boolean;\n onClose: () => void;\n}) => {\n const { tag, open, onClose } = props;\n const [description, setDescription] = React.useState(tag.description);\n const { t } = useTranslation();\n const [error, setError] = React.useState(false);\n const qetaApi = useApi(qetaApiRef);\n\n const handleUpdate = () => {\n qetaApi\n .updateTag(tag.tag, description)\n .then(ret => {\n if (ret) {\n onClose();\n return;\n }\n setError(true);\n })\n .catch(() => {\n setError(true);\n });\n };\n\n return (\n <Modal\n open={open}\n onClose={onClose}\n className=\"qetaEditTagModal\"\n aria-labelledby=\"modal-modal-title\"\n aria-describedby=\"modal-modal-description\"\n closeAfterTransition\n BackdropComponent={Backdrop}\n BackdropProps={{\n timeout: 500,\n }}\n >\n <ModalContent>\n {error && (\n <Alert severity=\"error\">{t('editTagModal.errorPosting')}</Alert>\n )}\n <Typography\n id=\"modal-modal-title\"\n className=\"qetaEditTagModalTitle\"\n variant=\"h6\"\n component=\"h2\"\n style={{ marginBottom: '1em' }}\n >\n {t('editTagModal.title', { tag: tag.tag })}\n </Typography>\n <Grid container>\n <Grid item xs={12}>\n <TextField\n variant=\"outlined\"\n label={t('editTagModal.description')}\n multiline\n minRows={10}\n style={{ width: '100%' }}\n value={description ?? ''}\n onChange={e => setDescription(e.target.value)}\n />\n </Grid>\n </Grid>\n <Button\n onClick={handleUpdate}\n className=\"qetaEditTagModalSaveBtn\"\n color=\"secondary\"\n >\n {t('editTagModal.saveButton')}\n </Button>\n <Button onClick={onClose} className=\"qetaEditTagModalCancelBtn\">\n {t('editTagModal.cancelButton')}\n </Button>\n </ModalContent>\n </Modal>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -14,6 +14,12 @@ import '@backstage/catalog-model';
|
|
|
14
14
|
import 'dataloader';
|
|
15
15
|
import '@backstage/plugin-catalog-react';
|
|
16
16
|
import 'react-use/lib/useAsync';
|
|
17
|
+
import { useIsModerator } from '../../hooks/useIsModerator.esm.js';
|
|
18
|
+
import { DeleteModal } from '../DeleteModal/DeleteModal.esm.js';
|
|
19
|
+
import DeleteIcon from '@material-ui/icons/Delete';
|
|
20
|
+
import EditIcon from '@material-ui/icons/Edit';
|
|
21
|
+
import Visibility from '@material-ui/icons/Visibility';
|
|
22
|
+
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
|
17
23
|
|
|
18
24
|
const TagGridItem = (props) => {
|
|
19
25
|
const { tag, onTagEdit } = props;
|
|
@@ -21,12 +27,19 @@ const TagGridItem = (props) => {
|
|
|
21
27
|
const navigate = useNavigate();
|
|
22
28
|
const { t } = useTranslation();
|
|
23
29
|
const tags = useTagsFollow();
|
|
30
|
+
const isModerator = useIsModerator();
|
|
24
31
|
const [editModalOpen, setEditModalOpen] = React__default.useState(false);
|
|
25
32
|
const handleEditModalOpen = () => setEditModalOpen(true);
|
|
26
33
|
const handleEditModalClose = () => {
|
|
27
34
|
setEditModalOpen(false);
|
|
28
35
|
onTagEdit();
|
|
29
36
|
};
|
|
37
|
+
const [deleteModalOpen, setDeleteModalOpen] = React__default.useState(false);
|
|
38
|
+
const handleDeleteModalOpen = () => setDeleteModalOpen(true);
|
|
39
|
+
const handleDeleteModalClose = () => {
|
|
40
|
+
setDeleteModalOpen(false);
|
|
41
|
+
onTagEdit();
|
|
42
|
+
};
|
|
30
43
|
return /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 4 }, /* @__PURE__ */ React__default.createElement(
|
|
31
44
|
Card,
|
|
32
45
|
{
|
|
@@ -48,7 +61,8 @@ const TagGridItem = (props) => {
|
|
|
48
61
|
} else {
|
|
49
62
|
tags.followTag(tag.tag);
|
|
50
63
|
}
|
|
51
|
-
}
|
|
64
|
+
},
|
|
65
|
+
startIcon: tags.isFollowingTag(tag.tag) ? /* @__PURE__ */ React__default.createElement(VisibilityOff, null) : /* @__PURE__ */ React__default.createElement(Visibility, null)
|
|
52
66
|
},
|
|
53
67
|
tags.isFollowingTag(tag.tag) ? t("tagButton.unfollow") : t("tagButton.follow")
|
|
54
68
|
))), /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(
|
|
@@ -56,9 +70,27 @@ const TagGridItem = (props) => {
|
|
|
56
70
|
{
|
|
57
71
|
size: "small",
|
|
58
72
|
onClick: handleEditModalOpen,
|
|
59
|
-
variant: "outlined"
|
|
73
|
+
variant: "outlined",
|
|
74
|
+
startIcon: /* @__PURE__ */ React__default.createElement(EditIcon, null)
|
|
60
75
|
},
|
|
61
76
|
t("tagButton.edit")
|
|
77
|
+
)), isModerator && /* @__PURE__ */ React__default.createElement(Grid, { item: true }, /* @__PURE__ */ React__default.createElement(
|
|
78
|
+
Button,
|
|
79
|
+
{
|
|
80
|
+
size: "small",
|
|
81
|
+
onClick: handleDeleteModalOpen,
|
|
82
|
+
variant: "contained",
|
|
83
|
+
color: "secondary",
|
|
84
|
+
startIcon: /* @__PURE__ */ React__default.createElement(DeleteIcon, null)
|
|
85
|
+
},
|
|
86
|
+
t("tagButton.delete")
|
|
87
|
+
), /* @__PURE__ */ React__default.createElement(
|
|
88
|
+
DeleteModal,
|
|
89
|
+
{
|
|
90
|
+
open: deleteModalOpen,
|
|
91
|
+
onClose: handleDeleteModalClose,
|
|
92
|
+
entity: tag
|
|
93
|
+
}
|
|
62
94
|
))))
|
|
63
95
|
), /* @__PURE__ */ React__default.createElement(
|
|
64
96
|
EditTagModal,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagGridItem.esm.js","sources":["../../../src/components/TagsGrid/TagGridItem.tsx"],"sourcesContent":["import {\n removeMarkdownFormatting,\n TagResponse,\n truncate,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { tagRouteRef } from '../../routes';\nimport { useNavigate } from 'react-router-dom';\nimport { EditTagModal } from './EditTagModal';\nimport DOMPurify from 'dompurify';\nimport { useTagsFollow, useTranslation } from '../../hooks';\n\nexport const TagGridItem = (props: {\n tag: TagResponse;\n onTagEdit: () => void;\n}) => {\n const { tag, onTagEdit } = props;\n const tagRoute = useRouteRef(tagRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const tags = useTagsFollow();\n\n const [editModalOpen, setEditModalOpen] = React.useState(false);\n const handleEditModalOpen = () => setEditModalOpen(true);\n const handleEditModalClose = () => {\n setEditModalOpen(false);\n onTagEdit();\n };\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea onClick={() => navigate(tagRoute({ tag: tag.tag }))}>\n <CardHeader title={tag.tag} />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', { count: tag.postsCount, itemType: 'post' })}\n {' · '}\n {t('common.followers', { count: tag.followerCount })}\n </Typography>\n <Typography variant=\"body2\">\n {' '}\n {DOMPurify.sanitize(\n truncate(removeMarkdownFormatting(tag.description ?? ''), 150),\n )}\n </Typography>\n </CardContent>\n </CardActionArea>\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('tagButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={tags.isFollowingTag(tag.tag) ? 'secondary' : 'primary'}\n onClick={() => {\n if (tags.isFollowingTag(tag.tag)) {\n tags.unfollowTag(tag.tag);\n } else {\n tags.followTag(tag.tag);\n }\n }}\n >\n {tags.isFollowingTag(tag.tag)\n ? t('tagButton.unfollow')\n : t('tagButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n <Grid item>\n <Button\n size=\"small\"\n onClick={handleEditModalOpen}\n variant=\"outlined\"\n >\n {t('tagButton.edit')}\n </Button>\n </Grid>\n </Grid>\n </CardActions>\n </Card>\n <EditTagModal\n tag={tag}\n open={editModalOpen}\n onClose={handleEditModalClose}\n />\n </Grid>\n );\n};\n"],"names":["React"],"mappings":"
|
|
1
|
+
{"version":3,"file":"TagGridItem.esm.js","sources":["../../../src/components/TagsGrid/TagGridItem.tsx"],"sourcesContent":["import {\n removeMarkdownFormatting,\n TagResponse,\n truncate,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { tagRouteRef } from '../../routes';\nimport { useNavigate } from 'react-router-dom';\nimport { EditTagModal } from './EditTagModal';\nimport DOMPurify from 'dompurify';\nimport { useIsModerator, useTagsFollow, useTranslation } from '../../hooks';\nimport { DeleteModal } from '../DeleteModal';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport Visibility from '@material-ui/icons/Visibility';\nimport VisibilityOff from '@material-ui/icons/VisibilityOff';\n\nexport const TagGridItem = (props: {\n tag: TagResponse;\n onTagEdit: () => void;\n}) => {\n const { tag, onTagEdit } = props;\n const tagRoute = useRouteRef(tagRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const tags = useTagsFollow();\n const isModerator = useIsModerator();\n\n const [editModalOpen, setEditModalOpen] = React.useState(false);\n const handleEditModalOpen = () => setEditModalOpen(true);\n const handleEditModalClose = () => {\n setEditModalOpen(false);\n onTagEdit();\n };\n\n const [deleteModalOpen, setDeleteModalOpen] = React.useState(false);\n const handleDeleteModalOpen = () => setDeleteModalOpen(true);\n const handleDeleteModalClose = () => {\n setDeleteModalOpen(false);\n onTagEdit();\n };\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea onClick={() => navigate(tagRoute({ tag: tag.tag }))}>\n <CardHeader title={tag.tag} />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', { count: tag.postsCount, itemType: 'post' })}\n {' · '}\n {t('common.followers', { count: tag.followerCount })}\n </Typography>\n <Typography variant=\"body2\">\n {' '}\n {DOMPurify.sanitize(\n truncate(removeMarkdownFormatting(tag.description ?? ''), 150),\n )}\n </Typography>\n </CardContent>\n </CardActionArea>\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('tagButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={tags.isFollowingTag(tag.tag) ? 'secondary' : 'primary'}\n onClick={() => {\n if (tags.isFollowingTag(tag.tag)) {\n tags.unfollowTag(tag.tag);\n } else {\n tags.followTag(tag.tag);\n }\n }}\n startIcon={\n tags.isFollowingTag(tag.tag) ? (\n <VisibilityOff />\n ) : (\n <Visibility />\n )\n }\n >\n {tags.isFollowingTag(tag.tag)\n ? t('tagButton.unfollow')\n : t('tagButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n <Grid item>\n <Button\n size=\"small\"\n onClick={handleEditModalOpen}\n variant=\"outlined\"\n startIcon={<EditIcon />}\n >\n {t('tagButton.edit')}\n </Button>\n </Grid>\n {isModerator && (\n <Grid item>\n <Button\n size=\"small\"\n onClick={handleDeleteModalOpen}\n variant=\"contained\"\n color=\"secondary\"\n startIcon={<DeleteIcon />}\n >\n {t('tagButton.delete')}\n </Button>\n <DeleteModal\n open={deleteModalOpen}\n onClose={handleDeleteModalClose}\n entity={tag}\n />\n </Grid>\n )}\n </Grid>\n </CardActions>\n </Card>\n <EditTagModal\n tag={tag}\n open={editModalOpen}\n onClose={handleEditModalClose}\n />\n </Grid>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -7,17 +7,20 @@ import '@backstage/catalog-model';
|
|
|
7
7
|
import 'dataloader';
|
|
8
8
|
import '@backstage/plugin-catalog-react';
|
|
9
9
|
import 'react-use/lib/useAsync';
|
|
10
|
+
import { useIsModerator } from '../../hooks/useIsModerator.esm.js';
|
|
10
11
|
import { QetaPagination } from '../QetaPagination/QetaPagination.esm.js';
|
|
11
12
|
import useDebounce from 'react-use/lib/useDebounce';
|
|
12
13
|
import { TagsGridContent } from './TagsGridContent.esm.js';
|
|
13
14
|
import { SearchBar } from '../SearchBar/SearchBar.esm.js';
|
|
14
|
-
import { Grid, Typography } from '@material-ui/core';
|
|
15
|
+
import { Grid, Typography, Button } from '@material-ui/core';
|
|
16
|
+
import { CreateTagModal } from './CreateTagModal.esm.js';
|
|
15
17
|
|
|
16
18
|
const TagsGrid = () => {
|
|
17
19
|
const [page, setPage] = React__default.useState(1);
|
|
18
20
|
const [pageCount, setPageCount] = React__default.useState(1);
|
|
19
21
|
const [tagsPerPage, setTagsPerPage] = React__default.useState(25);
|
|
20
22
|
const [searchQuery, setSearchQuery] = React__default.useState("");
|
|
23
|
+
const isModerator = useIsModerator();
|
|
21
24
|
const { t } = useTranslation();
|
|
22
25
|
const [filters, setFilters] = React__default.useState({
|
|
23
26
|
order: "desc",
|
|
@@ -55,20 +58,41 @@ const TagsGrid = () => {
|
|
|
55
58
|
setPageCount(Math.ceil(response.total / tagsPerPage));
|
|
56
59
|
}
|
|
57
60
|
}, [response, tagsPerPage]);
|
|
58
|
-
const
|
|
61
|
+
const onTagsModify = () => {
|
|
59
62
|
retry();
|
|
60
63
|
};
|
|
64
|
+
const [createModalOpen, setCreateModalOpen] = React__default.useState(false);
|
|
65
|
+
const handleCreateModalOpen = () => setCreateModalOpen(true);
|
|
66
|
+
const handleCreateModalClose = () => {
|
|
67
|
+
setCreateModalOpen(false);
|
|
68
|
+
onTagsModify();
|
|
69
|
+
};
|
|
61
70
|
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(Grid, { container: true, className: "qetaTagsContainer" }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12, md: 4 }, /* @__PURE__ */ React__default.createElement(
|
|
62
71
|
SearchBar,
|
|
63
72
|
{
|
|
64
73
|
onSearch: onSearchQueryChange,
|
|
65
74
|
label: t("tagPage.search.label")
|
|
66
75
|
}
|
|
67
|
-
))), /* @__PURE__ */ React__default.createElement(Grid, { container: true, justifyContent: "space-between" }, response && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6", className: "qetaTagsContainerTitle" }, t("tagPage.tags", { count: response.total }))), /* @__PURE__ */ React__default.createElement(
|
|
76
|
+
))), /* @__PURE__ */ React__default.createElement(Grid, { container: true, justifyContent: "space-between" }, response && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: isModerator ? 8 : 12 }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "h6", className: "qetaTagsContainerTitle" }, t("tagPage.tags", { count: response.total }))), response && isModerator && /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 4 }, /* @__PURE__ */ React__default.createElement(
|
|
77
|
+
Button,
|
|
78
|
+
{
|
|
79
|
+
variant: "contained",
|
|
80
|
+
color: "primary",
|
|
81
|
+
onClick: handleCreateModalOpen,
|
|
82
|
+
style: { float: "right" }
|
|
83
|
+
},
|
|
84
|
+
t("tagPage.createTag")
|
|
85
|
+
), /* @__PURE__ */ React__default.createElement(
|
|
86
|
+
CreateTagModal,
|
|
87
|
+
{
|
|
88
|
+
open: createModalOpen,
|
|
89
|
+
onClose: handleCreateModalClose
|
|
90
|
+
}
|
|
91
|
+
)), /* @__PURE__ */ React__default.createElement(
|
|
68
92
|
TagsGridContent,
|
|
69
93
|
{
|
|
70
94
|
response,
|
|
71
|
-
onTagEdit,
|
|
95
|
+
onTagEdit: onTagsModify,
|
|
72
96
|
loading,
|
|
73
97
|
error
|
|
74
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagsGrid.esm.js","sources":["../../../src/components/TagsGrid/TagsGrid.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\nimport { useQetaApi, useTranslation } from '../../hooks';\nimport { QetaPagination } from '../QetaPagination/QetaPagination';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { TagsGridContent } from './TagsGridContent';\nimport { SearchBar } from '../SearchBar/SearchBar';\nimport { Grid, Typography } from '@material-ui/core';\n\ntype TagFilters = {\n order: 'asc' | 'desc';\n orderBy: 'tag' | 'followersCount' | 'postsCount';\n searchQuery: string;\n};\n\nexport const TagsGrid = () => {\n const [page, setPage] = React.useState(1);\n const [pageCount, setPageCount] = React.useState(1);\n const [tagsPerPage, setTagsPerPage] = React.useState(25);\n const [searchQuery, setSearchQuery] = React.useState('');\n const { t } = useTranslation();\n const [filters, setFilters] = React.useState<TagFilters>({\n order: 'desc',\n orderBy: 'tag',\n searchQuery: '',\n });\n\n const onSearchQueryChange = (val: string) => {\n setPage(1);\n setSearchQuery(val);\n };\n\n const {\n value: response,\n loading,\n error,\n retry,\n } = useQetaApi(\n api =>\n api.getTags({\n limit: tagsPerPage,\n offset: (page - 1) * tagsPerPage,\n ...filters,\n }),\n [page, tagsPerPage, filters],\n );\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 400,\n [searchQuery],\n );\n\n useEffect(() => {\n if (response) {\n setPageCount(Math.ceil(response.total / tagsPerPage));\n }\n }, [response, tagsPerPage]);\n\n const
|
|
1
|
+
{"version":3,"file":"TagsGrid.esm.js","sources":["../../../src/components/TagsGrid/TagsGrid.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\nimport { useIsModerator, useQetaApi, useTranslation } from '../../hooks';\nimport { QetaPagination } from '../QetaPagination/QetaPagination';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { TagsGridContent } from './TagsGridContent';\nimport { SearchBar } from '../SearchBar/SearchBar';\nimport { Button, Grid, Typography } from '@material-ui/core';\nimport { CreateTagModal } from './CreateTagModal';\n\ntype TagFilters = {\n order: 'asc' | 'desc';\n orderBy: 'tag' | 'followersCount' | 'postsCount';\n searchQuery: string;\n};\n\nexport const TagsGrid = () => {\n const [page, setPage] = React.useState(1);\n const [pageCount, setPageCount] = React.useState(1);\n const [tagsPerPage, setTagsPerPage] = React.useState(25);\n const [searchQuery, setSearchQuery] = React.useState('');\n const isModerator = useIsModerator();\n const { t } = useTranslation();\n const [filters, setFilters] = React.useState<TagFilters>({\n order: 'desc',\n orderBy: 'tag',\n searchQuery: '',\n });\n\n const onSearchQueryChange = (val: string) => {\n setPage(1);\n setSearchQuery(val);\n };\n\n const {\n value: response,\n loading,\n error,\n retry,\n } = useQetaApi(\n api =>\n api.getTags({\n limit: tagsPerPage,\n offset: (page - 1) * tagsPerPage,\n ...filters,\n }),\n [page, tagsPerPage, filters],\n );\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 400,\n [searchQuery],\n );\n\n useEffect(() => {\n if (response) {\n setPageCount(Math.ceil(response.total / tagsPerPage));\n }\n }, [response, tagsPerPage]);\n\n const onTagsModify = () => {\n retry();\n };\n\n const [createModalOpen, setCreateModalOpen] = React.useState(false);\n const handleCreateModalOpen = () => setCreateModalOpen(true);\n const handleCreateModalClose = () => {\n setCreateModalOpen(false);\n onTagsModify();\n };\n\n return (\n <>\n <Grid container className=\"qetaTagsContainer\">\n <Grid item xs={12} md={4}>\n <SearchBar\n onSearch={onSearchQueryChange}\n label={t('tagPage.search.label')}\n />\n </Grid>\n </Grid>\n <Grid container justifyContent=\"space-between\">\n {response && (\n <Grid item xs={isModerator ? 8 : 12}>\n <Typography variant=\"h6\" className=\"qetaTagsContainerTitle\">\n {t('tagPage.tags', { count: response.total })}\n </Typography>\n </Grid>\n )}\n {response && isModerator && (\n <Grid item xs={4}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleCreateModalOpen}\n style={{ float: 'right' }}\n >\n {t('tagPage.createTag')}\n </Button>\n <CreateTagModal\n open={createModalOpen}\n onClose={handleCreateModalClose}\n />\n </Grid>\n )}\n <TagsGridContent\n response={response}\n onTagEdit={onTagsModify}\n loading={loading}\n error={error}\n />\n {response && response?.total > 0 && (\n <QetaPagination\n pageSize={tagsPerPage}\n handlePageChange={(_e, p) => setPage(p)}\n handlePageSizeChange={e => setTagsPerPage(Number(e.target.value))}\n page={page}\n pageCount={pageCount}\n />\n )}\n </Grid>\n </>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ import { useEntityAuthor } from '../../hooks/useEntityAuthor.esm.js';
|
|
|
11
11
|
import { useUserFollow } from '../../hooks/useUserFollow.esm.js';
|
|
12
12
|
import { useIdentityApi } from '../../hooks/useIdentityApi.esm.js';
|
|
13
13
|
import { Grid, Card, CardActionArea, CardHeader, Avatar, CardContent, Typography, CardActions, Tooltip, Button } from '@material-ui/core';
|
|
14
|
+
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
|
15
|
+
import Visibility from '@material-ui/icons/Visibility';
|
|
14
16
|
|
|
15
17
|
const UsersGridItem = (props) => {
|
|
16
18
|
const { user } = props;
|
|
@@ -82,7 +84,8 @@ const UsersGridItem = (props) => {
|
|
|
82
84
|
} else {
|
|
83
85
|
users.followUser(user.userRef);
|
|
84
86
|
}
|
|
85
|
-
}
|
|
87
|
+
},
|
|
88
|
+
startIcon: users.isFollowingUser(user.userRef) ? /* @__PURE__ */ React__default.createElement(VisibilityOff, null) : /* @__PURE__ */ React__default.createElement(Visibility, null)
|
|
86
89
|
},
|
|
87
90
|
users.isFollowingUser(user.userRef) ? t("userButton.unfollow") : t("userButton.follow")
|
|
88
91
|
)))))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UsersGridItem.esm.js","sources":["../../../src/components/UsersGrid/UsersGridItem.tsx"],"sourcesContent":["import { UserResponse } from '@drodil/backstage-plugin-qeta-common';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useNavigate } from 'react-router-dom';\nimport { useEntityPresentation } from '@backstage/plugin-catalog-react';\nimport { userRouteRef } from '../../routes';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { useIdentityApi, useTranslation, useUserFollow } from '../../hooks';\nimport { useEntityAuthor } from '../../hooks/useEntityAuthor';\nimport {\n Avatar,\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\n\nexport const UsersGridItem = (props: { user: UserResponse }) => {\n const { user } = props;\n const userRoute = useRouteRef(userRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const compound = parseEntityRef(user.userRef);\n const { primaryTitle, Icon } = useEntityPresentation(compound);\n const { name, initials, user: userEntity } = useEntityAuthor(user);\n const users = useUserFollow();\n const {\n value: currentUser,\n loading: loadingUser,\n error: userError,\n } = useIdentityApi(api => api.getBackstageIdentity(), []);\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea\n onClick={() => navigate(`${userRoute()}/${user.userRef}`)}\n >\n <CardHeader\n title={primaryTitle}\n avatar={\n Icon ? (\n <Avatar\n src={userEntity?.spec?.profile?.picture}\n className=\"avatar\"\n alt={name}\n variant=\"rounded\"\n >\n {initials}\n </Avatar>\n ) : null\n }\n />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', {\n count: user.totalQuestions,\n itemType: 'question',\n })}\n {' · '}\n {t('common.answers', {\n count: user.totalAnswers,\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalArticles,\n itemType: 'article',\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalComments,\n itemType: 'comment',\n })}\n {' · '}\n {t('common.votes', {\n count: user.totalVotes,\n })}\n {' · '}\n {t('common.viewsShort', {\n count: user.totalViews,\n })}\n </Typography>\n </CardContent>\n </CardActionArea>\n {!loadingUser &&\n !userError &&\n currentUser?.userEntityRef !== user.userRef && (\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('userButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={\n users.isFollowingUser(user.userRef)\n ? 'secondary'\n : 'primary'\n }\n onClick={() => {\n if (users.isFollowingUser(user.userRef)) {\n users.unfollowUser(user.userRef);\n } else {\n users.followUser(user.userRef);\n }\n }}\n >\n {users.isFollowingUser(user.userRef)\n ? t('userButton.unfollow')\n : t('userButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n </Grid>\n </CardActions>\n )}\n </Card>\n </Grid>\n );\n};\n"],"names":["React"],"mappings":"
|
|
1
|
+
{"version":3,"file":"UsersGridItem.esm.js","sources":["../../../src/components/UsersGrid/UsersGridItem.tsx"],"sourcesContent":["import { UserResponse } from '@drodil/backstage-plugin-qeta-common';\nimport React from 'react';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useNavigate } from 'react-router-dom';\nimport { useEntityPresentation } from '@backstage/plugin-catalog-react';\nimport { userRouteRef } from '../../routes';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { useIdentityApi, useTranslation, useUserFollow } from '../../hooks';\nimport { useEntityAuthor } from '../../hooks/useEntityAuthor';\nimport {\n Avatar,\n Button,\n Card,\n CardActionArea,\n CardActions,\n CardContent,\n CardHeader,\n Grid,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport VisibilityOff from '@material-ui/icons/VisibilityOff';\nimport Visibility from '@material-ui/icons/Visibility';\n\nexport const UsersGridItem = (props: { user: UserResponse }) => {\n const { user } = props;\n const userRoute = useRouteRef(userRouteRef);\n const navigate = useNavigate();\n const { t } = useTranslation();\n const compound = parseEntityRef(user.userRef);\n const { primaryTitle, Icon } = useEntityPresentation(compound);\n const { name, initials, user: userEntity } = useEntityAuthor(user);\n const users = useUserFollow();\n const {\n value: currentUser,\n loading: loadingUser,\n error: userError,\n } = useIdentityApi(api => api.getBackstageIdentity(), []);\n\n return (\n <Grid item xs={4}>\n <Card\n variant=\"outlined\"\n style={{ height: '100%', display: 'flex', flexDirection: 'column' }}\n >\n <CardActionArea\n onClick={() => navigate(`${userRoute()}/${user.userRef}`)}\n >\n <CardHeader\n title={primaryTitle}\n avatar={\n Icon ? (\n <Avatar\n src={userEntity?.spec?.profile?.picture}\n className=\"avatar\"\n alt={name}\n variant=\"rounded\"\n >\n {initials}\n </Avatar>\n ) : null\n }\n />\n <CardContent>\n <Typography variant=\"caption\">\n {t('common.posts', {\n count: user.totalQuestions,\n itemType: 'question',\n })}\n {' · '}\n {t('common.answers', {\n count: user.totalAnswers,\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalArticles,\n itemType: 'article',\n })}\n {' · '}\n {t('common.posts', {\n count: user.totalComments,\n itemType: 'comment',\n })}\n {' · '}\n {t('common.votes', {\n count: user.totalVotes,\n })}\n {' · '}\n {t('common.viewsShort', {\n count: user.totalViews,\n })}\n </Typography>\n </CardContent>\n </CardActionArea>\n {!loadingUser &&\n !userError &&\n currentUser?.userEntityRef !== user.userRef && (\n <CardActions style={{ marginTop: 'auto' }}>\n <Grid container justifyContent=\"center\">\n <Grid item>\n <Tooltip title={t('userButton.tooltip')}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color={\n users.isFollowingUser(user.userRef)\n ? 'secondary'\n : 'primary'\n }\n onClick={() => {\n if (users.isFollowingUser(user.userRef)) {\n users.unfollowUser(user.userRef);\n } else {\n users.followUser(user.userRef);\n }\n }}\n startIcon={\n users.isFollowingUser(user.userRef) ? (\n <VisibilityOff />\n ) : (\n <Visibility />\n )\n }\n >\n {users.isFollowingUser(user.userRef)\n ? t('userButton.unfollow')\n : t('userButton.follow')}\n </Button>\n </Tooltip>\n </Grid>\n </Grid>\n </CardActions>\n )}\n </Card>\n </Grid>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalContent.esm.js","sources":["../../../src/components/Utility/ModalContent.tsx"],"sourcesContent":["import { makeStyles } from '@material-ui/core';\nimport React from 'react';\n\nconst useStyles = makeStyles(theme => ({\n content: {\n position: 'absolute',\n top: '
|
|
1
|
+
{"version":3,"file":"ModalContent.esm.js","sources":["../../../src/components/Utility/ModalContent.tsx"],"sourcesContent":["import { makeStyles } from '@material-ui/core';\nimport React from 'react';\n\nconst useStyles = makeStyles(theme => ({\n content: {\n position: 'absolute',\n top: '50%',\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: '2em',\n '& button': {\n marginTop: '2em',\n float: 'right',\n },\n },\n}));\n\nexport const ModalContent = React.forwardRef<\n HTMLDivElement,\n { children: React.ReactNode }\n>((props: { children: React.ReactNode }, ref) => {\n const styles = useStyles();\n return (\n <div tabIndex={-1} className={styles.content} ref={ref}>\n {props.children}\n </div>\n );\n});\n"],"names":["React"],"mappings":";;;AAGA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,OAAS,EAAA;AAAA,IACP,QAAU,EAAA,UAAA;AAAA,IACV,GAAK,EAAA,KAAA;AAAA,IACL,IAAM,EAAA,KAAA;AAAA,IACN,SAAW,EAAA,uBAAA;AAAA,IACX,KAAO,EAAA,GAAA;AAAA,IACP,eAAA,EAAiB,KAAM,CAAA,OAAA,CAAQ,UAAW,CAAA,OAAA;AAAA,IAC1C,MAAQ,EAAA,CAAA,UAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,OAAO,QAAQ,CAAA,CAAA;AAAA,IAClD,YAAA,EAAc,MAAM,KAAM,CAAA,YAAA;AAAA,IAC1B,OAAS,EAAA,KAAA;AAAA,IACT,UAAY,EAAA;AAAA,MACV,SAAW,EAAA,KAAA;AAAA,MACX,KAAO,EAAA;AAAA;AACT;AAEJ,CAAE,CAAA,CAAA;AAEK,MAAM,YAAe,GAAAA,cAAA,CAAM,UAGhC,CAAA,CAAC,OAAsC,GAAQ,KAAA;AAC/C,EAAA,MAAM,SAAS,SAAU,EAAA;AACzB,EACE,uBAAAA,cAAA,CAAA,aAAA,CAAC,SAAI,QAAU,EAAA,CAAA,CAAA,EAAI,WAAW,MAAO,CAAA,OAAA,EAAS,GAC3C,EAAA,EAAA,KAAA,CAAM,QACT,CAAA;AAEJ,CAAC;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
2
2
|
import { IdentityApi } from '@backstage/core-plugin-api';
|
|
3
3
|
import * as _drodil_backstage_plugin_qeta_common from '@drodil/backstage-plugin-qeta-common';
|
|
4
|
-
import { QetaApi, PostType, PostResponse, Template, PostsResponse, AnswersResponse, AnswerResponse, Collection, PostsQuery, CollectionResponse, Post, Answer, Comment, Stat, StatisticsResponse, UserStat, GlobalStat, TemplatesResponse, Article, UserResponse, AIQuery } from '@drodil/backstage-plugin-qeta-common';
|
|
4
|
+
import { QetaApi, PostType, PostResponse, Template, PostsResponse, AnswersResponse, AnswerResponse, Collection, PostsQuery, CollectionResponse, TagResponse, Post, Answer, Comment, Stat, StatisticsResponse, UserStat, GlobalStat, TemplatesResponse, Article, UserResponse, AIQuery } from '@drodil/backstage-plugin-qeta-common';
|
|
5
5
|
import React, { CSSProperties } from 'react';
|
|
6
6
|
import { Entity, UserEntity } from '@backstage/catalog-model';
|
|
7
7
|
import { LinkProps } from '@backstage/core-components';
|
|
@@ -84,14 +84,16 @@ type Change<T extends Filters> = {
|
|
|
84
84
|
key: keyof T;
|
|
85
85
|
value: string | string[];
|
|
86
86
|
};
|
|
87
|
-
interface
|
|
88
|
-
onChange: (changes: Change<T> | Change<T>[]) => void;
|
|
89
|
-
filters: T;
|
|
87
|
+
interface CommonFilterPanelProps {
|
|
90
88
|
showEntityFilter?: boolean;
|
|
91
89
|
showTagFilter?: boolean;
|
|
92
90
|
answerFilters?: boolean;
|
|
93
91
|
type?: PostType;
|
|
94
92
|
}
|
|
93
|
+
interface FilterPanelProps<T extends Filters> extends CommonFilterPanelProps {
|
|
94
|
+
onChange: (changes: Change<T> | Change<T>[]) => void;
|
|
95
|
+
filters: T;
|
|
96
|
+
}
|
|
95
97
|
declare const FilterPanel: <T extends Filters>(props: FilterPanelProps<T>) => React.JSX.Element;
|
|
96
98
|
|
|
97
99
|
type PaginatedPostsProps = PostFilters & {
|
|
@@ -109,6 +111,7 @@ type PaginatedPostsProps = PostFilters & {
|
|
|
109
111
|
|
|
110
112
|
declare const PostsContainer: (props: PaginatedPostsProps & {
|
|
111
113
|
entity?: string;
|
|
114
|
+
filterPanelProps?: CommonFilterPanelProps;
|
|
112
115
|
}) => React.JSX.Element;
|
|
113
116
|
|
|
114
117
|
declare const PostList: (props: {
|
|
@@ -219,7 +222,7 @@ declare const MarkdownRenderer: (props: {
|
|
|
219
222
|
}) => React.JSX.Element;
|
|
220
223
|
|
|
221
224
|
declare const DeleteModal: (props: {
|
|
222
|
-
entity: PostResponse | AnswerResponse | CollectionResponse;
|
|
225
|
+
entity: PostResponse | AnswerResponse | CollectionResponse | TagResponse;
|
|
223
226
|
open: boolean;
|
|
224
227
|
onClose: () => void;
|
|
225
228
|
question?: PostResponse;
|
|
@@ -309,6 +312,7 @@ declare const UsersGrid: () => React.JSX.Element;
|
|
|
309
312
|
|
|
310
313
|
type PostGridProps = PaginatedPostsProps & {
|
|
311
314
|
allowRanking?: boolean;
|
|
315
|
+
filterPanelProps?: CommonFilterPanelProps;
|
|
312
316
|
};
|
|
313
317
|
declare const PostsGrid: (props: PostGridProps) => React.JSX.Element;
|
|
314
318
|
|
|
@@ -327,6 +331,7 @@ declare const CollectionForm: (props: CollectionFormProps) => React.JSX.Element;
|
|
|
327
331
|
type CollectionsGridProps = {
|
|
328
332
|
owner?: string;
|
|
329
333
|
showFilters?: boolean;
|
|
334
|
+
filterPanelProps?: CommonFilterPanelProps;
|
|
330
335
|
};
|
|
331
336
|
declare const CollectionsGrid: (props: CollectionsGridProps) => React.JSX.Element;
|
|
332
337
|
|
|
@@ -505,6 +510,13 @@ declare const useTranslation: () => {
|
|
|
505
510
|
readonly "editTagModal.description": "Tag description";
|
|
506
511
|
readonly "editTagModal.saveButton": "Save";
|
|
507
512
|
readonly "editTagModal.cancelButton": "Cancel";
|
|
513
|
+
readonly "createTagModal.title": "Create a new tag";
|
|
514
|
+
readonly "createTagModal.errorPosting": "Failed to create";
|
|
515
|
+
readonly "createTagModal.description": "Tag description";
|
|
516
|
+
readonly "createTagModal.cancelButton": "Cancel";
|
|
517
|
+
readonly "createTagModal.tagInput": "Tag";
|
|
518
|
+
readonly "createTagModal.createButton": "Create";
|
|
519
|
+
readonly "deleteModal.title.tag": "Are you sure you want to delete this tag?";
|
|
508
520
|
readonly "deleteModal.title.answer": "Are you sure you want to delete this answer?";
|
|
509
521
|
readonly "deleteModal.title.question": "Are you sure you want to delete this post?";
|
|
510
522
|
readonly "deleteModal.title.collection": "Are you sure you want to delete this collection?";
|
|
@@ -570,9 +582,9 @@ declare const useTranslation: () => {
|
|
|
570
582
|
readonly "templateList.descriptionInput.helperText": "Template description, what is it used for?";
|
|
571
583
|
readonly "templateList.submit.existingTemplate": "Save";
|
|
572
584
|
readonly "templateList.submit.newTemplate": "Create";
|
|
585
|
+
readonly "templateList.createButton": "Create";
|
|
573
586
|
readonly "templateList.deleteButton": "Delete";
|
|
574
587
|
readonly "templateList.editButton": "Edit";
|
|
575
|
-
readonly "templateList.createButton": "Create";
|
|
576
588
|
readonly "templateList.noTemplates": "No templates";
|
|
577
589
|
readonly "templateList.noTemplatesDescription": "Create a new template to get started";
|
|
578
590
|
readonly "templateList.questionTitleInput.label": "Default question title";
|
|
@@ -678,6 +690,7 @@ declare const useTranslation: () => {
|
|
|
678
690
|
readonly "tagPage.search.placeholder": "Search...";
|
|
679
691
|
readonly "tagPage.errorLoading": "Could not load tags";
|
|
680
692
|
readonly "tagPage.defaultTitle": "Tags";
|
|
693
|
+
readonly "tagPage.createTag": "Create tag";
|
|
681
694
|
readonly "tagPage.tags_zero": "No tags";
|
|
682
695
|
readonly "tagPage.tags_one": "{{count}} tag";
|
|
683
696
|
readonly "tagPage.tags_other": "{{count}} tags";
|
|
@@ -722,6 +735,7 @@ declare const useTranslation: () => {
|
|
|
722
735
|
readonly "collectionButton.tooltip": "By following a collection, you will get notified when ever a new post is added to the collection";
|
|
723
736
|
readonly "collectionButton.unfollow": "Unfollow";
|
|
724
737
|
readonly "tagButton.edit": "Edit";
|
|
738
|
+
readonly "tagButton.delete": "Delete";
|
|
725
739
|
readonly "tagButton.follow": "Follow";
|
|
726
740
|
readonly "tagButton.tooltip": "By following a tag, you will get notified when ever a new post with that tag is posted";
|
|
727
741
|
readonly "tagButton.unfollow": "Unfollow";
|
package/dist/translation.esm.js
CHANGED
|
@@ -164,11 +164,20 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
164
164
|
saveButton: "Save",
|
|
165
165
|
cancelButton: "Cancel"
|
|
166
166
|
},
|
|
167
|
+
createTagModal: {
|
|
168
|
+
title: "Create a new tag",
|
|
169
|
+
tagInput: "Tag",
|
|
170
|
+
description: "Tag description",
|
|
171
|
+
errorPosting: "Failed to create",
|
|
172
|
+
createButton: "Create",
|
|
173
|
+
cancelButton: "Cancel"
|
|
174
|
+
},
|
|
167
175
|
deleteModal: {
|
|
168
176
|
title: {
|
|
169
177
|
question: "Are you sure you want to delete this post?",
|
|
170
178
|
answer: "Are you sure you want to delete this answer?",
|
|
171
|
-
collection: "Are you sure you want to delete this collection?"
|
|
179
|
+
collection: "Are you sure you want to delete this collection?",
|
|
180
|
+
tag: "Are you sure you want to delete this tag?"
|
|
172
181
|
},
|
|
173
182
|
errorDeleting: "Failed to delete",
|
|
174
183
|
deleteButton: "Delete",
|
|
@@ -490,6 +499,7 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
490
499
|
tagPage: {
|
|
491
500
|
errorLoading: "Could not load tags",
|
|
492
501
|
defaultTitle: "Tags",
|
|
502
|
+
createTag: "Create tag",
|
|
493
503
|
search: {
|
|
494
504
|
label: "Search tag",
|
|
495
505
|
placeholder: "Search..."
|
|
@@ -558,6 +568,7 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
558
568
|
follow: "Follow",
|
|
559
569
|
unfollow: "Unfollow",
|
|
560
570
|
edit: "Edit",
|
|
571
|
+
delete: "Delete",
|
|
561
572
|
tooltip: "By following a tag, you will get notified when ever a new post with that tag is posted"
|
|
562
573
|
},
|
|
563
574
|
entityButton: {
|