@drodil/backstage-plugin-qeta-react 3.41.0 → 3.41.2

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.
@@ -1,6 +1,6 @@
1
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { Autocomplete } from '@material-ui/lab';
3
- import { getEntityTitle } from '../../utils/utils.esm.js';
3
+ import { getEntityTitle, getEntityDescription } from '../../utils/utils.esm.js';
4
4
  import { stringifyEntityRef } from '@backstage/catalog-model';
5
5
  import { Tooltip, Typography, TextField, CircularProgress } from '@material-ui/core';
6
6
  import { useState, useMemo, useEffect } from 'react';
@@ -72,7 +72,9 @@ const EntitiesInput = (props) => {
72
72
  catalogApi.getEntitiesByRefs({ entityRefs: refs }).catch((_) => setAvailableEntities(null)).then((catalogData) => {
73
73
  setLoading(false);
74
74
  setAvailableEntities(
75
- catalogData ? compact(catalogData.items) : null
75
+ catalogData ? compact(catalogData.items).sort(
76
+ (a, b) => getEntityTitle(a).localeCompare(getEntityTitle(b))
77
+ ) : null
76
78
  );
77
79
  });
78
80
  });
@@ -80,7 +82,6 @@ const EntitiesInput = (props) => {
80
82
  }
81
83
  if (entityKinds && entityKinds.length > 0) {
82
84
  catalogApi.getEntities({
83
- order: { field: "kind", order: "asc" },
84
85
  filter: { kind: entityKinds },
85
86
  fields: [
86
87
  "kind",
@@ -89,11 +90,16 @@ const EntitiesInput = (props) => {
89
90
  "metadata.title",
90
91
  "metadata.description",
91
92
  "spec.type",
92
- "spec.profile.displayName"
93
+ "spec.profile.displayName",
94
+ "spec.profile.email"
93
95
  ]
94
96
  }).catch((_) => setAvailableEntities(null)).then((data) => {
95
97
  setLoading(false);
96
- setAvailableEntities(data ? data.items : null);
98
+ setAvailableEntities(
99
+ data ? data.items.sort(
100
+ (a, b) => getEntityTitle(a).localeCompare(getEntityTitle(b))
101
+ ) : null
102
+ );
97
103
  });
98
104
  }
99
105
  }, [
@@ -151,19 +157,19 @@ const EntitiesInput = (props) => {
151
157
  }
152
158
  },
153
159
  renderOption: (option) => {
154
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
160
+ const stringified = stringifyEntityRef(option);
161
+ return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
155
162
  Tooltip,
156
163
  {
157
164
  arrow: true,
158
165
  placement: "right",
159
166
  title: /* @__PURE__ */ jsxs(Fragment, { children: [
160
167
  /* @__PURE__ */ jsx(Typography, { children: getEntityTitle(option) }),
161
- /* @__PURE__ */ jsx(Typography, { variant: "caption", children: stringifyEntityRef(option) }),
162
- /* @__PURE__ */ jsx(Typography, { variant: "caption", children: option.metadata.description })
168
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: getEntityDescription(option) })
163
169
  ] }),
164
170
  children: /* @__PURE__ */ jsx("span", { children: getEntityTitle(option, { withType: false }) })
165
171
  }
166
- ) });
172
+ ) }, stringified);
167
173
  },
