@drodil/backstage-plugin-qeta-react 3.59.6 → 3.59.7
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 +1 -0
- package/dist/translation.esm.js +1 -0
- package/dist/translation.esm.js.map +1 -1
- package/package.json +4 -4
|
@@ -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";
|
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
|
},
|