@backstage/plugin-scaffolder 1.38.2-next.2 → 1.38.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @backstage/plugin-scaffolder
2
2
 
3
+ ## 1.38.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9e773ee: Improves scaffolder entity pickers by using the catalog POST endpoint so large template filters are sent in the request body instead of the URL, helping avoid 431 errors and empty option lists.
8
+ - Updated dependencies
9
+ - @backstage/catalog-model@1.10.0
10
+ - @backstage/core-components@0.18.13
11
+ - @backstage/core-plugin-api@1.12.9
12
+ - @backstage/plugin-catalog-react@3.2.1
13
+ - @backstage/ui@0.17.1
14
+ - @backstage/integration@2.1.0
15
+ - @backstage/plugin-scaffolder-common@2.2.2
16
+ - @backstage/frontend-plugin-api@0.18.0
17
+ - @backstage/integration-react@1.2.21
18
+ - @backstage/plugin-permission-react@0.5.4
19
+ - @backstage/plugin-scaffolder-react@2.0.3
20
+ - @backstage/plugin-techdocs-react@1.3.14
21
+
22
+ ## 1.38.2-next.3
23
+
24
+ ### Patch Changes
25
+
26
+ - 9e773ee: Improves scaffolder entity pickers by using the catalog POST endpoint so large template filters are sent in the request body instead of the URL, helping avoid 431 errors and empty option lists.
27
+ - Updated dependencies
28
+ - @backstage/core-plugin-api@1.12.9-next.1
29
+ - @backstage/plugin-catalog-react@3.2.1-next.3
30
+ - @backstage/integration@2.1.0-next.1
31
+
3
32
  ## 1.38.2-next.2
4
33
 
5
34
  ### Patch Changes
@@ -47,9 +47,11 @@ const EntityPicker = (props) => {
47
47
  "spec.profile.displayName",
48
48
  "spec.type"
49
49
  ];
