@drodil/backstage-plugin-qeta-react 3.59.6 → 3.59.9
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/FilterPanel/FilterPanel.esm.js +3 -3
- package/dist/components/FilterPanel/FilterPanel.esm.js.map +1 -1
- package/dist/components/MarkdownEditor/MarkdownEditor.esm.js +1 -1
- package/dist/components/MarkdownEditor/MarkdownEditor.esm.js.map +1 -1
- package/dist/components/PostForm/EntitiesInput.esm.js +321 -83
- package/dist/components/PostForm/EntitiesInput.esm.js.map +1 -1
- package/dist/components/PostForm/TagInput.esm.js +175 -31
- package/dist/components/PostForm/TagInput.esm.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/translation.esm.js +1 -0
- package/dist/translation.esm.js.map +1 -1
- package/package.json +13 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { Autocomplete } from '@material-ui/lab';
|
|
3
3
|
import { Box, TextField, CircularProgress, Tooltip, Typography, Chip } from '@material-ui/core';
|
|
4
|
-
import { forwardRef, useState, useEffect, useMemo } from 'react';
|
|
4
|
+
import { forwardRef, useState, useRef, useEffect, useMemo } from 'react';
|
|
5
5
|
import { qetaApiRef } from '../../api.esm.js';
|
|
6
6
|
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
7
7
|
import { qetaCreateTagPermission, filterTags } from '@drodil/backstage-plugin-qeta-common';
|
|
@@ -12,6 +12,87 @@ import { permissionApiRef } from '@backstage/plugin-permission-react';
|
|
|
12
12
|
import { AuthorizeResult } from '@backstage/plugin-permission-common';
|
|
13
13
|
import { useDebounce } from 'react-use';
|
|
14
14
|
|
|
15
|
+
const TAG_SEARCH_LIMIT = 25;
|
|
16
|
+
const isCreateTagOption = (option) => typeof option !== "string";
|
|
17
|
+
const getTagOptionValue = (option) => isCreateTagOption(option) ? option.inputValue : option;
|
|
18
|
+
const getTagOptionLabel = (option) => isCreateTagOption(option) ? option.label : option;
|
|
19
|
+
const normalizeTagInput = (input) => filterTags([input])[0];
|
|
20
|
+
const getTagSearchRequest = (term) => ({
|
|
21
|
+
limit: TAG_SEARCH_LIMIT,
|
|
22
|
+
orderBy: "postsCount",
|
|
23
|
+
order: "desc",
|
|
24
|
+
...term ? { searchQuery: term } : {}
|
|
25
|
+
});
|
|
26
|
+
const getMatchingAllowedTags = (allowedTags, term) => {
|
|
27
|
+
const normalizedTerm = term.trim().toLocaleLowerCase();
|
|
28
|
+
if (!normalizedTerm) {
|
|
29
|
+
return allowedTags;
|
|
30
|
+
}
|
|
31
|
+
return allowedTags.filter(
|
|
32
|
+
(tag) => tag.toLocaleLowerCase().includes(normalizedTerm)
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
const mergeTags = (...groups) => {
|
|
36
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37
|
+
const merged = [];
|
|
38
|
+
for (const tag of groups.flat()) {
|
|
39
|
+
if (!seen.has(tag)) {
|
|
40
|
+
seen.add(tag);
|
|
41
|
+
merged.push(tag);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return merged;
|
|
45
|
+
};
|
|
46
|
+
const getTagDescriptions = (tags) => tags.reduce(
|
|
47
|
+
(acc, tag) => {
|
|
48
|
+
if (!tag.description) {
|
|
49
|
+
return acc;
|
|
50
|
+
}
|
|
51
|
+
acc[tag.tag] = tag.description;
|
|
52
|
+
return acc;
|
|
53
|
+
},
|
|
54
|
+
{}
|
|
55
|
+
);
|
|
56
|
+
const getFilteredTagOptions = ({
|
|
57
|
+
allowCreation,
|
|
58
|
+
getCreateOptionLabel,
|
|
59
|
+
inputValue,
|
|
60
|
+
maximumTags,
|
|
61
|
+
options,
|
|
62
|
+
selectedTags
|
|
63
|
+
}) => {
|
|
64
|
+
const trimmedInput = inputValue.trim();
|
|
65
|
+
const normalizedInput = trimmedInput.toLocaleLowerCase();
|
|
66
|
+
const filteredOptions = options.filter((option) => {
|
|
67
|
+
if (!normalizedInput) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return option.toLocaleLowerCase().includes(normalizedInput);
|
|
71
|
+
});
|
|
72
|
+
if (!allowCreation || !trimmedInput || selectedTags.length >= maximumTags) {
|
|
73
|
+
return filteredOptions;
|
|
74
|
+
}
|
|
75
|
+
const normalizedTag = normalizeTagInput(trimmedInput);
|
|
76
|
+
if (!normalizedTag) {
|
|
77
|
+
return filteredOptions;
|
|
78
|
+
}
|
|
79
|
+
const tagAlreadyExists = options.some(
|
|
80
|
+
(option) => option.toLocaleLowerCase() === normalizedTag
|
|
81
|
+
);
|
|
82
|
+
const tagAlreadySelected = selectedTags.some(
|
|
83
|
+
(tag) => tag.toLocaleLowerCase() === normalizedTag
|
|
84
|
+
);
|
|
85
|
+
if (tagAlreadyExists || tagAlreadySelected) {
|
|
86
|
+
return filteredOptions;
|
|
87
|
+
}
|
|
88
|
+
return [
|
|
89
|
+
...filteredOptions,
|
|
90
|
+
{
|
|
91
|
+
inputValue: trimmedInput,
|
|
92
|
+
label: getCreateOptionLabel(trimmedInput)
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
};
|
|
15
96
|
const TagInput = forwardRef((props, _ref) => {
|
|
16
97
|
const {
|
|
17
98
|
value,
|
|
@@ -35,7 +116,10 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
35
116
|
);
|
|
36
117
|
const [loading, setLoading] = useState(true);
|
|
37
118
|
const [suggestedTags, setSuggestedTags] = useState([]);
|
|
38
|
-
const [, setLoadingSuggestions] = useState(false);
|
|
119
|
+
const [loadingSuggestions, setLoadingSuggestions] = useState(false);
|
|
120
|
+
const [inputValue, setInputValue] = useState("");
|
|
121
|
+
const searchCache = useRef(/* @__PURE__ */ new Map());
|
|
122
|
+
const activeRequest = useRef(0);
|
|
39
123
|
useEffect(() => {
|
|
40
124
|
if (allowCreate !== void 0) {
|
|
41
125
|
return;
|
|
@@ -75,37 +159,73 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
75
159
|
() => config.getOptionalStringArray("qeta.tags.allowedTags") ?? [],
|
|
76
160
|
[config]
|
|
77
161
|
);
|
|
162
|
+
const selectedTags = useMemo(() => value ?? [], [value]);
|
|
78
163
|
const maximumTags = useMemo(
|
|
79
164
|
() => config.getOptionalNumber("qeta.tags.max") ?? 5,
|
|
80
165
|
[config]
|
|
81
166
|
);
|
|
82
167
|
const [availableTags, setAvailableTags] = useState([]);
|
|
83
168
|
const [tagDescriptions, setTagDescriptions] = useState({});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
169
|
+
const loadTags = useMemo(
|
|
170
|
+
() => async (term) => {
|
|
171
|
+
const trimmed = term.trim();
|
|
172
|
+
const cacheKey = trimmed.toLocaleLowerCase();
|
|
173
|
+
const matchingAllowedTags = getMatchingAllowedTags(allowedTags, trimmed);
|
|
174
|
+
const cached = searchCache.current.get(cacheKey);
|
|
175
|
+
if (cached) {
|
|
176
|
+
setLoading(false);
|
|
177
|
+
setAvailableTags(
|
|
178
|
+
(prev) => mergeTags(prev, cached.tags, matchingAllowedTags)
|
|
179
|
+
);
|
|
180
|
+
setTagDescriptions((prev) => ({
|
|
181
|
+
...prev,
|
|
182
|
+
...cached.descriptions
|
|
183
|
+
}));
|
|
88
184
|
return;
|
|
89
185
|
}
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
data.tags.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
186
|
+
const requestId = activeRequest.current + 1;
|
|
187
|
+
activeRequest.current = requestId;
|
|
188
|
+
setLoading(true);
|
|
189
|
+
try {
|
|
190
|
+
const data = await qetaApi.getTags(getTagSearchRequest(trimmed));
|
|
191
|
+
const remoteTags = data.tags.map((tag) => tag.tag);
|
|
192
|
+
const descriptions = getTagDescriptions(data.tags);
|
|
193
|
+
const nextTags = mergeTags(remoteTags, matchingAllowedTags);
|
|
194
|
+
if (activeRequest.current !== requestId) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
searchCache.current.set(cacheKey, {
|
|
198
|
+
tags: remoteTags,
|
|
199
|
+
descriptions
|
|
200
|
+
});
|
|
201
|
+
setAvailableTags((prev) => mergeTags(prev, nextTags));
|
|
202
|
+
setTagDescriptions((prev) => ({ ...prev, ...descriptions }));
|
|
203
|
+
} catch {
|
|
204
|
+
if (activeRequest.current === requestId) {
|
|
205
|
+
setAvailableTags((prev) => mergeTags(prev, matchingAllowedTags));
|
|
206
|
+
}
|
|
207
|
+
} finally {
|
|
208
|
+
if (activeRequest.current === requestId) {
|
|
209
|
+
setLoading(false);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
[allowedTags, qetaApi]
|
|
214
|
+
);
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
searchCache.current.clear();
|
|
217
|
+
activeRequest.current += 1;
|
|
218
|
+
setLoading(true);
|
|
219
|
+
loadTags("");
|
|
220
|
+
}, [loadTags]);
|
|
221
|
+
useDebounce(
|
|
222
|
+
() => {
|
|
223
|
+
loadTags(inputValue);
|
|
224
|
+
},
|
|
225
|
+
300,
|
|
226
|
+
[inputValue, loadTags]
|
|
227
|
+
);
|
|
228
|
+
if (allowCreation === false && !loading && availableTags.length === 0) {
|
|
109
229
|
return null;
|
|
110
230
|
}
|
|
111
231
|
const getHelperText = () => {
|
|
@@ -132,18 +252,41 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
132
252
|
multiple: true,
|
|
133
253
|
id: "tags-select",
|
|
134
254
|
className: "qetaTagInput",
|
|
135
|
-
value:
|
|
255
|
+
value: selectedTags,
|
|
136
256
|
loading,
|
|
137
257
|
autoHighlight: true,
|
|
138
258
|
autoComplete: true,
|
|
139
259
|
loadingText: t("common.loading"),
|
|
140
|
-
options: availableTags
|
|
260
|
+
options: availableTags,
|
|
141
261
|
freeSolo: allowCreation,
|
|
142
262
|
handleHomeEndKeys: true,
|
|
263
|
+
limitTags: maximumTags,
|
|
264
|
+
getOptionLabel: getTagOptionLabel,
|
|
265
|
+
filterOptions: (options, state) => getFilteredTagOptions({
|
|
266
|
+
allowCreation: allowCreation === true,
|
|
267
|
+
getCreateOptionLabel: (tag) => t("tagsInput.createOption", { tag }),
|
|
268
|
+
inputValue: state.inputValue,
|
|
269
|
+
maximumTags,
|
|
270
|
+
options: options.filter(
|
|
271
|
+
(option) => typeof option === "string"
|
|
272
|
+
),
|
|
273
|
+
selectedTags
|
|
274
|
+
}),
|
|
275
|
+
inputValue,
|
|
276
|
+
onInputChange: (_event, nextValue, reason) => {
|
|
277
|
+
if (reason === "reset") {
|
|
278
|
+
setInputValue("");
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
setInputValue(nextValue);
|
|
282
|
+
},
|
|
143
283
|
ListboxComponent: AutocompleteListboxComponent,
|
|
144
284
|
disableListWrap: true,
|
|
145
285
|
style,
|
|
146
286
|
renderOption: (option) => {
|
|
287
|
+
if (isCreateTagOption(option)) {
|
|
288
|
+
return option.label;
|
|
289
|
+
}
|
|
147
290
|
if (tagDescriptions[option]) {
|
|
148
291
|
return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
149
292
|
Tooltip,
|
|
@@ -158,8 +301,9 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
158
301
|
return option;
|
|
159
302
|
},
|
|
160
303
|
onChange: (_e, newValue) => {
|
|
161
|
-
const
|
|
162
|
-
|
|
304
|
+
const nextValues = newValue.map(getTagOptionValue);
|
|
305
|
+
const tags = filterTags(nextValues);
|
|
306
|
+
if (tags && tags.length <= maximumTags && tags.length === nextValues.length) {
|
|
163
307
|
onChange(tags);
|
|
164
308
|
}
|
|
165
309
|
},
|
|
@@ -171,7 +315,7 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
171
315
|
margin: "normal",
|
|
172
316
|
label: label ?? t("tagsInput.label"),
|
|
173
317
|
placeholder: t("tagsInput.placeholder"),
|
|
174
|
-
helperText: error
|
|
318
|
+
helperText: error ? error.message : getHelperText(),
|
|
175
319
|
FormHelperTextProps: {
|
|
176
320
|
style: { marginLeft: "0.2em" }
|
|
177
321
|
},
|
|
@@ -197,7 +341,7 @@ const TagInput = forwardRef((props, _ref) => {
|
|
|
197
341
|
size: "small",
|
|
198
342
|
onClick: () => handleSuggestedTagClick(tag),
|
|
199
343
|
style: { margin: "0 4px 4px 0" },
|
|
200
|
-
disabled: value?.includes(tag) || (value?.length ?? 0) >= maximumTags
|
|
344
|
+
disabled: value?.includes(tag) || (value?.length ?? 0) >= maximumTags || loadingSuggestions
|
|
201
345
|
},
|
|
202
346
|
tag
|
|
203
347
|
)) })
|
|
@@ -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 forwardRef,\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 = forwardRef<\n any,\n {\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 entities?: string[];\n label?: string;\n }\n>((props, _ref) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n entities,\n label,\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, entities, limit: 5 })\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, entities, 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(\n (acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n },\n {} as Record<string, string>,\n ),\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={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\nTagInput.displayName = 'TagInput';\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 forwardRef,\n HTMLAttributes,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { qetaApiRef } from '../../api';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n filterTags,\n qetaCreateTagPermission,\n type TagsQuery,\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\nconst TAG_SEARCH_LIMIT = 25;\n\ntype CreateTagOption = {\n inputValue: string;\n label: string;\n};\n\ntype TagAutocompleteOption = string | CreateTagOption;\n\nconst isCreateTagOption = (\n option: TagAutocompleteOption,\n): option is CreateTagOption => typeof option !== 'string';\n\nconst getTagOptionValue = (option: TagAutocompleteOption) =>\n isCreateTagOption(option) ? option.inputValue : option;\n\nconst getTagOptionLabel = (option: TagAutocompleteOption) =>\n isCreateTagOption(option) ? option.label : option;\n\nconst normalizeTagInput = (input: string) => filterTags([input])[0];\n\nconst getTagSearchRequest = (term: string): TagsQuery => ({\n limit: TAG_SEARCH_LIMIT,\n orderBy: 'postsCount',\n order: 'desc',\n ...(term ? { searchQuery: term } : {}),\n});\n\nconst getMatchingAllowedTags = (allowedTags: string[], term: string) => {\n const normalizedTerm = term.trim().toLocaleLowerCase();\n\n if (!normalizedTerm) {\n return allowedTags;\n }\n\n return allowedTags.filter(tag =>\n tag.toLocaleLowerCase().includes(normalizedTerm),\n );\n};\n\nconst mergeTags = (...groups: string[][]) => {\n const seen = new Set<string>();\n const merged: string[] = [];\n\n for (const tag of groups.flat()) {\n if (!seen.has(tag)) {\n seen.add(tag);\n merged.push(tag);\n }\n }\n\n return merged;\n};\n\nconst getTagDescriptions = (\n tags: Array<{ tag: string; description?: string }>,\n) =>\n tags.reduce(\n (acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n },\n {} as Record<string, string>,\n );\n\nconst getFilteredTagOptions = ({\n allowCreation,\n getCreateOptionLabel,\n inputValue,\n maximumTags,\n options,\n selectedTags,\n}: {\n allowCreation: boolean;\n getCreateOptionLabel: (tag: string) => string;\n inputValue: string;\n maximumTags: number;\n options: string[];\n selectedTags: string[];\n}): TagAutocompleteOption[] => {\n const trimmedInput = inputValue.trim();\n const normalizedInput = trimmedInput.toLocaleLowerCase();\n const filteredOptions = options.filter(option => {\n if (!normalizedInput) {\n return true;\n }\n\n return option.toLocaleLowerCase().includes(normalizedInput);\n });\n\n if (!allowCreation || !trimmedInput || selectedTags.length >= maximumTags) {\n return filteredOptions;\n }\n\n const normalizedTag = normalizeTagInput(trimmedInput);\n if (!normalizedTag) {\n return filteredOptions;\n }\n\n const tagAlreadyExists = options.some(\n option => option.toLocaleLowerCase() === normalizedTag,\n );\n const tagAlreadySelected = selectedTags.some(\n tag => tag.toLocaleLowerCase() === normalizedTag,\n );\n\n if (tagAlreadyExists || tagAlreadySelected) {\n return filteredOptions;\n }\n\n return [\n ...filteredOptions,\n {\n inputValue: trimmedInput,\n label: getCreateOptionLabel(trimmedInput),\n },\n ];\n};\n\nexport const TagInput = forwardRef<\n any,\n {\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 entities?: string[];\n label?: string;\n }\n>((props, _ref) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n entities,\n label,\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 [loadingSuggestions, setLoadingSuggestions] = useState(false);\n const [inputValue, setInputValue] = useState('');\n const searchCache = useRef<\n Map<string, { tags: string[]; descriptions: Record<string, string> }>\n >(new Map());\n const activeRequest = useRef(0);\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, entities, limit: 5 })\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, entities, qetaApi],\n );\n\n const allowedTags = useMemo(\n () => config.getOptionalStringArray('qeta.tags.allowedTags') ?? [],\n [config],\n );\n const selectedTags = useMemo(() => value ?? [], [value]);\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\n const loadTags = useMemo(\n () => async (term: string) => {\n const trimmed = term.trim();\n const cacheKey = trimmed.toLocaleLowerCase();\n const matchingAllowedTags = getMatchingAllowedTags(allowedTags, trimmed);\n const cached = searchCache.current.get(cacheKey);\n\n if (cached) {\n setLoading(false);\n setAvailableTags(prev =>\n mergeTags(prev, cached.tags, matchingAllowedTags),\n );\n setTagDescriptions(prev => ({\n ...prev,\n ...cached.descriptions,\n }));\n return;\n }\n\n const requestId = activeRequest.current + 1;\n activeRequest.current = requestId;\n setLoading(true);\n\n try {\n const data = await qetaApi.getTags(getTagSearchRequest(trimmed));\n const remoteTags = data.tags.map(tag => tag.tag);\n const descriptions = getTagDescriptions(data.tags);\n const nextTags = mergeTags(remoteTags, matchingAllowedTags);\n\n if (activeRequest.current !== requestId) {\n return;\n }\n\n searchCache.current.set(cacheKey, {\n tags: remoteTags,\n descriptions,\n });\n setAvailableTags(prev => mergeTags(prev, nextTags));\n setTagDescriptions(prev => ({ ...prev, ...descriptions }));\n } catch {\n if (activeRequest.current === requestId) {\n setAvailableTags(prev => mergeTags(prev, matchingAllowedTags));\n }\n } finally {\n if (activeRequest.current === requestId) {\n setLoading(false);\n }\n }\n },\n [allowedTags, qetaApi],\n );\n\n useEffect(() => {\n searchCache.current.clear();\n activeRequest.current += 1;\n setLoading(true);\n loadTags('');\n }, [loadTags]);\n\n useDebounce(\n () => {\n loadTags(inputValue);\n },\n 300,\n [inputValue, loadTags],\n );\n\n if (allowCreation === false && !loading && 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={selectedTags as TagAutocompleteOption[]}\n loading={loading}\n autoHighlight\n autoComplete\n loadingText={t('common.loading')}\n options={availableTags as TagAutocompleteOption[]}\n freeSolo={allowCreation}\n handleHomeEndKeys\n limitTags={maximumTags}\n getOptionLabel={getTagOptionLabel}\n filterOptions={(options, state) =>\n getFilteredTagOptions({\n allowCreation: allowCreation === true,\n getCreateOptionLabel: tag =>\n t('tagsInput.createOption' as never, { tag } as never) as string,\n inputValue: state.inputValue,\n maximumTags,\n options: options.filter(\n (option): option is string => typeof option === 'string',\n ),\n selectedTags,\n })\n }\n inputValue={inputValue}\n onInputChange={(_event, nextValue, reason) => {\n if (reason === 'reset') {\n setInputValue('');\n return;\n }\n\n setInputValue(nextValue);\n }}\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n renderOption={option => {\n if (isCreateTagOption(option)) {\n return option.label;\n }\n\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 nextValues = newValue.map(getTagOptionValue);\n const tags = filterTags(nextValues);\n if (\n tags &&\n tags.length <= maximumTags &&\n tags.length === nextValues.length\n ) {\n onChange(tags);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label={label ?? t('tagsInput.label')}\n placeholder={t('tagsInput.placeholder')}\n helperText={error ? 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) ||\n (value?.length ?? 0) >= maximumTags ||\n loadingSuggestions\n }\n />\n ))}\n </Box>\n </Box>\n )}{' '}\n </Box>\n );\n});\n\nTagInput.displayName = 'TagInput';\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1040,6 +1040,7 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1040
1040
|
readonly "tagsInput.helperText": "Add up to {{max}} tags";
|
|
1041
1041
|
readonly "tagsInput.minimumError": "Please add at least {{min}} tags";
|
|
1042
1042
|
readonly "tagsInput.allowAddHelperText": "You can create new tags by typing the tag and pressing enter";
|
|
1043
|
+
readonly "tagsInput.createOption": "Add {{tag}}";
|
|
1043
1044
|
readonly "tagsInput.suggestedTags": "Suggested tags";
|
|
1044
1045
|
readonly "askPage.title.newQuestion": "Ask a question";
|
|
1045
1046
|
readonly "askPage.title.existingQuestion": "Edit question";
|
|
@@ -1121,7 +1122,6 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1121
1122
|
readonly "favoritePage.title": "Favorited posts";
|
|
1122
1123
|
readonly "leftMenu.tags": "Tags";
|
|
1123
1124
|
readonly "leftMenu.entities": "Entities";
|
|
1124
|
-
readonly "leftMenu.content": "Content";
|
|
1125
1125
|
readonly "leftMenu.users": "Users";
|
|
1126
1126
|
readonly "leftMenu.collections": "Collections";
|
|
1127
1127
|
readonly "leftMenu.statistics": "Statistics";
|
|
@@ -1131,6 +1131,7 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1131
1131
|
readonly "leftMenu.moderate": "Moderate";
|
|
1132
1132
|
readonly "leftMenu.review": "Review";
|
|
1133
1133
|
readonly "leftMenu.settings": "Settings";
|
|
1134
|
+
readonly "leftMenu.content": "Content";
|
|
1134
1135
|
readonly "leftMenu.manage": "Manage";
|
|
1135
1136
|
readonly "leftMenu.buttonLabel": "Menu";
|
|
1136
1137
|
readonly "leftMenu.home": "Home";
|
|
@@ -1139,8 +1140,8 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1139
1140
|
readonly "leftMenu.community": "Community";
|
|
1140
1141
|
readonly "leftMenu.expand": "Expand menu";
|
|
1141
1142
|
readonly "leftMenu.collapse": "Collapse menu";
|
|
1142
|
-
readonly "moderatorPage.title": "Moderate";
|
|
1143
1143
|
readonly "moderatorPage.templates": "Templates";
|
|
1144
|
+
readonly "moderatorPage.title": "Moderate";
|
|
1144
1145
|
readonly "moderatorPage.tools": "Tools";
|
|
1145
1146
|
readonly "moderatorPage.templatesInfo": "Templates can be used to prefill question content for the user";
|
|
1146
1147
|
readonly "moderatorPage.deletedPosts": "Deleted posts";
|
|
@@ -1157,8 +1158,8 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1157
1158
|
readonly "settingsPage.aiAnswerExpanded.label": "Expand AI Answers by Default";
|
|
1158
1159
|
readonly "settingsPage.usePagination.description": "Use traditional pagination instead of infinite scrolling to load more items";
|
|
1159
1160
|
readonly "settingsPage.usePagination.label": "Use Pagination";
|
|
1160
|
-
readonly "settingsPage.viewTypePreferences.title": "View Type Preferences";
|
|
1161
1161
|
readonly "settingsPage.viewTypePreferences.default": "Default";
|
|
1162
|
+
readonly "settingsPage.viewTypePreferences.title": "View Type Preferences";
|
|
1162
1163
|
readonly "settingsPage.viewTypePreferences.description": "Choose how you want to view different types of content. Select \"Default\" to use the system default view.";
|
|
1163
1164
|
readonly "settingsPage.viewTypePreferences.labels.tags": "Tags";
|
|
1164
1165
|
readonly "settingsPage.viewTypePreferences.labels.entities": "Entities";
|
|
@@ -1230,15 +1231,15 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1230
1231
|
readonly "communityActivity.period.1y": "Last year";
|
|
1231
1232
|
readonly "homePage.tags": "Tags";
|
|
1232
1233
|
readonly "homePage.entities": "Entities";
|
|
1233
|
-
readonly "homePage.title": "Home";
|
|
1234
1234
|
readonly "homePage.users": "Users";
|
|
1235
1235
|
readonly "homePage.collections": "Collections";
|
|
1236
|
+
readonly "homePage.title": "Home";
|
|
1236
1237
|
readonly "homePage.followedItems": "Following";
|
|
1237
1238
|
readonly "homePage.noFollowedItems": "You are not following anything yet";
|
|
1238
1239
|
readonly "impactCard.reputation": "Reputation";
|
|
1239
|
-
readonly "impactCard.title": "Your impact";
|
|
1240
1240
|
readonly "impactCard.error": "Failed to load impact data";
|
|
1241
1241
|
readonly "impactCard.answers": "Answers";
|
|
1242
|
+
readonly "impactCard.title": "Your impact";
|
|
1242
1243
|
readonly "impactCard.links": "Links";
|
|
1243
1244
|
readonly "impactCard.questions": "Questions";
|
|
1244
1245
|
readonly "impactCard.articles": "Articles";
|
|
@@ -1250,8 +1251,8 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1250
1251
|
readonly "impactCard.answerScore": "Answer Score";
|
|
1251
1252
|
readonly "impactCard.postScore": "Post Score";
|
|
1252
1253
|
readonly "impactCard.correctAnswers": "Correct Answers";
|
|
1253
|
-
readonly "userBadges.title": "Badges";
|
|
1254
1254
|
readonly "userBadges.error": "Failed to load badges";
|
|
1255
|
+
readonly "userBadges.title": "Badges";
|
|
1255
1256
|
readonly "userBadges.noBadges": "No badges earned yet";
|
|
1256
1257
|
readonly "rightMenu.expand": "Expand sidebar";
|
|
1257
1258
|
readonly "rightMenu.collapse": "Collapse sidebar";
|
|
@@ -1407,9 +1408,9 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1407
1408
|
readonly "filterPanel.orderBy.updated": "Updated";
|
|
1408
1409
|
readonly "filterPanel.orderBy.reputation": "Reputation";
|
|
1409
1410
|
readonly "filterPanel.orderBy.entityRef": "Name";
|
|
1410
|
-
readonly "filterPanel.orderBy.title": "Title";
|
|
1411
1411
|
readonly "filterPanel.orderBy.posts": "Posts";
|
|
1412
1412
|
readonly "filterPanel.orderBy.answers": "Answers";
|
|
1413
|
+
readonly "filterPanel.orderBy.title": "Title";
|
|
1413
1414
|
readonly "filterPanel.orderBy.user": "Name";
|
|
1414
1415
|
readonly "filterPanel.orderBy.links": "Links";
|
|
1415
1416
|
readonly "filterPanel.orderBy.questions": "Questions";
|
|
@@ -1471,8 +1472,8 @@ declare const qetaTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
1471
1472
|
readonly "aiAnswerCard.regenerate": "Regenerate this answer";
|
|
1472
1473
|
readonly "aiAnswerCard.show": "Show";
|
|
1473
1474
|
readonly "aiAnswerCard.hide": "Hide";
|
|
1474
|
-
readonly "usersPage.title": "Users";
|
|
1475
1475
|
readonly "usersPage.users": "Users";
|
|
1476
|
+
readonly "usersPage.title": "Users";
|
|
1476
1477
|
readonly "usersPage.search.label": "Search user";
|
|
1477
1478
|
readonly "usersPage.search.placeholder": "Search...";
|
|
1478
1479
|
readonly "usersPage.errorLoading": "Could not load users";
|
package/dist/translation.esm.js
CHANGED
|
@@ -241,6 +241,7 @@ const qetaTranslationRef = createTranslationRef({
|
|
|
241
241
|
placeholder: "Type or select tags",
|
|
242
242
|
helperText: "Add up to {{max}} tags",
|
|
243
243
|
allowAddHelperText: "You can create new tags by typing the tag and pressing enter",
|
|
244
|
+
createOption: "Add {{tag}}",
|
|
244
245
|
minimumError: "Please add at least {{min}} tags",
|
|
245
246
|
suggestedTags: "Suggested tags"
|
|
246
247
|
},
|