168
174
  renderInput: (params) => {
169
175
  let helperText = "";
@@ -1 +1 @@
1
- {"version":3,"file":"EntitiesInput.esm.js","sources":["../../../src/components/PostForm/EntitiesInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport { getEntityTitle } from '../../utils/utils';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { qetaApiRef } from '../../api';\nimport { compact } from 'lodash';\nimport {\n AutocompleteListboxComponent,\n renderGroup,\n} from './AutocompleteListComponent';\nimport { AutocompleteProps } from '@material-ui/lab/Autocomplete/Autocomplete';\nimport { FieldError } from 'react-hook-form';\nimport { getSupportedEntityKinds } from '@drodil/backstage-plugin-qeta-common';\n\ntype CommonEntitiesInputProps = {\n singleValue?: string;\n required?: boolean;\n useOnlyUsedEntities?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n disabled?: boolean;\n kind?: string[];\n maximum?: number | null;\n error?: FieldError;\n label?: string;\n name?: string;\n placeholder?: string;\n autocompleteProps?: AutocompleteProps<any, any, any, any>;\n onChange: (value: any) => void;\n};\ntype SingleEntitiesInputValue = CommonEntitiesInputProps & {\n multiple: false;\n value?: Entity | null;\n onChange: (value: Entity) => void;\n};\n\ntype MultipleEntitiesInputValue = CommonEntitiesInputProps & {\n multiple?: true;\n value?: Entity[];\n onChange: (value: Entity[]) => void;\n};\n\nexport type EntitiesInputProps =\n | SingleEntitiesInputValue\n | MultipleEntitiesInputValue;\n\nexport const EntitiesInput = (props: EntitiesInputProps) => {\n const {\n value,\n singleValue,\n onChange,\n multiple = true,\n required = false,\n useOnlyUsedEntities = false,\n hideHelpText = false,\n style,\n disabled,\n kind,\n error,\n maximum,\n label,\n name = 'entities',\n placeholder,\n autocompleteProps,\n } = props;\n\n const configApi = useApi(configApiRef);\n const catalogApi = useApi(catalogApiRef);\n const qetaApi = useApi(qetaApiRef);\n const [availableEntities, setAvailableEntities] = useState<Entity[] | null>(\n [],\n );\n const [loading, setLoading] = useState(true);\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const entityKinds: string[] = useMemo(() => {\n if (kind) {\n return kind;\n }\n return getSupportedEntityKinds(configApi);\n }, [configApi, kind]);\n const max = useMemo(() => {\n if (maximum) {\n return maximum;\n }\n return configApi.getOptionalNumber('qeta.entities.max') ?? 3;\n }, [configApi, maximum]);\n\n useEffect(() => {\n if (singleValue) {\n catalogApi.getEntityByRef(singleValue).then(data => {\n setLoading(false);\n if (data) {\n setAvailableEntities([data]);\n }\n });\n }\n }, [catalogApi, singleValue]);\n\n useEffect(() => {\n if (singleValue) {\n return;\n }\n\n if (useOnlyUsedEntities) {\n qetaApi.getEntities().then(data => {\n const refs = data.entities.map(r => r.entityRef);\n catalogApi\n .getEntitiesByRefs({ entityRefs: refs })\n .catch(_ => setAvailableEntities(null))\n .then(catalogData => {\n setLoading(false);\n setAvailableEntities(\n catalogData ? compact(catalogData.items) : null,\n );\n });\n });\n return;\n }\n\n if (entityKinds && entityKinds.length > 0) {\n catalogApi\n .getEntities({\n order: { field: 'kind', order: 'asc' },\n filter: { kind: entityKinds },\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n 'metadata.description',\n 'spec.type',\n 'spec.profile.displayName',\n ],\n })\n .catch(_ => setAvailableEntities(null))\n .then(data => {\n setLoading(false);\n setAvailableEntities(data ? data.items : null);\n });\n }\n }, [\n catalogApi,\n singleValue,\n configApi,\n entityKinds,\n useOnlyUsedEntities,\n qetaApi,\n ]);\n\n const usedValue = useMemo(() => {\n if (!value) {\n return multiple ? [] : null;\n }\n return value;\n }, [value, multiple]);\n\n if (!availableEntities) {\n return null;\n }\n\n return (\n <Autocomplete\n multiple={multiple}\n autoHighlight\n autoComplete\n className=\"qetaEntitiesInput\"\n value={usedValue}\n disabled={disabled}\n loading={loading}\n loadingText={t('common.loading')}\n groupBy={entityKinds.length > 1 ? option => option.kind : undefined}\n renderGroup={renderGroup}\n handleHomeEndKeys\n options={availableEntities}\n getOptionLabel={getEntityTitle}\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n getOptionSelected={(o, v) =>\n stringifyEntityRef(o) === stringifyEntityRef(v)\n }\n onChange={(_e, newValue) => {\n if (multiple) {\n if (!newValue) {\n onChange([]);\n return;\n }\n const val = Array.isArray(newValue) ? newValue : [newValue];\n if (max === null || val.length <= max) {\n onChange(val.filter(v => typeof v !== 'string'));\n }\n } else {\n if (!newValue) {\n return;\n }\n onChange(newValue as Entity);\n }\n }}\n renderOption={(option: Entity) => {\n return (\n <>\n <Tooltip\n arrow\n placement=\"right\"\n title={\n <>\n <Typography>{getEntityTitle(option)}</Typography>\n <Typography variant=\"caption\">\n {stringifyEntityRef(option)}\n </Typography>\n <Typography variant=\"caption\">\n {option.metadata.description}\n </Typography>\n </>\n }\n >\n <span>{getEntityTitle(option, { withType: false })}</span>\n </Tooltip>\n </>\n );\n }}\n renderInput={params => {\n let helperText = '';\n if (!hideHelpText) {\n if (error && error.message) {\n helperText = error.message;\n } else {\n helperText = t('entitiesInput.helperText', { max: max.toString() });\n }\n }\n\n return (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n required={required}\n label={label || t('entitiesInput.label')}\n placeholder={placeholder || t('entitiesInput.placeholder')}\n helperText={helperText}\n name={name}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\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 {...autocompleteProps}\n />\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EntitiesInput.esm.js","sources":["../../../src/components/PostForm/EntitiesInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport { getEntityDescription, getEntityTitle } from '../../utils/utils';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport {\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { qetaApiRef } from '../../api';\nimport { compact } from 'lodash';\nimport {\n AutocompleteListboxComponent,\n renderGroup,\n} from './AutocompleteListComponent';\nimport { AutocompleteProps } from '@material-ui/lab/Autocomplete/Autocomplete';\nimport { FieldError } from 'react-hook-form';\nimport { getSupportedEntityKinds } from '@drodil/backstage-plugin-qeta-common';\n\ntype CommonEntitiesInputProps = {\n singleValue?: string;\n required?: boolean;\n useOnlyUsedEntities?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n disabled?: boolean;\n kind?: string[];\n maximum?: number | null;\n error?: FieldError;\n label?: string;\n name?: string;\n placeholder?: string;\n autocompleteProps?: AutocompleteProps<any, any, any, any>;\n onChange: (value: any) => void;\n};\ntype SingleEntitiesInputValue = CommonEntitiesInputProps & {\n multiple: false;\n value?: Entity | null;\n onChange: (value: Entity) => void;\n};\n\ntype MultipleEntitiesInputValue = CommonEntitiesInputProps & {\n multiple?: true;\n value?: Entity[];\n onChange: (value: Entity[]) => void;\n};\n\nexport type EntitiesInputProps =\n | SingleEntitiesInputValue\n | MultipleEntitiesInputValue;\n\nexport const EntitiesInput = (props: EntitiesInputProps) => {\n const {\n value,\n singleValue,\n onChange,\n multiple = true,\n required = false,\n useOnlyUsedEntities = false,\n hideHelpText = false,\n style,\n disabled,\n kind,\n error,\n maximum,\n label,\n name = 'entities',\n placeholder,\n autocompleteProps,\n } = props;\n\n const configApi = useApi(configApiRef);\n const catalogApi = useApi(catalogApiRef);\n const qetaApi = useApi(qetaApiRef);\n const [availableEntities, setAvailableEntities] = useState<Entity[] | null>(\n [],\n );\n const [loading, setLoading] = useState(true);\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const entityKinds: string[] = useMemo(() => {\n if (kind) {\n return kind;\n }\n return getSupportedEntityKinds(configApi);\n }, [configApi, kind]);\n const max = useMemo(() => {\n if (maximum) {\n return maximum;\n }\n return configApi.getOptionalNumber('qeta.entities.max') ?? 3;\n }, [configApi, maximum]);\n\n useEffect(() => {\n if (singleValue) {\n catalogApi.getEntityByRef(singleValue).then(data => {\n setLoading(false);\n if (data) {\n setAvailableEntities([data]);\n }\n });\n }\n }, [catalogApi, singleValue]);\n\n useEffect(() => {\n if (singleValue) {\n return;\n }\n\n if (useOnlyUsedEntities) {\n qetaApi.getEntities().then(data => {\n const refs = data.entities.map(r => r.entityRef);\n catalogApi\n .getEntitiesByRefs({ entityRefs: refs })\n .catch(_ => setAvailableEntities(null))\n .then(catalogData => {\n setLoading(false);\n setAvailableEntities(\n catalogData\n ? compact(catalogData.items).sort((a, b) =>\n getEntityTitle(a).localeCompare(getEntityTitle(b)),\n )\n : null,\n );\n });\n });\n return;\n }\n\n if (entityKinds && entityKinds.length > 0) {\n catalogApi\n .getEntities({\n filter: { kind: entityKinds },\n fields: [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n 'metadata.description',\n 'spec.type',\n 'spec.profile.displayName',\n 'spec.profile.email',\n ],\n })\n .catch(_ => setAvailableEntities(null))\n .then(data => {\n setLoading(false);\n setAvailableEntities(\n data\n ? data.items.sort((a, b) =>\n getEntityTitle(a).localeCompare(getEntityTitle(b)),\n )\n : null,\n );\n });\n }\n }, [\n catalogApi,\n singleValue,\n configApi,\n entityKinds,\n useOnlyUsedEntities,\n qetaApi,\n ]);\n\n const usedValue = useMemo(() => {\n if (!value) {\n return multiple ? [] : null;\n }\n return value;\n }, [value, multiple]);\n\n if (!availableEntities) {\n return null;\n }\n\n return (\n <Autocomplete\n multiple={multiple}\n autoHighlight\n autoComplete\n className=\"qetaEntitiesInput\"\n value={usedValue}\n disabled={disabled}\n loading={loading}\n loadingText={t('common.loading')}\n groupBy={entityKinds.length > 1 ? option => option.kind : undefined}\n renderGroup={renderGroup}\n handleHomeEndKeys\n options={availableEntities}\n getOptionLabel={getEntityTitle}\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n getOptionSelected={(o, v) =>\n stringifyEntityRef(o) === stringifyEntityRef(v)\n }\n onChange={(_e, newValue) => {\n if (multiple) {\n if (!newValue) {\n onChange([]);\n return;\n }\n const val = Array.isArray(newValue) ? newValue : [newValue];\n if (max === null || val.length <= max) {\n onChange(val.filter(v => typeof v !== 'string'));\n }\n } else {\n if (!newValue) {\n return;\n }\n onChange(newValue as Entity);\n }\n }}\n renderOption={(option: Entity) => {\n const stringified = stringifyEntityRef(option);\n return (\n <span key={stringified}>\n <Tooltip\n arrow\n placement=\"right\"\n title={\n <>\n <Typography>{getEntityTitle(option)}</Typography>\n <Typography variant=\"caption\">\n {getEntityDescription(option)}\n </Typography>\n </>\n }\n >\n <span>{getEntityTitle(option, { withType: false })}</span>\n </Tooltip>\n </span>\n );\n }}\n renderInput={params => {\n let helperText = '';\n if (!hideHelpText) {\n if (error && error.message) {\n helperText = error.message;\n } else {\n helperText = t('entitiesInput.helperText', { max: max.toString() });\n }\n }\n\n return (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n required={required}\n label={label || t('entitiesInput.label')}\n placeholder={placeholder || t('entitiesInput.placeholder')}\n helperText={helperText}\n name={name}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\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 {...autocompleteProps}\n />\n );\n};\n"],"names":[],"mappings":"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"}
@@ -87,7 +87,7 @@ const TagInput = (props) => {
87
87
  }
88
88
  const uniqueTags = [
89
89
  .../* @__PURE__ */ new Set([...allowedTags, ...data.tags.map((tag) => tag.tag)])
90
- ];
90
+ ].sort((a, b) => a.localeCompare(b));
91
91
  setAvailableTags(uniqueTags);
92
92
  setTagDescriptions(
93
93
  data.tags.reduce((acc, tag) => {
@@ -140,7 +140,7 @@ const TagInput = (props) => {
140
140
  style,
141
141
  renderOption: (option) => {
142
142
  if (tagDescriptions[option]) {
143
- return /* @__PURE__ */ jsx(
143
+ return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
144
144
  Tooltip,
145
145
  {
146
146
  arrow: true,
@@ -148,7 +148,7 @@ const TagInput = (props) => {
148
148
  title: /* @__PURE__ */ jsx(Typography, { children: tagDescriptions[option] }),
149
149
  children: /* @__PURE__ */ jsx("span", { children: option })
150
150
  }
151
- );
151
+ ) }, option);
152
152
  }
153
153
  return option;
154
154
  },
@@ -1 +1 @@
1
- {"version":3,"file":"TagInput.esm.js","sources":["../../../src/components/PostForm/TagInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport {\n Box,\n Chip,\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { qetaApiRef } from '../../api';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n filterTags,\n qetaCreateTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { FieldError } from 'react-hook-form';\nimport { AutocompleteListboxComponent } from './AutocompleteListComponent';\nimport { permissionApiRef } from '@backstage/plugin-permission-react';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { useDebounce } from 'react-use';\n\nexport const TagInput = (props: {\n value?: string[];\n onChange: (value: string[]) => void;\n error?: FieldError;\n allowCreate?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n title?: string;\n name?: string;\n content?: string;\n}) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n } = props;\n const qetaApi = useApi(qetaApiRef);\n const config = useApi(configApiRef);\n const permissions = useApi(permissionApiRef);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [allowCreation, setAllowCreation] = useState<boolean | undefined>(\n allowCreate,\n );\n const [loading, setLoading] = useState(true);\n const [suggestedTags, setSuggestedTags] = useState<string[]>([]);\n const [, setLoadingSuggestions] = useState(false);\n\n useEffect(() => {\n if (allowCreate !== undefined) {\n return;\n }\n\n if (config.getOptionalBoolean('qeta.permissions') === true) {\n permissions\n .authorize({\n permission: qetaCreateTagPermission,\n })\n .then(res => {\n if (res.result === AuthorizeResult.ALLOW) {\n setAllowCreation(true);\n } else {\n setAllowCreation(false);\n }\n });\n } else {\n setAllowCreation(\n config.getOptionalBoolean('qeta.tags.allowCreation') ?? true,\n );\n }\n }, [config, permissions, allowCreate]);\n\n useDebounce(\n () => {\n if (title && content) {\n setLoadingSuggestions(true);\n qetaApi\n .getTagSuggestions({ title, content })\n .then(response => {\n setSuggestedTags(response.tags);\n })\n .catch(() => {\n // Ignore errors\n })\n .finally(() => {\n setLoadingSuggestions(false);\n });\n }\n },\n 2000,\n [title, content, qetaApi],\n );\n\n const allowedTags = useMemo(\n () => config.getOptionalStringArray('qeta.tags.allowedTags') ?? [],\n [config],\n );\n const maximumTags = useMemo(\n () => config.getOptionalNumber('qeta.tags.max') ?? 5,\n [config],\n );\n\n const [availableTags, setAvailableTags] = useState<string[]>([]);\n const [tagDescriptions, setTagDescriptions] = useState<\n Record<string, string>\n >({});\n useEffect(() => {\n qetaApi\n .getTags()\n .catch(_ => setAvailableTags([]))\n .then(data => {\n setLoading(false);\n if (!data) {\n return;\n }\n\n const uniqueTags = [\n ...new Set([...allowedTags, ...data.tags.map(tag => tag.tag)]),\n ];\n setAvailableTags(uniqueTags);\n setTagDescriptions(\n data.tags.reduce((acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n }, {} as Record<string, string>),\n );\n });\n }, [qetaApi, allowCreation, allowedTags]);\n\n if (!allowCreation && availableTags.length === 0) {\n return null;\n }\n\n const getHelperText = () => {\n if (hideHelpText) {\n return '';\n }\n\n const baseText = t('tagsInput.helperText', {\n max: maximumTags.toString(10),\n });\n\n if (!allowCreation) {\n return baseText;\n }\n return `${baseText}. ${t('tagsInput.allowAddHelperText')}`;\n };\n\n const handleSuggestedTagClick = (tag: string) => {\n if (value && value.length < maximumTags && !value.includes(tag)) {\n onChange([...value, tag]);\n }\n };\n\n return (\n <Box>\n <Autocomplete\n multiple\n id=\"tags-select\"\n className=\"qetaTagInput\"\n value={value}\n loading={loading}\n autoHighlight\n autoComplete\n loadingText={t('common.loading')}\n options={availableTags ?? []}\n freeSolo={allowCreation}\n handleHomeEndKeys\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n renderOption={option => {\n if (tagDescriptions[option]) {\n return (\n <Tooltip\n arrow\n placement=\"right\"\n title={<Typography>{tagDescriptions[option]}</Typography>}\n >\n <span>{option}</span>\n </Tooltip>\n );\n }\n return option;\n }}\n onChange={(_e, newValue) => {\n const tags = filterTags(newValue);\n if (\n tags &&\n tags.length <= maximumTags &&\n tags.length === newValue.length\n ) {\n onChange(tags);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label={t('tagsInput.label')}\n placeholder={t('tagsInput.placeholder')}\n helperText={error !== undefined ? error.message : getHelperText()}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n name={name}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? (\n <CircularProgress color=\"inherit\" size={20} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n error={error !== undefined}\n />\n )}\n />\n {suggestedTags?.length > 0 && (\n <Box style={{ marginLeft: '4px' }}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {t('tagsInput.suggestedTags')}\n </Typography>\n <Box mt={0.5}>\n {suggestedTags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n size=\"small\"\n onClick={() => handleSuggestedTagClick(tag)}\n style={{ margin: '0 4px 4px 0' }}\n disabled={\n value?.includes(tag) || (value?.length ?? 0) >= maximumTags\n }\n />\n ))}\n </Box>\n </Box>\n )}{' '}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TagInput.esm.js","sources":["../../../src/components/PostForm/TagInput.tsx"],"sourcesContent":["import { Autocomplete } from '@material-ui/lab';\nimport {\n Box,\n Chip,\n CircularProgress,\n TextField,\n Tooltip,\n Typography,\n} from '@material-ui/core';\nimport {\n ComponentType,\n CSSProperties,\n HTMLAttributes,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { qetaApiRef } from '../../api';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n filterTags,\n qetaCreateTagPermission,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { FieldError } from 'react-hook-form';\nimport { AutocompleteListboxComponent } from './AutocompleteListComponent';\nimport { permissionApiRef } from '@backstage/plugin-permission-react';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { useDebounce } from 'react-use';\n\nexport const TagInput = (props: {\n value?: string[];\n onChange: (value: string[]) => void;\n error?: FieldError;\n allowCreate?: boolean;\n hideHelpText?: boolean;\n style?: CSSProperties;\n title?: string;\n name?: string;\n content?: string;\n}) => {\n const {\n value,\n onChange,\n error,\n allowCreate,\n hideHelpText = false,\n style,\n name = 'tags',\n title,\n content,\n } = props;\n const qetaApi = useApi(qetaApiRef);\n const config = useApi(configApiRef);\n const permissions = useApi(permissionApiRef);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [allowCreation, setAllowCreation] = useState<boolean | undefined>(\n allowCreate,\n );\n const [loading, setLoading] = useState(true);\n const [suggestedTags, setSuggestedTags] = useState<string[]>([]);\n const [, setLoadingSuggestions] = useState(false);\n\n useEffect(() => {\n if (allowCreate !== undefined) {\n return;\n }\n\n if (config.getOptionalBoolean('qeta.permissions') === true) {\n permissions\n .authorize({\n permission: qetaCreateTagPermission,\n })\n .then(res => {\n if (res.result === AuthorizeResult.ALLOW) {\n setAllowCreation(true);\n } else {\n setAllowCreation(false);\n }\n });\n } else {\n setAllowCreation(\n config.getOptionalBoolean('qeta.tags.allowCreation') ?? true,\n );\n }\n }, [config, permissions, allowCreate]);\n\n useDebounce(\n () => {\n if (title && content) {\n setLoadingSuggestions(true);\n qetaApi\n .getTagSuggestions({ title, content })\n .then(response => {\n setSuggestedTags(response.tags);\n })\n .catch(() => {\n // Ignore errors\n })\n .finally(() => {\n setLoadingSuggestions(false);\n });\n }\n },\n 2000,\n [title, content, qetaApi],\n );\n\n const allowedTags = useMemo(\n () => config.getOptionalStringArray('qeta.tags.allowedTags') ?? [],\n [config],\n );\n const maximumTags = useMemo(\n () => config.getOptionalNumber('qeta.tags.max') ?? 5,\n [config],\n );\n\n const [availableTags, setAvailableTags] = useState<string[]>([]);\n const [tagDescriptions, setTagDescriptions] = useState<\n Record<string, string>\n >({});\n useEffect(() => {\n qetaApi\n .getTags()\n .catch(_ => setAvailableTags([]))\n .then(data => {\n setLoading(false);\n if (!data) {\n return;\n }\n\n const uniqueTags = [\n ...new Set([...allowedTags, ...data.tags.map(tag => tag.tag)]),\n ].sort((a, b) => a.localeCompare(b));\n setAvailableTags(uniqueTags);\n setTagDescriptions(\n data.tags.reduce((acc, tag) => {\n if (!tag.description) {\n return acc;\n }\n acc[tag.tag] = tag.description;\n return acc;\n }, {} as Record<string, string>),\n );\n });\n }, [qetaApi, allowCreation, allowedTags]);\n\n if (!allowCreation && availableTags.length === 0) {\n return null;\n }\n\n const getHelperText = () => {\n if (hideHelpText) {\n return '';\n }\n\n const baseText = t('tagsInput.helperText', {\n max: maximumTags.toString(10),\n });\n\n if (!allowCreation) {\n return baseText;\n }\n return `${baseText}. ${t('tagsInput.allowAddHelperText')}`;\n };\n\n const handleSuggestedTagClick = (tag: string) => {\n if (value && value.length < maximumTags && !value.includes(tag)) {\n onChange([...value, tag]);\n }\n };\n\n return (\n <Box>\n <Autocomplete\n multiple\n id=\"tags-select\"\n className=\"qetaTagInput\"\n value={value}\n loading={loading}\n autoHighlight\n autoComplete\n loadingText={t('common.loading')}\n options={availableTags ?? []}\n freeSolo={allowCreation}\n handleHomeEndKeys\n ListboxComponent={\n AutocompleteListboxComponent as ComponentType<\n HTMLAttributes<HTMLElement>\n >\n }\n disableListWrap\n style={style}\n renderOption={option => {\n if (tagDescriptions[option]) {\n return (\n <span key={option}>\n <Tooltip\n arrow\n placement=\"right\"\n title={<Typography>{tagDescriptions[option]}</Typography>}\n >\n <span>{option}</span>\n </Tooltip>\n </span>\n );\n }\n return option;\n }}\n onChange={(_e, newValue) => {\n const tags = filterTags(newValue);\n if (\n tags &&\n tags.length <= maximumTags &&\n tags.length === newValue.length\n ) {\n onChange(tags);\n }\n }}\n renderInput={params => (\n <TextField\n {...params}\n variant=\"outlined\"\n margin=\"normal\"\n label={t('tagsInput.label')}\n placeholder={t('tagsInput.placeholder')}\n helperText={error !== undefined ? error.message : getHelperText()}\n FormHelperTextProps={{\n style: { marginLeft: '0.2em' },\n }}\n name={name}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? (\n <CircularProgress color=\"inherit\" size={20} />\n ) : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n error={error !== undefined}\n />\n )}\n />\n {suggestedTags?.length > 0 && (\n <Box style={{ marginLeft: '4px' }}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {t('tagsInput.suggestedTags')}\n </Typography>\n <Box mt={0.5}>\n {suggestedTags.map(tag => (\n <Chip\n key={tag}\n label={tag}\n size=\"small\"\n onClick={() => handleSuggestedTagClick(tag)}\n style={{ margin: '0 4px 4px 0' }}\n disabled={\n value?.includes(tag) || (value?.length ?? 0) >= maximumTags\n }\n />\n ))}\n </Box>\n </Box>\n )}{' '}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -91,8 +91,8 @@ const PostsContainer = (props) => {
91
91
  });
92
92
  }
93
93
  return /* @__PURE__ */ jsxs(Box, { className: "qetaPostsContainer", children: [
94
- showTitle && /* @__PURE__ */ jsx(Box, { mb: 3, children: /* @__PURE__ */ jsxs(Grid, { container: true, alignItems: "center", justifyContent: "space-between", children: [
95
- /* @__PURE__ */ jsx(Grid, { item: true, children: /* @__PURE__ */ jsxs(
94
+ (showTitle || showAskButton || showWriteButton || showLinkButton) && /* @__PURE__ */ jsx(Box, { mb: 3, children: /* @__PURE__ */ jsxs(Grid, { container: true, alignItems: "center", justifyContent: "space-between", children: [
95
+ /* @__PURE__ */ jsx(Grid, { item: true, children: showTitle && /* @__PURE__ */ jsxs(
96
96
  Typography,
97
97
  {
98
98
  variant: "h5",
@@ -1 +1 @@
1
- {"version":3,"file":"PostsContainer.esm.js","sources":["../../../src/components/PostsContainer/PostsContainer.tsx"],"sourcesContent":["import {\n CommonFilterPanelProps,\n FilterPanel,\n PostFilters,\n} from '../FilterPanel/FilterPanel';\nimport { PostList } from './PostList';\nimport { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { TagFollowButton } from '../Buttons/TagFollowButton';\nimport { EntityFollowButton } from '../Buttons/EntityFollowButton';\nimport { CreateLinkButton, WriteArticleButton } from '../Buttons';\nimport { ViewToggle, ViewType } from '../ViewToggle/ViewToggle';\nimport { capitalize } from 'lodash';\nimport {\n PaginatedPostsProps,\n usePaginatedPosts,\n} from '../../hooks/usePaginatedPosts';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { SearchBar } from '../SearchBar/SearchBar';\nimport { Box, Button, Collapse, Grid, Typography } from '@material-ui/core';\nimport FilterList from '@material-ui/icons/FilterList';\n\nexport type PostsContainerProps = PaginatedPostsProps & {\n entity?: string;\n filterPanelProps?: CommonFilterPanelProps;\n showTypeLabel?: boolean;\n view?: ViewType;\n onViewChange?: (view: ViewType) => void;\n};\n\nexport const PostsContainer = (props: PostsContainerProps) => {\n const {\n type,\n tags,\n author,\n entity,\n showFilters,\n showTitle,\n title,\n favorite,\n showAskButton,\n showWriteButton,\n showLinkButton,\n showNoQuestionsBtn,\n showTypeLabel,\n view,\n onViewChange,\n } = props;\n const {\n onSearchQueryChange,\n filters,\n response,\n loading,\n error,\n setShowFilterPanel,\n showFilterPanel,\n onFilterChange,\n onPageChange,\n onPageSizeChange,\n page,\n postsPerPage,\n pageCount,\n } = usePaginatedPosts(props);\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const itemType = capitalize(t(`common.${type ?? 'post'}`, {}));\n let shownTitle = title;\n let link = undefined;\n let btn = undefined;\n if (author) {\n shownTitle = t(`postsContainer.title.by`, { itemType });\n link = <EntityRefLink entityRef={author} hideIcon defaultKind=\"user\" />;\n } else if (entity) {\n shownTitle = t(`postsContainer.title.about`, { itemType });\n link = <EntityRefLink entityRef={entity} />;\n btn = <EntityFollowButton entityRef={entity} />;\n } else if (tags) {\n shownTitle = `#${tags.join(', #')}`;\n if (tags.length === 1) {\n btn = <TagFollowButton tag={tags[0]} />;\n }\n } else if (favorite) {\n shownTitle = t('postsContainer.title.favorite', {\n itemType: itemType.toLowerCase(),\n });\n }\n\n return (\n <Box className=\"qetaPostsContainer\">\n {showTitle && (\n <Box mb={3}>\n <Grid container alignItems=\"center\" justifyContent=\"space-between\">\n <Grid item>\n <Typography\n variant=\"h5\"\n className=\"qetaPostsContainerTitle\"\n style={{ fontWeight: 500, paddingBottom: 2 }}\n >\n {shownTitle} {link} {btn}\n </Typography>\n </Grid>\n <Grid item>\n {showAskButton && (\n <AskQuestionButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n {showWriteButton && (\n <WriteArticleButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n {showLinkButton && (\n <CreateLinkButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n </Grid>\n </Grid>\n </Box>\n )}\n <Grid container alignItems=\"flex-end\" justifyContent=\"space-between\">\n <Grid item xs={12} md={4}>\n <SearchBar\n onSearch={onSearchQueryChange}\n label={t('postsContainer.search.label', {\n itemType: itemType.toLowerCase(),\n })}\n loading={loading}\n />\n </Grid>\n </Grid>\n {response && (\n <Box mt={2} mb={2}>\n <Grid container alignItems=\"center\" justifyContent=\"space-between\">\n <Grid item>\n <Typography\n variant=\"h6\"\n className=\"qetaPostsContainerQuestionCount\"\n style={{ fontWeight: 500, paddingBottom: 2 }}\n >\n {t('common.posts', { count: response?.total ?? 0, itemType })}\n </Typography>\n </Grid>\n <Grid item>\n <Grid container spacing={1} alignItems=\"center\">\n {view && onViewChange && (\n <Grid item>\n <ViewToggle view={view} onChange={onViewChange} />\n </Grid>\n )}\n {(showFilters ?? true) && (\n <Grid item>\n <Button\n onClick={() => {\n setShowFilterPanel(!showFilterPanel);\n }}\n className=\"qetaPostsContainerFilterPanelBtn\"\n startIcon={<FilterList />}\n >\n {t('filterPanel.filterButton')}\n </Button>\n </Grid>\n )}\n </Grid>\n </Grid>\n </Grid>\n </Box>\n )}\n {(showFilters ?? true) && (\n <Collapse in={showFilterPanel}>\n <FilterPanel<PostFilters>\n onChange={onFilterChange}\n filters={filters}\n type={type}\n showEntityFilter={entity === undefined}\n {...props.filterPanelProps}\n />\n </Collapse>\n )}\n <PostList\n loading={loading}\n error={error}\n response={response}\n onPageChange={onPageChange}\n onPageSizeChange={onPageSizeChange}\n entity={entity ?? filters.entity}\n page={page}\n pageSize={postsPerPage}\n pageCount={pageCount}\n showNoQuestionsBtn={showNoQuestionsBtn}\n entityPage={entity !== undefined}\n tags={tags ?? filters.tags}\n type={type}\n showTypeLabel={showTypeLabel}\n />\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostsContainer.esm.js","sources":["../../../src/components/PostsContainer/PostsContainer.tsx"],"sourcesContent":["import {\n CommonFilterPanelProps,\n FilterPanel,\n PostFilters,\n} from '../FilterPanel/FilterPanel';\nimport { PostList } from './PostList';\nimport { AskQuestionButton } from '../Buttons/AskQuestionButton';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { TagFollowButton } from '../Buttons/TagFollowButton';\nimport { EntityFollowButton } from '../Buttons/EntityFollowButton';\nimport { CreateLinkButton, WriteArticleButton } from '../Buttons';\nimport { ViewToggle, ViewType } from '../ViewToggle/ViewToggle';\nimport { capitalize } from 'lodash';\nimport {\n PaginatedPostsProps,\n usePaginatedPosts,\n} from '../../hooks/usePaginatedPosts';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { SearchBar } from '../SearchBar/SearchBar';\nimport { Box, Button, Collapse, Grid, Typography } from '@material-ui/core';\nimport FilterList from '@material-ui/icons/FilterList';\n\nexport type PostsContainerProps = PaginatedPostsProps & {\n entity?: string;\n filterPanelProps?: CommonFilterPanelProps;\n showTypeLabel?: boolean;\n view?: ViewType;\n onViewChange?: (view: ViewType) => void;\n};\n\nexport const PostsContainer = (props: PostsContainerProps) => {\n const {\n type,\n tags,\n author,\n entity,\n showFilters,\n showTitle,\n title,\n favorite,\n showAskButton,\n showWriteButton,\n showLinkButton,\n showNoQuestionsBtn,\n showTypeLabel,\n view,\n onViewChange,\n } = props;\n const {\n onSearchQueryChange,\n filters,\n response,\n loading,\n error,\n setShowFilterPanel,\n showFilterPanel,\n onFilterChange,\n onPageChange,\n onPageSizeChange,\n page,\n postsPerPage,\n pageCount,\n } = usePaginatedPosts(props);\n const { t } = useTranslationRef(qetaTranslationRef);\n\n const itemType = capitalize(t(`common.${type ?? 'post'}`, {}));\n let shownTitle = title;\n let link = undefined;\n let btn = undefined;\n if (author) {\n shownTitle = t(`postsContainer.title.by`, { itemType });\n link = <EntityRefLink entityRef={author} hideIcon defaultKind=\"user\" />;\n } else if (entity) {\n shownTitle = t(`postsContainer.title.about`, { itemType });\n link = <EntityRefLink entityRef={entity} />;\n btn = <EntityFollowButton entityRef={entity} />;\n } else if (tags) {\n shownTitle = `#${tags.join(', #')}`;\n if (tags.length === 1) {\n btn = <TagFollowButton tag={tags[0]} />;\n }\n } else if (favorite) {\n shownTitle = t('postsContainer.title.favorite', {\n itemType: itemType.toLowerCase(),\n });\n }\n\n return (\n <Box className=\"qetaPostsContainer\">\n {(showTitle || showAskButton || showWriteButton || showLinkButton) && (\n <Box mb={3}>\n <Grid container alignItems=\"center\" justifyContent=\"space-between\">\n <Grid item>\n {showTitle && (\n <Typography\n variant=\"h5\"\n className=\"qetaPostsContainerTitle\"\n style={{ fontWeight: 500, paddingBottom: 2 }}\n >\n {shownTitle} {link} {btn}\n </Typography>\n )}\n </Grid>\n <Grid item>\n {showAskButton && (\n <AskQuestionButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n {showWriteButton && (\n <WriteArticleButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n {showLinkButton && (\n <CreateLinkButton\n entity={entity ?? filters.entity}\n entityPage={entity !== undefined}\n tags={tags}\n />\n )}\n </Grid>\n </Grid>\n </Box>\n )}\n <Grid container alignItems=\"flex-end\" justifyContent=\"space-between\">\n <Grid item xs={12} md={4}>\n <SearchBar\n onSearch={onSearchQueryChange}\n label={t('postsContainer.search.label', {\n itemType: itemType.toLowerCase(),\n })}\n loading={loading}\n />\n </Grid>\n </Grid>\n {response && (\n <Box mt={2} mb={2}>\n <Grid container alignItems=\"center\" justifyContent=\"space-between\">\n <Grid item>\n <Typography\n variant=\"h6\"\n className=\"qetaPostsContainerQuestionCount\"\n style={{ fontWeight: 500, paddingBottom: 2 }}\n >\n {t('common.posts', { count: response?.total ?? 0, itemType })}\n </Typography>\n </Grid>\n <Grid item>\n <Grid container spacing={1} alignItems=\"center\">\n {view && onViewChange && (\n <Grid item>\n <ViewToggle view={view} onChange={onViewChange} />\n </Grid>\n )}\n {(showFilters ?? true) && (\n <Grid item>\n <Button\n onClick={() => {\n setShowFilterPanel(!showFilterPanel);\n }}\n className=\"qetaPostsContainerFilterPanelBtn\"\n startIcon={<FilterList />}\n >\n {t('filterPanel.filterButton')}\n </Button>\n </Grid>\n )}\n </Grid>\n </Grid>\n </Grid>\n </Box>\n )}\n {(showFilters ?? true) && (\n <Collapse in={showFilterPanel}>\n <FilterPanel<PostFilters>\n onChange={onFilterChange}\n filters={filters}\n type={type}\n showEntityFilter={entity === undefined}\n {...props.filterPanelProps}\n />\n </Collapse>\n )}\n <PostList\n loading={loading}\n error={error}\n response={response}\n onPageChange={onPageChange}\n onPageSizeChange={onPageSizeChange}\n entity={entity ?? filters.entity}\n page={page}\n pageSize={postsPerPage}\n pageCount={pageCount}\n showNoQuestionsBtn={showNoQuestionsBtn}\n entityPage={entity !== undefined}\n tags={tags ?? filters.tags}\n type={type}\n showTypeLabel={showTypeLabel}\n />\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import '@drodil/backstage-plugin-qeta-common';
16
16
  import '@backstage/plugin-permission-common';
17
17
  import { Grid, Typography, ButtonGroup, Button, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, TablePagination } from '@material-ui/core';
18
18
  import RefreshIcon from '@material-ui/icons/Refresh';
19
+ import { LoadingGrid } from '../LoadingGrid/LoadingGrid.esm.js';
19
20
 
20
21
  const PostsTable = (props) => {
21
22
  const [page, setPage] = useState(1);
@@ -81,6 +82,9 @@ const PostsTable = (props) => {
81
82
  setQuestionsPerPage(parseInt(event.target.value, 10));
82
83
  setPage(1);
83
84
  };
85
+ if (loading) {
86
+ return /* @__PURE__ */ jsx(LoadingGrid, {});
87
+ }
84
88
  if (error || response === void 0) {
85
89
  return /* @__PURE__ */ jsx(WarningPanel, { severity: "error", title: t("postsTable.errorLoading"), children: error?.message });
86
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PostsTable.esm.js","sources":["../../../src/components/PostsTable/PostsTable.tsx"],"sourcesContent":["import { ChangeEvent, useState } from 'react';\nimport { LinkButton, Progress, WarningPanel } from '@backstage/core-components';\nimport { PostsTableRow } from './PostsTableRow';\nimport { useQetaApi } from '../../hooks';\nimport {\n Button,\n ButtonGroup,\n Grid,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TablePagination,\n TableRow,\n Typography,\n} from '@material-ui/core';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport { PostType } from '@drodil/backstage-plugin-qeta-common';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\ntype QuickFilterType = 'latest' | 'favorites' | 'most_viewed';\n\nexport const PostsTable = (props: {\n hideTitle?: boolean;\n rowsPerPage?: number;\n quickFilter?: QuickFilterType;\n postType?: PostType;\n}) => {\n const [page, setPage] = useState(1);\n const [questionsPerPage, setQuestionsPerPage] = useState(\n props.rowsPerPage ?? 10,\n );\n const [quickFilter, setQuickFilter] = useState(props.quickFilter ?? 'latest');\n const [refresh, setRefresh] = useState(0);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [filters, setFilters] = useState({\n order: 'desc',\n orderBy: 'created',\n noAnswers: 'false',\n noCorrectAnswer: 'false',\n noVotes: 'false',\n searchQuery: '',\n favorite: false,\n });\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api =>\n api.getPosts({\n type: props.postType,\n limit: questionsPerPage,\n offset: (page - 1) * questionsPerPage,\n includeEntities: true,\n includeExperts: false,\n ...(filters as any),\n }),\n [page, filters, questionsPerPage, refresh],\n );\n\n const handleQuickFilterChange = (filter: QuickFilterType) => {\n setQuickFilter(filter);\n if (filter === 'latest') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'created',\n favorite: false,\n });\n } else if (filter === 'favorites') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'created',\n favorite: true,\n });\n } else if (filter === 'most_viewed') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'views',\n favorite: false,\n });\n }\n };\n\n const handleChangePage = (_: unknown, newPage: number) => {\n setPage(newPage + 1);\n };\n\n const handleChangeRowsPerPage = (event: ChangeEvent<HTMLInputElement>) => {\n setQuestionsPerPage(parseInt(event.target.value, 10));\n setPage(1);\n };\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('postsTable.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n return (\n <>\n <Grid\n container\n justifyContent=\"space-between\"\n alignItems=\"center\"\n style={{ marginBottom: '1em' }}\n className=\"qetaPostsTableGrid\"\n >\n <Grid item>\n {props.hideTitle === true ? null : (\n <Typography variant=\"h5\">{t('pluginName')}</Typography>\n )}\n </Grid>\n <Grid item>\n <ButtonGroup>\n <Button\n color={quickFilter === 'latest' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('latest')}\n >\n {t('postsTable.latest')}\n </Button>\n <Button\n color={quickFilter === 'favorites' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('favorites')}\n >\n {t('postsTable.favorites')}\n </Button>\n <Button\n color={quickFilter === 'most_viewed' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('most_viewed')}\n >\n {t('postsTable.mostViewed')}\n </Button>\n </ButtonGroup>\n <LinkButton\n to=\"#\"\n variant=\"text\"\n onClick={() => setRefresh(refresh + 1)}\n >\n <RefreshIcon />\n </LinkButton>\n </Grid>\n </Grid>\n <TableContainer>\n <Table className=\"qetaQuestionsTable\">\n <TableHead>\n <TableRow>\n <TableCell>{t('postsTable.cells.title')}</TableCell>\n <TableCell>{t('postsTable.cells.author')}</TableCell>\n {props.postType === undefined && (\n <TableCell>{t('postsTable.cells.type')}</TableCell>\n )}\n <TableCell>{t('postsTable.cells.asked')}</TableCell>\n <TableCell>{t('postsTable.cells.updated')}</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell>\n <Progress />\n </TableCell>\n </TableRow>\n ) : null}\n {response.posts.map(q => (\n <PostsTableRow\n key={q.id}\n post={q}\n showIcon={props.postType === undefined}\n />\n ))}\n </TableBody>\n </Table>\n <TablePagination\n rowsPerPageOptions={[5, 10, 20, 30, 40, 50]}\n component=\"div\"\n count={response.total}\n rowsPerPage={questionsPerPage}\n page={page - 1}\n onPageChange={handleChangePage}\n onRowsPerPageChange={handleChangeRowsPerPage}\n />\n </TableContainer>\n </>\n );\n};\n\n/**\n * @deprecated Use `PostsTable` instead\n */\nexport const QuestionsTable = PostsTable;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostsTable.esm.js","sources":["../../../src/components/PostsTable/PostsTable.tsx"],"sourcesContent":["import { ChangeEvent, useState } from 'react';\nimport { LinkButton, Progress, WarningPanel } from '@backstage/core-components';\nimport { PostsTableRow } from './PostsTableRow';\nimport { useQetaApi } from '../../hooks';\nimport {\n Button,\n ButtonGroup,\n Grid,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TablePagination,\n TableRow,\n Typography,\n} from '@material-ui/core';\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport { PostType } from '@drodil/backstage-plugin-qeta-common';\nimport { qetaTranslationRef } from '../../translation.ts';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { LoadingGrid } from '../LoadingGrid/LoadingGrid';\n\ntype QuickFilterType = 'latest' | 'favorites' | 'most_viewed';\n\nexport const PostsTable = (props: {\n hideTitle?: boolean;\n rowsPerPage?: number;\n quickFilter?: QuickFilterType;\n postType?: PostType;\n}) => {\n const [page, setPage] = useState(1);\n const [questionsPerPage, setQuestionsPerPage] = useState(\n props.rowsPerPage ?? 10,\n );\n const [quickFilter, setQuickFilter] = useState(props.quickFilter ?? 'latest');\n const [refresh, setRefresh] = useState(0);\n const { t } = useTranslationRef(qetaTranslationRef);\n const [filters, setFilters] = useState({\n order: 'desc',\n orderBy: 'created',\n noAnswers: 'false',\n noCorrectAnswer: 'false',\n noVotes: 'false',\n searchQuery: '',\n favorite: false,\n });\n const {\n value: response,\n loading,\n error,\n } = useQetaApi(\n api =>\n api.getPosts({\n type: props.postType,\n limit: questionsPerPage,\n offset: (page - 1) * questionsPerPage,\n includeEntities: true,\n includeExperts: false,\n ...(filters as any),\n }),\n [page, filters, questionsPerPage, refresh],\n );\n\n const handleQuickFilterChange = (filter: QuickFilterType) => {\n setQuickFilter(filter);\n if (filter === 'latest') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'created',\n favorite: false,\n });\n } else if (filter === 'favorites') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'created',\n favorite: true,\n });\n } else if (filter === 'most_viewed') {\n setFilters({\n ...filters,\n order: 'desc',\n orderBy: 'views',\n favorite: false,\n });\n }\n };\n\n const handleChangePage = (_: unknown, newPage: number) => {\n setPage(newPage + 1);\n };\n\n const handleChangeRowsPerPage = (event: ChangeEvent<HTMLInputElement>) => {\n setQuestionsPerPage(parseInt(event.target.value, 10));\n setPage(1);\n };\n\n if (loading) {\n return <LoadingGrid />;\n }\n\n if (error || response === undefined) {\n return (\n <WarningPanel severity=\"error\" title={t('postsTable.errorLoading')}>\n {error?.message}\n </WarningPanel>\n );\n }\n\n return (\n <>\n <Grid\n container\n justifyContent=\"space-between\"\n alignItems=\"center\"\n style={{ marginBottom: '1em' }}\n className=\"qetaPostsTableGrid\"\n >\n <Grid item>\n {props.hideTitle === true ? null : (\n <Typography variant=\"h5\">{t('pluginName')}</Typography>\n )}\n </Grid>\n <Grid item>\n <ButtonGroup>\n <Button\n color={quickFilter === 'latest' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('latest')}\n >\n {t('postsTable.latest')}\n </Button>\n <Button\n color={quickFilter === 'favorites' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('favorites')}\n >\n {t('postsTable.favorites')}\n </Button>\n <Button\n color={quickFilter === 'most_viewed' ? 'primary' : undefined}\n onClick={() => handleQuickFilterChange('most_viewed')}\n >\n {t('postsTable.mostViewed')}\n </Button>\n </ButtonGroup>\n <LinkButton\n to=\"#\"\n variant=\"text\"\n onClick={() => setRefresh(refresh + 1)}\n >\n <RefreshIcon />\n </LinkButton>\n </Grid>\n </Grid>\n <TableContainer>\n <Table className=\"qetaQuestionsTable\">\n <TableHead>\n <TableRow>\n <TableCell>{t('postsTable.cells.title')}</TableCell>\n <TableCell>{t('postsTable.cells.author')}</TableCell>\n {props.postType === undefined && (\n <TableCell>{t('postsTable.cells.type')}</TableCell>\n )}\n <TableCell>{t('postsTable.cells.asked')}</TableCell>\n <TableCell>{t('postsTable.cells.updated')}</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n <TableRow>\n <TableCell>\n <Progress />\n </TableCell>\n </TableRow>\n ) : null}\n {response.posts.map(q => (\n <PostsTableRow\n key={q.id}\n post={q}\n showIcon={props.postType === undefined}\n />\n ))}\n </TableBody>\n </Table>\n <TablePagination\n rowsPerPageOptions={[5, 10, 20, 30, 40, 50]}\n component=\"div\"\n count={response.total}\n rowsPerPage={questionsPerPage}\n page={page - 1}\n onPageChange={handleChangePage}\n onRowsPerPageChange={handleChangeRowsPerPage}\n />\n </TableContainer>\n </>\n );\n};\n\n/**\n * @deprecated Use `PostsTable` instead\n */\nexport const QuestionsTable = PostsTable;\n"],"names":[],"mappings":"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"}
@@ -40,6 +40,16 @@ const getEntityTitle = (entity, opts) => {
40
40
  const stringified = stringifyEntityRef(entity);
41
41
  return `${entity.metadata.title ?? formatEntityName(stringified) ?? stringified}${withType && entity.spec?.type ? ` (${entity.spec.type})` : ""}`;
42
42
  };
43
+ const getEntityDescription = (entity) => {
44
+ const parts = [stringifyEntityRef(entity)];
45
+ if (entity.metadata.description) {
46
+ parts.push(entity.metadata.description.split("\n")[0]);
47
+ }
48
+ if ((isUserEntity(entity) || isGroupEntity(entity)) && entity.spec?.profile?.email) {
49
+ parts.push(entity.spec.profile.email);
50
+ }
51
+ return parts.join(", ");
52
+ };
43
53
  const formatDate = (localDate) => {
44
54
  let date = localDate.getDate();
45
55
  let month = localDate.getMonth() + 1;
@@ -133,5 +143,5 @@ const useConfirmNavigationIfEdited = (edited) => {
133
143
  }, [edited, msg]);
134
144
  };
135
145
 
136
- export { formatDate, formatEntityName, getEntityTitle, getFiltersWithDateRange, imageUpload, useConfirmNavigationIfEdited };
146
+ export { formatDate, formatEntityName, getEntityDescription, getEntityTitle, getFiltersWithDateRange, imageUpload, useConfirmNavigationIfEdited };
137
147
  //# sourceMappingURL=utils.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.esm.js","sources":["../../src/utils/utils.ts"],"sourcesContent":["import {\n Entity,\n isGroupEntity,\n isUserEntity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Filters } from '../components/FilterPanel/FilterPanel';\nimport FileType from 'file-type';\nimport { ErrorApi } from '@backstage/core-plugin-api';\nimport { QetaApi } from '@drodil/backstage-plugin-qeta-common';\nimport { useEffect } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../translation.ts';\n\nexport const imageUpload = (opts: {\n qetaApi: QetaApi;\n errorApi: ErrorApi;\n onImageUpload?: (id: number) => void;\n postId?: number;\n answerId?: number;\n collectionId?: number;\n}) => {\n const { qetaApi, errorApi, onImageUpload, postId, answerId, collectionId } =\n opts;\n // eslint-disable-next-line func-names\n return async function* (data: ArrayBuffer) {\n const fileType = await FileType.fromBuffer(data);\n\n const mimeType = fileType ? fileType.mime : 'text/plain';\n const attachment = await qetaApi.postAttachment(\n new Blob([data], { type: mimeType }),\n { postId, answerId, collectionId },\n );\n if ('errors' in attachment) {\n errorApi.post({\n name: 'Upload failed',\n message: attachment.errors?.map(e => e.message).join(', ') ?? '',\n });\n return false;\n }\n onImageUpload?.(attachment.id);\n yield attachment.locationUri;\n return true;\n };\n};\n\nexport const formatEntityName = (username?: string) => {\n if (!username) {\n return '';\n }\n const plainName = username.split(/[/:]+/).pop();\n return plainName\n ?.split(/[_.-]+/)\n .map(a => a.charAt(0).toUpperCase() + a.slice(1))\n .join(' ');\n};\n\nexport const getEntityTitle = (\n entity: Entity,\n opts?: { withType: boolean },\n): string => {\n const { withType } = opts || { withType: true };\n if (\n (isUserEntity(entity) || isGroupEntity(entity)) &&\n entity.spec?.profile?.displayName\n ) {\n return entity.spec.profile.displayName;\n }\n\n const stringified = stringifyEntityRef(entity);\n return `${\n entity.metadata.title ?? formatEntityName(stringified) ?? stringified\n }${withType && entity.spec?.type ? ` (${entity.spec.type})` : ''}`;\n};\n\nexport const formatDate = (localDate: Date) => {\n let date: any = localDate.getDate();\n let month: any = localDate.getMonth() + 1;\n if (date < 10) {\n date = `0${date}`;\n }\n\n if (month < 10) {\n month = `0${month}`;\n }\n return `${localDate.getFullYear()}-${month}-${date}`;\n};\n\nexport type FiltersWithDateRange = Filters & {\n fromDate: string;\n toDate: string;\n};\n\nexport const getFiltersWithDateRange = (filters: Filters) => {\n let filtersWithDateRange: FiltersWithDateRange;\n const to = new Date();\n const from = new Date(to);\n if (filters.dateRange) {\n let fromDate = '';\n let toDate = '';\n\n switch (filters.dateRange) {\n case '7-days':\n toDate = formatDate(to);\n from.setDate(to.getDate() - 6);\n fromDate = formatDate(from);\n break;\n\n case '30-days':\n toDate = formatDate(to);\n from.setDate(to.getDate() - 29);\n fromDate = formatDate(from);\n break;\n default:\n if (filters.dateRange.indexOf('--') > 0) {\n fromDate = filters.dateRange.split('--')[0];\n toDate = filters.dateRange.split('--')[1];\n }\n break;\n }\n if (fromDate && toDate) {\n filtersWithDateRange = { ...filters, fromDate, toDate };\n delete filtersWithDateRange.dateRange;\n return filtersWithDateRange;\n }\n }\n\n if ('dateRange' in filters) {\n delete filters.dateRange;\n }\n\n return filters;\n};\n\nexport const useConfirmNavigationIfEdited = (edited: boolean) => {\n const { t } = useTranslationRef(qetaTranslationRef);\n const msg = t('common.unsaved_changes');\n\n useEffect(() => {\n const handleBeforeUnload = (event: BeforeUnloadEvent) => {\n if (edited) {\n event.preventDefault();\n event.returnValue = msg; // Included for legacy support, e.g. Chrome/Edge < 119\n }\n };\n\n const handleLocationChange = (event: any) => {\n if (edited) {\n // eslint-disable-next-line no-alert\n const response = window.confirm(msg);\n if (!response) {\n event.preventDefault();\n }\n }\n };\n\n window.addEventListener('beforeunload', handleBeforeUnload);\n\n // Modern browsers with Navigation API\n if ('navigation' in window && window.navigation) {\n // @ts-ignore\n window.navigation.addEventListener('navigate', handleLocationChange);\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n // @ts-ignore\n window.navigation.removeEventListener('navigate', handleLocationChange);\n };\n }\n\n // Fallback: Use popstate + history monitoring\n window.addEventListener('popstate', handleLocationChange);\n\n const originalPushState = window.history.pushState;\n const originalReplaceState = window.history.replaceState;\n\n window.history.pushState = (...args) => {\n originalPushState.apply(window.history, args);\n handleLocationChange(new PopStateEvent('navigate', { state: args[0] }));\n };\n\n window.history.replaceState = (...args) => {\n originalReplaceState.apply(window.history, args);\n handleLocationChange(new PopStateEvent('navigate', { state: args[0] }));\n };\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n window.removeEventListener('popstate', handleLocationChange);\n window.history.pushState = originalPushState;\n window.history.replaceState = originalReplaceState;\n };\n }, [edited, msg]);\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.esm.js","sources":["../../src/utils/utils.ts"],"sourcesContent":["import {\n Entity,\n isGroupEntity,\n isUserEntity,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Filters } from '../components/FilterPanel/FilterPanel';\nimport FileType from 'file-type';\nimport { ErrorApi } from '@backstage/core-plugin-api';\nimport { QetaApi } from '@drodil/backstage-plugin-qeta-common';\nimport { useEffect } from 'react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { qetaTranslationRef } from '../translation.ts';\n\nexport const imageUpload = (opts: {\n qetaApi: QetaApi;\n errorApi: ErrorApi;\n onImageUpload?: (id: number) => void;\n postId?: number;\n answerId?: number;\n collectionId?: number;\n}) => {\n const { qetaApi, errorApi, onImageUpload, postId, answerId, collectionId } =\n opts;\n // eslint-disable-next-line func-names\n return async function* (data: ArrayBuffer) {\n const fileType = await FileType.fromBuffer(data);\n\n const mimeType = fileType ? fileType.mime : 'text/plain';\n const attachment = await qetaApi.postAttachment(\n new Blob([data], { type: mimeType }),\n { postId, answerId, collectionId },\n );\n if ('errors' in attachment) {\n errorApi.post({\n name: 'Upload failed',\n message: attachment.errors?.map(e => e.message).join(', ') ?? '',\n });\n return false;\n }\n onImageUpload?.(attachment.id);\n yield attachment.locationUri;\n return true;\n };\n};\n\nexport const formatEntityName = (username?: string) => {\n if (!username) {\n return '';\n }\n const plainName = username.split(/[/:]+/).pop();\n return plainName\n ?.split(/[_.-]+/)\n .map(a => a.charAt(0).toUpperCase() + a.slice(1))\n .join(' ');\n};\n\nexport const getEntityTitle = (\n entity: Entity,\n opts?: { withType: boolean },\n): string => {\n const { withType } = opts || { withType: true };\n if (\n (isUserEntity(entity) || isGroupEntity(entity)) &&\n entity.spec?.profile?.displayName\n ) {\n return entity.spec.profile.displayName;\n }\n\n const stringified = stringifyEntityRef(entity);\n return `${\n entity.metadata.title ?? formatEntityName(stringified) ?? stringified\n }${withType && entity.spec?.type ? ` (${entity.spec.type})` : ''}`;\n};\n\nexport const getEntityDescription = (entity: Entity): string => {\n const parts = [stringifyEntityRef(entity)];\n if (entity.metadata.description) {\n parts.push(entity.metadata.description.split('\\n')[0]);\n }\n if (\n (isUserEntity(entity) || isGroupEntity(entity)) &&\n entity.spec?.profile?.email\n ) {\n parts.push(entity.spec.profile.email);\n }\n return parts.join(', ');\n};\n\nexport const formatDate = (localDate: Date) => {\n let date: any = localDate.getDate();\n let month: any = localDate.getMonth() + 1;\n if (date < 10) {\n date = `0${date}`;\n }\n\n if (month < 10) {\n month = `0${month}`;\n }\n return `${localDate.getFullYear()}-${month}-${date}`;\n};\n\nexport type FiltersWithDateRange = Filters & {\n fromDate: string;\n toDate: string;\n};\n\nexport const getFiltersWithDateRange = (filters: Filters) => {\n let filtersWithDateRange: FiltersWithDateRange;\n const to = new Date();\n const from = new Date(to);\n if (filters.dateRange) {\n let fromDate = '';\n let toDate = '';\n\n switch (filters.dateRange) {\n case '7-days':\n toDate = formatDate(to);\n from.setDate(to.getDate() - 6);\n fromDate = formatDate(from);\n break;\n\n case '30-days':\n toDate = formatDate(to);\n from.setDate(to.getDate() - 29);\n fromDate = formatDate(from);\n break;\n default:\n if (filters.dateRange.indexOf('--') > 0) {\n fromDate = filters.dateRange.split('--')[0];\n toDate = filters.dateRange.split('--')[1];\n }\n break;\n }\n if (fromDate && toDate) {\n filtersWithDateRange = { ...filters, fromDate, toDate };\n delete filtersWithDateRange.dateRange;\n return filtersWithDateRange;\n }\n }\n\n if ('dateRange' in filters) {\n delete filters.dateRange;\n }\n\n return filters;\n};\n\nexport const useConfirmNavigationIfEdited = (edited: boolean) => {\n const { t } = useTranslationRef(qetaTranslationRef);\n const msg = t('common.unsaved_changes');\n\n useEffect(() => {\n const handleBeforeUnload = (event: BeforeUnloadEvent) => {\n if (edited) {\n event.preventDefault();\n event.returnValue = msg; // Included for legacy support, e.g. Chrome/Edge < 119\n }\n };\n\n const handleLocationChange = (event: any) => {\n if (edited) {\n // eslint-disable-next-line no-alert\n const response = window.confirm(msg);\n if (!response) {\n event.preventDefault();\n }\n }\n };\n\n window.addEventListener('beforeunload', handleBeforeUnload);\n\n // Modern browsers with Navigation API\n if ('navigation' in window && window.navigation) {\n // @ts-ignore\n window.navigation.addEventListener('navigate', handleLocationChange);\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n // @ts-ignore\n window.navigation.removeEventListener('navigate', handleLocationChange);\n };\n }\n\n // Fallback: Use popstate + history monitoring\n window.addEventListener('popstate', handleLocationChange);\n\n const originalPushState = window.history.pushState;\n const originalReplaceState = window.history.replaceState;\n\n window.history.pushState = (...args) => {\n originalPushState.apply(window.history, args);\n handleLocationChange(new PopStateEvent('navigate', { state: args[0] }));\n };\n\n window.history.replaceState = (...args) => {\n originalReplaceState.apply(window.history, args);\n handleLocationChange(new PopStateEvent('navigate', { state: args[0] }));\n };\n\n return () => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n window.removeEventListener('popstate', handleLocationChange);\n window.history.pushState = originalPushState;\n window.history.replaceState = originalReplaceState;\n };\n }, [edited, msg]);\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "frontend",
8
8
  "backstage.io"
9
9
  ],
10
- "version": "3.41.0",
10
+ "version": "3.41.2",
11
11
  "main": "dist/index.esm.js",
12
12
  "types": "dist/index.d.ts",
13
13
  "prepublishOnly": "yarn tsc && yarn build",
@@ -57,7 +57,7 @@
57
57
  "@backstage/plugin-permission-common": "^0.9.1",
58
58
  "@backstage/plugin-permission-react": "^0.4.36",
59
59
  "@backstage/plugin-signals-react": "^0.0.15",
60
- "@drodil/backstage-plugin-qeta-common": "^3.41.0",
60
+ "@drodil/backstage-plugin-qeta-common": "^3.41.2",
61
61
  "@jsdevtools/rehype-toc": "^3.0.2",
62
62
  "@material-ui/core": "^4.12.2",
63
63
  "@material-ui/icons": "^4.11.3",