@drodil/backstage-plugin-qeta-react 3.55.2 → 3.55.4
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/ArticleContent/ArticleButtons.esm.js +1 -1
- package/dist/components/Badges/BadgeChip.esm.js +14 -6
- package/dist/components/Badges/BadgeChip.esm.js.map +1 -1
- package/dist/components/Badges/UserBadges.esm.js +2 -2
- package/dist/components/Badges/UserBadges.esm.js.map +1 -1
- package/dist/components/Buttons/AddToCollectionButton.esm.js +1 -1
- package/dist/components/Buttons/EntityFollowButton.esm.js +1 -1
- package/dist/components/Buttons/TagFollowButton.esm.js +1 -1
- package/dist/components/Buttons/UserFollowButton.esm.js +1 -1
- package/dist/components/CollectionsContainer/CollectionListItem.esm.js +1 -1
- package/dist/components/ContentHeader/ContentHeader.esm.js +1 -1
- package/dist/components/EntitiesContainer/EntityListItem.esm.js +1 -1
- package/dist/components/FollowedLists/FollowedEntitiesList.esm.js +1 -1
- package/dist/components/FollowedLists/FollowedTagsList.esm.js +1 -1
- package/dist/components/FollowedLists/FollowedUsersList.esm.js +1 -1
- package/dist/components/HomePageCards/ImpactCard.esm.js +1 -1
- package/dist/components/HomePageCards/PostsCard.esm.js +2 -1
- package/dist/components/HomePageCards/PostsCard.esm.js.map +1 -1
- package/dist/components/LeftMenu/LeftMenu.esm.js +4 -15
- package/dist/components/LeftMenu/LeftMenu.esm.js.map +1 -1
- package/dist/components/LinkCard/LinkCard.esm.js +1 -1
- package/dist/components/Links/Links.esm.js +1 -1
- package/dist/components/PostForm/EntitiesInput.esm.js +2 -1
- package/dist/components/PostForm/EntitiesInput.esm.js.map +1 -1
- package/dist/components/PostForm/TagInput.esm.js +1 -1
- package/dist/components/PostForm/TagInput.esm.js.map +1 -1
- package/dist/components/PostHighlightList/PostHighlightList.esm.js +1 -1
- package/dist/components/PostsContainer/PostListItem.esm.js +1 -1
- package/dist/components/PostsContainer/PostsContainer.esm.js +2 -1
- package/dist/components/PostsContainer/PostsContainer.esm.js.map +1 -1
- package/dist/components/PostsContainer/PostsGridItem.esm.js +1 -1
- package/dist/components/PostsTable/PostsTable.esm.js +1 -1
- package/dist/components/QetaContext/QetaContext.esm.js +154 -4
- package/dist/components/QetaContext/QetaContext.esm.js.map +1 -1
- package/dist/components/QuestionCard/QuestionCard.esm.js +1 -1
- package/dist/components/SuggestionsCard/SuggestionsCard.esm.js +1 -1
- package/dist/components/TagsAndEntities/EntityChip.esm.js +1 -1
- package/dist/components/TagsAndEntities/TagChip.esm.js +1 -1
- package/dist/components/TagsAndEntities/UserChip.esm.js +1 -1
- package/dist/components/TagsContainer/TagListItem.esm.js +1 -1
- package/dist/components/TemplateList/TemplateForm.esm.js +2 -1
- package/dist/components/TemplateList/TemplateForm.esm.js.map +1 -1
- package/dist/components/TemplateList/TemplateList.esm.js +1 -1
- package/dist/components/Timeline/TimelineItem.esm.js +1 -1
- package/dist/components/TopRankingUsersCard/TopRankingUsersCard.esm.js +1 -1
- package/dist/components/UsersContainer/UserListItem.esm.js +1 -1
- package/dist/components/UsersContainer/UsersGridItem.esm.js +1 -1
- package/dist/hooks/useUserSettings.esm.js +8 -104
- package/dist/hooks/useUserSettings.esm.js.map +1 -1
- package/dist/index.d.ts +19 -10
- package/dist/translation.esm.js +3 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +2 -2
|
@@ -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 { 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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"}
|
|
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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"}
|
|
@@ -19,7 +19,7 @@ import { Button, Box, List, ListItem, ListItemText, ListItemSecondaryAction, Ico
|
|
|
19
19
|
import { useNavigate } from 'react-router-dom';
|
|
20
20
|
import 'react-use/lib/useDebounce';
|
|
21
21
|
import '../FilterPanel/FilterPanel.esm.js';
|
|
22
|
-
import '
|
|
22
|
+
import '../QetaContext/QetaContext.esm.js';
|
|
23
23
|
import { Progress, WarningPanel } from '@backstage/core-components';
|
|
24
24
|
import EditIcon from '@material-ui/icons/Edit';
|
|
25
25
|
import DeleteIcon from '@material-ui/icons/Delete';
|
|
@@ -19,7 +19,7 @@ import '@drodil/backstage-plugin-qeta-common';
|
|
|
19
19
|
import '@backstage/plugin-permission-common';
|
|
20
20
|
import 'react-use/lib/useDebounce';
|
|
21
21
|
import '../FilterPanel/FilterPanel.esm.js';
|
|
22
|
-
import '
|
|
22
|
+
import '../QetaContext/QetaContext.esm.js';
|
|
23
23
|
|
|
24
24
|
const useStyles = makeStyles((theme) => ({
|
|
25
25
|
root: {
|
|
@@ -21,7 +21,7 @@ import '@backstage/plugin-permission-common';
|
|
|
21
21
|
import 'react-router-dom';
|
|
22
22
|
import 'react-use/lib/useDebounce';
|
|
23
23
|
import '../FilterPanel/FilterPanel.esm.js';
|
|
24
|
-
import '
|
|
24
|
+
import '../QetaContext/QetaContext.esm.js';
|
|
25
25
|
|
|
26
26
|
const useStyles = makeStyles((theme) => {
|
|
27
27
|
return {
|
|
@@ -17,7 +17,7 @@ import { makeStyles, Avatar, Box, Tooltip, Typography } from '@material-ui/core'
|
|
|
17
17
|
import { Link } from 'react-router-dom';
|
|
18
18
|
import 'react-use/lib/useDebounce';
|
|
19
19
|
import '../FilterPanel/FilterPanel.esm.js';
|
|
20
|
-
import '
|
|
20
|
+
import '../QetaContext/QetaContext.esm.js';
|
|
21
21
|
import { UserFollowButton } from '../Buttons/UserFollowButton.esm.js';
|
|
22
22
|
import Visibility from '@material-ui/icons/Visibility';
|
|
23
23
|
import QuestionAnswerIcon from '@material-ui/icons/QuestionAnswer';
|
|
@@ -18,7 +18,7 @@ import { makeStyles, Card, Box, Avatar, Tooltip, Typography, CardContent, Grid }
|
|
|
18
18
|
import 'react-router-dom';
|
|
19
19
|
import 'react-use/lib/useDebounce';
|
|
20
20
|
import '../FilterPanel/FilterPanel.esm.js';
|
|
21
|
-
import '
|
|
21
|
+
import '../QetaContext/QetaContext.esm.js';
|
|
22
22
|
import { UserFollowButton } from '../Buttons/UserFollowButton.esm.js';
|
|
23
23
|
import Visibility from '@material-ui/icons/Visibility';
|
|
24
24
|
import QuestionAnswerIcon from '@material-ui/icons/QuestionAnswer';
|
|
@@ -1,110 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
-
import { merge } from 'lodash';
|
|
1
|
+
import { useQetaContext } from '../components/QetaContext/QetaContext.esm.js';
|
|
4
2
|
|
|
5
|
-
const DEFAULT_SETTINGS = {
|
|
6
|
-
autoSaveEnabled: false,
|
|
7
|
-
anonymousPosting: false,
|
|
8
|
-
filterPanelExpanded: {},
|
|
9
|
-
viewType: {},
|
|
10
|
-
aiAnswerExpanded: false,
|
|
11
|
-
usePagination: false
|
|
12
|
-
};
|
|
13
|
-
const BUCKET_KEY = "qeta";
|
|
14
|
-
const STORAGE_KEY = "qeta-user-settings";
|
|
15
3
|
const useUserSettings = () => {
|
|
16
|
-
const
|
|
17
|
-
const [settings, setSettings] = useState(DEFAULT_SETTINGS);
|
|
18
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
19
|
-
const settingsRef = useRef(DEFAULT_SETTINGS);
|
|
20
|
-
const isUpdatingRef = useRef(false);
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
settingsRef.current = settings;
|
|
23
|
-
}, [settings]);
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
const bucket = storageApi.forBucket(BUCKET_KEY);
|
|
26
|
-
const snapshot = bucket.snapshot(STORAGE_KEY);
|
|
27
|
-
const stored = snapshot.value;
|
|
28
|
-
if (stored) {
|
|
29
|
-
const merged = merge({}, DEFAULT_SETTINGS, stored);
|
|
30
|
-
setSettings(merged);
|
|
31
|
-
settingsRef.current = merged;
|
|
32
|
-
}
|
|
33
|
-
setIsLoaded(true);
|
|
34
|
-
const subscription = bucket.observe$(STORAGE_KEY).subscribe({
|
|
35
|
-
next: (newSnapshot) => {
|
|
36
|
-
if (isUpdatingRef.current) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const value = newSnapshot.value;
|
|
40
|
-
if (value) {
|
|
41
|
-
const merged = merge({}, DEFAULT_SETTINGS, value);
|
|
42
|
-
setSettings(merged);
|
|
43
|
-
settingsRef.current = merged;
|
|
44
|
-
} else {
|
|
45
|
-
setSettings(DEFAULT_SETTINGS);
|
|
46
|
-
settingsRef.current = DEFAULT_SETTINGS;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
return () => {
|
|
51
|
-
subscription.unsubscribe();
|
|
52
|
-
};
|
|
53
|
-
}, [storageApi]);
|
|
54
|
-
const updateSettings = useCallback(
|
|
55
|
-
async (updates) => {
|
|
56
|
-
const bucket = storageApi.forBucket(BUCKET_KEY);
|
|
57
|
-
const currentSettings = settingsRef.current;
|
|
58
|
-
const newSettings = { ...currentSettings };
|
|
59
|
-
Object.keys(updates).forEach((key) => {
|
|
60
|
-
const k = key;
|
|
61
|
-
const value = updates[k];
|
|
62
|
-
if (value !== void 0) {
|
|
63
|
-
if (k === "viewType" || k === "filterPanelExpanded") {
|
|
64
|
-
newSettings[k] = value;
|
|
65
|
-
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
66
|
-
newSettings[k] = merge({}, currentSettings[k], value);
|
|
67
|
-
} else {
|
|
68
|
-
newSettings[k] = value;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
settingsRef.current = newSettings;
|
|
73
|
-
setSettings(newSettings);
|
|
74
|
-
isUpdatingRef.current = true;
|
|
75
|
-
try {
|
|
76
|
-
await bucket.set(STORAGE_KEY, newSettings);
|
|
77
|
-
} finally {
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
isUpdatingRef.current = false;
|
|
80
|
-
}, 100);
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
[storageApi]
|
|
84
|
-
);
|
|
85
|
-
const getSetting = useCallback(
|
|
86
|
-
(key) => {
|
|
87
|
-
return settingsRef.current[key] ?? DEFAULT_SETTINGS[key];
|
|
88
|
-
},
|
|
89
|
-
[]
|
|
90
|
-
);
|
|
91
|
-
const setSetting = useCallback(
|
|
92
|
-
async (key, value) => {
|
|
93
|
-
await updateSettings({ [key]: value });
|
|
94
|
-
},
|
|
95
|
-
[updateSettings]
|
|
96
|
-
);
|
|
97
|
-
const resetSettings = useCallback(async () => {
|
|
98
|
-
const bucket = storageApi.forBucket("qeta");
|
|
99
|
-
await bucket.set(STORAGE_KEY, DEFAULT_SETTINGS);
|
|
100
|
-
}, [storageApi]);
|
|
4
|
+
const context = useQetaContext();
|
|
101
5
|
return {
|
|
102
|
-
settings:
|
|
103
|
-
updateSettings,
|
|
104
|
-
getSetting,
|
|
105
|
-
setSetting,
|
|
106
|
-
resetSettings,
|
|
107
|
-
isLoaded
|
|
6
|
+
settings: context.settings,
|
|
7
|
+
updateSettings: context.updateSettings,
|
|
8
|
+
getSetting: context.getSetting,
|
|
9
|
+
setSetting: context.setSetting,
|
|
10
|
+
resetSettings: context.resetSettings,
|
|
11
|
+
isLoaded: context.isSettingsLoaded ?? false
|
|
108
12
|
};
|
|
109
13
|
};
|
|
110
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUserSettings.esm.js","sources":["../../src/hooks/useUserSettings.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useUserSettings.esm.js","sources":["../../src/hooks/useUserSettings.ts"],"sourcesContent":["import {\n useQetaContext,\n UserSettings,\n} from '../components/QetaContext/QetaContext';\n\nexport type { UserSettings } from '../components/QetaContext/QetaContext';\n\nexport type UserSettingsHook = {\n settings: UserSettings;\n updateSettings: (updates: Partial<UserSettings>) => Promise<void>;\n getSetting: <K extends keyof UserSettings>(key: K) => UserSettings[K];\n setSetting: <K extends keyof UserSettings>(\n key: K,\n value: UserSettings[K],\n ) => Promise<void>;\n resetSettings: () => Promise<void>;\n isLoaded: boolean;\n};\n\nexport const useUserSettings = (): UserSettingsHook => {\n const context = useQetaContext();\n\n return {\n settings: context.settings!,\n updateSettings: context.updateSettings!,\n getSetting: context.getSetting!,\n setSetting: context.setSetting!,\n resetSettings: context.resetSettings!,\n isLoaded: context.isSettingsLoaded ?? false,\n };\n};\n"],"names":[],"mappings":";;AAmBO,MAAM,kBAAkB,MAAwB;AACrD,EAAA,MAAM,UAAU,cAAe,EAAA;AAE/B,EAAO,OAAA;AAAA,IACL,UAAU,OAAQ,CAAA,QAAA;AAAA,IAClB,gBAAgB,OAAQ,CAAA,cAAA;AAAA,IACxB,YAAY,OAAQ,CAAA,UAAA;AAAA,IACpB,YAAY,OAAQ,CAAA,UAAA;AAAA,IACpB,eAAe,OAAQ,CAAA,aAAA;AAAA,IACvB,QAAA,EAAU,QAAQ,gBAAoB,IAAA;AAAA,GACxC;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -531,6 +531,14 @@ declare const FaviconItem: (props: {
|
|
|
531
531
|
entity: PostResponse;
|
|
532
532
|
}) => react_jsx_runtime.JSX.Element;
|
|
533
533
|
|
|
534
|
+
type UserSettings = {
|
|
535
|
+
autoSaveEnabled: boolean;
|
|
536
|
+
anonymousPosting: boolean;
|
|
537
|
+
filterPanelExpanded: Record<string, boolean>;
|
|
538
|
+
viewType: Record<string, ViewType>;
|
|
539
|
+
aiAnswerExpanded: boolean;
|
|
540
|
+
usePagination: boolean;
|
|
541
|
+
};
|
|
534
542
|
type QetaContextProps = {
|
|
535
543
|
remarkPlugins?: PluggableList;
|
|
536
544
|
rehypePlugins?: PluggableList;
|
|
@@ -546,6 +554,12 @@ type QetaContextProps = {
|
|
|
546
554
|
tags?: string[];
|
|
547
555
|
entities?: string[];
|
|
548
556
|
} | undefined>>;
|
|
557
|
+
settings?: UserSettings;
|
|
558
|
+
updateSettings?: (updates: Partial<UserSettings>) => Promise<void>;
|
|
559
|
+
getSetting?: <K extends keyof UserSettings>(key: K) => UserSettings[K];
|
|
560
|
+
setSetting?: <K extends keyof UserSettings>(key: K, value: UserSettings[K]) => Promise<void>;
|
|
561
|
+
resetSettings?: () => Promise<void>;
|
|
562
|
+
isSettingsLoaded?: boolean;
|
|
549
563
|
};
|
|
550
564
|
declare const QetaContext: react.Context<QetaContextProps>;
|
|
551
565
|
declare const QetaProvider: (props: PropsWithChildren<QetaContextProps>) => react_jsx_runtime.JSX.Element;
|
|
@@ -754,15 +768,7 @@ declare function useQetaEntities<T, F>(props: QetaEntitiesProps<T, F>): {
|
|
|
754
768
|
fetchNextPage: () => void;
|
|
755
769
|
};
|
|
756
770
|
|
|
757
|
-
type
|
|
758
|
-
autoSaveEnabled: boolean;
|
|
759
|
-
anonymousPosting: boolean;
|
|
760
|
-
filterPanelExpanded: Record<string, boolean>;
|
|
761
|
-
viewType: Record<string, ViewType>;
|
|
762
|
-
aiAnswerExpanded: boolean;
|
|
763
|
-
usePagination: boolean;
|
|
764
|
-
};
|
|
765
|
-
declare const useUserSettings: () => {
|
|
771
|
+
type UserSettingsHook = {
|
|
766
772
|
settings: UserSettings;
|
|
767
773
|
updateSettings: (updates: Partial<UserSettings>) => Promise<void>;
|
|
768
774
|
getSetting: <K extends keyof UserSettings>(key: K) => UserSettings[K];
|
|
@@ -770,6 +776,7 @@ declare const useUserSettings: () => {
|
|
|
770
776
|
resetSettings: () => Promise<void>;
|
|
771
777
|
isLoaded: boolean;
|
|
772
778
|
};
|
|
779
|
+
declare const useUserSettings: () => UserSettingsHook;
|
|
773
780
|
|
|
774
781
|
/** @alpha */
|
|
775
782
|
declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"qeta", {
|
|
@@ -1085,6 +1092,8 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1085
1092
|
readonly "settingsPage.autoSave.label": "Enable Auto-save";
|
|
1086
1093
|
readonly "settingsPage.editorPreferences": "Editor Preferences";
|
|
1087
1094
|
readonly "settingsPage.displayPreferences": "Display Preferences";
|
|
1095
|
+
readonly "settingsPage.resetAllSettings": "Reset All Settings";
|
|
1096
|
+
readonly "settingsPage.resetAllSettingsDescription": "Reset all user settings to their default values. This will clear all your preferences including view types, auto-save, pagination, and other settings.";
|
|
1088
1097
|
readonly "settingsPage.anonymousPosting.description": "Set posts and answers to anonymous by default when creating new content";
|
|
1089
1098
|
readonly "settingsPage.anonymousPosting.label": "Post Anonymously by default";
|
|
1090
1099
|
readonly "settingsPage.aiAnswerExpanded.description": "Show AI-generated answers in expanded state when viewing questions";
|
|
@@ -1482,4 +1491,4 @@ type QetaOverrides = Overrides & {
|
|
|
1482
1491
|
[Name in keyof QetaComponentsNameToClassKey]?: Partial<StyleRules<QetaComponentsNameToClassKey[Name]>>;
|
|
1483
1492
|
};
|
|
1484
1493
|
|
|
1485
|
-
export { AIAnswerCard, AddToCollectionButton, AnswerCard, AnswerForm, AnswerListItem, AnswersContainer, AnswersGridItem, ArticleContent, AskQuestionButton, AuthorLink, BadgeChip, ButtonContainer, CollectionFollowButton, CollectionForm, CollectionsContainer, ContentHeader, ContentHeaderButton, ContentHeaderCard, type ContentHeaderCardProps, type ContentHeaderProps, CreateCollectionButton, CreateLinkButton, CreateTagModal, DeleteModal, DeletedBanner, DraftBanner, EditTagModal, EntitiesContainer, EntitiesGridItem, EntityFollowButton, EntityListItem, FaviconItem, type FilterChange, FilterPanel, FollowedCollectionsList, FollowedEntitiesList, FollowedTagsList, FollowedUsersList, type GridType, ImpactCard, LeftMenu, LeftMenuButton, LinkCard, MarkdownRenderer, ObsoleteBanner, ObsoleteModal, OpenLinkButton, PostForm, PostHighlightList, PostHighlightListContainer, PostHighlightListContent, PostListItem, PostsCard, PostsContainer, type PostsContainerProps, PostsGridItem, PostsTable, QetaContext, type QetaContextProps, type QetaEntitiesProps, type QetaOverrides, QetaProvider, QuestionCard, type QuestionFormValues, QuestionsTable, RankingButtons, RelativeTimeWithTooltip, SelectTemplateList, StatsChart, StatusChip, SuggestionsCard, type TagAndEntitiesFormValues, TagFollowButton, TagGridItem, TagListItem, TagsContainer, type TemplateFormValues, TemplateList, Timeline, TimelineItemCard, TopRankingUsers, TrophyIcon, UpdatedByLink, UserBadges, UserFollowButton, UserLink, UserListItem, type UserSettings, UsersContainer, UsersGridItem, ValidReviewModal, ViewToggle, type ViewType, WriteArticleButton, articleRouteRef, articlesRouteRef, askRouteRef, collectionCreateRouteRef, collectionEditRouteRef, collectionRouteRef, collectionsRouteRef, createLinkRouteRef, editArticleRouteRef, editLinkRouteRef, editQuestionRouteRef, entitiesRouteRef, entityRouteRef, favoriteQuestionsRouteRef, linkRouteRef, linksRouteRef, moderatorRouteRef, qetaApiRef, qetaRouteRef, qetaTranslationRef, qetaTranslations, questionRouteRef, questionsRouteRef, reviewRouteRef, settingsRouteRef, statisticsRouteRef, tagRouteRef, tagsRouteRef, useAI, useCanReview, useCollectionsFollow, useEntityAuthor, useEntityFollow, useGridPageSize, useIdentityApi, useIsModerator, useListItemStyles, useQetaApi, useQetaContext, useQetaEntities, useTagsFollow, useUserFollow, useUserInfo, useUserSettings, useVoting, userRouteRef, usersRouteRef, writeRouteRef };
|
|
1494
|
+
export { AIAnswerCard, AddToCollectionButton, AnswerCard, AnswerForm, AnswerListItem, AnswersContainer, AnswersGridItem, ArticleContent, AskQuestionButton, AuthorLink, BadgeChip, ButtonContainer, CollectionFollowButton, CollectionForm, CollectionsContainer, ContentHeader, ContentHeaderButton, ContentHeaderCard, type ContentHeaderCardProps, type ContentHeaderProps, CreateCollectionButton, CreateLinkButton, CreateTagModal, DeleteModal, DeletedBanner, DraftBanner, EditTagModal, EntitiesContainer, EntitiesGridItem, EntityFollowButton, EntityListItem, FaviconItem, type FilterChange, FilterPanel, FollowedCollectionsList, FollowedEntitiesList, FollowedTagsList, FollowedUsersList, type GridType, ImpactCard, LeftMenu, LeftMenuButton, LinkCard, MarkdownRenderer, ObsoleteBanner, ObsoleteModal, OpenLinkButton, PostForm, PostHighlightList, PostHighlightListContainer, PostHighlightListContent, PostListItem, PostsCard, PostsContainer, type PostsContainerProps, PostsGridItem, PostsTable, QetaContext, type QetaContextProps, type QetaEntitiesProps, type QetaOverrides, QetaProvider, QuestionCard, type QuestionFormValues, QuestionsTable, RankingButtons, RelativeTimeWithTooltip, SelectTemplateList, StatsChart, StatusChip, SuggestionsCard, type TagAndEntitiesFormValues, TagFollowButton, TagGridItem, TagListItem, TagsContainer, type TemplateFormValues, TemplateList, Timeline, TimelineItemCard, TopRankingUsers, TrophyIcon, UpdatedByLink, UserBadges, UserFollowButton, UserLink, UserListItem, type UserSettings, type UserSettingsHook, UsersContainer, UsersGridItem, ValidReviewModal, ViewToggle, type ViewType, WriteArticleButton, articleRouteRef, articlesRouteRef, askRouteRef, collectionCreateRouteRef, collectionEditRouteRef, collectionRouteRef, collectionsRouteRef, createLinkRouteRef, editArticleRouteRef, editLinkRouteRef, editQuestionRouteRef, entitiesRouteRef, entityRouteRef, favoriteQuestionsRouteRef, linkRouteRef, linksRouteRef, moderatorRouteRef, qetaApiRef, qetaRouteRef, qetaTranslationRef, qetaTranslations, questionRouteRef, questionsRouteRef, reviewRouteRef, settingsRouteRef, statisticsRouteRef, tagRouteRef, tagsRouteRef, useAI, useCanReview, useCollectionsFollow, useEntityAuthor, useEntityFollow, useGridPageSize, useIdentityApi, useIsModerator, useListItemStyles, useQetaApi, useQetaContext, useQetaEntities, useTagsFollow, useUserFollow, useUserInfo, useUserSettings, useVoting, userRouteRef, usersRouteRef, writeRouteRef };
|
package/dist/translation.esm.js
CHANGED
|
@@ -441,7 +441,9 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
441
441
|
userCollections: "User page collections",
|
|
442
442
|
userAnswers: "User page answers"
|
|
443
443
|
}
|
|
444
|
-
}
|
|
444
|
+
},
|
|
445
|
+
resetAllSettings: "Reset All Settings",
|
|
446
|
+
resetAllSettingsDescription: "Reset all user settings to their default values. This will clear all your preferences including view types, auto-save, pagination, and other settings."
|
|
445
447
|
},
|
|
446
448
|
suggestionsCard: {
|
|
447
449
|
title: "Suggestions",
|