@drodil/backstage-plugin-qeta-react 3.42.0 → 3.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AnswerForm/AnswerForm.esm.js +26 -4
- package/dist/components/AnswerForm/AnswerForm.esm.js.map +1 -1
- package/dist/components/ArticleContent/ArticleButtons.esm.js +9 -2
- package/dist/components/ArticleContent/ArticleButtons.esm.js.map +1 -1
- package/dist/components/Buttons/AddToCollectionButton.esm.js +12 -0
- package/dist/components/Buttons/AddToCollectionButton.esm.js.map +1 -1
- package/dist/components/Buttons/FavoriteButton.esm.js +22 -5
- package/dist/components/Buttons/FavoriteButton.esm.js.map +1 -1
- package/dist/components/CollectionForm/CollectionForm.esm.js +26 -9
- package/dist/components/CollectionForm/CollectionForm.esm.js.map +1 -1
- package/dist/components/CommentSection/CommentListItem.esm.js +45 -8
- package/dist/components/CommentSection/CommentListItem.esm.js.map +1 -1
- package/dist/components/CommentSection/CommentSection.esm.js +28 -13
- package/dist/components/CommentSection/CommentSection.esm.js.map +1 -1
- package/dist/components/LinkCard/LinkCard.esm.js +12 -3
- package/dist/components/LinkCard/LinkCard.esm.js.map +1 -1
- package/dist/components/PostForm/PostForm.esm.js +8 -4
- package/dist/components/PostForm/PostForm.esm.js.map +1 -1
- package/dist/components/PostForm/TagInput.esm.js +2 -2
- package/dist/components/PostForm/TagInput.esm.js.map +1 -1
- package/dist/components/TagsGrid/CreateTagModal.esm.js +17 -2
- package/dist/components/TagsGrid/CreateTagModal.esm.js.map +1 -1
- package/dist/components/TagsGrid/EditTagModal.esm.js +19 -5
- package/dist/components/TagsGrid/EditTagModal.esm.js.map +1 -1
- package/dist/components/TemplateList/TemplateForm.esm.js +28 -10
- package/dist/components/TemplateList/TemplateForm.esm.js.map +1 -1
- package/dist/hooks/usePaginatedPosts.esm.js +11 -0
- package/dist/hooks/usePaginatedPosts.esm.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/translation.esm.js +2 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagInput.esm.js","sources":["../../../src/components/PostForm/TagInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport {\n Box,\n Chip,\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { qetaApiRef } from '../../api';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n filterTags,\n qetaCreateTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { FieldError } from 'react-hook-form';\nimport { AutocompleteListboxComponent } from './AutocompleteListComponent';\nimport { permissionApiRef } from '@backstage/plugin-permission-react';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { useDebounce } from 'react-use';\n\nexport const TagInput = (props: {\n value?: string[];\n onChange: (value: string[]) => void;\n error?: FieldError;\n allowCreate?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n title?: string;\n name?: string;\n content?: string;\n}) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n } = props;\n const qetaApi = useApi(qetaApiRef);\n const config = useApi(configApiRef);\n const permissions = useApi(permissionApiRef);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [allowCreation, setAllowCreation] = useState<boolean | undefined>(\n allowCreate,\n );\n const [loading, setLoading] = useState(true);\n const [suggestedTags, setSuggestedTags] = useState<string[]>([]);\n const [, setLoadingSuggestions] = useState(false);\n\n useEffect(() => {\n if (allowCreate !== undefined) {\n return;\n }\n\n if (config.getOptionalBoolean('qeta.permissions') === true) {\n permissions\n .authorize({\n permission: qetaCreateTagPermission,\n })\n .then(res => {\n if (res.result === AuthorizeResult.ALLOW) {\n setAllowCreation(true);\n } else {\n setAllowCreation(false);\n }\n });\n } else {\n setAllowCreation(\n config.getOptionalBoolean('qeta.tags.allowCreation') ?? true,\n );\n }\n }, [config, permissions, allowCreate]);\n\n useDebounce(\n () => {\n if (title && content) {\n setLoadingSuggestions(true);\n qetaApi\n .getTagSuggestions({ title, content })\n .then(response => {\n setSuggestedTags(response.tags);\n })\n .catch(() => {\n // Ignore errors\n })\n .finally(() => {\n setLoadingSuggestions(false);\n });\n }\n },\n 2000,\n [title, content, qetaApi],\n );\n\n const allowedTags = useMemo(\n () => config.getOptionalStringArray('qeta.tags.allowedTags') ?? [],\n [config],\n );\n const maximumTags = useMemo(\n () => config.getOptionalNumber('qeta.tags.max') ?? 5,\n [config],\n );\n\n const [availableTags, setAvailableTags] = useState<string[]>([]);\n const [tagDescriptions, setTagDescriptions] = useState<\n Record<string, string>\n >({});\n useEffect(() => {\n qetaApi\n .getTags()\n .catch(_ => setAvailableTags([]))\n .then(data => {\n setLoading(false);\n if (!data) {\n return;\n }\n\n const uniqueTags = [\n ...new Set([...allowedTags, ...data.tags.map(tag => tag.tag)]),\n ].sort((a, b) => a.localeCompare(b));\n setAvailableTags(uniqueTags);\n setTagDescriptions(\n data.tags.reduce((acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n }, {} as Record<string, string>),\n );\n });\n }, [qetaApi, allowCreation, allowedTags]);\n\n if (!allowCreation && availableTags.length === 0) {\n return null;\n }\n\n const getHelperText = () => {\n if (hideHelpText) {\n return '';\n }\n\n const baseText = t('tagsInput.helperText', {\n max: maximumTags.toString(10),\n });\n\n if (!allowCreation) {\n return baseText;\n }\n return `${baseText}. ${t('tagsInput.allowAddHelperText')}`;\n };\n\n const handleSuggestedTagClick = (tag: string) => {\n if (value && value.length < maximumTags && !value.includes(tag)) {\n onChange([...value, tag]);\n }\n };\n\n return (\n <Box>\n <Autocomplete\n multiple\n id=\"tags-select\"\n className=\"qetaTagInput\"\n value={value}\n loading={loading}\n autoHighlight\n autoComplete\n loadingText={t('common.loading')}\n options={availableTags ?? []}\n freeSolo={allowCreation}\n handleHomeEndKeys\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n renderOption={option => {\n if (tagDescriptions[option]) {\n return (\n <span key={option}>\n <Tooltip\n arrow\n placement=\"right\"\n title={<Typography>{tagDescriptions[option]}</Typography>}\n >\n <span>{option}</span>\n </Tooltip>\n </span>\n );\n }\n return option;\n }}\n onChange={(_e, newValue) => {\n const tags = filterTags(newValue);\n if (\n tags &&\n tags.length <= maximumTags &&\n tags.length === newValue.length\n ) {\n onChange(tags);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label={t('tagsInput.label')}\n placeholder={t('tagsInput.placeholder')}\n helperText={error !== undefined ? error.message : getHelperText()}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n name={name}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? (\n <CircularProgress color=\"inherit\" size={20} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n error={error !== undefined}\n />\n )}\n />\n {suggestedTags?.length > 0 && (\n <Box style={{ marginLeft: '4px' }}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {t('tagsInput.suggestedTags')}\n </Typography>\n <Box mt={0.5}>\n {suggestedTags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n size=\"small\"\n onClick={() => handleSuggestedTagClick(tag)}\n style={{ margin: '0 4px 4px 0' }}\n disabled={\n value?.includes(tag) || (value?.length ?? 0) >= maximumTags\n }\n />\n ))}\n </Box>\n </Box>\n )}{' '}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TagInput.esm.js","sources":["../../../src/components/PostForm/TagInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport {\n Box,\n Chip,\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { qetaApiRef } from '../../api';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n filterTags,\n qetaCreateTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { FieldError } from 'react-hook-form';\nimport { AutocompleteListboxComponent } from './AutocompleteListComponent';\nimport { permissionApiRef } from '@backstage/plugin-permission-react';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { useDebounce } from 'react-use';\n\nexport const TagInput = (props: {\n value?: string[];\n onChange: (value: string[]) => void;\n error?: FieldError;\n allowCreate?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n title?: string;\n name?: string;\n content?: string;\n}) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n } = props;\n const qetaApi = useApi(qetaApiRef);\n const config = useApi(configApiRef);\n const permissions = useApi(permissionApiRef);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [allowCreation, setAllowCreation] = useState<boolean | undefined>(\n allowCreate,\n );\n const [loading, setLoading] = useState(true);\n const [suggestedTags, setSuggestedTags] = useState<string[]>([]);\n const [, setLoadingSuggestions] = useState(false);\n\n useEffect(() => {\n if (allowCreate !== undefined) {\n return;\n }\n\n if (config.getOptionalBoolean('qeta.permissions') === true) {\n permissions\n .authorize({\n permission: qetaCreateTagPermission,\n })\n .catch(_ => setAllowCreation(false))\n .then(res => {\n if (res && res.result === AuthorizeResult.ALLOW) {\n setAllowCreation(true);\n } else {\n setAllowCreation(false);\n }\n });\n } else {\n setAllowCreation(\n config.getOptionalBoolean('qeta.tags.allowCreation') ?? true,\n );\n }\n }, [config, permissions, allowCreate]);\n\n useDebounce(\n () => {\n if (title && content) {\n setLoadingSuggestions(true);\n qetaApi\n .getTagSuggestions({ title, content })\n .then(response => {\n setSuggestedTags(response.tags);\n })\n .catch(() => {\n // Ignore errors\n })\n .finally(() => {\n setLoadingSuggestions(false);\n });\n }\n },\n 2000,\n [title, content, qetaApi],\n );\n\n const allowedTags = useMemo(\n () => config.getOptionalStringArray('qeta.tags.allowedTags') ?? [],\n [config],\n );\n const maximumTags = useMemo(\n () => config.getOptionalNumber('qeta.tags.max') ?? 5,\n [config],\n );\n\n const [availableTags, setAvailableTags] = useState<string[]>([]);\n const [tagDescriptions, setTagDescriptions] = useState<\n Record<string, string>\n >({});\n useEffect(() => {\n qetaApi\n .getTags()\n .catch(_ => setAvailableTags([]))\n .then(data => {\n setLoading(false);\n if (!data) {\n return;\n }\n\n const uniqueTags = [\n ...new Set([...allowedTags, ...data.tags.map(tag => tag.tag)]),\n ].sort((a, b) => a.localeCompare(b));\n setAvailableTags(uniqueTags);\n setTagDescriptions(\n data.tags.reduce((acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n }, {} as Record<string, string>),\n );\n });\n }, [qetaApi, allowCreation, allowedTags]);\n\n if (!allowCreation && availableTags.length === 0) {\n return null;\n }\n\n const getHelperText = () => {\n if (hideHelpText) {\n return '';\n }\n\n const baseText = t('tagsInput.helperText', {\n max: maximumTags.toString(10),\n });\n\n if (!allowCreation) {\n return baseText;\n }\n return `${baseText}. ${t('tagsInput.allowAddHelperText')}`;\n };\n\n const handleSuggestedTagClick = (tag: string) => {\n if (value && value.length < maximumTags && !value.includes(tag)) {\n onChange([...value, tag]);\n }\n };\n\n return (\n <Box>\n <Autocomplete\n multiple\n id=\"tags-select\"\n className=\"qetaTagInput\"\n value={value}\n loading={loading}\n autoHighlight\n autoComplete\n loadingText={t('common.loading')}\n options={availableTags ?? []}\n freeSolo={allowCreation}\n handleHomeEndKeys\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n renderOption={option => {\n if (tagDescriptions[option]) {\n return (\n <span key={option}>\n <Tooltip\n arrow\n placement=\"right\"\n title={<Typography>{tagDescriptions[option]}</Typography>}\n >\n <span>{option}</span>\n </Tooltip>\n </span>\n );\n }\n return option;\n }}\n onChange={(_e, newValue) => {\n const tags = filterTags(newValue);\n if (\n tags &&\n tags.length <= maximumTags &&\n tags.length === newValue.length\n ) {\n onChange(tags);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label={t('tagsInput.label')}\n placeholder={t('tagsInput.placeholder')}\n helperText={error !== undefined ? error.message : getHelperText()}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n name={name}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? (\n <CircularProgress color=\"inherit\" size={20} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n error={error !== undefined}\n />\n )}\n />\n {suggestedTags?.length > 0 && (\n <Box style={{ marginLeft: '4px' }}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {t('tagsInput.suggestedTags')}\n </Typography>\n <Box mt={0.5}>\n {suggestedTags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n size=\"small\"\n onClick={() => handleSuggestedTagClick(tag)}\n style={{ margin: '0 4px 4px 0' }}\n disabled={\n value?.includes(tag) || (value?.length ?? 0) >= maximumTags\n }\n />\n ))}\n </Box>\n </Box>\n )}{' '}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,13 +2,14 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { Modal, Backdrop, Typography, Grid, TextField, Button } from '@material-ui/core';
|
|
3
3
|
import { Alert } from '@material-ui/lab';
|
|
4
4
|
import { useState } from 'react';
|
|
5
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useApi, alertApiRef } from '@backstage/core-plugin-api';
|
|
6
6
|
import { qetaApiRef } from '../../api.esm.js';
|
|
7
7
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
8
8
|
import { qetaTranslationRef } from '../../translation.esm.js';
|
|
9
9
|
import { ModalContent } from '../Utility/ModalContent.esm.js';
|
|
10
10
|
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
11
11
|
import { EntitiesInput } from '../PostForm/EntitiesInput.esm.js';
|
|
12
|
+
import { isValidTag } from '@drodil/backstage-plugin-qeta-common';
|
|
12
13
|
|
|
13
14
|
const CreateTagModal = (props) => {
|
|
14
15
|
const { open, onClose, isModerator } = props;
|
|
@@ -16,9 +17,18 @@ const CreateTagModal = (props) => {
|
|
|
16
17
|
const [description, setDescription] = useState("");
|
|
17
18
|
const [experts, setExperts] = useState([]);
|
|
18
19
|
const { t } = useTranslationRef(qetaTranslationRef);
|
|
20
|
+
const alertApi = useApi(alertApiRef);
|
|
19
21
|
const [error, setError] = useState(false);
|
|
20
22
|
const qetaApi = useApi(qetaApiRef);
|
|
21
23
|
const handleCreate = () => {
|
|
24
|
+
if (!isValidTag(tag)) {
|
|
25
|
+
alertApi.post({
|
|
26
|
+
message: t("createTagModal.invalidTagAlert"),
|
|
27
|
+
severity: "error",
|
|
28
|
+
display: "transient"
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
22
32
|
qetaApi.createTag(
|
|
23
33
|
tag,
|
|
24
34
|
description,
|
|
@@ -32,7 +42,12 @@ const CreateTagModal = (props) => {
|
|
|
32
42
|
return;
|
|
33
43
|
}
|
|
34
44
|
setError(true);
|
|
35
|
-
}).catch(() => {
|
|
45
|
+
}).catch((e) => {
|
|
46
|
+
alertApi.post({
|
|
47
|
+
message: e.message,
|
|
48
|
+
severity: "error",
|
|
49
|
+
display: "transient"
|
|
50
|
+
});
|
|
36
51
|
setError(true);
|
|
37
52
|
});
|
|
38
53
|
};
|
|
@@ -1 +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 { useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { ModalContent } from '../Utility/ModalContent';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { EntitiesInput } from '../PostForm/EntitiesInput.tsx';\n\nexport const CreateTagModal = (props: {\n open: boolean;\n onClose: () => void;\n isModerator?: boolean;\n}) => {\n const { open, onClose, isModerator } = props;\n const [tag, setTag] = useState('');\n const [description, setDescription] = useState('');\n const [experts, setExperts] = useState<Entity[]>([]);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [error, setError] = useState(false);\n const qetaApi = useApi(qetaApiRef);\n\n const handleCreate = () => {\n qetaApi\n .createTag(\n tag,\n description,\n isModerator ? experts.map(stringifyEntityRef) : undefined,\n )\n .then(ret => {\n if (ret) {\n setTag('');\n setDescription('');\n setExperts([]);\n onClose();\n return;\n }\n setError(true);\n })\n .catch(
|
|
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 { useState } from 'react';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { ModalContent } from '../Utility/ModalContent';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { EntitiesInput } from '../PostForm/EntitiesInput.tsx';\nimport { isValidTag } from '@drodil/backstage-plugin-qeta-common';\n\nexport const CreateTagModal = (props: {\n open: boolean;\n onClose: () => void;\n isModerator?: boolean;\n}) => {\n const { open, onClose, isModerator } = props;\n const [tag, setTag] = useState('');\n const [description, setDescription] = useState('');\n const [experts, setExperts] = useState<Entity[]>([]);\n const { t } = useTranslationRef(qetaTranslationRef);\n const alertApi = useApi(alertApiRef);\n const [error, setError] = useState(false);\n const qetaApi = useApi(qetaApiRef);\n\n const handleCreate = () => {\n if (!isValidTag(tag)) {\n alertApi.post({\n message: t('createTagModal.invalidTagAlert'),\n severity: 'error',\n display: 'transient',\n });\n return;\n }\n\n qetaApi\n .createTag(\n tag,\n description,\n isModerator ? experts.map(stringifyEntityRef) : undefined,\n )\n .then(ret => {\n if (ret) {\n setTag('');\n setDescription('');\n setExperts([]);\n onClose();\n return;\n }\n setError(true);\n })\n .catch(e => {\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n });\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 {isModerator && (\n <Grid item xs={12}>\n <EntitiesInput\n value={experts}\n onChange={setExperts}\n maximum={null}\n kind={['User']}\n hideHelpText\n label={t('editTagModal.expertsLabel')}\n placeholder={t('editTagModal.expertsPlaceholder')}\n />\n </Grid>\n )}\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":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { Modal, Backdrop, Typography, Grid, TextField, Button } from '@material-ui/core';
|
|
3
3
|
import { Alert } from '@material-ui/lab';
|
|
4
4
|
import { useState, useEffect } from 'react';
|
|
5
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
5
|
+
import { useApi, alertApiRef } from '@backstage/core-plugin-api';
|
|
6
6
|
import { qetaApiRef } from '../../api.esm.js';
|
|
7
7
|
import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
|
|
8
8
|
import { qetaTranslationRef } from '../../translation.esm.js';
|
|
@@ -20,14 +20,23 @@ const EditTagModal = (props) => {
|
|
|
20
20
|
const [error, setError] = useState(false);
|
|
21
21
|
const qetaApi = useApi(qetaApiRef);
|
|
22
22
|
const catalogApi = useApi(catalogApiRef);
|
|
23
|
+
const alertApi = useApi(alertApiRef);
|
|
23
24
|
useEffect(() => {
|
|
24
25
|
if (!isModerator || !tag.experts || tag.experts.length === 0) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
|
-
catalogApi.getEntitiesByRefs({ entityRefs: tag.experts }).
|
|
28
|
-
|
|
28
|
+
catalogApi.getEntitiesByRefs({ entityRefs: tag.experts }).catch(
|
|
29
|
+
(e) => alertApi.post({
|
|
30
|
+
message: e.message,
|
|
31
|
+
severity: "error",
|
|
32
|
+
display: "transient"
|
|
33
|
+
})
|
|
34
|
+
).then((resp) => {
|
|
35
|
+
if (resp) {
|
|
36
|
+
setExperts(compact(resp.items));
|
|
37
|
+
}
|
|
29
38
|
});
|
|
30
|
-
}, [catalogApi, isModerator, tag.experts]);
|
|
39
|
+
}, [alertApi, catalogApi, isModerator, tag.experts]);
|
|
31
40
|
const handleUpdate = () => {
|
|
32
41
|
qetaApi.updateTag(
|
|
33
42
|
tag.id,
|
|
@@ -39,8 +48,13 @@ const EditTagModal = (props) => {
|
|
|
39
48
|
return;
|
|
40
49
|
}
|
|
41
50
|
setError(true);
|
|
42
|
-
}).catch(() => {
|
|
51
|
+
}).catch((e) => {
|
|
43
52
|
setError(true);
|
|
53
|
+
alertApi.post({
|
|
54
|
+
message: e.message,
|
|
55
|
+
severity: "error",
|
|
56
|
+
display: "transient"
|
|
57
|
+
});
|
|
44
58
|
});
|
|
45
59
|
};
|
|
46
60
|
return /* @__PURE__ */ jsx(
|
|
@@ -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 { useEffect, useState } from 'react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { ModalContent } from '../Utility/ModalContent';\nimport { EntitiesInput } from '../PostForm/EntitiesInput.tsx';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { compact } from 'lodash';\n\nexport const EditTagModal = (props: {\n tag: TagResponse;\n open: boolean;\n onClose: () => void;\n isModerator?: boolean;\n}) => {\n const { tag, open, onClose, isModerator } = props;\n const [description, setDescription] = useState(tag.description);\n const [experts, setExperts] = useState<Entity[]>([]);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [error, setError] = useState(false);\n const qetaApi = useApi(qetaApiRef);\n const catalogApi = useApi(catalogApiRef);\n\n useEffect(() => {\n if (!isModerator || !tag.experts || tag.experts.length === 0) {\n return;\n }\n catalogApi.getEntitiesByRefs({ entityRefs: tag.experts }).then(resp => {\n
|
|
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 { useEffect, useState } from 'react';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { ModalContent } from '../Utility/ModalContent';\nimport { EntitiesInput } from '../PostForm/EntitiesInput.tsx';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { compact } from 'lodash';\n\nexport const EditTagModal = (props: {\n tag: TagResponse;\n open: boolean;\n onClose: () => void;\n isModerator?: boolean;\n}) => {\n const { tag, open, onClose, isModerator } = props;\n const [description, setDescription] = useState(tag.description);\n const [experts, setExperts] = useState<Entity[]>([]);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [error, setError] = useState(false);\n const qetaApi = useApi(qetaApiRef);\n const catalogApi = useApi(catalogApiRef);\n const alertApi = useApi(alertApiRef);\n\n useEffect(() => {\n if (!isModerator || !tag.experts || tag.experts.length === 0) {\n return;\n }\n catalogApi\n .getEntitiesByRefs({ entityRefs: tag.experts })\n .catch(e =>\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n }),\n )\n .then(resp => {\n if (resp) {\n setExperts(compact(resp.items));\n }\n });\n }, [alertApi, catalogApi, isModerator, tag.experts]);\n\n const handleUpdate = () => {\n qetaApi\n .updateTag(\n tag.id,\n description,\n isModerator ? experts.map(stringifyEntityRef) : undefined,\n )\n .then(ret => {\n if (ret) {\n onClose();\n return;\n }\n setError(true);\n })\n .catch(e => {\n setError(true);\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n });\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 {isModerator && (\n <Grid item xs={12}>\n <EntitiesInput\n value={experts}\n onChange={setExperts}\n maximum={null}\n kind={['User']}\n hideHelpText\n label={t('editTagModal.expertsLabel')}\n placeholder={t('editTagModal.expertsPlaceholder')}\n />\n </Grid>\n )}\n </Grid>\n\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":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
|
-
import { useApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import { useApi, alertApiRef } from '@backstage/core-plugin-api';
|
|
4
4
|
import { qetaApiRef } from '../../api.esm.js';
|
|
5
5
|
import 'react-use';
|
|
6
6
|
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
@@ -60,6 +60,7 @@ const TemplateForm = (props) => {
|
|
|
60
60
|
const [posting, setPosting] = useState(false);
|
|
61
61
|
const catalogApi = useApi(catalogApiRef);
|
|
62
62
|
const qetaApi = useApi(qetaApiRef);
|
|
63
|
+
const alertApi = useApi(alertApiRef);
|
|
63
64
|
const [error, setError] = useState(false);
|
|
64
65
|
const [values, setValues] = useState(getDefaultValues());
|
|
65
66
|
const { isModerator } = useIsModerator();
|
|
@@ -78,20 +79,33 @@ const TemplateForm = (props) => {
|
|
|
78
79
|
});
|
|
79
80
|
useEffect(() => {
|
|
80
81
|
if (id) {
|
|
81
|
-
getValues(qetaApi, catalogApi, id.toString(10)).
|
|
82
|
-
|
|
82
|
+
getValues(qetaApi, catalogApi, id.toString(10)).catch(
|
|
83
|
+
(e) => alertApi.post({
|
|
84
|
+
message: e.message,
|
|
85
|
+
severity: "error",
|
|
86
|
+
display: "transient"
|
|
87
|
+
})
|
|
88
|
+
).then((data) => {
|
|
89
|
+
if (data) {
|
|
90
|
+
setValues(data);
|
|
91
|
+
}
|
|
83
92
|
});
|
|
84
93
|
}
|
|
85
|
-
}, [qetaApi, catalogApi, id]);
|
|
94
|
+
}, [qetaApi, catalogApi, id, alertApi]);
|
|
86
95
|
const postTemplate = (data) => {
|
|
87
96
|
setPosting(true);
|
|
88
97
|
if (id) {
|
|
89
98
|
qetaApi.updateTemplate(id, formToRequest(data)).then((_q) => {
|
|
90
99
|
reset();
|
|
91
100
|
onPost();
|
|
92
|
-
}).catch((
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
}).catch((e) => {
|
|
102
|
+
setError(true);
|
|
103
|
+
alertApi.post({
|
|
104
|
+
message: e.message,
|
|
105
|
+
severity: "error",
|
|
106
|
+
display: "transient"
|
|
107
|
+
});
|
|
108
|
+
}).finally(() => setPosting(false));
|
|
95
109
|
return;
|
|
96
110
|
}
|
|
97
111
|
qetaApi.createTemplate(formToRequest(data)).then((q) => {
|
|
@@ -101,10 +115,14 @@ const TemplateForm = (props) => {
|
|
|
101
115
|
}
|
|
102
116
|
reset();
|
|
103
117
|
onPost();
|
|
104
|
-
}).catch((
|
|
118
|
+
}).catch((e) => {
|
|
105
119
|
setError(true);
|
|
106
|
-
|
|
107
|
-
|
|
120
|
+
alertApi.post({
|
|
121
|
+
message: e.message,
|
|
122
|
+
severity: "error",
|
|
123
|
+
display: "transient"
|
|
124
|
+
});
|
|
125
|
+
}).finally(() => setPosting(false));
|
|
108
126
|
};
|
|
109
127
|
if (!isModerator) {
|
|
110
128
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateForm.esm.js","sources":["../../../src/components/TemplateList/TemplateForm.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useIsModerator } from '../../hooks';\nimport { QetaApi, TemplateRequest } from '@drodil/backstage-plugin-qeta-common';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { Controller, useForm } from 'react-hook-form';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { compact } from 'lodash';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { MarkdownEditor } from '../MarkdownEditor/MarkdownEditor';\nimport { TagInput } from '../PostForm/TagInput';\nimport { EntitiesInput } from '../PostForm/EntitiesInput';\nimport { TemplateFormValues } from '../PostForm/types';\nimport { Button, TextField } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\n\nconst formToRequest = (form: TemplateFormValues): TemplateRequest => {\n return {\n ...form,\n entities: form.entities?.map(stringifyEntityRef),\n };\n};\n\nconst getDefaultValues = (): TemplateFormValues => {\n return {\n title: '',\n description: '',\n tags: [],\n entities: [],\n };\n};\n\nconst getValues = async (\n api: QetaApi,\n catalogApi: CatalogApi,\n id?: string,\n): Promise<TemplateFormValues> => {\n if (!id) {\n return getDefaultValues();\n }\n\n const template = await api.getTemplate(id);\n const entities =\n template.entities && template.entities.length > 0\n ? await catalogApi.getEntitiesByRefs({\n entityRefs: template.entities,\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n ],\n })\n : [];\n return {\n title: template.title,\n description: template.description,\n questionTitle: template.questionTitle,\n questionContent: template.questionContent,\n tags: template.tags ?? [],\n entities: 'items' in entities ? compact(entities.items) : [],\n };\n};\n\nexport const TemplateForm = (props: { id?: number; onPost: () => void }) => {\n const { id, onPost } = props;\n const [posting, setPosting] = useState(false);\n const catalogApi = useApi(catalogApiRef);\n const qetaApi = useApi(qetaApiRef);\n const [error, setError] = useState(false);\n const [values, setValues] = useState(getDefaultValues());\n const { isModerator } = useIsModerator();\n const { t } = useTranslationRef(qetaTranslationRef);\n const {\n register,\n handleSubmit,\n control,\n getValues: getFormValues,\n setValue,\n reset,\n formState: { errors },\n } = useForm<TemplateFormValues>({\n values,\n defaultValues: getDefaultValues(),\n });\n\n useEffect(() => {\n if (id) {\n getValues(qetaApi, catalogApi, id.toString(10)).then(data => {\n setValues(data);\n });\n }\n }, [qetaApi, catalogApi, id]);\n\n const postTemplate = (data: TemplateFormValues) => {\n setPosting(true);\n\n if (id) {\n qetaApi\n .updateTemplate(id, formToRequest(data))\n .then(_q => {\n reset();\n onPost();\n })\n .catch(_e => {\n setPosting(false);\n });\n return;\n }\n qetaApi\n .createTemplate(formToRequest(data))\n .then(q => {\n if (!q || !q.id) {\n setError(true);\n return;\n }\n reset();\n onPost();\n })\n .catch(_e => {\n setError(true);\n setPosting(false);\n });\n };\n\n if (!isModerator) {\n return null;\n }\n\n return (\n <form onSubmit={handleSubmit(postTemplate)}>\n {error && (\n <Alert severity=\"error\">{t('templateList.errorPosting')}</Alert>\n )}\n <TextField\n label={t('templateList.titleInput.label')}\n className=\"qetaTemplateFormTitle\"\n required\n fullWidth\n error={'title' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n helperText={t('templateList.titleInput.helperText')}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n {\n // @ts-ignore\n ...register('title', { required: true, maxLength: 255 })\n }\n />\n\n <TextField\n label={t('templateList.descriptionInput.label')}\n className=\"qetaTemplateFormDescription\"\n required\n fullWidth\n error={'description' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n helperText={t('templateList.descriptionInput.helperText')}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n {\n // @ts-ignore\n ...register('description', { required: true, maxLength: 255 })\n }\n />\n\n <TextField\n label={t('templateList.questionTitleInput.label')}\n className=\"qetaTemplateFormQuestionTitle\"\n fullWidth\n error={'questionTitle' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n helperText={t('templateList.questionTitleInput.helperText')}\n {\n // @ts-ignore\n ...register('questionTitle', { maxLength: 255 })\n }\n />\n\n <Controller\n control={control}\n rules={{}}\n render={({ field: { onChange, value } }) => (\n <MarkdownEditor\n value={value ?? ''}\n disableAttachments\n onChange={onChange}\n height={400}\n error={'questionContent' in errors}\n placeholder={t('templateList.questionContentInput.placeholder')}\n onTagsChange={tags => {\n const existing = getFormValues('tags') ?? [];\n const newTags = [...new Set([...existing, ...tags])];\n setValue('tags', newTags, { shouldValidate: true });\n }}\n />\n )}\n name=\"questionContent\"\n />\n <Controller\n control={control}\n render={({\n field: { onChange, value },\n fieldState: { error: tagError },\n }) => <TagInput value={value} onChange={onChange} error={tagError} />}\n name=\"tags\"\n />\n <Controller\n control={control}\n render={({ field: { onChange, value } }) => (\n <EntitiesInput value={value} onChange={onChange} />\n )}\n name=\"entities\"\n />\n <Button\n color=\"primary\"\n type=\"submit\"\n variant=\"contained\"\n disabled={posting}\n >\n {id\n ? t('templateList.submit.existingTemplate')\n : t('templateList.submit.newTemplate')}\n </Button>\n </form>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TemplateForm.esm.js","sources":["../../../src/components/TemplateList/TemplateForm.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { useIsModerator } from '../../hooks';\nimport { QetaApi, TemplateRequest } from '@drodil/backstage-plugin-qeta-common';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { qetaApiRef } from '../../api';\nimport { Controller, useForm } from 'react-hook-form';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { compact } from 'lodash';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { MarkdownEditor } from '../MarkdownEditor/MarkdownEditor';\nimport { TagInput } from '../PostForm/TagInput';\nimport { EntitiesInput } from '../PostForm/EntitiesInput';\nimport { TemplateFormValues } from '../PostForm/types';\nimport { Button, TextField } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\n\nconst formToRequest = (form: TemplateFormValues): TemplateRequest => {\n return {\n ...form,\n entities: form.entities?.map(stringifyEntityRef),\n };\n};\n\nconst getDefaultValues = (): TemplateFormValues => {\n return {\n title: '',\n description: '',\n tags: [],\n entities: [],\n };\n};\n\nconst getValues = async (\n api: QetaApi,\n catalogApi: CatalogApi,\n id?: string,\n): Promise<TemplateFormValues> => {\n if (!id) {\n return getDefaultValues();\n }\n\n const template = await api.getTemplate(id);\n const entities =\n template.entities && template.entities.length > 0\n ? await catalogApi.getEntitiesByRefs({\n entityRefs: template.entities,\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n ],\n })\n : [];\n return {\n title: template.title,\n description: template.description,\n questionTitle: template.questionTitle,\n questionContent: template.questionContent,\n tags: template.tags ?? [],\n entities: 'items' in entities ? compact(entities.items) : [],\n };\n};\n\nexport const TemplateForm = (props: { id?: number; onPost: () => void }) => {\n const { id, onPost } = props;\n const [posting, setPosting] = useState(false);\n const catalogApi = useApi(catalogApiRef);\n const qetaApi = useApi(qetaApiRef);\n const alertApi = useApi(alertApiRef);\n const [error, setError] = useState(false);\n const [values, setValues] = useState(getDefaultValues());\n const { isModerator } = useIsModerator();\n const { t } = useTranslationRef(qetaTranslationRef);\n const {\n register,\n handleSubmit,\n control,\n getValues: getFormValues,\n setValue,\n reset,\n formState: { errors },\n } = useForm<TemplateFormValues>({\n values,\n defaultValues: getDefaultValues(),\n });\n\n useEffect(() => {\n if (id) {\n getValues(qetaApi, catalogApi, id.toString(10))\n .catch(e =>\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n }),\n )\n .then(data => {\n if (data) {\n setValues(data);\n }\n });\n }\n }, [qetaApi, catalogApi, id, alertApi]);\n\n const postTemplate = (data: TemplateFormValues) => {\n setPosting(true);\n\n if (id) {\n qetaApi\n .updateTemplate(id, formToRequest(data))\n .then(_q => {\n reset();\n onPost();\n })\n .catch(e => {\n setError(true);\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n });\n })\n .finally(() => setPosting(false));\n return;\n }\n qetaApi\n .createTemplate(formToRequest(data))\n .then(q => {\n if (!q || !q.id) {\n setError(true);\n return;\n }\n reset();\n onPost();\n })\n .catch(e => {\n setError(true);\n alertApi.post({\n message: e.message,\n severity: 'error',\n display: 'transient',\n });\n })\n .finally(() => setPosting(false));\n };\n\n if (!isModerator) {\n return null;\n }\n\n return (\n <form onSubmit={handleSubmit(postTemplate)}>\n {error && (\n <Alert severity=\"error\">{t('templateList.errorPosting')}</Alert>\n )}\n <TextField\n label={t('templateList.titleInput.label')}\n className=\"qetaTemplateFormTitle\"\n required\n fullWidth\n error={'title' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n helperText={t('templateList.titleInput.helperText')}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n {\n // @ts-ignore\n ...register('title', { required: true, maxLength: 255 })\n }\n />\n\n <TextField\n label={t('templateList.descriptionInput.label')}\n className=\"qetaTemplateFormDescription\"\n required\n fullWidth\n error={'description' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n helperText={t('templateList.descriptionInput.helperText')}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n {\n // @ts-ignore\n ...register('description', { required: true, maxLength: 255 })\n }\n />\n\n <TextField\n label={t('templateList.questionTitleInput.label')}\n className=\"qetaTemplateFormQuestionTitle\"\n fullWidth\n error={'questionTitle' in errors}\n margin=\"normal\"\n variant=\"outlined\"\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n helperText={t('templateList.questionTitleInput.helperText')}\n {\n // @ts-ignore\n ...register('questionTitle', { maxLength: 255 })\n }\n />\n\n <Controller\n control={control}\n rules={{}}\n render={({ field: { onChange, value } }) => (\n <MarkdownEditor\n value={value ?? ''}\n disableAttachments\n onChange={onChange}\n height={400}\n error={'questionContent' in errors}\n placeholder={t('templateList.questionContentInput.placeholder')}\n onTagsChange={tags => {\n const existing = getFormValues('tags') ?? [];\n const newTags = [...new Set([...existing, ...tags])];\n setValue('tags', newTags, { shouldValidate: true });\n }}\n />\n )}\n name=\"questionContent\"\n />\n <Controller\n control={control}\n render={({\n field: { onChange, value },\n fieldState: { error: tagError },\n }) => <TagInput value={value} onChange={onChange} error={tagError} />}\n name=\"tags\"\n />\n <Controller\n control={control}\n render={({ field: { onChange, value } }) => (\n <EntitiesInput value={value} onChange={onChange} />\n )}\n name=\"entities\"\n />\n <Button\n color=\"primary\"\n type=\"submit\"\n variant=\"contained\"\n disabled={posting}\n >\n {id\n ? t('templateList.submit.existingTemplate')\n : t('templateList.submit.newTemplate')}\n </Button>\n </form>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,17 @@ function usePaginatedPosts(props) {
|
|
|
48
48
|
showFilterPanel ? "true" : "false"
|
|
49
49
|
);
|
|
50
50
|
}, [showFilterPanel]);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
setFilters((prev) => ({
|
|
53
|
+
...prev,
|
|
54
|
+
tags,
|
|
55
|
+
entities: entities ?? (entity ? [entity] : void 0),
|
|
56
|
+
type,
|
|
57
|
+
status,
|
|
58
|
+
collectionId: props.collectionId
|
|
59
|
+
}));
|
|
60
|
+
setPage(1);
|
|
61
|
+
}, [tags, entities, entity, type, status, props.collectionId]);
|
|
51
62
|
const onPageChange = (value) => {
|
|
52
63
|
setPage(value);
|
|
53
64
|
setSearchParams((prev) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePaginatedPosts.esm.js","sources":["../../src/hooks/usePaginatedPosts.ts"],"sourcesContent":["import { useAnalytics } from '@backstage/core-plugin-api';\nimport { useEffect, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n FilterKey,\n filterKeys,\n PostFilters,\n} from '../components/FilterPanel/FilterPanel';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { getFiltersWithDateRange } from '../utils';\nimport { filterTags, PostStatus } from '@drodil/backstage-plugin-qeta-common';\nimport { useQetaApi } from './useQetaApi';\n\nexport type PaginatedPostsProps = PostFilters & {\n author?: string;\n showFilters?: boolean;\n showTitle?: boolean;\n title?: string;\n favorite?: boolean;\n showAskButton?: boolean;\n showWriteButton?: boolean;\n showLinkButton?: boolean;\n showNoQuestionsBtn?: boolean;\n initialPageSize?: number;\n collectionId?: number;\n status?: PostStatus;\n};\n\nexport type PostFilterChange = {\n key: keyof PostFilters;\n value?: PostFilters[keyof PostFilters];\n};\n\nconst EXPANDED_LOCAL_STORAGE_KEY = 'qeta-post-filters-expanded';\n\nexport function usePaginatedPosts(props: PaginatedPostsProps) {\n const {\n type,\n tags,\n author,\n entities,\n entity,\n favorite,\n initialPageSize,\n status,\n } = props;\n const analytics = useAnalytics();\n const [page, setPage] = useState(1);\n const [pageCount, setPageCount] = useState(1);\n const [postsPerPage, setPostsPerPage] = useState(initialPageSize ?? 10);\n const [showFilterPanel, setShowFilterPanel] = useState(\n localStorage.getItem(EXPANDED_LOCAL_STORAGE_KEY) === 'true',\n );\n const [searchParams, setSearchParams] = useSearchParams();\n const [searchQuery, setSearchQuery] = useState('');\n const [filters, setFilters] = useState<PostFilters>({\n order: props.order ?? 'desc',\n orderBy: props.orderBy ?? 'created',\n noAnswers: props.noAnswers ?? 'false',\n noCorrectAnswer: props.noCorrectAnswer ?? 'false',\n noVotes: props.noVotes ?? 'false',\n searchQuery: props.searchQuery ?? '',\n entities: entities ?? (entity ? [entity] : undefined),\n tags: tags,\n dateRange: '',\n collectionId: props.collectionId,\n status,\n type,\n });\n\n useEffect(() => {\n localStorage.setItem(\n EXPANDED_LOCAL_STORAGE_KEY,\n showFilterPanel ? 'true' : 'false',\n );\n }, [showFilterPanel]);\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 loadNextPage = () => {\n setPage(prev => prev + 1);\n };\n\n const onFilterChange = (changes: PostFilterChange | PostFilterChange[]) => {\n const changesArray = Array.isArray(changes) ? changes : [changes];\n setPage(1);\n setFilters(prev => {\n const newValue = { ...prev };\n for (const { key, value } of changesArray) {\n (newValue as any)[key] = value;\n }\n return newValue;\n });\n setSearchParams(prev => {\n const newValue = prev;\n for (const { key, value } of changesArray) {\n if (!filterKeys.includes(key as FilterKey)) {\n continue;\n }\n if (!value || value === 'false') {\n newValue.delete(key);\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n newValue.delete(key);\n } else {\n newValue.set(key, value.join(','));\n }\n } else if (typeof value === 'number') {\n newValue.set(key, String(value));\n } else if (value.length > 0) {\n newValue.set(key, value);\n } else {\n newValue.delete(key);\n }\n }\n return newValue;\n });\n };\n\n const onSearchQueryChange = (query: string) => {\n onPageChange(1);\n if (query) {\n analytics.captureEvent('qeta_search', query);\n }\n setSearchQuery(query);\n };\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 400,\n [searchQuery],\n );\n\n useEffect(() => {\n let filtersApplied = false;\n searchParams.forEach((value, key) => {\n try {\n if (key === 'page') {\n const pv = Number.parseInt(value, 10);\n if (pv > 0) {\n setPage(pv);\n } else {\n setPage(1);\n }\n } else if (key === 'postsPerPage') {\n const qpp = Number.parseInt(value, 10);\n if (qpp > 0) setPostsPerPage(qpp);\n } else if (filterKeys.includes(key as FilterKey)) {\n filtersApplied = true;\n if (key === 'tags') {\n filters.tags = filterTags(value.split(',')) ?? [];\n } else if (key === 'entities') {\n filters.entities = value.split(',');\n } else {\n (filters as any)[key] = value;\n }\n }\n } catch (_e) {\n // NOOP\n }\n });\n setFilters(filters);\n if (filtersApplied) {\n setShowFilterPanel(true);\n }\n }, [searchParams, filters]);\n\n const {\n value: response,\n loading,\n error,\n retry,\n } = useQetaApi(\n api => {\n return api.getPosts({\n type,\n limit: postsPerPage,\n offset: (page - 1) * postsPerPage,\n includeEntities: true,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n author,\n favorite,\n status,\n ...(getFiltersWithDateRange(filters) as any),\n });\n },\n [type, page, filters, postsPerPage],\n );\n\n useEffect(() => {\n if (response) {\n setPageCount(Math.ceil(response.total / postsPerPage));\n }\n }, [response, postsPerPage]);\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 setPostsPerPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('postsPerPage', String(value));\n return newValue;\n });\n };\n\n return {\n page,\n setPage,\n postsPerPage,\n setPostsPerPage,\n showFilterPanel,\n setShowFilterPanel,\n searchParams,\n setSearchParams,\n searchQuery,\n setSearchQuery,\n filters,\n setFilters,\n onPageChange,\n onPageSizeChange,\n onFilterChange,\n onSearchQueryChange,\n response,\n loading,\n error,\n loadNextPage,\n pageCount,\n retry,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usePaginatedPosts.esm.js","sources":["../../src/hooks/usePaginatedPosts.ts"],"sourcesContent":["import { useAnalytics } from '@backstage/core-plugin-api';\nimport { useEffect, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n FilterKey,\n filterKeys,\n PostFilters,\n} from '../components/FilterPanel/FilterPanel';\nimport useDebounce from 'react-use/lib/useDebounce';\nimport { getFiltersWithDateRange } from '../utils';\nimport { filterTags, PostStatus } from '@drodil/backstage-plugin-qeta-common';\nimport { useQetaApi } from './useQetaApi';\n\nexport type PaginatedPostsProps = PostFilters & {\n author?: string;\n showFilters?: boolean;\n showTitle?: boolean;\n title?: string;\n favorite?: boolean;\n showAskButton?: boolean;\n showWriteButton?: boolean;\n showLinkButton?: boolean;\n showNoQuestionsBtn?: boolean;\n initialPageSize?: number;\n collectionId?: number;\n status?: PostStatus;\n};\n\nexport type PostFilterChange = {\n key: keyof PostFilters;\n value?: PostFilters[keyof PostFilters];\n};\n\nconst EXPANDED_LOCAL_STORAGE_KEY = 'qeta-post-filters-expanded';\n\nexport function usePaginatedPosts(props: PaginatedPostsProps) {\n const {\n type,\n tags,\n author,\n entities,\n entity,\n favorite,\n initialPageSize,\n status,\n } = props;\n const analytics = useAnalytics();\n const [page, setPage] = useState(1);\n const [pageCount, setPageCount] = useState(1);\n const [postsPerPage, setPostsPerPage] = useState(initialPageSize ?? 10);\n const [showFilterPanel, setShowFilterPanel] = useState(\n localStorage.getItem(EXPANDED_LOCAL_STORAGE_KEY) === 'true',\n );\n const [searchParams, setSearchParams] = useSearchParams();\n const [searchQuery, setSearchQuery] = useState('');\n const [filters, setFilters] = useState<PostFilters>({\n order: props.order ?? 'desc',\n orderBy: props.orderBy ?? 'created',\n noAnswers: props.noAnswers ?? 'false',\n noCorrectAnswer: props.noCorrectAnswer ?? 'false',\n noVotes: props.noVotes ?? 'false',\n searchQuery: props.searchQuery ?? '',\n entities: entities ?? (entity ? [entity] : undefined),\n tags: tags,\n dateRange: '',\n collectionId: props.collectionId,\n status,\n type,\n });\n\n useEffect(() => {\n localStorage.setItem(\n EXPANDED_LOCAL_STORAGE_KEY,\n showFilterPanel ? 'true' : 'false',\n );\n }, [showFilterPanel]);\n\n useEffect(() => {\n setFilters(prev => ({\n ...prev,\n tags: tags,\n entities: entities ?? (entity ? [entity] : undefined),\n type,\n status,\n collectionId: props.collectionId,\n }));\n setPage(1);\n }, [tags, entities, entity, type, status, props.collectionId]);\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 loadNextPage = () => {\n setPage(prev => prev + 1);\n };\n\n const onFilterChange = (changes: PostFilterChange | PostFilterChange[]) => {\n const changesArray = Array.isArray(changes) ? changes : [changes];\n setPage(1);\n setFilters(prev => {\n const newValue = { ...prev };\n for (const { key, value } of changesArray) {\n (newValue as any)[key] = value;\n }\n return newValue;\n });\n setSearchParams(prev => {\n const newValue = prev;\n for (const { key, value } of changesArray) {\n if (!filterKeys.includes(key as FilterKey)) {\n continue;\n }\n if (!value || value === 'false') {\n newValue.delete(key);\n } else if (Array.isArray(value)) {\n if (value.length === 0) {\n newValue.delete(key);\n } else {\n newValue.set(key, value.join(','));\n }\n } else if (typeof value === 'number') {\n newValue.set(key, String(value));\n } else if (value.length > 0) {\n newValue.set(key, value);\n } else {\n newValue.delete(key);\n }\n }\n return newValue;\n });\n };\n\n const onSearchQueryChange = (query: string) => {\n onPageChange(1);\n if (query) {\n analytics.captureEvent('qeta_search', query);\n }\n setSearchQuery(query);\n };\n\n useDebounce(\n () => {\n if (filters.searchQuery !== searchQuery) {\n setFilters({ ...filters, searchQuery: searchQuery });\n }\n },\n 400,\n [searchQuery],\n );\n\n useEffect(() => {\n let filtersApplied = false;\n searchParams.forEach((value, key) => {\n try {\n if (key === 'page') {\n const pv = Number.parseInt(value, 10);\n if (pv > 0) {\n setPage(pv);\n } else {\n setPage(1);\n }\n } else if (key === 'postsPerPage') {\n const qpp = Number.parseInt(value, 10);\n if (qpp > 0) setPostsPerPage(qpp);\n } else if (filterKeys.includes(key as FilterKey)) {\n filtersApplied = true;\n if (key === 'tags') {\n filters.tags = filterTags(value.split(',')) ?? [];\n } else if (key === 'entities') {\n filters.entities = value.split(',');\n } else {\n (filters as any)[key] = value;\n }\n }\n } catch (_e) {\n // NOOP\n }\n });\n setFilters(filters);\n if (filtersApplied) {\n setShowFilterPanel(true);\n }\n }, [searchParams, filters]);\n\n const {\n value: response,\n loading,\n error,\n retry,\n } = useQetaApi(\n api => {\n return api.getPosts({\n type,\n limit: postsPerPage,\n offset: (page - 1) * postsPerPage,\n includeEntities: true,\n includeAnswers: false,\n includeComments: false,\n includeAttachments: false,\n includeExperts: false,\n author,\n favorite,\n status,\n ...(getFiltersWithDateRange(filters) as any),\n });\n },\n [type, page, filters, postsPerPage],\n );\n\n useEffect(() => {\n if (response) {\n setPageCount(Math.ceil(response.total / postsPerPage));\n }\n }, [response, postsPerPage]);\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 setPostsPerPage(value);\n setSearchParams(prev => {\n const newValue = prev;\n newValue.set('postsPerPage', String(value));\n return newValue;\n });\n };\n\n return {\n page,\n setPage,\n postsPerPage,\n setPostsPerPage,\n showFilterPanel,\n setShowFilterPanel,\n searchParams,\n setSearchParams,\n searchQuery,\n setSearchQuery,\n filters,\n setFilters,\n onPageChange,\n onPageSizeChange,\n onFilterChange,\n onSearchQueryChange,\n response,\n loading,\n error,\n loadNextPage,\n pageCount,\n retry,\n };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -764,6 +764,7 @@ declare const qetaTranslationRef: _backstage_core_plugin_api_alpha.TranslationRe
|
|
|
764
764
|
readonly "createTagModal.cancelButton": "Cancel";
|
|
765
765
|
readonly "createTagModal.tagInput": "Tag";
|
|
766
766
|
readonly "createTagModal.createButton": "Create";
|
|
767
|
+
readonly "createTagModal.invalidTagAlert": "Invalid tag given. Tags can only contain lowercase letters, numbers, hyphens, and underscores. Tag must be less than 255 characters.";
|
|
767
768
|
readonly "deleteModal.title.answer": "Are you sure you want to delete this answer?";
|
|
768
769
|
readonly "deleteModal.title.tag": "Are you sure you want to delete this tag?";
|
|
769
770
|
readonly "deleteModal.title.collection": "Are you sure you want to delete this collection?";
|
package/dist/translation.esm.js
CHANGED
|
@@ -278,7 +278,8 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
278
278
|
description: "Tag description",
|
|
279
279
|
errorPosting: "Failed to create",
|
|
280
280
|
createButton: "Create",
|
|
281
|
-
cancelButton: "Cancel"
|
|
281
|
+
cancelButton: "Cancel",
|
|
282
|
+
invalidTagAlert: "Invalid tag given. Tags can only contain lowercase letters, numbers, hyphens, and underscores. Tag must be less than 255 characters."
|
|
282
283
|
},
|
|
283
284
|
deleteModal: {
|
|
284
285
|
title: {
|