50
- const { items } = await catalogApi.getEntities(
51
- catalogFilter ? { filter: catalogFilter, fields } : { filter: void 0, fields }
52
- );
50
+ const streamRequest = catalogFilter ? { query: {}, filter: catalogFilter, fields } : { fields };
51
+ const items = [];
52
+ for await (const batch of catalogApi.streamEntities(streamRequest)) {
53
+ items.push(...batch);
54
+ }
53
55
  const entityRefToPresentation = new Map(
54
56
  await Promise.all(
55
57
  items.map(async (item) => {
@@ -1 +1 @@
1
- {"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n EntityDisplayName,\n EntityRefPresentationSnapshot,\n catalogApiRef,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteChangeReason,\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport {\n type Key,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n onChange,\n schema: {\n title = t('fields.entityPicker.title'),\n description = t('fields.entityPicker.description'),\n },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n errors,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n const autoSelect = uiSchema?.['ui:options']?.autoSelect ?? true;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n 'spec.type',\n ];\n const { items } = await catalogApi.getEntities(\n catalogFilter\n ? { filter: catalogFilter, fields }\n : { filter: undefined, fields },\n );\n\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n\n return { catalogEntities: items, entityRefToPresentation };\n });\n\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (freeSoloValue: string) => {\n try {\n // Will throw if defaultKind or defaultNamespace are not set\n const parsedRef = parseEntityRef(freeSoloValue, {\n defaultKind,\n defaultNamespace,\n });\n\n return stringifyEntityRef(parsedRef);\n } catch (err) {\n return freeSoloValue;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then\n // fall back to the given value.\n const selectedEntity =\n entities?.catalogEntities.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n // BUI: options for autocomplete\n const buiOptions = useMemo(\n () =>\n (entities?.catalogEntities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = entities?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [entities],\n );\n\n // BUI: controlled input value\n const [inputValue, setInputValue] = useState(formData || '');\n\n useEffect(() => {\n if (formData) {\n const opt = buiOptions.find(o => o.value === formData);\n setInputValue(opt?.label || formData);\n } else {\n setInputValue('');\n }\n }, [formData, buiOptions]);\n\n const selectedKey =\n formData && buiOptions.some(o => o.value === formData) ? formData : null;\n\n const lastCommittedRef = useRef(formData);\n\n useEffect(() => {\n lastCommittedRef.current = formData;\n }, [formData]);\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (key !== null) {\n const value = String(key);\n lastCommittedRef.current = value;\n onChange(value);\n } else if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n lastCommittedRef.current = entityRef;\n onChange(entityRef);\n } else {\n lastCommittedRef.current = undefined;\n onChange(undefined);\n }\n },\n [onChange, allowArbitraryValues, inputValue, defaultKind, defaultNamespace],\n );\n\n const handleBlur = useCallback(() => {\n if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n if (lastCommittedRef.current !== entityRef) {\n lastCommittedRef.current = entityRef;\n onChange(entityRef);\n }\n }\n }, [\n allowArbitraryValues,\n inputValue,\n defaultKind,\n defaultNamespace,\n onChange,\n ]);\n\n // Auto-select when only one entity and required\n useEffect(() => {\n if (theme === 'bui') {\n if (\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1 &&\n !formData\n ) {\n onChange(stringifyEntityRef(entities.catalogEntities[0]));\n }\n } else {\n if (\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1 &&\n selectedEntity === ''\n ) {\n onChange(stringifyEntityRef(entities.catalogEntities[0]));\n }\n }\n }, [\n entities,\n onChange,\n selectedEntity,\n formData,\n required,\n allowArbitraryValues,\n theme,\n ]);\n\n if (theme === 'bui') {\n const isAutoSelected =\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected}\n selectedKey={selectedKey}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n onBlur={handleBlur}\n isLoading={loading}\n options={buiOptions}\n allowsCustomValue={allowArbitraryValues}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n disabled={\n isDisabled ||\n (required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1)\n }\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities?.catalogEntities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.entityRef!\n }\n autoSelect={autoSelect}\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n variant=\"outlined\"\n required={required}\n disabled={isDisabled}\n InputProps={params.InputProps}\n />\n )}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
1
+ {"version":3,"file":"EntityPicker.esm.js","sources":["../../../../src/components/fields/EntityPicker/EntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n EntityDisplayName,\n EntityRefPresentationSnapshot,\n catalogApiRef,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteChangeReason,\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport {\n type Key,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n EntityPickerFilterQueryValue,\n EntityPickerProps,\n EntityPickerUiOptions,\n EntityPickerFilterQuery,\n} from './schema';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\n\nexport { EntityPickerSchema } from './schema';\n\n/**\n * The underlying component that is rendered in the form for the `EntityPicker`\n * field extension.\n *\n * @public\n */\nexport const EntityPicker = (props: EntityPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n onChange,\n schema: {\n title = t('fields.entityPicker.title'),\n description = t('fields.entityPicker.description'),\n },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n errors,\n } = props;\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n const autoSelect = uiSchema?.['ui:options']?.autoSelect ?? true;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n\n const { value: entities, loading } = useAsync(async () => {\n const fields = [\n 'kind',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.title',\n 'metadata.description',\n 'spec.profile.displayName',\n 'spec.type',\n ];\n const streamRequest = catalogFilter\n ? { query: {}, filter: catalogFilter, fields }\n : { fields };\n const items: Entity[] = [];\n for await (const batch of catalogApi.streamEntities(streamRequest)) {\n items.push(...batch);\n }\n\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n\n return { catalogEntities: items, entityRefToPresentation };\n });\n\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n\n const getLabel = useCallback(\n (freeSoloValue: string) => {\n try {\n // Will throw if defaultKind or defaultNamespace are not set\n const parsedRef = parseEntityRef(freeSoloValue, {\n defaultKind,\n defaultNamespace,\n });\n\n return stringifyEntityRef(parsedRef);\n } catch (err) {\n return freeSoloValue;\n }\n },\n [defaultKind, defaultNamespace],\n );\n\n const onSelect = useCallback(\n (_: any, ref: string | Entity | null, reason: AutocompleteChangeReason) => {\n // ref can either be a string from free solo entry or\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n onChange(ref ? stringifyEntityRef(ref as Entity) : undefined);\n } else {\n if (reason === 'blur' || reason === 'create-option') {\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n // We need to check against formData here as that's the previous value for this field.\n if (formData !== ref || allowArbitraryValues) {\n onChange(entityRef);\n }\n }\n }\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // Since free solo can be enabled, attempt to parse as a full entity ref first, then\n // fall back to the given value.\n const selectedEntity =\n entities?.catalogEntities.find(e => stringifyEntityRef(e) === formData) ??\n (allowArbitraryValues && formData ? getLabel(formData) : '');\n\n // BUI: options for autocomplete\n const buiOptions = useMemo(\n () =>\n (entities?.catalogEntities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = entities?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [entities],\n );\n\n // BUI: controlled input value\n const [inputValue, setInputValue] = useState(formData || '');\n\n useEffect(() => {\n if (formData) {\n const opt = buiOptions.find(o => o.value === formData);\n setInputValue(opt?.label || formData);\n } else {\n setInputValue('');\n }\n }, [formData, buiOptions]);\n\n const selectedKey =\n formData && buiOptions.some(o => o.value === formData) ? formData : null;\n\n const lastCommittedRef = useRef(formData);\n\n useEffect(() => {\n lastCommittedRef.current = formData;\n }, [formData]);\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (key !== null) {\n const value = String(key);\n lastCommittedRef.current = value;\n onChange(value);\n } else if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n lastCommittedRef.current = entityRef;\n onChange(entityRef);\n } else {\n lastCommittedRef.current = undefined;\n onChange(undefined);\n }\n },\n [onChange, allowArbitraryValues, inputValue, defaultKind, defaultNamespace],\n );\n\n const handleBlur = useCallback(() => {\n if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n if (lastCommittedRef.current !== entityRef) {\n lastCommittedRef.current = entityRef;\n onChange(entityRef);\n }\n }\n }, [\n allowArbitraryValues,\n inputValue,\n defaultKind,\n defaultNamespace,\n onChange,\n ]);\n\n // Auto-select when only one entity and required\n useEffect(() => {\n if (theme === 'bui') {\n if (\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1 &&\n !formData\n ) {\n onChange(stringifyEntityRef(entities.catalogEntities[0]));\n }\n } else {\n if (\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1 &&\n selectedEntity === ''\n ) {\n onChange(stringifyEntityRef(entities.catalogEntities[0]));\n }\n }\n }, [\n entities,\n onChange,\n selectedEntity,\n formData,\n required,\n allowArbitraryValues,\n theme,\n ]);\n\n if (theme === 'bui') {\n const isAutoSelected =\n required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected}\n selectedKey={selectedKey}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n onBlur={handleBlur}\n isLoading={loading}\n options={buiOptions}\n allowsCustomValue={allowArbitraryValues}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n disabled={\n isDisabled ||\n (required &&\n !allowArbitraryValues &&\n entities?.catalogEntities.length === 1)\n }\n id={idSchema?.$id}\n value={selectedEntity}\n loading={loading}\n onChange={onSelect}\n options={entities?.catalogEntities || []}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.entityRef!\n }\n autoSelect={autoSelect}\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n variant=\"outlined\"\n required={required}\n disabled={isDisabled}\n InputProps={params.InputProps}\n />\n )}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n\n/**\n * Converts a especial `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<EntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: EntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n * If `allowedKinds` is specified in the `uiSchema` will support the legacy `allowedKinds` option.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: EntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const allowedKinds = uiSchema['ui:options']?.allowedKinds;\n\n const catalogFilter: EntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter ||\n (allowedKinds && { kind: allowedKinds });\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
@@ -45,9 +45,11 @@ const MultiEntityPicker = (props) => {
45
45
  const catalogApi = useApi(catalogApiRef);
46
46
  const entityPresentationApi = useApi(entityPresentationApiRef);
47
47
  const { value: entities, loading } = useAsync(async () => {
48
- const { items } = await catalogApi.getEntities(
49
- catalogFilter ? { filter: catalogFilter } : void 0
50
- );
48
+ const streamRequest = catalogFilter ? { query: {}, filter: catalogFilter } : {};
49
+ const items = [];
50
+ for await (const batch of catalogApi.streamEntities(streamRequest)) {
51
+ items.push(...batch);
52
+ }
51
53
  const entityRefToPresentation = new Map(
52
54
  await Promise.all(
53
55
  items.map(async (item) => {
@@ -1 +1 @@
1
- {"version":3,"file":"MultiEntityPicker.esm.js","sources":["../../../../src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n entityPresentationApiRef,\n EntityDisplayName,\n EntityRefPresentationSnapshot,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteChangeReason,\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport { type Key, useCallback, useEffect, useMemo, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { FieldValidation } from '@rjsf/utils';\nimport {\n MultiEntityPickerFilterQueryValue,\n MultiEntityPickerProps,\n MultiEntityPickerUiOptions,\n MultiEntityPickerFilterQuery,\n} from './schema';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\nimport { chipStyle, chipRemoveStyle } from '../buiChipStyles';\n\nexport { MultiEntityPickerSchema } from './schema';\n\n// AutocompleteChangeReason events that can be triggered when a user inputs a freeSolo option\nconst FREE_SOLO_EVENTS: readonly AutocompleteChangeReason[] = [\n 'blur',\n 'create-option',\n];\n\n/**\n * The underlying component that is rendered in the form for the `MultiEntityPicker`\n * field extension.\n */\nexport const MultiEntityPicker = (props: MultiEntityPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n onChange,\n schema: {\n title = t('fields.multiEntityPicker.title'),\n description = t('fields.multiEntityPicker.description'),\n },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n errors,\n } = props;\n\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n const maxItems = props.schema.maxItems;\n\n const [noOfItemsSelected, setNoOfItemsSelected] = useState(0);\n\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const { value: entities, loading } = useAsync(async () => {\n const { items } = await catalogApi.getEntities(\n catalogFilter ? { filter: catalogFilter } : undefined,\n );\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n return { entities: items, entityRefToPresentation };\n });\n\n const onSelect = useCallback(\n (_: any, refs: (string | Entity)[], reason: AutocompleteChangeReason) => {\n const values = refs\n .map(ref => {\n // If the ref is not a string, then it was a selected option in the picker\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n return ref ? stringifyEntityRef(ref as Entity) : undefined;\n }\n\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n\n // We need to check against formData here as that's the previous value for this field.\n if (\n // If value already matches what exists in form data, allow it\n formData?.includes(ref) ||\n // If arbitrary values are allowed and the reason is a free solo event, allow it\n (allowArbitraryValues && FREE_SOLO_EVENTS.includes(reason))\n ) {\n return entityRef;\n }\n\n return undefined;\n })\n .filter(ref => ref !== undefined) as string[];\n\n setNoOfItemsSelected(values.length);\n onChange(values);\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // BUI: options and selection state\n const allOptions = useMemo(\n () =>\n (entities?.entities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = entities?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [entities],\n );\n\n const selectedValues = useMemo(() => formData || [], [formData]);\n const availableOptions = useMemo(\n () => allOptions.filter(o => !selectedValues.includes(o.value)),\n [allOptions, selectedValues],\n );\n\n const [inputValue, setInputValue] = useState('');\n\n const atMaxItems =\n maxItems !== undefined && selectedValues.length >= maxItems;\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (atMaxItems) return;\n\n if (key !== null) {\n const newValue = String(key);\n if (!selectedValues.includes(newValue)) {\n onChange([...selectedValues, newValue]);\n }\n } else if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n if (!selectedValues.includes(entityRef)) {\n onChange([...selectedValues, entityRef]);\n }\n }\n setInputValue('');\n },\n [\n atMaxItems,\n selectedValues,\n onChange,\n allowArbitraryValues,\n inputValue,\n defaultKind,\n defaultNamespace,\n ],\n );\n\n const handleRemove = useCallback(\n (value: string) => {\n onChange(selectedValues.filter(v => v !== value));\n },\n [selectedValues, onChange],\n );\n\n useEffect(() => {\n if (required && !allowArbitraryValues && entities?.entities?.length === 1) {\n onChange([stringifyEntityRef(entities.entities[0])]);\n }\n }, [entities, onChange, required, allowArbitraryValues]);\n\n if (theme === 'bui') {\n const isAutoSelected =\n required && !allowArbitraryValues && entities?.entities?.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <div>\n {selectedValues.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--bui-space-1)',\n marginBottom: 'var(--bui-space-2)',\n }}\n >\n {selectedValues.map(value => {\n const opt = allOptions.find(o => o.value === value);\n return (\n <span key={value} style={chipStyle}>\n {opt?.label || value}\n {!isDisabled && !isAutoSelected && (\n <button\n type=\"button\"\n onClick={() => handleRemove(value)}\n style={chipRemoveStyle}\n aria-label={`Remove ${opt?.label || value}`}\n >\n &times;\n </button>\n )}\n </span>\n );\n })}\n </div>\n )}\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected || atMaxItems}\n selectedKey={null}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={availableOptions}\n allowsCustomValue={allowArbitraryValues}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </div>\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n multiple\n filterSelectedOptions\n disabled={\n isDisabled ||\n (required &&\n !allowArbitraryValues &&\n entities?.entities?.length === 1)\n }\n id={idSchema?.$id}\n defaultValue={formData}\n loading={loading}\n onChange={onSelect}\n options={entities?.entities || []}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.entityRef!\n }\n getOptionDisabled={_options =>\n maxItems ? noOfItemsSelected >= maxItems : false\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n disabled={isDisabled}\n margin=\"dense\"\n FormHelperTextProps={{\n margin: 'dense',\n style: { marginLeft: 0 },\n }}\n variant=\"outlined\"\n required={required}\n InputProps={{\n ...params.InputProps,\n required: formData?.length === 0 && required,\n }}\n />\n )}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n\nexport const validateMultiEntityPickerValidation = (\n values: string[],\n validation: FieldValidation,\n) => {\n values.forEach(value => {\n try {\n parseEntityRef(value);\n } catch {\n validation.addError(`${value} is not a valid entity ref`);\n }\n });\n};\n\n/**\n * Converts a special `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<MultiEntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: MultiEntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: MultiEntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const catalogFilter: MultiEntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter;\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
1
+ {"version":3,"file":"MultiEntityPicker.esm.js","sources":["../../../../src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n type EntityFilterQuery,\n CATALOG_FILTER_EXISTS,\n} from '@backstage/catalog-client';\nimport {\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n catalogApiRef,\n entityPresentationApiRef,\n EntityDisplayName,\n EntityRefPresentationSnapshot,\n} from '@backstage/plugin-catalog-react';\nimport TextField from '@material-ui/core/TextField';\nimport Autocomplete, {\n AutocompleteChangeReason,\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport { type Key, useCallback, useEffect, useMemo, useState } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { FieldValidation } from '@rjsf/utils';\nimport {\n MultiEntityPickerFilterQueryValue,\n MultiEntityPickerProps,\n MultiEntityPickerUiOptions,\n MultiEntityPickerFilterQuery,\n} from './schema';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\nimport { chipStyle, chipRemoveStyle } from '../buiChipStyles';\n\nexport { MultiEntityPickerSchema } from './schema';\n\n// AutocompleteChangeReason events that can be triggered when a user inputs a freeSolo option\nconst FREE_SOLO_EVENTS: readonly AutocompleteChangeReason[] = [\n 'blur',\n 'create-option',\n];\n\n/**\n * The underlying component that is rendered in the form for the `MultiEntityPicker`\n * field extension.\n */\nexport const MultiEntityPicker = (props: MultiEntityPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n onChange,\n schema: {\n title = t('fields.multiEntityPicker.title'),\n description = t('fields.multiEntityPicker.description'),\n },\n required,\n uiSchema,\n rawErrors,\n formData,\n idSchema,\n errors,\n } = props;\n\n const catalogFilter = buildCatalogFilter(uiSchema);\n const defaultKind = uiSchema['ui:options']?.defaultKind;\n const defaultNamespace =\n uiSchema['ui:options']?.defaultNamespace || undefined;\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n const allowArbitraryValues =\n uiSchema['ui:options']?.allowArbitraryValues ?? true;\n const maxItems = props.schema.maxItems;\n\n const [noOfItemsSelected, setNoOfItemsSelected] = useState(0);\n\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const { value: entities, loading } = useAsync(async () => {\n const streamRequest = catalogFilter\n ? { query: {}, filter: catalogFilter }\n : {};\n const items: Entity[] = [];\n for await (const batch of catalogApi.streamEntities(streamRequest)) {\n items.push(...batch);\n }\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n return { entities: items, entityRefToPresentation };\n });\n\n const onSelect = useCallback(\n (_: any, refs: (string | Entity)[], reason: AutocompleteChangeReason) => {\n const values = refs\n .map(ref => {\n // If the ref is not a string, then it was a selected option in the picker\n if (typeof ref !== 'string') {\n // if ref does not exist: pass 'undefined' to trigger validation for required value\n return ref ? stringifyEntityRef(ref as Entity) : undefined;\n }\n\n // Add in default namespace, etc.\n let entityRef = ref;\n try {\n // Attempt to parse the entity ref into it's full form.\n entityRef = stringifyEntityRef(\n parseEntityRef(ref as string, {\n defaultKind,\n defaultNamespace,\n }),\n );\n } catch (err) {\n // If the passed in value isn't an entity ref, do nothing.\n }\n\n // We need to check against formData here as that's the previous value for this field.\n if (\n // If value already matches what exists in form data, allow it\n formData?.includes(ref) ||\n // If arbitrary values are allowed and the reason is a free solo event, allow it\n (allowArbitraryValues && FREE_SOLO_EVENTS.includes(reason))\n ) {\n return entityRef;\n }\n\n return undefined;\n })\n .filter(ref => ref !== undefined) as string[];\n\n setNoOfItemsSelected(values.length);\n onChange(values);\n },\n [onChange, formData, defaultKind, defaultNamespace, allowArbitraryValues],\n );\n\n // BUI: options and selection state\n const allOptions = useMemo(\n () =>\n (entities?.entities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = entities?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [entities],\n );\n\n const selectedValues = useMemo(() => formData || [], [formData]);\n const availableOptions = useMemo(\n () => allOptions.filter(o => !selectedValues.includes(o.value)),\n [allOptions, selectedValues],\n );\n\n const [inputValue, setInputValue] = useState('');\n\n const atMaxItems =\n maxItems !== undefined && selectedValues.length >= maxItems;\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n if (atMaxItems) return;\n\n if (key !== null) {\n const newValue = String(key);\n if (!selectedValues.includes(newValue)) {\n onChange([...selectedValues, newValue]);\n }\n } else if (allowArbitraryValues && inputValue) {\n let entityRef = inputValue;\n try {\n entityRef = stringifyEntityRef(\n parseEntityRef(inputValue, { defaultKind, defaultNamespace }),\n );\n } catch {\n // If the input isn't a valid entity ref, use it as-is\n }\n if (!selectedValues.includes(entityRef)) {\n onChange([...selectedValues, entityRef]);\n }\n }\n setInputValue('');\n },\n [\n atMaxItems,\n selectedValues,\n onChange,\n allowArbitraryValues,\n inputValue,\n defaultKind,\n defaultNamespace,\n ],\n );\n\n const handleRemove = useCallback(\n (value: string) => {\n onChange(selectedValues.filter(v => v !== value));\n },\n [selectedValues, onChange],\n );\n\n useEffect(() => {\n if (required && !allowArbitraryValues && entities?.entities?.length === 1) {\n onChange([stringifyEntityRef(entities.entities[0])]);\n }\n }, [entities, onChange, required, allowArbitraryValues]);\n\n if (theme === 'bui') {\n const isAutoSelected =\n required && !allowArbitraryValues && entities?.entities?.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <div>\n {selectedValues.length > 0 && (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 'var(--bui-space-1)',\n marginBottom: 'var(--bui-space-2)',\n }}\n >\n {selectedValues.map(value => {\n const opt = allOptions.find(o => o.value === value);\n return (\n <span key={value} style={chipStyle}>\n {opt?.label || value}\n {!isDisabled && !isAutoSelected && (\n <button\n type=\"button\"\n onClick={() => handleRemove(value)}\n style={chipRemoveStyle}\n aria-label={`Remove ${opt?.label || value}`}\n >\n &times;\n </button>\n )}\n </span>\n );\n })}\n </div>\n )}\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected || atMaxItems}\n selectedKey={null}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={availableOptions}\n allowsCustomValue={allowArbitraryValues}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </div>\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n multiple\n filterSelectedOptions\n disabled={\n isDisabled ||\n (required &&\n !allowArbitraryValues &&\n entities?.entities?.length === 1)\n }\n id={idSchema?.$id}\n defaultValue={formData}\n loading={loading}\n onChange={onSelect}\n options={entities?.entities || []}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n getOptionLabel={option =>\n // option can be a string due to freeSolo.\n typeof option === 'string'\n ? option\n : entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.entityRef!\n }\n getOptionDisabled={_options =>\n maxItems ? noOfItemsSelected >= maxItems : false\n }\n autoSelect\n freeSolo={allowArbitraryValues}\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n disabled={isDisabled}\n margin=\"dense\"\n FormHelperTextProps={{\n margin: 'dense',\n style: { marginLeft: 0 },\n }}\n variant=\"outlined\"\n required={required}\n InputProps={{\n ...params.InputProps,\n required: formData?.length === 0 && required,\n }}\n />\n )}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n entities?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n\nexport const validateMultiEntityPickerValidation = (\n values: string[],\n validation: FieldValidation,\n) => {\n values.forEach(value => {\n try {\n parseEntityRef(value);\n } catch {\n validation.addError(`${value} is not a valid entity ref`);\n }\n });\n};\n\n/**\n * Converts a special `{exists: true}` value to the `CATALOG_FILTER_EXISTS` symbol.\n *\n * @param value - The value to convert.\n * @returns The converted value.\n */\nfunction convertOpsValues(\n value: Exclude<MultiEntityPickerFilterQueryValue, Array<any>>,\n): string | symbol {\n if (typeof value === 'object' && value.exists) {\n return CATALOG_FILTER_EXISTS;\n }\n return value?.toString();\n}\n\n/**\n * Converts schema filters to entity filter query, replacing `{exists:true}` values\n * with the constant `CATALOG_FILTER_EXISTS`.\n *\n * @param schemaFilters - An object containing schema filters with keys as filter names\n * and values as filter values.\n * @returns An object with the same keys as the input object, but with `{exists:true}` values\n * transformed to `CATALOG_FILTER_EXISTS` symbol.\n */\nfunction convertSchemaFiltersToQuery(\n schemaFilters: MultiEntityPickerFilterQuery,\n): Exclude<EntityFilterQuery, Array<any>> {\n const query: EntityFilterQuery = {};\n\n for (const [key, value] of Object.entries(schemaFilters)) {\n if (Array.isArray(value)) {\n query[key] = value;\n } else {\n query[key] = convertOpsValues(value);\n }\n }\n\n return query;\n}\n\n/**\n * Builds an `EntityFilterQuery` based on the `uiSchema` passed in.\n * If `catalogFilter` is specified in the `uiSchema`, it is converted to a `EntityFilterQuery`.\n *\n * @param uiSchema The `uiSchema` of an `EntityPicker` component.\n * @returns An `EntityFilterQuery` based on the `uiSchema`, or `undefined` if `catalogFilter` is not specified in the `uiSchema`.\n */\nfunction buildCatalogFilter(\n uiSchema: MultiEntityPickerProps['uiSchema'],\n): EntityFilterQuery | undefined {\n const catalogFilter: MultiEntityPickerUiOptions['catalogFilter'] | undefined =\n uiSchema['ui:options']?.catalogFilter;\n\n if (!catalogFilter) {\n return undefined;\n }\n\n if (Array.isArray(catalogFilter)) {\n return catalogFilter.map(convertSchemaFiltersToQuery);\n }\n\n return convertSchemaFiltersToQuery(catalogFilter);\n}\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
@@ -41,12 +41,16 @@ const MyGroupsPicker = (props) => {
41
41
  errorApi.post(new NotFoundError("No user entity ref found"));
42
42
  return { catalogEntities: [], entityRefToPresentation: /* @__PURE__ */ new Map() };
43
43
  }
44
- const { items } = await catalogApi.getEntities({
44
+ const items = [];
45
+ for await (const batch of catalogApi.streamEntities({
46
+ query: {},
45
47
  filter: {
46
48
  kind: "Group",
47
49
  ["relations.hasMember"]: [userEntityRef]
48
50
  }
49
- });
51
+ })) {
52
+ items.push(...batch);
53
+ }
50
54
  const entityRefToPresentation = new Map(
51
55
  await Promise.all(
52
56
  items.map(async (item) => {
@@ -1 +1 @@
1
- {"version":3,"file":"MyGroupsPicker.esm.js","sources":["../../../../src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type Key,\n ChangeEvent,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n errorApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport TextField from '@material-ui/core/TextField';\nimport { MyGroupsPickerProps, MyGroupsPickerSchema } from './schema';\nimport Autocomplete, {\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport {\n catalogApiRef,\n EntityDisplayName,\n entityPresentationApiRef,\n EntityRefPresentationSnapshot,\n} from '@backstage/plugin-catalog-react';\nimport { NotFoundError } from '@backstage/errors';\nimport useAsync from 'react-use/esm/useAsync';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\n\nexport { MyGroupsPickerSchema };\n\nexport const MyGroupsPicker = (props: MyGroupsPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n schema: {\n title = t('fields.myGroupsPicker.title'),\n description = t('fields.myGroupsPicker.description'),\n },\n required,\n rawErrors,\n onChange,\n formData,\n uiSchema,\n idSchema,\n errors,\n } = props;\n\n const identityApi = useApi(identityApiRef);\n const catalogApi = useApi(catalogApiRef);\n const errorApi = useApi(errorApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const { value: groups, loading } = useAsync(async () => {\n const { userEntityRef } = await identityApi.getBackstageIdentity();\n\n if (!userEntityRef) {\n errorApi.post(new NotFoundError('No user entity ref found'));\n return { catalogEntities: [], entityRefToPresentation: new Map() };\n }\n\n const { items } = await catalogApi.getEntities({\n filter: {\n kind: 'Group',\n ['relations.hasMember']: [userEntityRef],\n },\n });\n\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n\n return { catalogEntities: items, entityRefToPresentation };\n });\n\n // MUI: update handler\n const updateChange = (_: ChangeEvent<{}>, value: Entity | null) => {\n onChange(value ? stringifyEntityRef(value) : '');\n };\n\n const selectedEntity =\n groups?.catalogEntities.find(e => stringifyEntityRef(e) === formData) ||\n null;\n\n // BUI: options\n const buiOptions = useMemo(\n () =>\n (groups?.catalogEntities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = groups?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [groups],\n );\n\n const [inputValue, setInputValue] = useState('');\n\n useEffect(() => {\n if (formData) {\n const opt = buiOptions.find(o => o.value === formData);\n setInputValue(opt?.label || formData);\n } else {\n setInputValue('');\n }\n }, [formData, buiOptions]);\n\n const selectedKey =\n formData && buiOptions.some(o => o.value === formData) ? formData : null;\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n onChange(key !== null ? String(key) : '');\n },\n [onChange],\n );\n\n useEffect(() => {\n if (required && groups?.catalogEntities.length === 1 && !selectedEntity) {\n onChange(stringifyEntityRef(groups.catalogEntities[0]));\n }\n }, [groups, onChange, selectedEntity, required]);\n\n if (theme === 'bui') {\n const isAutoSelected = required && groups?.catalogEntities.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected}\n selectedKey={selectedKey}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={buiOptions}\n allowsCustomValue={false}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n disabled={required && groups?.catalogEntities.length === 1}\n id=\"OwnershipEntityRefPicker-dropdown\"\n options={groups?.catalogEntities || []}\n value={selectedEntity}\n loading={loading}\n onChange={updateChange}\n getOptionLabel={option =>\n groups?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!\n }\n autoSelect\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n groups?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":";;;;;;;;;;;;;;;;AAsDO,MAAM,cAAA,GAAiB,CAAC,KAAA,KAA+B;AAC5D,EAAA,MAAM,QAAQ,kBAAA,EAAmB;AACjC,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,wBAAwB,CAAA;AACxD,EAAA,MAAM;AAAA,IACJ,MAAA,EAAQ;AAAA,MACN,KAAA,GAAQ,EAAE,6BAA6B,CAAA;AAAA,MACvC,WAAA,GAAc,EAAE,mCAAmC;AAAA,KACrD;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,MAAM,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAA,MAAM,qBAAA,GAAwB,OAAO,wBAAwB,CAAA;AAC7D,EAAA,MAAM,UAAA,GAAa,QAAA,GAAW,aAAa,CAAA,IAAK,KAAA;AAEhD,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAQ,GAAI,SAAS,YAAY;AACtD,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,YAAY,oBAAA,EAAqB;AAEjE,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,QAAA,CAAS,IAAA,CAAK,IAAI,aAAA,CAAc,0BAA0B,CAAC,CAAA;AAC3D,MAAA,OAAO,EAAE,eAAA,EAAiB,IAAI,uBAAA,kBAAyB,IAAI,KAAI,EAAE;AAAA,IACnE;AAEA,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,WAAW,WAAA,CAAY;AAAA,MAC7C,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,OAAA;AAAA,QACN,CAAC,qBAAqB,GAAG,CAAC,aAAa;AAAA;AACzC,KACD,CAAA;AAED,IAAA,MAAM,0BAA0B,IAAI,GAAA;AAAA,MAIlC,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,KAAA,CAAM,GAAA,CAAI,OAAM,IAAA,KAAQ;AACtB,UAAA,MAAM,YAAA,GAAe,MAAM,qBAAA,CAAsB,SAAA,CAAU,IAAI,CAAA,CAC5D,OAAA;AACH,UAAA,OAAO,CAAC,kBAAA,CAAmB,IAAI,CAAA,EAAG,YAAY,CAAA;AAAA,QAIhD,CAAC;AAAA;AACH,KACF;AAEA,IAAA,OAAO,EAAE,eAAA,EAAiB,KAAA,EAAO,uBAAA,EAAwB;AAAA,EAC3D,CAAC,CAAA;AAGD,EAAA,MAAM,YAAA,GAAe,CAAC,CAAA,EAAoB,KAAA,KAAyB;AACjE,IAAA,QAAA,CAAS,KAAA,GAAQ,kBAAA,CAAmB,KAAK,CAAA,GAAI,EAAE,CAAA;AAAA,EACjD,CAAA;AAEA,EAAA,MAAM,cAAA,GACJ,QAAQ,eAAA,CAAgB,IAAA,CAAK,OAAK,kBAAA,CAAmB,CAAC,CAAA,KAAM,QAAQ,CAAA,IACpE,IAAA;AAGF,EAAA,MAAM,UAAA,GAAa,OAAA;AAAA,IACjB,OACG,MAAA,EAAQ,eAAA,IAAmB,EAAC,EAAG,IAAI,CAAA,MAAA,KAAU;AAC5C,MAAA,MAAM,SAAA,GAAY,mBAAmB,MAAM,CAAA;AAC3C,MAAA,MAAM,YAAA,GAAe,MAAA,EAAQ,uBAAA,CAAwB,GAAA,CAAI,SAAS,CAAA;AAClE,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,SAAA;AAAA,QACP,KAAA,EAAO,cAAc,YAAA,IAAgB;AAAA,OACvC;AAAA,IACF,CAAC,CAAA;AAAA,IACH,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,EAAE,CAAA;AAE/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,MAAM,UAAA,CAAW,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,UAAU,QAAQ,CAAA;AACrD,MAAA,aAAA,CAAc,GAAA,EAAK,SAAS,QAAQ,CAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,EAAE,CAAA;AAAA,IAClB;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,UAAU,CAAC,CAAA;AAEzB,EAAA,MAAM,WAAA,GACJ,YAAY,UAAA,CAAW,IAAA,CAAK,OAAK,CAAA,CAAE,KAAA,KAAU,QAAQ,CAAA,GAAI,QAAA,GAAW,IAAA;AAEtE,EAAA,MAAM,qBAAA,GAAwB,WAAA;AAAA,IAC5B,CAAC,GAAA,KAAoB;AACnB,MAAA,QAAA,CAAS,GAAA,KAAQ,IAAA,GAAO,MAAA,CAAO,GAAG,IAAI,EAAE,CAAA;AAAA,IAC1C,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAY,MAAA,EAAQ,eAAA,CAAgB,MAAA,KAAW,CAAA,IAAK,CAAC,cAAA,EAAgB;AACvE,MAAA,QAAA,CAAS,kBAAA,CAAmB,MAAA,CAAO,eAAA,CAAgB,CAAC,CAAC,CAAC,CAAA;AAAA,IACxD;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,QAAA,EAAU,cAAA,EAAgB,QAAQ,CAAC,CAAA;AAE/C,EAAA,IAAI,UAAU,KAAA,EAAO;AACnB,IAAA,MAAM,cAAA,GAAiB,QAAA,IAAY,MAAA,EAAQ,eAAA,CAAgB,MAAA,KAAW,CAAA;AAEtE,IAAA,uBACE,GAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,SAAA;AAAA,QACA,cAAA,EAAgB,QAAA,CAAS,gBAAgB,CAAA,IAAK,WAAA;AAAA,QAC9C,QAAA;AAAA,QACA,QAAA,EAAU,UAAA;AAAA,QACV,MAAA;AAAA,QAEA,QAAA,kBAAA,GAAA;AAAA,UAACA,YAAA;AAAA,UAAA;AAAA,YACC,IAAI,QAAA,EAAU,GAAA;AAAA,YACd,KAAA,EAAO,KAAA;AAAA,YACP,UAAA,EAAY,QAAA;AAAA,YACZ,YAAY,UAAA,IAAc,cAAA;AAAA,YAC1B,WAAA;AAAA,YACA,UAAA;AAAA,YACA,aAAA,EAAe,aAAA;AAAA,YACf,iBAAA,EAAmB,qBAAA;AAAA,YACnB,SAAA,EAAW,OAAA;AAAA,YACX,OAAA,EAAS,UAAA;AAAA,YACT,iBAAA,EAAmB,KAAA;AAAA,YACnB,SAAA,EAAW,SAAA,IAAa,SAAA,CAAU,MAAA,GAAS;AAAA;AAAA;AAC7C;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,cAAA,EAAgB,QAAA,CAAS,gBAAgB,CAAA,IAAK,WAAA;AAAA,MAC9C,QAAA;AAAA,MACA,QAAA,EAAU,UAAA;AAAA,MACV,MAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAACC,eAAA;AAAA,QAAA;AAAA,UACC,QAAA,EAAU,QAAA,IAAY,MAAA,EAAQ,eAAA,CAAgB,MAAA,KAAW,CAAA;AAAA,UACzD,EAAA,EAAG,mCAAA;AAAA,UACH,OAAA,EAAS,MAAA,EAAQ,eAAA,IAAmB,EAAC;AAAA,UACrC,KAAA,EAAO,cAAA;AAAA,UACP,OAAA;AAAA,UACA,QAAA,EAAU,YAAA;AAAA,UACV,cAAA,EAAgB,YACd,MAAA,EAAQ,uBAAA,CAAwB,IAAI,kBAAA,CAAmB,MAAM,CAAC,CAAA,EAC1D,YAAA;AAAA,UAEN,UAAA,EAAU,IAAA;AAAA,UACV,aAAa,CAAA,MAAA,qBACX,GAAA;AAAA,YAACC,YAAA;AAAA,YAAA;AAAA,cACE,GAAG,MAAA;AAAA,cACJ,KAAA,EAAO,KAAA;AAAA,cACP,MAAA,EAAO,OAAA;AAAA,cACP,mBAAA,EAAqB,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAO,EAAE,UAAA,EAAY,GAAE,EAAE;AAAA,cACjE,OAAA,EAAQ,UAAA;AAAA,cACR,QAAA;AAAA,cACA,YAAY,MAAA,CAAO;AAAA;AAAA,WACrB;AAAA,UAEF,YAAA,EAAc,CAAA,MAAA,qBAAU,GAAA,CAAC,iBAAA,EAAA,EAAkB,WAAW,MAAA,EAAQ,CAAA;AAAA,UAC9D,eAAe,mBAAA,CAA4B;AAAA,YACzC,SAAA,EAAW,YACT,MAAA,EAAQ,uBAAA,CAAwB,IAAI,kBAAA,CAAmB,MAAM,CAAC,CAAA,EAC1D;AAAA,WACP,CAAA;AAAA,UACD,gBAAA,EAAkB;AAAA;AAAA;AACpB;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"MyGroupsPicker.esm.js","sources":["../../../../src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type Key,\n ChangeEvent,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n errorApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport TextField from '@material-ui/core/TextField';\nimport { MyGroupsPickerProps, MyGroupsPickerSchema } from './schema';\nimport Autocomplete, {\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete';\nimport {\n catalogApiRef,\n EntityDisplayName,\n entityPresentationApiRef,\n EntityRefPresentationSnapshot,\n} from '@backstage/plugin-catalog-react';\nimport { NotFoundError } from '@backstage/errors';\nimport useAsync from 'react-use/esm/useAsync';\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport { VirtualizedListbox } from '../VirtualizedListbox';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { scaffolderTranslationRef } from '../../../translation';\nimport {\n ScaffolderField,\n useScaffolderTheme,\n} from '@backstage/plugin-scaffolder-react/alpha';\nimport { Autocomplete as BuiAutocomplete } from '../Autocomplete';\n\nexport { MyGroupsPickerSchema };\n\nexport const MyGroupsPicker = (props: MyGroupsPickerProps) => {\n const theme = useScaffolderTheme();\n const { t } = useTranslationRef(scaffolderTranslationRef);\n const {\n schema: {\n title = t('fields.myGroupsPicker.title'),\n description = t('fields.myGroupsPicker.description'),\n },\n required,\n rawErrors,\n onChange,\n formData,\n uiSchema,\n idSchema,\n errors,\n } = props;\n\n const identityApi = useApi(identityApiRef);\n const catalogApi = useApi(catalogApiRef);\n const errorApi = useApi(errorApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const isDisabled = uiSchema?.['ui:disabled'] ?? false;\n\n const { value: groups, loading } = useAsync(async () => {\n const { userEntityRef } = await identityApi.getBackstageIdentity();\n\n if (!userEntityRef) {\n errorApi.post(new NotFoundError('No user entity ref found'));\n return { catalogEntities: [], entityRefToPresentation: new Map() };\n }\n\n const items: Entity[] = [];\n for await (const batch of catalogApi.streamEntities({\n query: {},\n filter: {\n kind: 'Group',\n ['relations.hasMember']: [userEntityRef],\n },\n })) {\n items.push(...batch);\n }\n\n const entityRefToPresentation = new Map<\n string,\n EntityRefPresentationSnapshot\n >(\n await Promise.all(\n items.map(async item => {\n const presentation = await entityPresentationApi.forEntity(item)\n .promise;\n return [stringifyEntityRef(item), presentation] as [\n string,\n EntityRefPresentationSnapshot,\n ];\n }),\n ),\n );\n\n return { catalogEntities: items, entityRefToPresentation };\n });\n\n // MUI: update handler\n const updateChange = (_: ChangeEvent<{}>, value: Entity | null) => {\n onChange(value ? stringifyEntityRef(value) : '');\n };\n\n const selectedEntity =\n groups?.catalogEntities.find(e => stringifyEntityRef(e) === formData) ||\n null;\n\n // BUI: options\n const buiOptions = useMemo(\n () =>\n (groups?.catalogEntities || []).map(entity => {\n const entityRef = stringifyEntityRef(entity);\n const presentation = groups?.entityRefToPresentation.get(entityRef);\n return {\n value: entityRef,\n label: presentation?.primaryTitle || entityRef,\n };\n }),\n [groups],\n );\n\n const [inputValue, setInputValue] = useState('');\n\n useEffect(() => {\n if (formData) {\n const opt = buiOptions.find(o => o.value === formData);\n setInputValue(opt?.label || formData);\n } else {\n setInputValue('');\n }\n }, [formData, buiOptions]);\n\n const selectedKey =\n formData && buiOptions.some(o => o.value === formData) ? formData : null;\n\n const handleSelectionChange = useCallback(\n (key: Key | null) => {\n onChange(key !== null ? String(key) : '');\n },\n [onChange],\n );\n\n useEffect(() => {\n if (required && groups?.catalogEntities.length === 1 && !selectedEntity) {\n onChange(stringifyEntityRef(groups.catalogEntities[0]));\n }\n }, [groups, onChange, selectedEntity, required]);\n\n if (theme === 'bui') {\n const isAutoSelected = required && groups?.catalogEntities.length === 1;\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <BuiAutocomplete\n id={idSchema?.$id}\n label={title}\n isRequired={required}\n isDisabled={isDisabled || isAutoSelected}\n selectedKey={selectedKey}\n inputValue={inputValue}\n onInputChange={setInputValue}\n onSelectionChange={handleSelectionChange}\n isLoading={loading}\n options={buiOptions}\n allowsCustomValue={false}\n isInvalid={rawErrors && rawErrors.length > 0}\n />\n </ScaffolderField>\n );\n }\n\n return (\n <ScaffolderField\n rawErrors={rawErrors}\n rawDescription={uiSchema['ui:description'] ?? description}\n required={required}\n disabled={isDisabled}\n errors={errors}\n >\n <Autocomplete\n disabled={required && groups?.catalogEntities.length === 1}\n id=\"OwnershipEntityRefPicker-dropdown\"\n options={groups?.catalogEntities || []}\n value={selectedEntity}\n loading={loading}\n onChange={updateChange}\n getOptionLabel={option =>\n groups?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!\n }\n autoSelect\n renderInput={params => (\n <TextField\n {...params}\n label={title}\n margin=\"dense\"\n FormHelperTextProps={{ margin: 'dense', style: { marginLeft: 0 } }}\n variant=\"outlined\"\n required={required}\n InputProps={params.InputProps}\n />\n )}\n renderOption={option => <EntityDisplayName entityRef={option} />}\n filterOptions={createFilterOptions<Entity>({\n stringify: option =>\n groups?.entityRefToPresentation.get(stringifyEntityRef(option))\n ?.primaryTitle!,\n })}\n ListboxComponent={VirtualizedListbox}\n />\n </ScaffolderField>\n );\n};\n"],"names":["BuiAutocomplete","Autocomplete","TextField"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  var name = "@backstage/plugin-scaffolder";
2
- var version = "1.38.2-next.2";
2
+ var version = "1.38.2";
3
3
  var description = "The Backstage plugin that helps you create new things";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-scaffolder",
3
- "version": "1.38.2-next.2",
3
+ "version": "1.38.2",
4
4
  "description": "The Backstage plugin that helps you create new things",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -70,24 +70,24 @@
70
70
  "test": "backstage-cli package test"
71
71
  },
72
72
  "dependencies": {
73
- "@backstage/catalog-client": "1.16.1",
74
- "@backstage/catalog-model": "1.9.0",
75
- "@backstage/core-components": "0.18.13-next.2",
76
- "@backstage/core-plugin-api": "1.12.9-next.0",
77
- "@backstage/errors": "1.3.1",
78
- "@backstage/filter-predicates": "0.1.4",
79
- "@backstage/frontend-plugin-api": "0.18.0-next.0",
80
- "@backstage/integration": "2.1.0-next.0",
81
- "@backstage/integration-react": "1.2.21-next.1",
82
- "@backstage/plugin-catalog-common": "1.1.10",
83
- "@backstage/plugin-catalog-react": "3.2.1-next.2",
84
- "@backstage/plugin-permission-react": "0.5.4-next.0",
85
- "@backstage/plugin-scaffolder-common": "2.2.2-next.0",
86
- "@backstage/plugin-scaffolder-react": "2.0.3-next.2",
87
- "@backstage/plugin-techdocs-common": "0.1.1",
88
- "@backstage/plugin-techdocs-react": "1.3.14-next.1",
89
- "@backstage/types": "1.2.2",
90
- "@backstage/ui": "0.17.1-next.0",
73
+ "@backstage/catalog-client": "^1.16.1",
74
+ "@backstage/catalog-model": "^1.10.0",
75
+ "@backstage/core-components": "^0.18.13",
76
+ "@backstage/core-plugin-api": "^1.12.9",
77
+ "@backstage/errors": "^1.3.1",
78
+ "@backstage/filter-predicates": "^0.1.4",
79
+ "@backstage/frontend-plugin-api": "^0.18.0",
80
+ "@backstage/integration": "^2.1.0",
81
+ "@backstage/integration-react": "^1.2.21",
82
+ "@backstage/plugin-catalog-common": "^1.1.10",
83
+ "@backstage/plugin-catalog-react": "^3.2.1",
84
+ "@backstage/plugin-permission-react": "^0.5.4",
85
+ "@backstage/plugin-scaffolder-common": "^2.2.2",
86
+ "@backstage/plugin-scaffolder-react": "^2.0.3",
87
+ "@backstage/plugin-techdocs-common": "^0.1.1",
88
+ "@backstage/plugin-techdocs-react": "^1.3.14",
89
+ "@backstage/types": "^1.2.2",
90
+ "@backstage/ui": "^0.17.1",
91
91
  "@codemirror/language": "^6.0.0",
92
92
  "@codemirror/legacy-modes": "^6.1.0",
93
93
  "@codemirror/view": "^6.0.0",
@@ -120,14 +120,14 @@
120
120
  "zod-to-json-schema": "^3.25.1"
121
121
  },
122
122
  "devDependencies": {
123
- "@backstage/cli": "0.36.5-next.1",
124
- "@backstage/core-app-api": "1.20.4-next.1",
125
- "@backstage/dev-utils": "1.1.26-next.2",
126
- "@backstage/frontend-test-utils": "0.6.3-next.1",
127
- "@backstage/plugin-catalog": "2.0.8-next.2",
128
- "@backstage/plugin-permission-common": "0.9.9",
129
- "@backstage/plugin-techdocs": "1.18.0-next.2",
130
- "@backstage/test-utils": "1.7.21-next.1",
123
+ "@backstage/cli": "^0.36.5",
124
+ "@backstage/core-app-api": "^1.20.4",
125
+ "@backstage/dev-utils": "^1.1.26",
126
+ "@backstage/frontend-test-utils": "^0.6.3",
127
+ "@backstage/plugin-catalog": "^2.0.8",
128
+ "@backstage/plugin-permission-common": "^0.9.10",
129
+ "@backstage/plugin-techdocs": "^1.18.0",
130
+ "@backstage/test-utils": "^1.7.21",
131
131
  "@testing-library/dom": "^10.0.0",
132
132
  "@testing-library/jest-dom": "^6.0.0",
133
133
  "@testing-library/react": "^16.0.0",