chore: adding some more useful state to the context
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -538,10 +538,6 @@ export type TemplateParameterSchema = {
|
||||
description?: string;
|
||||
schema: JsonObject;
|
||||
}>;
|
||||
EXPERIMENTAL_formDecorators?: {
|
||||
id: string;
|
||||
input?: JsonObject;
|
||||
}[];
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Content,
|
||||
InfoCard,
|
||||
@@ -28,7 +28,7 @@ import { useTemplateParameterSchema } from '../../hooks/useTemplateParameterSche
|
||||
import { Stepper, type StepperProps } from '../Stepper/Stepper';
|
||||
import {
|
||||
SecretsContextProvider,
|
||||
useTemplateSecrets,
|
||||
useInternalTemplateSecrets,
|
||||
} from '../../../secrets/SecretsContext';
|
||||
import { useFilteredSchemaProperties } from '../../hooks/useFilteredSchemaProperties';
|
||||
import { ReviewStepProps } from '@backstage/plugin-scaffolder-react';
|
||||
@@ -88,11 +88,14 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
const { loading, manifest, error } = useTemplateParameterSchema(templateRef);
|
||||
const sortedManifest = useFilteredSchemaProperties(manifest);
|
||||
const minutesSaved = useTemplateTimeSavedMinutes(templateRef);
|
||||
const { setSecrets } = useTemplateSecrets();
|
||||
const { setSecrets } = useInternalTemplateSecrets();
|
||||
const formDecorators = useFormDecorators();
|
||||
const [formState, setFormState] = useState<Record<string, JsonValue>>({});
|
||||
|
||||
const workflowOnCreate = useCallback(
|
||||
async (formState: Record<string, JsonValue>) => {
|
||||
async (originalFormState: Record<string, JsonValue>) => {
|
||||
setFormState(originalFormState);
|
||||
|
||||
if (manifest?.EXPERIMENTAL_formDecorators && formDecorators?.size) {
|
||||
// for each of the form decorators, go and call the decorator with the context
|
||||
await Promise.all(
|
||||
@@ -106,6 +109,8 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
|
||||
await formDecorator.fn({
|
||||
setSecrets,
|
||||
setFormState,
|
||||
formState,
|
||||
input: decorator.input,
|
||||
});
|
||||
}),
|
||||
@@ -124,6 +129,7 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => {
|
||||
manifest?.EXPERIMENTAL_formDecorators,
|
||||
formDecorators,
|
||||
onCreate,
|
||||
formState,
|
||||
analytics,
|
||||
templateName,
|
||||
minutesSaved,
|
||||
|
||||
@@ -14,11 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { AnyApiRef } from '@backstage/core-plugin-api';
|
||||
import { JsonValue } from '@backstage/types';
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type ScaffolderFormDecoratorContext<TInput> = {
|
||||
input: TInput;
|
||||
setSecrets: (input: Record<string, string>) => void;
|
||||
formState: Record<string, JsonValue>;
|
||||
|
||||
setFormState: Dispatch<SetStateAction<Record<string, JsonValue>>>;
|
||||
setSecrets: Dispatch<SetStateAction<Record<string, string>>>;
|
||||
};
|
||||
|
||||
export type ScaffolderFormDecorator<
|
||||
|
||||
@@ -94,3 +94,15 @@ export const useTemplateSecrets = (): ScaffolderUseTemplateSecrets => {
|
||||
|
||||
return { setSecrets, secrets };
|
||||
};
|
||||
|
||||
export const useInternalTemplateSecrets = () => {
|
||||
const value = useContext(SecretsContext)?.atVersion(1);
|
||||
|
||||
if (!value) {
|
||||
throw new Error(
|
||||
'useTemplateSecrets must be used within a SecretsContextProvider',
|
||||
);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
@@ -20,14 +20,16 @@ import { ScaffolderFormDecorator } from '@backstage/plugin-scaffolder-react/alph
|
||||
export class DefaultScaffolderFormDecoratorsApi
|
||||
implements ScaffolderFormDecoratorsApi
|
||||
{
|
||||
constructor(
|
||||
private constructor(
|
||||
private readonly options: {
|
||||
decorators: Array<ScaffolderFormDecorator>;
|
||||
},
|
||||
) {}
|
||||
|
||||
static create(options: { decorators: ScaffolderFormDecorator[] }) {
|
||||
return new DefaultScaffolderFormDecoratorsApi(options);
|
||||
static create(options?: { decorators: ScaffolderFormDecorator[] }) {
|
||||
return new DefaultScaffolderFormDecoratorsApi(
|
||||
options ?? { decorators: [] },
|
||||
);
|
||||
}
|
||||
|
||||
async getFormDecorators(): Promise<ScaffolderFormDecorator[]> {
|
||||
|
||||
@@ -71,6 +71,8 @@ describe('useFormDecorators', () => {
|
||||
expect(testDecorator).toBeDefined();
|
||||
|
||||
await testDecorator.fn({
|
||||
formState: {},
|
||||
setFormState: () => {},
|
||||
setSecrets: () => {},
|
||||
input: { test: 'input value' },
|
||||
});
|
||||
|
||||
@@ -78,6 +78,8 @@ import {
|
||||
} from './components/fields/MyGroupsPicker/MyGroupsPicker';
|
||||
import { RepoBranchPicker } from './components/fields/RepoBranchPicker/RepoBranchPicker';
|
||||
import { RepoBranchPickerSchema } from './components/fields/RepoBranchPicker/schema';
|
||||
import { formDecoratorsApiRef } from './alpha/api/ref';
|
||||
import { DefaultScaffolderFormDecoratorsApi } from './alpha/api/FormDecoratorsApi';
|
||||
|
||||
/**
|
||||
* The main plugin export for the scaffolder.
|
||||
@@ -102,6 +104,11 @@ export const scaffolderPlugin = createPlugin({
|
||||
identityApi,
|
||||
}),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: formDecoratorsApiRef,
|
||||
deps: {},
|
||||
factory: () => DefaultScaffolderFormDecoratorsApi.create(),
|
||||
}),
|
||||
],
|
||||
routes: {
|
||||
root: rootRouteRef,
|
||||
|
||||
Reference in New Issue
Block a user