@backstage/plugin-scaffolder 0.13.0 → 0.15.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 +120 -0
- package/dist/esm/{Router-8ca04a51.esm.js → Router-47c9a9ee.esm.js} +193 -28
- package/dist/esm/Router-47c9a9ee.esm.js.map +1 -0
- package/dist/esm/{index-7ce19edf.esm.js → index-ced3b204.esm.js} +67 -232
- package/dist/esm/index-ced3b204.esm.js.map +1 -0
- package/dist/index.d.ts +202 -93
- package/dist/index.esm.js +2 -5
- package/dist/index.esm.js.map +1 -1
- package/package.json +17 -17
- package/dist/esm/Router-8ca04a51.esm.js.map +0 -1
- package/dist/esm/index-7ce19edf.esm.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,19 +2,24 @@
|
|
|
2
2
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
3
|
import { DiscoveryApi, FetchApi, ApiHolder, Extension } from '@backstage/core-plugin-api';
|
|
4
4
|
import { ScmIntegrationRegistry } from '@backstage/integration';
|
|
5
|
-
import { JsonObject, Observable } from '@backstage/types';
|
|
6
|
-
import
|
|
7
|
-
import { TaskSpec, TemplateEntityV1beta2 } from '@backstage/plugin-scaffolder-common';
|
|
5
|
+
import { JsonObject, JsonValue, Observable } from '@backstage/types';
|
|
6
|
+
import { TaskSpec, TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
|
8
7
|
import { JSONSchema7 } from 'json-schema';
|
|
9
|
-
import
|
|
10
|
-
import React__default, { ComponentProps, ComponentType } from 'react';
|
|
8
|
+
import React, { ComponentType } from 'react';
|
|
11
9
|
import { FieldValidation, FieldProps } from '@rjsf/core';
|
|
12
|
-
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
13
10
|
import { Entity } from '@backstage/catalog-model';
|
|
14
|
-
import { IconButton } from '@material-ui/core';
|
|
15
11
|
|
|
12
|
+
/**
|
|
13
|
+
* The status of each task in a Scaffolder Job
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
16
17
|
declare type ScaffolderTaskStatus = 'open' | 'processing' | 'failed' | 'completed' | 'skipped';
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The shape of each task returned from the `scaffolder-backend`
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
18
23
|
declare type ScaffolderTask = {
|
|
19
24
|
id: string;
|
|
20
25
|
spec: TaskSpec;
|
|
@@ -22,6 +27,11 @@ declare type ScaffolderTask = {
|
|
|
22
27
|
lastHeartbeatAt: string;
|
|
23
28
|
createdAt: string;
|
|
24
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* The response shape for the `listActions` call to the `scaffolder-backend`
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
25
35
|
declare type ListActionsResponse = Array<{
|
|
26
36
|
id: string;
|
|
27
37
|
description?: string;
|
|
@@ -30,21 +40,25 @@ declare type ListActionsResponse = Array<{
|
|
|
30
40
|
output?: JSONSchema7;
|
|
31
41
|
};
|
|
32
42
|
}>;
|
|
43
|
+
/** @public */
|
|
33
44
|
declare type ScaffolderOutputLink = {
|
|
34
45
|
title?: string;
|
|
35
46
|
icon?: string;
|
|
36
47
|
url?: string;
|
|
37
48
|
entityRef?: string;
|
|
38
49
|
};
|
|
50
|
+
/** @public */
|
|
39
51
|
declare type ScaffolderTaskOutput = {
|
|
40
|
-
/** @deprecated use the `links` property to link out to relevant resources */
|
|
41
|
-
entityRef?: string;
|
|
42
|
-
/** @deprecated use the `links` property to link out to relevant resources */
|
|
43
|
-
remoteUrl?: string;
|
|
44
52
|
links?: ScaffolderOutputLink[];
|
|
45
53
|
} & {
|
|
46
54
|
[key: string]: unknown;
|
|
47
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* The shape of each entry of parameters which gets rendered
|
|
58
|
+
* as a seperate step in the wizard input
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
48
62
|
declare type TemplateParameterSchema = {
|
|
49
63
|
title: string;
|
|
50
64
|
steps: Array<{
|
|
@@ -52,6 +66,11 @@ declare type TemplateParameterSchema = {
|
|
|
52
66
|
schema: JsonObject;
|
|
53
67
|
}>;
|
|
54
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* The shape of a `LogEvent` message from the `scaffolder-backend`
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
55
74
|
declare type LogEvent = {
|
|
56
75
|
type: 'log' | 'completion';
|
|
57
76
|
body: {
|
|
@@ -63,17 +82,37 @@ declare type LogEvent = {
|
|
|
63
82
|
id: string;
|
|
64
83
|
taskId: string;
|
|
65
84
|
};
|
|
85
|
+
/**
|
|
86
|
+
* The input options to the `scaffold` method of the `ScaffolderClient`.
|
|
87
|
+
*
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
66
90
|
interface ScaffolderScaffoldOptions {
|
|
67
91
|
templateRef: string;
|
|
68
|
-
values: Record<string,
|
|
92
|
+
values: Record<string, JsonValue>;
|
|
69
93
|
secrets?: Record<string, string>;
|
|
70
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The response shape of the `scaffold` method of the `ScaffolderClient`.
|
|
97
|
+
*
|
|
98
|
+
* @public
|
|
99
|
+
*/
|
|
71
100
|
interface ScaffolderScaffoldResponse {
|
|
72
101
|
taskId: string;
|
|
73
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* The arguments for `getIntegrationsList`.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
74
108
|
interface ScaffolderGetIntegrationsListOptions {
|
|
75
109
|
allowedHosts: string[];
|
|
76
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* The response shape for `getIntegrationsList`.
|
|
113
|
+
*
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
77
116
|
interface ScaffolderGetIntegrationsListResponse {
|
|
78
117
|
integrations: {
|
|
79
118
|
type: string;
|
|
@@ -81,6 +120,11 @@ interface ScaffolderGetIntegrationsListResponse {
|
|
|
81
120
|
host: string;
|
|
82
121
|
}[];
|
|
83
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* The input options to the `streamLogs` method of the `ScaffolderClient`.
|
|
125
|
+
*
|
|
126
|
+
* @public
|
|
127
|
+
*/
|
|
84
128
|
interface ScaffolderStreamLogsOptions {
|
|
85
129
|
taskId: string;
|
|
86
130
|
after?: number;
|
|
@@ -160,9 +204,9 @@ declare type CustomFieldValidator<TFieldReturnValue> = (data: TFieldReturnValue,
|
|
|
160
204
|
*
|
|
161
205
|
* @public
|
|
162
206
|
*/
|
|
163
|
-
declare type FieldExtensionOptions<TFieldReturnValue = unknown,
|
|
207
|
+
declare type FieldExtensionOptions<TFieldReturnValue = unknown, TInputProps = unknown> = {
|
|
164
208
|
name: string;
|
|
165
|
-
component: (props:
|
|
209
|
+
component: (props: FieldExtensionComponentProps<TFieldReturnValue, TInputProps>) => JSX.Element | null;
|
|
166
210
|
validation?: CustomFieldValidator<TFieldReturnValue>;
|
|
167
211
|
};
|
|
168
212
|
/**
|
|
@@ -177,54 +221,12 @@ interface FieldExtensionComponentProps<TFieldReturnValue, TUiOptions extends {}
|
|
|
177
221
|
};
|
|
178
222
|
}
|
|
179
223
|
|
|
180
|
-
declare function createScaffolderFieldExtension<TReturnValue = unknown, TInputProps = unknown>(options: FieldExtensionOptions<TReturnValue, TInputProps>): Extension<() => null>;
|
|
181
|
-
declare const ScaffolderFieldExtensions: React__default.ComponentType;
|
|
182
|
-
|
|
183
|
-
declare const scaffolderPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
184
|
-
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
185
|
-
}, {
|
|
186
|
-
registerComponent: _backstage_core_plugin_api.ExternalRouteRef<undefined, true>;
|
|
187
|
-
}>;
|
|
188
|
-
declare const EntityPickerFieldExtension: () => null;
|
|
189
|
-
declare const EntityNamePickerFieldExtension: () => null;
|
|
190
|
-
declare const RepoUrlPickerFieldExtension: () => null;
|
|
191
|
-
declare const OwnerPickerFieldExtension: () => null;
|
|
192
|
-
declare const ScaffolderPage: ({ TemplateCardComponent, TaskPageComponent, groups, }: {
|
|
193
|
-
TemplateCardComponent?: React.ComponentType<{
|
|
194
|
-
template: _backstage_plugin_scaffolder_common.TemplateEntityV1beta2;
|
|
195
|
-
}> | undefined;
|
|
196
|
-
TaskPageComponent?: React.ComponentType<{}> | undefined;
|
|
197
|
-
groups?: {
|
|
198
|
-
title?: string | undefined;
|
|
199
|
-
titleComponent?: React.ReactNode;
|
|
200
|
-
filter: (entity: _backstage_catalog_model.Entity) => boolean;
|
|
201
|
-
}[] | undefined;
|
|
202
|
-
}) => JSX.Element;
|
|
203
|
-
declare const OwnedEntityPickerFieldExtension: () => null;
|
|
204
224
|
/**
|
|
205
|
-
*
|
|
225
|
+
* The input props that can be specified under `ui:options` for the
|
|
226
|
+
* `RepoUrlPicker` field extension.
|
|
227
|
+
*
|
|
206
228
|
* @public
|
|
207
229
|
*/
|
|
208
|
-
declare const EntityTagsPickerFieldExtension: () => null;
|
|
209
|
-
|
|
210
|
-
interface EntityPickerUiOptions {
|
|
211
|
-
allowedKinds?: string[];
|
|
212
|
-
defaultKind?: string;
|
|
213
|
-
allowArbitraryValues?: boolean;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Entity Picker
|
|
217
|
-
*/
|
|
218
|
-
declare const EntityPicker: (props: FieldExtensionComponentProps<string, EntityPickerUiOptions>) => JSX.Element;
|
|
219
|
-
|
|
220
|
-
interface OwnerPickerUiOptions {
|
|
221
|
-
allowedKinds?: string[];
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Owner Picker
|
|
225
|
-
*/
|
|
226
|
-
declare const OwnerPicker: (props: FieldExtensionComponentProps<string, OwnerPickerUiOptions>) => JSX.Element;
|
|
227
|
-
|
|
228
230
|
interface RepoUrlPickerUiOptions {
|
|
229
231
|
allowedHosts?: string[];
|
|
230
232
|
allowedOwners?: string[];
|
|
@@ -238,62 +240,169 @@ interface RepoUrlPickerUiOptions {
|
|
|
238
240
|
};
|
|
239
241
|
};
|
|
240
242
|
}
|
|
243
|
+
|
|
241
244
|
/**
|
|
242
|
-
*
|
|
245
|
+
* The input props that can be specified under `ui:options` for the
|
|
246
|
+
* `EntityTagsPicker` field extension.
|
|
247
|
+
*
|
|
248
|
+
* @public
|
|
243
249
|
*/
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
apiHolder: ApiHolder;
|
|
248
|
-
}) => void;
|
|
250
|
+
interface EntityTagsPickerUiOptions {
|
|
251
|
+
kinds?: string[];
|
|
252
|
+
}
|
|
249
253
|
|
|
250
|
-
|
|
254
|
+
/**
|
|
255
|
+
* The input props that can be specified under `ui:options` for the
|
|
256
|
+
* `EntityPicker` field extension.
|
|
257
|
+
*
|
|
258
|
+
* @public
|
|
259
|
+
*/
|
|
260
|
+
interface EntityPickerUiOptions {
|
|
251
261
|
allowedKinds?: string[];
|
|
252
262
|
defaultKind?: string;
|
|
263
|
+
allowArbitraryValues?: boolean;
|
|
253
264
|
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* A type used to wrap up the FieldExtension to embed the ReturnValue and the InputProps
|
|
268
|
+
*
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
271
|
+
declare type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null;
|
|
254
272
|
/**
|
|
255
|
-
*
|
|
273
|
+
* Method for creating field extensions that can be used in the scaffolder
|
|
274
|
+
* frontend form.
|
|
275
|
+
* @public
|
|
256
276
|
*/
|
|
257
|
-
declare
|
|
258
|
-
|
|
259
|
-
interface EntityTagsPickerUiOptions {
|
|
260
|
-
kinds?: string[];
|
|
261
|
-
}
|
|
277
|
+
declare function createScaffolderFieldExtension<TReturnValue = unknown, TInputProps = unknown>(options: FieldExtensionOptions<TReturnValue, TInputProps>): Extension<FieldExtensionComponent<TReturnValue, TInputProps>>;
|
|
262
278
|
/**
|
|
263
|
-
*
|
|
279
|
+
* The Wrapping component for defining fields extensions inside
|
|
280
|
+
*
|
|
281
|
+
* @public
|
|
264
282
|
*/
|
|
265
|
-
declare const
|
|
283
|
+
declare const ScaffolderFieldExtensions: React.ComponentType;
|
|
266
284
|
|
|
267
|
-
declare type Props = ComponentProps<typeof IconButton> & {
|
|
268
|
-
entity: Entity;
|
|
269
|
-
};
|
|
270
285
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
286
|
+
* The input props that can be specified under `ui:options` for the
|
|
287
|
+
* `OwnedEntityPicker` field extension.
|
|
288
|
+
*
|
|
289
|
+
* @public
|
|
273
290
|
*/
|
|
274
|
-
|
|
291
|
+
interface OwnedEntityPickerUiOptions {
|
|
292
|
+
allowedKinds?: string[];
|
|
293
|
+
defaultKind?: string;
|
|
294
|
+
}
|
|
275
295
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
296
|
+
/**
|
|
297
|
+
* The props for the entrypoint `ScaffolderPage` component the plugin.
|
|
298
|
+
* @public
|
|
299
|
+
*/
|
|
300
|
+
declare type RouterProps = {
|
|
301
|
+
components?: {
|
|
302
|
+
TemplateCardComponent?: ComponentType<{
|
|
303
|
+
template: TemplateEntityV1beta3;
|
|
304
|
+
}> | undefined;
|
|
305
|
+
TaskPageComponent?: ComponentType<{}>;
|
|
306
|
+
};
|
|
307
|
+
groups?: Array<{
|
|
281
308
|
title?: string;
|
|
282
|
-
titleComponent?:
|
|
309
|
+
titleComponent?: React.ReactNode;
|
|
283
310
|
filter: (entity: Entity) => boolean;
|
|
284
|
-
}
|
|
311
|
+
}>;
|
|
285
312
|
};
|
|
286
|
-
declare const TemplateList: ({ TemplateCardComponent, group, }: TemplateListProps) => JSX.Element | null;
|
|
287
313
|
|
|
314
|
+
/**
|
|
315
|
+
* The input props that can be specified under `ui:options` for the
|
|
316
|
+
* `OwnerPicker` field extension.
|
|
317
|
+
*
|
|
318
|
+
* @public
|
|
319
|
+
*/
|
|
320
|
+
interface OwnerPickerUiOptions {
|
|
321
|
+
allowedKinds?: string[];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* The validation function for the `repoUrl` that is returned from the
|
|
326
|
+
* field extension. Ensures that you have all the required fields filled for
|
|
327
|
+
* the different providers that exist.
|
|
328
|
+
*
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
331
|
+
declare const repoPickerValidation: (value: string, validation: FieldValidation, context: {
|
|
332
|
+
apiHolder: ApiHolder;
|
|
333
|
+
}) => void;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* The main plugin export for the scaffolder.
|
|
337
|
+
* @public
|
|
338
|
+
*/
|
|
339
|
+
declare const scaffolderPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
340
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
341
|
+
}, {
|
|
342
|
+
registerComponent: _backstage_core_plugin_api.ExternalRouteRef<undefined, true>;
|
|
343
|
+
}>;
|
|
344
|
+
/**
|
|
345
|
+
* A field extension for selecting an Entity that exists in the Catalog.
|
|
346
|
+
*
|
|
347
|
+
* @public
|
|
348
|
+
*/
|
|
349
|
+
declare const EntityPickerFieldExtension: FieldExtensionComponent<string, EntityPickerUiOptions>;
|
|
350
|
+
/**
|
|
351
|
+
* The field extension for selecting a name for a new Entity in the Catalog.
|
|
352
|
+
*
|
|
353
|
+
* @public
|
|
354
|
+
*/
|
|
355
|
+
declare const EntityNamePickerFieldExtension: FieldExtensionComponent<string, {}>;
|
|
356
|
+
/**
|
|
357
|
+
* The field extension which provides the ability to select a RepositoryUrl.
|
|
358
|
+
* Currently this is an encoded URL that looks something like the following `github.com?repo=myRepoName&owner=backstage`.
|
|
359
|
+
*
|
|
360
|
+
* @public
|
|
361
|
+
*/
|
|
362
|
+
declare const RepoUrlPickerFieldExtension: FieldExtensionComponent<string, RepoUrlPickerUiOptions>;
|
|
363
|
+
/**
|
|
364
|
+
* A field extension for picking users and groups out of the Catalog.
|
|
365
|
+
*
|
|
366
|
+
* @public
|
|
367
|
+
*/
|
|
368
|
+
declare const OwnerPickerFieldExtension: FieldExtensionComponent<string, OwnerPickerUiOptions>;
|
|
369
|
+
/**
|
|
370
|
+
* The Router and main entrypoint to the Scaffolder plugin.
|
|
371
|
+
*
|
|
372
|
+
* @public
|
|
373
|
+
*/
|
|
374
|
+
declare const ScaffolderPage: (props: RouterProps) => JSX.Element;
|
|
375
|
+
/**
|
|
376
|
+
* A field extension to show all the Entities that are owned by the current logged-in User for use in templates.
|
|
377
|
+
*
|
|
378
|
+
* @public
|
|
379
|
+
*/
|
|
380
|
+
declare const OwnedEntityPickerFieldExtension: FieldExtensionComponent<string, OwnedEntityPickerUiOptions>;
|
|
381
|
+
/**
|
|
382
|
+
* EntityTagsPickerFieldExtension
|
|
383
|
+
* @public
|
|
384
|
+
*/
|
|
385
|
+
declare const EntityTagsPickerFieldExtension: FieldExtensionComponent<string[], EntityTagsPickerUiOptions>;
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* The component to select the `type` of `Template` that you will see in the table.
|
|
389
|
+
*
|
|
390
|
+
* @public
|
|
391
|
+
*/
|
|
288
392
|
declare const TemplateTypePicker: () => JSX.Element | null;
|
|
289
393
|
|
|
394
|
+
/**
|
|
395
|
+
* The return type from the useTemplateSecrets hook.
|
|
396
|
+
* @public
|
|
397
|
+
*/
|
|
398
|
+
interface ScaffolderUseTemplateSecrets {
|
|
399
|
+
setSecrets: (input: Record<string, string>) => void;
|
|
400
|
+
}
|
|
290
401
|
/**
|
|
291
402
|
* Hook to access the secrets context.
|
|
292
403
|
* @public
|
|
293
404
|
*/
|
|
294
|
-
declare const useTemplateSecrets: () =>
|
|
295
|
-
setSecret: (input: Record<string, string>) => void;
|
|
296
|
-
};
|
|
405
|
+
declare const useTemplateSecrets: () => ScaffolderUseTemplateSecrets;
|
|
297
406
|
|
|
298
407
|
/**
|
|
299
408
|
* TaskPageProps for constructing a TaskPage
|
|
@@ -312,4 +421,4 @@ declare type TaskPageProps = {
|
|
|
312
421
|
*/
|
|
313
422
|
declare const TaskPage: ({ loadingText }: TaskPageProps) => JSX.Element;
|
|
314
423
|
|
|
315
|
-
export { CustomFieldValidator, EntityNamePickerFieldExtension,
|
|
424
|
+
export { CustomFieldValidator, EntityNamePickerFieldExtension, EntityPickerFieldExtension, EntityPickerUiOptions, EntityTagsPickerFieldExtension, EntityTagsPickerUiOptions, FieldExtensionComponent, FieldExtensionComponentProps, FieldExtensionOptions, ListActionsResponse, LogEvent, OwnedEntityPickerFieldExtension, OwnedEntityPickerUiOptions, OwnerPickerFieldExtension, OwnerPickerUiOptions, RepoUrlPickerFieldExtension, RepoUrlPickerUiOptions, RouterProps, ScaffolderApi, ScaffolderClient, ScaffolderFieldExtensions, ScaffolderGetIntegrationsListOptions, ScaffolderGetIntegrationsListResponse, ScaffolderOutputLink, ScaffolderPage, ScaffolderScaffoldOptions, ScaffolderScaffoldResponse, ScaffolderStreamLogsOptions, ScaffolderTask, ScaffolderTaskOutput, ScaffolderTaskStatus, ScaffolderUseTemplateSecrets, TaskPage, TaskPageProps, TemplateParameterSchema, TemplateTypePicker, createScaffolderFieldExtension, repoPickerValidation, scaffolderApiRef, scaffolderPlugin, useTemplateSecrets };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { p as EntityNamePickerFieldExtension, o as EntityPickerFieldExtension, q as EntityTagsPickerFieldExtension, u as OwnedEntityPickerFieldExtension, t as OwnerPickerFieldExtension, v as RepoUrlPickerFieldExtension, l as ScaffolderClient, n as ScaffolderFieldExtensions, w as ScaffolderPage, k as TaskPage, T as TemplateTypePicker, m as createScaffolderFieldExtension, r as repoPickerValidation, f as scaffolderApiRef, x as scaffolderPlugin, y as useTemplateSecrets } from './esm/index-ced3b204.esm.js';
|
|
2
2
|
import '@backstage/catalog-model';
|
|
3
3
|
import '@backstage/core-plugin-api';
|
|
4
4
|
import '@backstage/errors';
|
|
@@ -18,10 +18,6 @@ import '@material-ui/core/Input';
|
|
|
18
18
|
import '@material-ui/core/InputLabel';
|
|
19
19
|
import '@backstage/core-components';
|
|
20
20
|
import 'react-use/lib/useDebounce';
|
|
21
|
-
import '@material-ui/icons/Star';
|
|
22
|
-
import '@material-ui/icons/StarBorder';
|
|
23
|
-
import '@material-ui/icons/Warning';
|
|
24
|
-
import 'react-router';
|
|
25
21
|
import 'lodash/capitalize';
|
|
26
22
|
import '@material-ui/icons/CheckBox';
|
|
27
23
|
import '@material-ui/icons/CheckBoxOutlineBlank';
|
|
@@ -37,6 +33,7 @@ import '@material-ui/icons/Check';
|
|
|
37
33
|
import '@material-ui/icons/FiberManualRecord';
|
|
38
34
|
import 'classnames';
|
|
39
35
|
import 'luxon';
|
|
36
|
+
import 'react-router';
|
|
40
37
|
import 'react-use/lib/useInterval';
|
|
41
38
|
import 'use-immer';
|
|
42
39
|
import '@material-ui/icons/Language';
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder",
|
|
3
3
|
"description": "The Backstage plugin that helps you create new things",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -34,18 +34,18 @@
|
|
|
34
34
|
"clean": "backstage-cli package clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@backstage/catalog-client": "^0.
|
|
38
|
-
"@backstage/catalog-model": "^0.
|
|
37
|
+
"@backstage/catalog-client": "^0.9.0",
|
|
38
|
+
"@backstage/catalog-model": "^0.13.0",
|
|
39
39
|
"@backstage/config": "^0.1.15",
|
|
40
|
-
"@backstage/core-components": "^0.
|
|
41
|
-
"@backstage/core-plugin-api": "^0.
|
|
40
|
+
"@backstage/core-components": "^0.9.1",
|
|
41
|
+
"@backstage/core-plugin-api": "^0.8.0",
|
|
42
42
|
"@backstage/errors": "^0.2.2",
|
|
43
|
-
"@backstage/integration": "^0.
|
|
44
|
-
"@backstage/integration-react": "^0.1.
|
|
45
|
-
"@backstage/plugin-catalog-common": "^0.
|
|
46
|
-
"@backstage/plugin-catalog-react": "^0.
|
|
47
|
-
"@backstage/plugin-permission-react": "^0.3.
|
|
48
|
-
"@backstage/plugin-scaffolder-common": "^0.
|
|
43
|
+
"@backstage/integration": "^0.8.0",
|
|
44
|
+
"@backstage/integration-react": "^0.1.25",
|
|
45
|
+
"@backstage/plugin-catalog-common": "^0.2.2",
|
|
46
|
+
"@backstage/plugin-catalog-react": "^0.9.0",
|
|
47
|
+
"@backstage/plugin-permission-react": "^0.3.3",
|
|
48
|
+
"@backstage/plugin-scaffolder-common": "^0.3.0",
|
|
49
49
|
"@backstage/theme": "^0.2.15",
|
|
50
50
|
"@backstage/types": "^0.1.3",
|
|
51
51
|
"@material-ui/core": "^4.12.2",
|
|
@@ -73,11 +73,11 @@
|
|
|
73
73
|
"react": "^16.13.1 || ^17.0.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@backstage/cli": "^0.
|
|
77
|
-
"@backstage/core-app-api": "^0.
|
|
78
|
-
"@backstage/dev-utils": "^0.2.
|
|
79
|
-
"@backstage/plugin-catalog": "^0.
|
|
80
|
-
"@backstage/test-utils": "^0.
|
|
76
|
+
"@backstage/cli": "^0.15.2",
|
|
77
|
+
"@backstage/core-app-api": "^0.6.0",
|
|
78
|
+
"@backstage/dev-utils": "^0.2.25",
|
|
79
|
+
"@backstage/plugin-catalog": "^0.10.0",
|
|
80
|
+
"@backstage/test-utils": "^0.3.0",
|
|
81
81
|
"@testing-library/jest-dom": "^5.10.1",
|
|
82
82
|
"@testing-library/react": "^11.2.5",
|
|
83
83
|
"@testing-library/react-hooks": "^7.0.2",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"files": [
|
|
93
93
|
"dist"
|
|
94
94
|
],
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "60c4e39d1fcaeb10d6488ada1d907f34dc2a105a"
|
|
96
96
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Router-8ca04a51.esm.js","sources":["../../src/extensions/default.ts","../../src/components/ScaffolderPage/ScaffolderPage.tsx","../../src/components/MultistepJsonForm/schema.ts","../../src/components/MultistepJsonForm/FieldOverrides/DescriptionField.tsx","../../src/components/MultistepJsonForm/MultistepJsonForm.tsx","../../src/components/TemplatePage/TemplatePage.tsx","../../src/components/ActionsPage/ActionsPage.tsx","../../src/components/Router.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 { EntityPicker } from '../components/fields/EntityPicker';\nimport {\n EntityNamePicker,\n entityNamePickerValidation,\n} from '../components/fields/EntityNamePicker';\nimport { EntityTagsPicker } from '../components/fields/EntityTagsPicker';\nimport { OwnerPicker } from '../components/fields/OwnerPicker';\nimport {\n repoPickerValidation,\n RepoUrlPicker,\n} from '../components/fields/RepoUrlPicker';\nimport { FieldExtensionOptions } from './types';\nimport { OwnedEntityPicker } from '../components/fields/OwnedEntityPicker';\n\nexport const DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS: FieldExtensionOptions<any>[] =\n [\n {\n component: EntityPicker,\n name: 'EntityPicker',\n },\n {\n component: EntityNamePicker,\n name: 'EntityNamePicker',\n validation: entityNamePickerValidation,\n },\n {\n component: EntityTagsPicker,\n name: 'EntityTagsPicker',\n },\n {\n component: RepoUrlPicker,\n name: 'RepoUrlPicker',\n validation: repoPickerValidation,\n },\n {\n component: OwnerPicker,\n name: 'OwnerPicker',\n },\n {\n component: OwnedEntityPicker,\n name: 'OwnedEntityPicker',\n },\n ];\n","/*\n * Copyright 2020 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 Content,\n ContentHeader,\n CreateButton,\n Header,\n Lifecycle,\n Page,\n SupportButton,\n} from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport { TemplateEntityV1beta2 } from '@backstage/plugin-scaffolder-common';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport {\n EntityKindPicker,\n EntityListProvider,\n EntitySearchBar,\n EntityTagPicker,\n UserListPicker,\n} from '@backstage/plugin-catalog-react';\nimport { makeStyles } from '@material-ui/core';\nimport React, { ComponentType } from 'react';\nimport { registerComponentRouteRef } from '../../routes';\nimport { TemplateList } from '../TemplateList';\nimport { TemplateTypePicker } from '../TemplateTypePicker';\nimport { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';\nimport { usePermission } from '@backstage/plugin-permission-react';\n\nconst useStyles = makeStyles(theme => ({\n contentWrapper: {\n display: 'grid',\n gridTemplateAreas: \"'filters' 'grid'\",\n gridTemplateColumns: '250px 1fr',\n gridColumnGap: theme.spacing(2),\n },\n}));\n\nexport type ScaffolderPageProps = {\n TemplateCardComponent?:\n | ComponentType<{ template: TemplateEntityV1beta2 }>\n | undefined;\n groups?: Array<{\n title?: string;\n titleComponent?: React.ReactNode;\n filter: (entity: Entity) => boolean;\n }>;\n};\n\nexport const ScaffolderPageContents = ({\n TemplateCardComponent,\n groups,\n}: ScaffolderPageProps) => {\n const styles = useStyles();\n const registerComponentLink = useRouteRef(registerComponentRouteRef);\n const otherTemplatesGroup = {\n title: groups ? 'Other Templates' : 'Templates',\n filter: (entity: Entity) => {\n const filtered = (groups ?? []).map(group => group.filter(entity));\n return !filtered.some(result => result === true);\n },\n };\n\n const { allowed } = usePermission(catalogEntityCreatePermission);\n\n return (\n <Page themeId=\"home\">\n <Header\n pageTitleOverride=\"Create a New Component\"\n title={\n <>\n Create a New Component <Lifecycle shorthand />\n </>\n }\n subtitle=\"Create new software components using standard templates\"\n />\n <Content>\n <ContentHeader title=\"Available Templates\">\n {allowed && (\n <CreateButton\n title=\"Register Existing Component\"\n to={registerComponentLink && registerComponentLink()}\n />\n )}\n <SupportButton>\n Create new software components using standard templates. Different\n templates create different kinds of components (services, websites,\n documentation, ...).\n </SupportButton>\n </ContentHeader>\n\n <div className={styles.contentWrapper}>\n <div>\n <EntitySearchBar />\n <EntityKindPicker initialFilter=\"template\" hidden />\n <UserListPicker\n initialFilter=\"all\"\n availableFilters={['all', 'starred']}\n />\n <TemplateTypePicker />\n <EntityTagPicker />\n </div>\n <div>\n {groups &&\n groups.map((group, index) => (\n <TemplateList\n key={index}\n TemplateCardComponent={TemplateCardComponent}\n group={group}\n />\n ))}\n <TemplateList\n key=\"other\"\n TemplateCardComponent={TemplateCardComponent}\n group={otherTemplatesGroup}\n />\n </div>\n </div>\n </Content>\n </Page>\n );\n};\n\nexport const ScaffolderPage = ({\n TemplateCardComponent,\n groups,\n}: ScaffolderPageProps) => (\n <EntityListProvider>\n <ScaffolderPageContents\n TemplateCardComponent={TemplateCardComponent}\n groups={groups}\n />\n </EntityListProvider>\n);\n","/*\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 { JsonObject } from '@backstage/types';\nimport { FormProps } from '@rjsf/core';\n\nfunction isObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction extractUiSchema(schema: JsonObject, uiSchema: JsonObject) {\n if (!isObject(schema)) {\n return;\n }\n\n const { properties, items, anyOf, oneOf, allOf, dependencies } = schema;\n\n for (const propName in schema) {\n if (!schema.hasOwnProperty(propName)) {\n continue;\n }\n\n if (propName.startsWith('ui:')) {\n uiSchema[propName] = schema[propName];\n delete schema[propName];\n }\n }\n\n if (isObject(properties)) {\n for (const propName in properties) {\n if (!properties.hasOwnProperty(propName)) {\n continue;\n }\n\n const schemaNode = properties[propName];\n if (!isObject(schemaNode)) {\n continue;\n }\n const innerUiSchema = {};\n uiSchema[propName] = innerUiSchema;\n extractUiSchema(schemaNode, innerUiSchema);\n }\n }\n\n if (isObject(items)) {\n const innerUiSchema = {};\n uiSchema.items = innerUiSchema;\n extractUiSchema(items, innerUiSchema);\n }\n\n if (Array.isArray(anyOf)) {\n for (const schemaNode of anyOf) {\n if (!isObject(schemaNode)) {\n continue;\n }\n extractUiSchema(schemaNode, uiSchema);\n }\n }\n\n if (Array.isArray(oneOf)) {\n for (const schemaNode of oneOf) {\n if (!isObject(schemaNode)) {\n continue;\n }\n extractUiSchema(schemaNode, uiSchema);\n }\n }\n\n if (Array.isArray(allOf)) {\n for (const schemaNode of allOf) {\n if (!isObject(schemaNode)) {\n continue;\n }\n extractUiSchema(schemaNode, uiSchema);\n }\n }\n\n if (isObject(dependencies)) {\n for (const depName of Object.keys(dependencies)) {\n const schemaNode = dependencies[depName];\n if (!isObject(schemaNode)) {\n continue;\n }\n extractUiSchema(schemaNode, uiSchema);\n }\n }\n}\n\nexport function transformSchemaToProps(inputSchema: JsonObject): {\n schema: FormProps<any>['schema'];\n uiSchema: FormProps<any>['uiSchema'];\n} {\n inputSchema.type = inputSchema.type || 'object';\n const schema = JSON.parse(JSON.stringify(inputSchema));\n delete schema.title; // Rendered separately\n const uiSchema = {};\n extractUiSchema(schema, uiSchema);\n return { schema, uiSchema };\n}\n","/*\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 React from 'react';\nimport { MarkdownContent } from '@backstage/core-components';\nimport { FieldProps } from '@rjsf/core';\n\nexport const DescriptionField = ({ description }: FieldProps) =>\n description && <MarkdownContent content={description} linkTarget=\"_blank\" />;\n","/*\n * Copyright 2020 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 { JsonObject } from '@backstage/types';\nimport {\n Box,\n Button,\n Paper,\n Step as StepUI,\n StepContent,\n StepLabel,\n Stepper,\n Typography,\n} from '@material-ui/core';\nimport {\n errorApiRef,\n useApi,\n featureFlagsApiRef,\n} from '@backstage/core-plugin-api';\nimport { FormProps, IChangeEvent, UiSchema, withTheme } from '@rjsf/core';\nimport { Theme as MuiTheme } from '@rjsf/material-ui';\nimport React, { useState } from 'react';\nimport { transformSchemaToProps } from './schema';\nimport { Content, StructuredMetadataTable } from '@backstage/core-components';\nimport cloneDeep from 'lodash/cloneDeep';\nimport * as fieldOverrides from './FieldOverrides';\n\nconst Form = withTheme(MuiTheme);\ntype Step = {\n schema: JsonObject;\n title: string;\n} & Partial<Omit<FormProps<any>, 'schema'>>;\n\ntype Props = {\n /**\n * Steps for the form, each contains title and form schema\n */\n steps: Step[];\n formData: Record<string, any>;\n onChange: (e: IChangeEvent) => void;\n onReset: () => void;\n onFinish: () => Promise<void>;\n widgets?: FormProps<any>['widgets'];\n fields?: FormProps<any>['fields'];\n};\n\nexport function getUiSchemasFromSteps(steps: Step[]): UiSchema[] {\n const uiSchemas: Array<UiSchema> = [];\n steps.forEach(step => {\n const schemaProps = step.schema.properties as JsonObject;\n for (const key in schemaProps) {\n if (schemaProps.hasOwnProperty(key)) {\n const uiSchema = schemaProps[key] as UiSchema;\n uiSchema.name = key;\n uiSchemas.push(uiSchema);\n }\n }\n });\n return uiSchemas;\n}\n\nexport function getReviewData(formData: Record<string, any>, steps: Step[]) {\n const uiSchemas = getUiSchemasFromSteps(steps);\n const reviewData: Record<string, any> = {};\n for (const key in formData) {\n if (formData.hasOwnProperty(key)) {\n const uiSchema = uiSchemas.find(us => us.name === key);\n\n if (!uiSchema) {\n reviewData[key] = formData[key];\n continue;\n }\n\n if (uiSchema['ui:widget'] === 'password') {\n reviewData[key] = '******';\n continue;\n }\n\n if (!uiSchema['ui:backstage'] || !uiSchema['ui:backstage'].review) {\n reviewData[key] = formData[key];\n continue;\n }\n\n const review = uiSchema['ui:backstage'].review as JsonObject;\n if (!review.show) {\n continue;\n }\n\n if (review.mask) {\n reviewData[key] = review.mask;\n continue;\n }\n reviewData[key] = formData[key];\n }\n }\n\n return reviewData;\n}\n\nexport const MultistepJsonForm = (props: Props) => {\n const { formData, onChange, onReset, onFinish, fields, widgets } = props;\n const [activeStep, setActiveStep] = useState(0);\n const [disableButtons, setDisableButtons] = useState(false);\n const errorApi = useApi(errorApiRef);\n const featureFlagApi = useApi(featureFlagsApiRef);\n const featureFlagKey = 'backstage:featureFlag';\n const filterOutProperties = (step: Step): Step => {\n const filteredStep = cloneDeep(step);\n const removedPropertyKeys: Array<string> = [];\n if (filteredStep.schema.properties) {\n filteredStep.schema.properties = Object.fromEntries(\n Object.entries(filteredStep.schema.properties).filter(\n ([key, value]) => {\n if (value[featureFlagKey]) {\n if (featureFlagApi.isActive(value[featureFlagKey])) {\n return true;\n }\n removedPropertyKeys.push(key);\n return false;\n }\n return true;\n },\n ),\n );\n\n // remove the feature flag property key from required if they are not active\n filteredStep.schema.required = Array.isArray(filteredStep.schema.required)\n ? filteredStep.schema.required?.filter(\n r => !removedPropertyKeys.includes(r as string),\n )\n : filteredStep.schema.required;\n }\n return filteredStep;\n };\n\n const steps = props.steps\n .filter(step => {\n const featureFlag = step.schema[featureFlagKey];\n return (\n typeof featureFlag !== 'string' || featureFlagApi.isActive(featureFlag)\n );\n })\n .map(filterOutProperties);\n\n const handleReset = () => {\n setActiveStep(0);\n onReset();\n };\n const handleNext = () => {\n setActiveStep(Math.min(activeStep + 1, steps.length));\n };\n const handleBack = () => setActiveStep(Math.max(activeStep - 1, 0));\n const handleCreate = async () => {\n setDisableButtons(true);\n try {\n await onFinish();\n } catch (err) {\n setDisableButtons(false);\n errorApi.post(err);\n }\n };\n\n return (\n <>\n <Stepper activeStep={activeStep} orientation=\"vertical\">\n {steps.map(({ title, schema, ...formProps }, index) => {\n return (\n <StepUI key={title}>\n <StepLabel\n aria-label={`Step ${index + 1} ${title}`}\n aria-disabled=\"false\"\n tabIndex={0}\n >\n <Typography variant=\"h6\" component=\"h3\">\n {title}\n </Typography>\n </StepLabel>\n <StepContent key={title}>\n <Form\n showErrorList={false}\n fields={{ ...fieldOverrides, ...fields }}\n widgets={widgets}\n noHtml5Validate\n formData={formData}\n onChange={onChange}\n onSubmit={e => {\n if (e.errors.length === 0) handleNext();\n }}\n {...formProps}\n {...transformSchemaToProps(schema)}\n >\n <Button disabled={activeStep === 0} onClick={handleBack}>\n Back\n </Button>\n <Button variant=\"contained\" color=\"primary\" type=\"submit\">\n Next step\n </Button>\n </Form>\n </StepContent>\n </StepUI>\n );\n })}\n </Stepper>\n {activeStep === steps.length && (\n <Content>\n <Paper square elevation={0}>\n <Typography variant=\"h6\">Review and create</Typography>\n <StructuredMetadataTable\n dense\n metadata={getReviewData(formData, steps)}\n />\n <Box mb={4} />\n <Button onClick={handleBack} disabled={disableButtons}>\n Back\n </Button>\n <Button onClick={handleReset} disabled={disableButtons}>\n Reset\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={handleCreate}\n disabled={disableButtons}\n >\n Create\n </Button>\n </Paper>\n </Content>\n )}\n </>\n );\n};\n","/*\n * Copyright 2020 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 { JsonObject, JsonValue } from '@backstage/types';\nimport { LinearProgress } from '@material-ui/core';\nimport { FormValidation, IChangeEvent } from '@rjsf/core';\nimport qs from 'qs';\nimport React, { useCallback, useContext, useState } from 'react';\nimport { generatePath, Navigate, useNavigate } from 'react-router';\nimport { useParams } from 'react-router-dom';\nimport useAsync from 'react-use/lib/useAsync';\nimport { scaffolderApiRef } from '../../api';\nimport { CustomFieldValidator, FieldExtensionOptions } from '../../extensions';\nimport { SecretsContext } from '../secrets/SecretsContext';\nimport { rootRouteRef } from '../../routes';\nimport { MultistepJsonForm } from '../MultistepJsonForm';\n\nimport {\n Content,\n Header,\n InfoCard,\n Lifecycle,\n Page,\n} from '@backstage/core-components';\nimport {\n ApiHolder,\n errorApiRef,\n useApi,\n useApiHolder,\n useRouteRef,\n} from '@backstage/core-plugin-api';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\n\nconst useTemplateParameterSchema = (templateRef: string) => {\n const scaffolderApi = useApi(scaffolderApiRef);\n const { value, loading, error } = useAsync(\n () => scaffolderApi.getTemplateParameterSchema(templateRef),\n [scaffolderApi, templateRef],\n );\n return { schema: value, loading, error };\n};\n\nfunction isObject(obj: unknown): obj is JsonObject {\n return typeof obj === 'object' && obj !== null && !Array.isArray(obj);\n}\n\nexport const createValidator = (\n rootSchema: JsonObject,\n validators: Record<string, undefined | CustomFieldValidator<unknown>>,\n context: {\n apiHolder: ApiHolder;\n },\n) => {\n function validate(\n schema: JsonObject,\n formData: JsonObject,\n errors: FormValidation,\n ) {\n const schemaProps = schema.properties;\n if (!isObject(schemaProps)) {\n return;\n }\n\n for (const [key, propData] of Object.entries(formData)) {\n const propValidation = errors[key];\n\n if (isObject(propData)) {\n const propSchemaProps = schemaProps[key];\n if (isObject(propSchemaProps)) {\n validate(\n propSchemaProps,\n propData as JsonObject,\n propValidation as FormValidation,\n );\n }\n } else {\n const propSchema = schemaProps[key];\n const fieldName =\n isObject(propSchema) && (propSchema['ui:field'] as string);\n if (fieldName && typeof validators[fieldName] === 'function') {\n validators[fieldName]!(\n propData as JsonValue,\n propValidation,\n context,\n );\n }\n }\n }\n }\n\n return (formData: JsonObject, errors: FormValidation) => {\n validate(rootSchema, formData, errors);\n return errors;\n };\n};\n\nexport const TemplatePage = ({\n customFieldExtensions = [],\n}: {\n customFieldExtensions?: FieldExtensionOptions[];\n}) => {\n const apiHolder = useApiHolder();\n const secretsContext = useContext(SecretsContext);\n const errorApi = useApi(errorApiRef);\n const scaffolderApi = useApi(scaffolderApiRef);\n const { templateName } = useParams();\n const navigate = useNavigate();\n const rootLink = useRouteRef(rootRouteRef);\n const { schema, loading, error } = useTemplateParameterSchema(templateName);\n const [formState, setFormState] = useState<Record<string, any>>(() => {\n const query = qs.parse(window.location.search, {\n ignoreQueryPrefix: true,\n });\n\n try {\n return JSON.parse(query.formData as string);\n } catch (e) {\n return query.formData ?? {};\n }\n });\n const handleFormReset = () => setFormState({});\n const handleChange = useCallback(\n (e: IChangeEvent) => setFormState(e.formData),\n [setFormState],\n );\n\n const handleCreate = async () => {\n const { taskId } = await scaffolderApi.scaffold({\n templateRef: stringifyEntityRef({\n name: templateName,\n kind: 'template',\n namespace: 'default',\n }),\n values: formState,\n secrets: secretsContext?.secrets,\n });\n\n const formParams = qs.stringify(\n { formData: formState },\n { addQueryPrefix: true },\n );\n const newUrl = `${window.location.pathname}${formParams}`;\n // We use direct history manipulation since useSearchParams and\n // useNavigate in react-router-dom cause unnecessary extra rerenders.\n // Also make sure to replace the state rather than pushing to avoid\n // extra back/forward slots.\n window.history?.replaceState(null, document.title, newUrl);\n\n navigate(generatePath(`${rootLink()}/tasks/:taskId`, { taskId }));\n };\n\n if (error) {\n errorApi.post(new Error(`Failed to load template, ${error}`));\n return <Navigate to={rootLink()} />;\n }\n if (!loading && !schema) {\n errorApi.post(new Error('Template was not found.'));\n return <Navigate to={rootLink()} />;\n }\n\n const customFieldComponents = Object.fromEntries(\n customFieldExtensions.map(({ name, component }) => [name, component]),\n );\n\n const customFieldValidators = Object.fromEntries(\n customFieldExtensions.map(({ name, validation }) => [name, validation]),\n );\n\n return (\n <Page themeId=\"home\">\n <Header\n pageTitleOverride=\"Create a New Component\"\n title={\n <>\n Create a New Component <Lifecycle shorthand />\n </>\n }\n subtitle=\"Create new software components using standard templates\"\n />\n <Content>\n {loading && <LinearProgress data-testid=\"loading-progress\" />}\n {schema && (\n <InfoCard\n title={schema.title}\n noPadding\n titleTypographyProps={{ component: 'h2' }}\n >\n <MultistepJsonForm\n formData={formState}\n fields={customFieldComponents}\n onChange={handleChange}\n onReset={handleFormReset}\n onFinish={handleCreate}\n steps={schema.steps.map(step => {\n return {\n ...step,\n validate: createValidator(\n step.schema,\n customFieldValidators,\n { apiHolder },\n ),\n };\n })}\n />\n </InfoCard>\n )}\n </Content>\n </Page>\n );\n};\n","/*\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 React from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport { scaffolderApiRef } from '../../api';\nimport {\n Typography,\n Paper,\n Table,\n TableBody,\n Box,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n makeStyles,\n} from '@material-ui/core';\nimport { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport classNames from 'classnames';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n Progress,\n Content,\n Header,\n Page,\n ErrorPage,\n} from '@backstage/core-components';\n\nconst useStyles = makeStyles(theme => ({\n code: {\n fontFamily: 'Menlo, monospace',\n padding: theme.spacing(1),\n backgroundColor:\n theme.palette.type === 'dark'\n ? theme.palette.grey[700]\n : theme.palette.grey[300],\n display: 'inline-block',\n borderRadius: 5,\n border: `1px solid ${theme.palette.grey[500]}`,\n position: 'relative',\n },\n\n codeRequired: {\n '&::after': {\n position: 'absolute',\n content: '\"*\"',\n top: 0,\n right: theme.spacing(0.5),\n fontWeight: 'bolder',\n color: theme.palette.error.light,\n },\n },\n}));\n\nexport const ActionsPage = () => {\n const api = useApi(scaffolderApiRef);\n const classes = useStyles();\n const { loading, value, error } = useAsync(async () => {\n return api.listActions();\n });\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return (\n <ErrorPage\n statusMessage=\"Failed to load installed actions\"\n status=\"500\"\n />\n );\n }\n\n const formatRows = (input: JSONSchema7) => {\n const properties = input.properties;\n if (!properties) {\n return undefined;\n }\n\n return Object.entries(properties).map(entry => {\n const [key] = entry;\n const props = entry[1] as unknown as JSONSchema7;\n const codeClassname = classNames(classes.code, {\n [classes.codeRequired]: input.required?.includes(key),\n });\n\n return (\n <TableRow key={key}>\n <TableCell>\n <div className={codeClassname}>{key}</div>\n </TableCell>\n <TableCell>{props.title}</TableCell>\n <TableCell>{props.description}</TableCell>\n <TableCell>\n <span className={classes.code}>{props.type}</span>\n </TableCell>\n </TableRow>\n );\n });\n };\n\n const renderTable = (input: JSONSchema7) => {\n if (!input.properties) {\n return undefined;\n }\n return (\n <TableContainer component={Paper}>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>Title</TableCell>\n <TableCell>Description</TableCell>\n <TableCell>Type</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>{formatRows(input)}</TableBody>\n </Table>\n </TableContainer>\n );\n };\n\n const renderTables = (name: string, input?: JSONSchema7Definition[]) => {\n if (!input) {\n return undefined;\n }\n\n return (\n <>\n <Typography variant=\"h6\">{name}</Typography>\n {input.map((i, index) => (\n <div key={index}>{renderTable(i as unknown as JSONSchema7)}</div>\n ))}\n </>\n );\n };\n\n const items = value?.map(action => {\n if (action.id.startsWith('legacy:')) {\n return undefined;\n }\n\n const oneOf = renderTables('oneOf', action.schema?.input?.oneOf);\n return (\n <Box pb={4} key={action.id}>\n <Typography variant=\"h4\" className={classes.code}>\n {action.id}\n </Typography>\n <Typography>{action.description}</Typography>\n {action.schema?.input && (\n <Box pb={2}>\n <Typography variant=\"h5\">Input</Typography>\n {renderTable(action.schema.input)}\n {oneOf}\n </Box>\n )}\n {action.schema?.output && (\n <Box pb={2}>\n <Typography variant=\"h5\">Output</Typography>\n {renderTable(action.schema.output)}\n </Box>\n )}\n </Box>\n );\n });\n\n return (\n <Page themeId=\"home\">\n <Header\n pageTitleOverride=\"Create a New Component\"\n title=\"Installed actions\"\n subtitle=\"This is the collection of all installed actions\"\n />\n <Content>{items}</Content>\n </Page>\n );\n};\n","/*\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 React, { ComponentType } from 'react';\nimport { Routes, Route, useOutlet } from 'react-router';\nimport { Entity } from '@backstage/catalog-model';\nimport { TemplateEntityV1beta2 } from '@backstage/plugin-scaffolder-common';\nimport { ScaffolderPage } from './ScaffolderPage';\nimport { TemplatePage } from './TemplatePage';\nimport { TaskPage } from './TaskPage';\nimport { ActionsPage } from './ActionsPage';\nimport { SecretsContextProvider } from './secrets/SecretsContext';\n\nimport {\n FieldExtensionOptions,\n FIELD_EXTENSION_WRAPPER_KEY,\n FIELD_EXTENSION_KEY,\n DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS,\n} from '../extensions';\nimport { useElementFilter } from '@backstage/core-plugin-api';\n\ntype RouterProps = {\n TemplateCardComponent?:\n | ComponentType<{ template: TemplateEntityV1beta2 }>\n | undefined;\n TaskPageComponent?: ComponentType<{}>;\n groups?: Array<{\n title?: string;\n titleComponent?: React.ReactNode;\n filter: (entity: Entity) => boolean;\n }>;\n};\n\nexport const Router = ({\n TemplateCardComponent,\n TaskPageComponent,\n groups,\n}: RouterProps) => {\n const outlet = useOutlet();\n const TaskPageElement = TaskPageComponent || TaskPage;\n\n const customFieldExtensions = useElementFilter(outlet, elements =>\n elements\n .selectByComponentData({\n key: FIELD_EXTENSION_WRAPPER_KEY,\n })\n .findComponentData<FieldExtensionOptions>({\n key: FIELD_EXTENSION_KEY,\n }),\n );\n\n const fieldExtensions = [\n ...customFieldExtensions,\n ...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(\n ({ name }) =>\n !customFieldExtensions.some(\n customFieldExtension => customFieldExtension.name === name,\n ),\n ),\n ];\n\n return (\n <Routes>\n <Route\n path=\"/\"\n element={\n <ScaffolderPage\n TemplateCardComponent={TemplateCardComponent}\n groups={groups}\n />\n }\n />\n <Route\n path=\"/templates/:templateName\"\n element={\n <SecretsContextProvider>\n <TemplatePage customFieldExtensions={fieldExtensions} />\n </SecretsContextProvider>\n }\n />\n <Route path=\"/tasks/:taskId\" element={<TaskPageElement />} />\n <Route path=\"/actions\" element={<ActionsPage />} />\n </Routes>\n );\n};\n"],"names":["useStyles","isObject","MuiTheme","StepUI"],"mappings":"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"}
|