chore: hook to get the field extensions

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2023-01-05 09:52:40 +01:00
parent 34a8a2c73b
commit 7e7575409e
9 changed files with 93 additions and 46 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
---
'@backstage/plugin-scaffolder-react': patch
'@backstage/plugin-scaffolder-react': major
---
Re-home some of the common types, components, hooks and `(route|api)Ref`'s for the `@backstage/plugin-scaffolder` to this package for easy re-use across things that want to interact with the `scaffolder`.
Re-home some of the common types, components, hooks and `scaffolderApiRef` for the `@backstage/plugin-scaffolder` to this package for easy re-use across things that want to interact with the `scaffolder`.
+8 -3
View File
@@ -16,8 +16,13 @@
import { createApiRef } from '@backstage/core-plugin-api';
import { ScaffolderApi } from './types';
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
/** @public */
export const scaffolderApiRef = createApiRef<ScaffolderApi>({
id: 'plugin.scaffolder.service',
});
export const scaffolderApiRef = getOrCreateGlobalSingleton(
'scaffolder:scaffolder-api-ref',
() =>
createApiRef<ScaffolderApi>({
id: 'plugin.scaffolder.service',
}),
);
@@ -22,17 +22,7 @@ import {
FieldExtensionComponentProps,
} from './types';
import { Extension, attachComponentData } from '@backstage/core-plugin-api';
/**
* The key used to store the field extension data for the `<ScaffolderFieldExtensions />` component
* @public
*/
export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1';
/**
* The key used to store the field extension data for any `<FieldExtension />` component
* @public
*/
export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1';
import { FIELD_EXTENSION_KEY, FIELD_EXTENSION_WRAPPER_KEY } from './keys';
/**
* A type used to wrap up the FieldExtension to embed the ReturnValue and the InputProps
@@ -0,0 +1,21 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const FIELD_EXTENSION_WRAPPER_KEY = 'scaffolder.extensions.wrapper.v1';
/**
* The key used to store the field extension data for any `<FieldExtension />` component
*/
export const FIELD_EXTENSION_KEY = 'scaffolder.extensions.field.v1';
@@ -0,0 +1,17 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { useCustomFieldExtensions } from './useCustomFieldExtensions';
@@ -0,0 +1,38 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useElementFilter } from '@backstage/core-plugin-api';
import { FieldExtensionOptions } from '../extensions';
import {
FIELD_EXTENSION_KEY,
FIELD_EXTENSION_WRAPPER_KEY,
} from '../extensions/keys';
import { NextFieldExtensionOptions } from '../next';
/**
* Hook that returns all custom field extensions from the current outlet.
* @public
*/
export const useCustomFieldExtensions = (outlet: React.ReactNode) => {
return useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: FIELD_EXTENSION_WRAPPER_KEY,
})
.findComponentData<FieldExtensionOptions | NextFieldExtensionOptions>({
key: FIELD_EXTENSION_KEY,
}),
);
};
+1
View File
@@ -18,5 +18,6 @@ export * from './extensions';
export * from './types';
export * from './secrets';
export * from './api';
export * from './hooks';
export * from './next';
+3 -13
View File
@@ -30,10 +30,8 @@ import {
useRouteRefParams,
} from '@backstage/core-plugin-api';
import {
FIELD_EXTENSION_KEY,
FIELD_EXTENSION_WRAPPER_KEY,
FieldExtensionOptions,
SecretsContextProvider,
useCustomFieldExtensions,
} from '@backstage/plugin-scaffolder-react';
import { ListTasksPage } from './ListTasksPage';
import { LayoutOptions, LAYOUTS_KEY, LAYOUTS_WRAPPER_KEY } from '../layouts';
@@ -94,16 +92,7 @@ export const Router = (props: RouterProps) => {
const outlet = useOutlet();
const TaskPageElement = TaskPageComponent ?? TaskPage;
const customFieldExtensions = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: FIELD_EXTENSION_WRAPPER_KEY,
})
.findComponentData<FieldExtensionOptions>({
key: FIELD_EXTENSION_KEY,
}),
);
const customFieldExtensions = useCustomFieldExtensions(outlet);
const fieldExtensions = [
...customFieldExtensions,
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(
@@ -114,6 +103,7 @@ export const Router = (props: RouterProps) => {
),
];
// todo(blam): this should also be moved to a hook in -react
const customLayouts = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
+2 -17
View File
@@ -18,14 +18,11 @@ import { Routes, Route, useOutlet } from 'react-router-dom';
import { TemplateListPage } from '../TemplateListPage';
import { TemplateWizardPage } from '../TemplateWizardPage';
import {
FIELD_EXTENSION_WRAPPER_KEY,
FIELD_EXTENSION_KEY,
NextFieldExtensionOptions,
FieldExtensionOptions,
SecretsContextProvider,
useCustomFieldExtensions,
} from '@backstage/plugin-scaffolder-react';
import { useElementFilter } from '@backstage/core-plugin-api';
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
import { TemplateGroupFilter } from '../TemplateListPage/TemplateGroups';
import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default';
@@ -55,20 +52,8 @@ export type NextRouterProps = {
*/
export const Router = (props: PropsWithChildren<NextRouterProps>) => {
const { components: { TemplateCardComponent } = {} } = props;
const outlet = useOutlet() || props.children;
// todo(blam): move this out into a `useFieldExtensions` hook exported by -react
const customFieldExtensions = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: FIELD_EXTENSION_WRAPPER_KEY,
})
.findComponentData<FieldExtensionOptions | NextFieldExtensionOptions>({
key: FIELD_EXTENSION_KEY,
}),
);
const customFieldExtensions = useCustomFieldExtensions(outlet);
const fieldExtensions = [
...customFieldExtensions,
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(