@backstage/plugin-catalog-import 0.13.16 → 0.13.17-next.0

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,14 @@
1
1
  # @backstage/plugin-catalog-import
2
2
 
3
+ ## 0.13.17-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 5d6a62b: Fixed the owner selected in the import stepper being written to the generated `catalog-info.yaml` as a display name instead of an entity reference. Groups are still suggested by their display name, but selecting one now sets a valid `spec.owner`, for example picking `My Team` results in `my-team`.
8
+ - Updated dependencies
9
+ - @backstage/plugin-catalog-react@3.2.2-next.0
10
+ - @backstage/core-components@0.18.14-next.0
11
+
3
12
  ## 0.13.16
4
13
 
5
14
  ### Patch Changes
@@ -5,6 +5,19 @@ import Autocomplete from '@material-ui/lab/Autocomplete';
5
5
  import { Fragment } from 'react';
6
6
  import { Controller } from 'react-hook-form';
7
7
 
8
+ function optionLabel(option) {
9
+ return typeof option === "string" ? option : option.label;
10
+ }
11
+ function optionValue(value, options) {
12
+ if (value === null) {
13
+ return null;
14
+ }
15
+ if (typeof value !== "string") {
16
+ return value.id;
17
+ }
18
+ const option = options.find((o) => typeof o !== "string" && o.label === value);
19
+ return option && typeof option !== "string" ? option.id : value;
20
+ }
8
21
  const AutocompleteTextField = (props) => {
9
22
  const {
10
23
  name,
@@ -31,7 +44,8 @@ const AutocompleteTextField = (props) => {
31
44
  options: options || [],
32
45
  autoSelect: true,
33
46
  freeSolo: true,
34
- onChange: (_event, value) => onChange(value),
47
+ getOptionLabel: optionLabel,
48
+ onChange: (_event, value) => onChange(optionValue(value, options)),
35
49
  renderInput: (params) => /* @__PURE__ */ jsx(
36
50
  TextField,
37
51
  {
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteTextField.esm.js","sources":["../../../src/components/StepPrepareCreatePullRequest/AutocompleteTextField.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 */\n\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport TextField from '@material-ui/core/TextField';\nimport { TextFieldProps } from '@material-ui/core/TextField/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { ComponentProps, ReactNode, ChangeEvent, Fragment } from 'react';\nimport { Controller, FieldErrors } from 'react-hook-form';\n\n/**\n * Props for {@link AutocompleteTextField}.\n *\n * @public\n */\nexport interface AutocompleteTextFieldProps<TFieldValue extends string> {\n name: TFieldValue;\n options: string[];\n required?: boolean;\n\n errors?: FieldErrors;\n rules?: ComponentProps<typeof Controller>['rules'];\n\n loading?: boolean;\n loadingText?: string;\n\n helperText?: ReactNode;\n errorHelperText?: string;\n\n textFieldProps?: Omit<TextFieldProps, 'required' | 'fullWidth'>;\n}\n\n/**\n * An autocompletion text field for the catalog import flows.\n *\n * @public\n */\nexport const AutocompleteTextField = <TFieldValue extends string>(\n props: AutocompleteTextFieldProps<TFieldValue>,\n) => {\n const {\n name,\n options,\n required,\n errors,\n rules,\n loading = false,\n loadingText,\n helperText,\n errorHelperText,\n textFieldProps = {},\n } = props;\n\n return (\n <Controller\n name={name}\n rules={rules}\n render={({ field: { onChange } }) => (\n <Autocomplete\n loading={loading}\n loadingText={loadingText}\n options={options || []}\n autoSelect\n freeSolo\n onChange={(_event: ChangeEvent<{}>, value: string | null) =>\n onChange(value)\n }\n renderInput={params => (\n <TextField\n {...params}\n helperText={(errors?.[name] && errorHelperText) || helperText}\n error={Boolean(errors?.[name])}\n margin=\"normal\"\n variant=\"outlined\"\n required={required}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <Fragment>\n {loading ? (\n <CircularProgress color=\"inherit\" size=\"1em\" />\n ) : null}\n {params.InputProps.endAdornment}\n </Fragment>\n ),\n }}\n {...textFieldProps}\n />\n )}\n />\n )}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAkDO,MAAM,qBAAA,GAAwB,CACnC,KAAA,KACG;AACH,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,WAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAiB;AAAC,GACpB,GAAI,KAAA;AAEJ,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAA,IAAW,qBAC7B,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,OAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA,EAAS,WAAW,EAAC;AAAA,UACrB,UAAA,EAAU,IAAA;AAAA,UACV,QAAA,EAAQ,IAAA;AAAA,UACR,QAAA,EAAU,CAAC,MAAA,EAAyB,KAAA,KAClC,SAAS,KAAK,CAAA;AAAA,UAEhB,aAAa,CAAA,MAAA,qBACX,GAAA;AAAA,YAAC,SAAA;AAAA,YAAA;AAAA,cACE,GAAG,MAAA;AAAA,cACJ,UAAA,EAAa,MAAA,GAAS,IAAI,CAAA,IAAK,eAAA,IAAoB,UAAA;AAAA,cACnD,KAAA,EAAO,OAAA,CAAQ,MAAA,GAAS,IAAI,CAAC,CAAA;AAAA,cAC7B,MAAA,EAAO,QAAA;AAAA,cACP,OAAA,EAAQ,UAAA;AAAA,cACR,QAAA;AAAA,cACA,UAAA,EAAY;AAAA,gBACV,GAAG,MAAA,CAAO,UAAA;AAAA,gBACV,YAAA,uBACG,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,kBAAA,OAAA,uBACE,gBAAA,EAAA,EAAiB,KAAA,EAAM,SAAA,EAAU,IAAA,EAAK,OAAM,CAAA,GAC3C,IAAA;AAAA,kBACH,OAAO,UAAA,CAAW;AAAA,iBAAA,EACrB;AAAA,eAEJ;AAAA,cACC,GAAG;AAAA;AAAA;AACN;AAAA;AAEJ;AAAA,GAEJ;AAEJ;;;;"}
1
+ {"version":3,"file":"AutocompleteTextField.esm.js","sources":["../../../src/components/StepPrepareCreatePullRequest/AutocompleteTextField.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 */\n\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport TextField from '@material-ui/core/TextField';\nimport { TextFieldProps } from '@material-ui/core/TextField/TextField';\nimport Autocomplete from '@material-ui/lab/Autocomplete';\nimport { ComponentProps, ReactNode, ChangeEvent, Fragment } from 'react';\nimport { Controller, FieldErrors } from 'react-hook-form';\n\n/**\n * An option of {@link AutocompleteTextField}.\n *\n * Plain strings are used both as the visible label and as the selected value,\n * while the object form allows the option to be presented with a different\n * label than the value it selects.\n *\n * @public\n */\nexport type AutocompleteTextFieldOption =\n | string\n | { label: string; id: string };\n\nfunction optionLabel(option: AutocompleteTextFieldOption): string {\n return typeof option === 'string' ? option : option.label;\n}\n\n/**\n * Resolves the value that is stored in the form for a selection.\n *\n * `autoSelect` combined with `freeSolo` makes the autocompletion emit the raw\n * input string rather than the option object, both when an option is picked\n * from the list and when the field is blurred. Labelled options are therefore\n * matched back to their id, so that the form never stores a display label.\n */\nfunction optionValue(\n value: AutocompleteTextFieldOption | null,\n options: AutocompleteTextFieldOption[],\n): string | null {\n if (value === null) {\n return null;\n }\n if (typeof value !== 'string') {\n return value.id;\n }\n const option = options.find(o => typeof o !== 'string' && o.label === value);\n return option && typeof option !== 'string' ? option.id : value;\n}\n\n/**\n * Props for {@link AutocompleteTextField}.\n *\n * @public\n */\nexport interface AutocompleteTextFieldProps<TFieldValue extends string> {\n name: TFieldValue;\n options: AutocompleteTextFieldOption[];\n required?: boolean;\n\n errors?: FieldErrors;\n rules?: ComponentProps<typeof Controller>['rules'];\n\n loading?: boolean;\n loadingText?: string;\n\n helperText?: ReactNode;\n errorHelperText?: string;\n\n textFieldProps?: Omit<TextFieldProps, 'required' | 'fullWidth'>;\n}\n\n/**\n * An autocompletion text field for the catalog import flows.\n *\n * @public\n */\nexport const AutocompleteTextField = <TFieldValue extends string>(\n props: AutocompleteTextFieldProps<TFieldValue>,\n) => {\n const {\n name,\n options,\n required,\n errors,\n rules,\n loading = false,\n loadingText,\n helperText,\n errorHelperText,\n textFieldProps = {},\n } = props;\n\n return (\n <Controller\n name={name}\n rules={rules}\n render={({ field: { onChange } }) => (\n <Autocomplete\n loading={loading}\n loadingText={loadingText}\n options={options || []}\n autoSelect\n freeSolo\n getOptionLabel={optionLabel}\n onChange={(\n _event: ChangeEvent<{}>,\n value: AutocompleteTextFieldOption | null,\n ) => onChange(optionValue(value, options))}\n renderInput={params => (\n <TextField\n {...params}\n helperText={(errors?.[name] && errorHelperText) || helperText}\n error={Boolean(errors?.[name])}\n margin=\"normal\"\n variant=\"outlined\"\n required={required}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <Fragment>\n {loading ? (\n <CircularProgress color=\"inherit\" size=\"1em\" />\n ) : null}\n {params.InputProps.endAdornment}\n </Fragment>\n ),\n }}\n {...textFieldProps}\n />\n )}\n />\n )}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAoCA,SAAS,YAAY,MAAA,EAA6C;AAChE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,GAAS,MAAA,CAAO,KAAA;AACtD;AAUA,SAAS,WAAA,CACP,OACA,OAAA,EACe;AACf,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,KAAA,CAAM,EAAA;AAAA,EACf;AACA,EAAA,MAAM,MAAA,GAAS,QAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA;AAC3E,EAAA,OAAO,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,GAAW,OAAO,EAAA,GAAK,KAAA;AAC5D;AA6BO,MAAM,qBAAA,GAAwB,CACnC,KAAA,KACG;AACH,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,WAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAiB;AAAC,GACpB,GAAI,KAAA;AAEJ,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAA,IAAW,qBAC7B,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,OAAA;AAAA,UACA,WAAA;AAAA,UACA,OAAA,EAAS,WAAW,EAAC;AAAA,UACrB,UAAA,EAAU,IAAA;AAAA,UACV,QAAA,EAAQ,IAAA;AAAA,UACR,cAAA,EAAgB,WAAA;AAAA,UAChB,QAAA,EAAU,CACR,MAAA,EACA,KAAA,KACG,SAAS,WAAA,CAAY,KAAA,EAAO,OAAO,CAAC,CAAA;AAAA,UACzC,aAAa,CAAA,MAAA,qBACX,GAAA;AAAA,YAAC,SAAA;AAAA,YAAA;AAAA,cACE,GAAG,MAAA;AAAA,cACJ,UAAA,EAAa,MAAA,GAAS,IAAI,CAAA,IAAK,eAAA,IAAoB,UAAA;AAAA,cACnD,KAAA,EAAO,OAAA,CAAQ,MAAA,GAAS,IAAI,CAAC,CAAA;AAAA,cAC7B,MAAA,EAAO,QAAA;AAAA,cACP,OAAA,EAAQ,UAAA;AAAA,cACR,QAAA;AAAA,cACA,UAAA,EAAY;AAAA,gBACV,GAAG,MAAA,CAAO,UAAA;AAAA,gBACV,YAAA,uBACG,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,kBAAA,OAAA,uBACE,gBAAA,EAAA,EAAiB,KAAA,EAAM,SAAA,EAAU,IAAA,EAAK,OAAM,CAAA,GAC3C,IAAA;AAAA,kBACH,OAAO,UAAA,CAAW;AAAA,iBAAA,EACrB;AAAA,eAEJ;AAAA,cACC,GAAG;AAAA;AAAA;AACN;AAAA;AAEJ;AAAA,GAEJ;AAEJ;;;;"}
@@ -2,7 +2,7 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { useApi, errorApiRef } from '@backstage/core-plugin-api';
3
3
  import { toError } from '@backstage/errors';
4
4
  import { useTranslationRef } from '@backstage/frontend-plugin-api';
5
- import { catalogApiRef, entityPresentationApiRef } from '@backstage/plugin-catalog-react';
5
+ import { catalogApiRef, entityPresentationApiRef, humanizeEntityRef } from '@backstage/plugin-catalog-react';
6
6
  import Box from '@material-ui/core/Box';
7
7
  import FormHelperText from '@material-ui/core/FormHelperText';
8
8
  import Grid from '@material-ui/core/Grid';
@@ -73,12 +73,18 @@ const StepPrepareCreatePullRequest = (props) => {
73
73
  const groupEntities = await catalogApi.getEntities({
74
74
  filter: { kind: "group" }
75
75
  });
76
- const presentations = await Promise.all(
77
- groupEntities.items.map(
78
- (e) => entityPresentationApi.forEntity(e, { defaultKind: "group" }).promise
79
- )
76
+ const options = await Promise.all(
77
+ groupEntities.items.map(async (entity) => ({
78
+ label: (await entityPresentationApi.forEntity(entity, {
79
+ defaultKind: "group"
80
+ }).promise).primaryTitle,
81
+ // The selected value is written verbatim to `spec.owner` of the
82
+ // generated entity, so it has to be an entity reference rather than a
83
+ // display name.
84
+ id: humanizeEntityRef(entity, { defaultKind: "group" })
85
+ }))
80
86
  );
81
- return presentations.map((p) => p.primaryTitle).sort();
87
+ return options.sort((a, b) => a.label.localeCompare(b.label));
82
88
  });
83
89
  const handleResult = useCallback(
84
90
  async (data) => {
@@ -1 +1 @@
1
- {"version":3,"file":"StepPrepareCreatePullRequest.esm.js","sources":["../../../src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.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 */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { errorApiRef, useApi } from '@backstage/core-plugin-api';\nimport { toError } from '@backstage/errors';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n catalogApiRef,\n entityPresentationApiRef,\n} from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode, useCallback, useEffect, useState } from 'react';\nimport { NestedValue, UseFormReturn } from 'react-hook-form';\nimport useAsync from 'react-use/esm/useAsync';\nimport YAML from 'yaml';\n\nimport { AnalyzeResult, catalogImportApiRef } from '../../api';\nimport { useCatalogFilename } from '../../hooks';\nimport { catalogImportTranslationRef } from '../../translation';\nimport { PartialEntity } from '../../types';\nimport { BackButton, NextButton } from '../Buttons';\nimport { PrepareResult } from '../useImportState';\nimport { PreparePullRequestForm } from './PreparePullRequestForm';\nimport { PreviewCatalogInfoComponent } from './PreviewCatalogInfoComponent';\nimport { PreviewPullRequestComponent } from './PreviewPullRequestComponent';\n\nconst useStyles = makeStyles(theme => ({\n previewCard: {\n marginTop: theme.spacing(1),\n },\n previewCardContent: {\n paddingTop: 0,\n },\n}));\n\ntype FormData = {\n title: string;\n body: string;\n componentName: string;\n owner: string;\n useCodeowners: boolean;\n};\n\n/**\n * Helper for unpacking NestedValue into the underlying type.\n *\n * @public\n * @deprecated This is a copy of the type from react-hook-form, and will be removed in a future release\n */\nexport type UnpackNestedValue<T> = T extends NestedValue<infer U>\n ? U\n : T extends Date | FileList | File | Blob\n ? T\n : T extends object\n ? {\n [K in keyof T]: UnpackNestedValue<T[K]>;\n }\n : T;\n\n/**\n * Props for {@link StepPrepareCreatePullRequest}.\n *\n * @public\n */\nexport interface StepPrepareCreatePullRequestProps {\n analyzeResult: Extract<AnalyzeResult, { type: 'repository' }>;\n onPrepare: (\n result: PrepareResult,\n opts?: { notRepeatable?: boolean },\n ) => void;\n onGoBack?: () => void;\n\n renderFormFields: (\n props: Pick<\n UseFormReturn<FormData>,\n 'register' | 'setValue' | 'formState'\n > & {\n values: UnpackNestedValue<FormData>;\n groups: string[];\n groupsLoading: boolean;\n },\n ) => ReactNode;\n}\n\nexport function generateEntities(\n entities: PartialEntity[],\n componentName: string,\n owner?: string,\n): Entity[] {\n return entities.map(e => ({\n ...e,\n apiVersion: e.apiVersion!,\n kind: e.kind!,\n metadata: {\n ...e.metadata,\n name: componentName,\n },\n spec: {\n ...e.spec,\n ...(owner ? { owner } : {}),\n },\n }));\n}\n\n/**\n * Prepares a pull request.\n *\n * @public\n */\nexport const StepPrepareCreatePullRequest = (\n props: StepPrepareCreatePullRequestProps,\n) => {\n const { analyzeResult, onPrepare, onGoBack, renderFormFields } = props;\n\n const { t } = useTranslationRef(catalogImportTranslationRef);\n const classes = useStyles();\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const catalogImportApi = useApi(catalogImportApiRef);\n const errorApi = useApi(errorApiRef);\n\n const [submitted, setSubmitted] = useState(false);\n const [error, setError] = useState<string>();\n\n const catalogFilename = useCatalogFilename();\n\n const {\n loading: prDefaultsLoading,\n value: prDefaults,\n error: prDefaultsError,\n } = useAsync(\n () => catalogImportApi.preparePullRequest!(),\n [catalogImportApi.preparePullRequest],\n );\n\n useEffect(() => {\n if (prDefaultsError) {\n errorApi.post(prDefaultsError);\n }\n }, [prDefaultsError, errorApi]);\n\n const { loading: groupsLoading, value: groups } = useAsync(async () => {\n const groupEntities = await catalogApi.getEntities({\n filter: { kind: 'group' },\n });\n\n const presentations = await Promise.all(\n groupEntities.items.map(\n e =>\n entityPresentationApi.forEntity(e, { defaultKind: 'group' }).promise,\n ),\n );\n return presentations.map(p => p.primaryTitle).sort();\n });\n\n const handleResult = useCallback(\n async (data: FormData) => {\n setSubmitted(true);\n\n try {\n const pr = await catalogImportApi.submitPullRequest({\n repositoryUrl: analyzeResult.url,\n title: data.title,\n body: data.body,\n fileContent: generateEntities(\n analyzeResult.generatedEntities,\n data.componentName,\n data.owner,\n )\n .map(e => YAML.stringify(e))\n .join('---\\n'),\n });\n\n onPrepare(\n {\n type: 'repository',\n url: analyzeResult.url,\n integrationType: analyzeResult.integrationType,\n pullRequest: {\n url: pr.link,\n },\n locations: [\n {\n target: pr.location,\n entities: generateEntities(\n analyzeResult.generatedEntities,\n data.componentName,\n data.owner,\n ).map(e => ({\n kind: e.kind,\n namespace: e.metadata.namespace!,\n name: e.metadata.name,\n })),\n },\n ],\n },\n { notRepeatable: true },\n );\n } catch (e) {\n setError(toError(e).message);\n setSubmitted(false);\n }\n },\n [\n analyzeResult.generatedEntities,\n analyzeResult.integrationType,\n analyzeResult.url,\n catalogImportApi,\n onPrepare,\n ],\n );\n\n return (\n <>\n <Typography>\n {t('stepPrepareCreatePullRequest.description', {\n integrationType: analyzeResult.integrationType,\n catalogFilename: <code>{catalogFilename}</code>,\n })}\n </Typography>\n\n {!prDefaultsLoading && (\n <PreparePullRequestForm<FormData>\n onSubmit={handleResult}\n defaultValues={{\n title: prDefaults?.title ?? '',\n body: prDefaults?.body ?? '',\n owner:\n (analyzeResult.generatedEntities[0]?.spec?.owner as string) || '',\n componentName:\n analyzeResult.generatedEntities[0]?.metadata?.name || '',\n useCodeowners: false,\n }}\n render={({ values, formState, register, setValue }) => (\n <>\n {renderFormFields({\n values,\n formState,\n register,\n setValue,\n groups: groups ?? [],\n groupsLoading,\n })}\n\n <Box marginTop={2}>\n <Typography variant=\"h6\">\n {t('stepPrepareCreatePullRequest.previewPr.title')}\n </Typography>\n </Box>\n\n <PreviewPullRequestComponent\n title={values.title}\n description={values.body}\n classes={{\n card: classes.previewCard,\n cardContent: classes.previewCardContent,\n }}\n />\n\n <Box marginTop={2} marginBottom={1}>\n <Typography variant=\"h6\">\n {t('stepPrepareCreatePullRequest.previewCatalogInfo.title')}\n </Typography>\n </Box>\n\n <PreviewCatalogInfoComponent\n entities={generateEntities(\n analyzeResult.generatedEntities,\n values.componentName,\n values.owner,\n )}\n repositoryUrl={analyzeResult.url}\n classes={{\n card: classes.previewCard,\n cardContent: classes.previewCardContent,\n }}\n />\n\n {error && <FormHelperText error>{error}</FormHelperText>}\n\n <Grid container spacing={0}>\n {onGoBack && (\n <BackButton onClick={onGoBack} disabled={submitted} />\n )}\n <NextButton\n type=\"submit\"\n disabled={Boolean(\n formState.errors.title ||\n formState.errors.body ||\n formState.errors.owner,\n )}\n loading={submitted}\n >\n {t('stepPrepareCreatePullRequest.nextButtonText')}\n </NextButton>\n </Grid>\n </>\n )}\n />\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StepPrepareCreatePullRequest.esm.js","sources":["../../../src/components/StepPrepareCreatePullRequest/StepPrepareCreatePullRequest.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 */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { errorApiRef, useApi } from '@backstage/core-plugin-api';\nimport { toError } from '@backstage/errors';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport {\n catalogApiRef,\n entityPresentationApiRef,\n humanizeEntityRef,\n} from '@backstage/plugin-catalog-react';\nimport Box from '@material-ui/core/Box';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode, useCallback, useEffect, useState } from 'react';\nimport { NestedValue, UseFormReturn } from 'react-hook-form';\nimport useAsync from 'react-use/esm/useAsync';\nimport YAML from 'yaml';\n\nimport { AnalyzeResult, catalogImportApiRef } from '../../api';\nimport { useCatalogFilename } from '../../hooks';\nimport { catalogImportTranslationRef } from '../../translation';\nimport { PartialEntity } from '../../types';\nimport { BackButton, NextButton } from '../Buttons';\nimport { PrepareResult } from '../useImportState';\nimport { PreparePullRequestForm } from './PreparePullRequestForm';\nimport { PreviewCatalogInfoComponent } from './PreviewCatalogInfoComponent';\nimport { PreviewPullRequestComponent } from './PreviewPullRequestComponent';\nimport { AutocompleteTextFieldOption } from './AutocompleteTextField';\n\nconst useStyles = makeStyles(theme => ({\n previewCard: {\n marginTop: theme.spacing(1),\n },\n previewCardContent: {\n paddingTop: 0,\n },\n}));\n\ntype FormData = {\n title: string;\n body: string;\n componentName: string;\n owner: string;\n useCodeowners: boolean;\n};\n\n/**\n * Helper for unpacking NestedValue into the underlying type.\n *\n * @public\n * @deprecated This is a copy of the type from react-hook-form, and will be removed in a future release\n */\nexport type UnpackNestedValue<T> = T extends NestedValue<infer U>\n ? U\n : T extends Date | FileList | File | Blob\n ? T\n : T extends object\n ? {\n [K in keyof T]: UnpackNestedValue<T[K]>;\n }\n : T;\n\n/**\n * Props for {@link StepPrepareCreatePullRequest}.\n *\n * @public\n */\nexport interface StepPrepareCreatePullRequestProps {\n analyzeResult: Extract<AnalyzeResult, { type: 'repository' }>;\n onPrepare: (\n result: PrepareResult,\n opts?: { notRepeatable?: boolean },\n ) => void;\n onGoBack?: () => void;\n\n renderFormFields: (\n props: Pick<\n UseFormReturn<FormData>,\n 'register' | 'setValue' | 'formState'\n > & {\n values: UnpackNestedValue<FormData>;\n groups: AutocompleteTextFieldOption[];\n groupsLoading: boolean;\n },\n ) => ReactNode;\n}\n\nexport function generateEntities(\n entities: PartialEntity[],\n componentName: string,\n owner?: string,\n): Entity[] {\n return entities.map(e => ({\n ...e,\n apiVersion: e.apiVersion!,\n kind: e.kind!,\n metadata: {\n ...e.metadata,\n name: componentName,\n },\n spec: {\n ...e.spec,\n ...(owner ? { owner } : {}),\n },\n }));\n}\n\n/**\n * Prepares a pull request.\n *\n * @public\n */\nexport const StepPrepareCreatePullRequest = (\n props: StepPrepareCreatePullRequestProps,\n) => {\n const { analyzeResult, onPrepare, onGoBack, renderFormFields } = props;\n\n const { t } = useTranslationRef(catalogImportTranslationRef);\n const classes = useStyles();\n const catalogApi = useApi(catalogApiRef);\n const entityPresentationApi = useApi(entityPresentationApiRef);\n const catalogImportApi = useApi(catalogImportApiRef);\n const errorApi = useApi(errorApiRef);\n\n const [submitted, setSubmitted] = useState(false);\n const [error, setError] = useState<string>();\n\n const catalogFilename = useCatalogFilename();\n\n const {\n loading: prDefaultsLoading,\n value: prDefaults,\n error: prDefaultsError,\n } = useAsync(\n () => catalogImportApi.preparePullRequest!(),\n [catalogImportApi.preparePullRequest],\n );\n\n useEffect(() => {\n if (prDefaultsError) {\n errorApi.post(prDefaultsError);\n }\n }, [prDefaultsError, errorApi]);\n\n const { loading: groupsLoading, value: groups } = useAsync(async () => {\n const groupEntities = await catalogApi.getEntities({\n filter: { kind: 'group' },\n });\n\n const options = await Promise.all(\n groupEntities.items.map(async entity => ({\n label: (\n await entityPresentationApi.forEntity(entity, {\n defaultKind: 'group',\n }).promise\n ).primaryTitle,\n // The selected value is written verbatim to `spec.owner` of the\n // generated entity, so it has to be an entity reference rather than a\n // display name.\n id: humanizeEntityRef(entity, { defaultKind: 'group' }),\n })),\n );\n\n return options.sort((a, b) => a.label.localeCompare(b.label));\n });\n\n const handleResult = useCallback(\n async (data: FormData) => {\n setSubmitted(true);\n\n try {\n const pr = await catalogImportApi.submitPullRequest({\n repositoryUrl: analyzeResult.url,\n title: data.title,\n body: data.body,\n fileContent: generateEntities(\n analyzeResult.generatedEntities,\n data.componentName,\n data.owner,\n )\n .map(e => YAML.stringify(e))\n .join('---\\n'),\n });\n\n onPrepare(\n {\n type: 'repository',\n url: analyzeResult.url,\n integrationType: analyzeResult.integrationType,\n pullRequest: {\n url: pr.link,\n },\n locations: [\n {\n target: pr.location,\n entities: generateEntities(\n analyzeResult.generatedEntities,\n data.componentName,\n data.owner,\n ).map(e => ({\n kind: e.kind,\n namespace: e.metadata.namespace!,\n name: e.metadata.name,\n })),\n },\n ],\n },\n { notRepeatable: true },\n );\n } catch (e) {\n setError(toError(e).message);\n setSubmitted(false);\n }\n },\n [\n analyzeResult.generatedEntities,\n analyzeResult.integrationType,\n analyzeResult.url,\n catalogImportApi,\n onPrepare,\n ],\n );\n\n return (\n <>\n <Typography>\n {t('stepPrepareCreatePullRequest.description', {\n integrationType: analyzeResult.integrationType,\n catalogFilename: <code>{catalogFilename}</code>,\n })}\n </Typography>\n\n {!prDefaultsLoading && (\n <PreparePullRequestForm<FormData>\n onSubmit={handleResult}\n defaultValues={{\n title: prDefaults?.title ?? '',\n body: prDefaults?.body ?? '',\n owner:\n (analyzeResult.generatedEntities[0]?.spec?.owner as string) || '',\n componentName:\n analyzeResult.generatedEntities[0]?.metadata?.name || '',\n useCodeowners: false,\n }}\n render={({ values, formState, register, setValue }) => (\n <>\n {renderFormFields({\n values,\n formState,\n register,\n setValue,\n groups: groups ?? [],\n groupsLoading,\n })}\n\n <Box marginTop={2}>\n <Typography variant=\"h6\">\n {t('stepPrepareCreatePullRequest.previewPr.title')}\n </Typography>\n </Box>\n\n <PreviewPullRequestComponent\n title={values.title}\n description={values.body}\n classes={{\n card: classes.previewCard,\n cardContent: classes.previewCardContent,\n }}\n />\n\n <Box marginTop={2} marginBottom={1}>\n <Typography variant=\"h6\">\n {t('stepPrepareCreatePullRequest.previewCatalogInfo.title')}\n </Typography>\n </Box>\n\n <PreviewCatalogInfoComponent\n entities={generateEntities(\n analyzeResult.generatedEntities,\n values.componentName,\n values.owner,\n )}\n repositoryUrl={analyzeResult.url}\n classes={{\n card: classes.previewCard,\n cardContent: classes.previewCardContent,\n }}\n />\n\n {error && <FormHelperText error>{error}</FormHelperText>}\n\n <Grid container spacing={0}>\n {onGoBack && (\n <BackButton onClick={onGoBack} disabled={submitted} />\n )}\n <NextButton\n type=\"submit\"\n disabled={Boolean(\n formState.errors.title ||\n formState.errors.body ||\n formState.errors.owner,\n )}\n loading={submitted}\n >\n {t('stepPrepareCreatePullRequest.nextButtonText')}\n </NextButton>\n </Grid>\n </>\n )}\n />\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -340,6 +340,19 @@ interface StepInitAnalyzeUrlProps {
340
340
  */
341
341
  declare const StepInitAnalyzeUrl: (props: StepInitAnalyzeUrlProps) => react_jsx_runtime.JSX.Element;
342
342
 
343
+ /**
344
+ * An option of {@link AutocompleteTextField}.
345
+ *
346
+ * Plain strings are used both as the visible label and as the selected value,
347
+ * while the object form allows the option to be presented with a different
348
+ * label than the value it selects.
349
+ *
350
+ * @public
351
+ */
352
+ type AutocompleteTextFieldOption = string | {
353
+ label: string;
354
+ id: string;
355
+ };
343
356
  /**
344
357
  * Props for {@link AutocompleteTextField}.
345
358
  *
@@ -347,7 +360,7 @@ declare const StepInitAnalyzeUrl: (props: StepInitAnalyzeUrlProps) => react_jsx_
347
360
  */
348
361
  interface AutocompleteTextFieldProps<TFieldValue extends string> {
349
362
  name: TFieldValue;
350
- options: string[];
363
+ options: AutocompleteTextFieldOption[];
351
364
  required?: boolean;
352
365
  errors?: FieldErrors;
353
366
  rules?: ComponentProps<typeof Controller>['rules'];
@@ -458,7 +471,7 @@ interface StepPrepareCreatePullRequestProps {
458
471
  onGoBack?: () => void;
459
472
  renderFormFields: (props: Pick<UseFormReturn<FormData>, 'register' | 'setValue' | 'formState'> & {
460
473
  values: UnpackNestedValue<FormData>;
461
- groups: string[];
474
+ groups: AutocompleteTextFieldOption[];
462
475
  groupsLoading: boolean;
463
476
  }) => ReactNode;
464
477
  }
@@ -540,4 +553,4 @@ declare const catalogImportTranslationRef: _backstage_frontend_plugin_api.Transl
540
553
  }>;
541
554
 
542
555
  export { AutocompleteTextField, CatalogImportClient, CatalogImportPage, DefaultImportPage, EntityListComponent, ImportInfoCard, ImportStepper, PreparePullRequestForm, PreviewCatalogInfoComponent, PreviewPullRequestComponent, StepInitAnalyzeUrl, StepPrepareCreatePullRequest, catalogImportApiRef, catalogImportPlugin, catalogImportTranslationRef, defaultGenerateStepper, catalogImportPlugin as plugin };
543
- export type { AnalyzeResult, AutocompleteTextFieldProps, CatalogImportApi, EntityListComponentProps, ImportFlows, ImportInfoCardProps, ImportState, ImportStepperProps, PreparePullRequestFormProps, PrepareResult, PreviewCatalogInfoComponentProps, PreviewPullRequestComponentProps, StepInitAnalyzeUrlProps, StepPrepareCreatePullRequestProps, UnpackNestedValue };
556
+ export type { AnalyzeResult, AutocompleteTextFieldOption, AutocompleteTextFieldProps, CatalogImportApi, EntityListComponentProps, ImportFlows, ImportInfoCardProps, ImportState, ImportStepperProps, PreparePullRequestFormProps, PrepareResult, PreviewCatalogInfoComponentProps, PreviewPullRequestComponentProps, StepInitAnalyzeUrlProps, StepPrepareCreatePullRequestProps, UnpackNestedValue };
@@ -1,5 +1,5 @@
1
1
  var name = "@backstage/plugin-catalog-import";
2
- var version = "0.13.16";
2
+ var version = "0.13.17-next.0";
3
3
  var description = "A Backstage plugin the helps you import entities into your catalog";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-import",
3
- "version": "0.13.16",
3
+ "version": "0.13.17-next.0",
4
4
  "description": "A Backstage plugin the helps you import entities into your catalog",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -66,18 +66,18 @@
66
66
  "test": "backstage-cli package test"
67
67
  },
68
68
  "dependencies": {
69
- "@backstage/catalog-client": "^1.16.1",
70
- "@backstage/catalog-model": "^1.10.0",
71
- "@backstage/config": "^1.3.8",
72
- "@backstage/core-components": "^0.18.13",
73
- "@backstage/core-plugin-api": "^1.12.9",
74
- "@backstage/errors": "^1.3.1",
75
- "@backstage/frontend-plugin-api": "^0.18.0",
76
- "@backstage/integration": "^2.1.0",
77
- "@backstage/integration-react": "^1.2.21",
78
- "@backstage/plugin-catalog-common": "^1.1.10",
79
- "@backstage/plugin-catalog-react": "^3.2.1",
80
- "@backstage/plugin-permission-react": "^0.5.4",
69
+ "@backstage/catalog-client": "1.16.1",
70
+ "@backstage/catalog-model": "1.10.0",
71
+ "@backstage/config": "1.3.8",
72
+ "@backstage/core-components": "0.18.14-next.0",
73
+ "@backstage/core-plugin-api": "1.12.9",
74
+ "@backstage/errors": "1.3.1",
75
+ "@backstage/frontend-plugin-api": "0.18.0",
76
+ "@backstage/integration": "2.1.0",
77
+ "@backstage/integration-react": "1.2.21",
78
+ "@backstage/plugin-catalog-common": "1.1.10",
79
+ "@backstage/plugin-catalog-react": "3.2.2-next.0",
80
+ "@backstage/plugin-permission-react": "0.5.4",
81
81
  "@material-ui/core": "^4.12.2",
82
82
  "@material-ui/icons": "^4.9.1",
83
83
  "@material-ui/lab": "4.0.0-alpha.61",
@@ -91,11 +91,11 @@
91
91
  "yaml": "^2.0.0"
92
92
  },
93
93
  "devDependencies": {
94
- "@backstage/cli": "^0.36.5",
95
- "@backstage/core-app-api": "^1.20.4",
96
- "@backstage/dev-utils": "^1.1.26",
97
- "@backstage/plugin-catalog": "^2.0.8",
98
- "@backstage/test-utils": "^1.7.21",
94
+ "@backstage/cli": "0.36.6-next.0",
95
+ "@backstage/core-app-api": "1.20.5-next.0",
96
+ "@backstage/dev-utils": "1.1.27-next.0",
97
+ "@backstage/plugin-catalog": "2.0.9-next.0",
98
+ "@backstage/test-utils": "1.7.22-next.0",
99
99
  "@testing-library/dom": "^10.0.0",
100
100
  "@testing-library/jest-dom": "^6.0.0",
101
101
  "@testing-library/react": "^16.0.0",