Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 6 additions & 30 deletions apps/portal/examples/advanced-template/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,14 @@ spec:
type: string
description: The name of the repository (e.g. my-service)

# --- UPDATED DATABASE CONFIGURATION STEP ---
- title: Database Configuration
properties:
requireDatabase:
title: Add Database
type: boolean
description: Check to provision a database for this project
default: false
dependencies:
requireDatabase:
oneOf:
- properties:
requireDatabase:
const: false
- properties:
requireDatabase:
const: true
databaseType:
title: Database Type
type: string
enum: [postgres]
default: postgres
databaseName:
title: Database Name
type: string
description: The name of the database to create
databaseVersion:
title: Database Version
type: string
description: Select the PostgreSQL version
enum: ['13', '14', '15', '16']
default: '15'
required: [databaseType, databaseName, databaseVersion]
databaseConfig:
title: Database Settings
type: object
ui:field: DatabasePicker
# --- END OF NEW STEP ---

- title: Repository & Webhook
required:
Expand Down
13 changes: 8 additions & 5 deletions apps/portal/packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { RequirePermission } from '@backstage/plugin-permission-react';
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
import { NotificationsPage } from '@backstage/plugin-notifications';
import { SignalsDisplay } from '@backstage/plugin-signals';
import { ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder-react';
import { DatabasePickerExtension } from './scaffolder';

const app = createApp({
Expand Down Expand Up @@ -96,11 +97,13 @@ const routes = (
<ReportIssue />
</TechDocsAddons>
</Route>
<Route path="/create" element={<ScaffolderPage />}>
{scaffolderFieldExtensions.map(Extension => (
<Extension key={Extension.name} />
))}
</Route>
<Route path="/create" element={
<ScaffolderPage>
<ScaffolderFieldExtensions>
<DatabasePickerExtension />
</ScaffolderFieldExtensions>
</ScaffolderPage>
} />
<Route path="/api-docs" element={<ApiExplorerPage />} />
<Route
path="/catalog-import"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,61 @@
import React from 'react';
import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react';
import { FormControl, InputLabel, Select, MenuItem, TextField } from '@material-ui/core';

// Define the exact state structure expected by PhuocHoan's CUE schema
interface DatabaseConfig {
dbType: string;
dbName?: string;
}

export const DatabasePicker = ({
onChange,
rawErrors,
required,
formData,
uiSchema,
schema,
formContext,
}: FieldExtensionComponentProps<string>) => {
// Todo: Implementation
return <></>;
};
}: FieldExtensionComponentProps<DatabaseConfig>) => {
// Default to 'none' if no data is present
const dbType = formData?.dbType || 'none';
const dbName = formData?.dbName || '';

const handleTypeChange = (event: React.ChangeEvent<{ value: unknown }>) => {
const newType = event.target.value as string;
onChange({
dbType: newType,
// Clear the dbName if they switch back to "No Database"
...(newType === 'postgres' ? { dbName: dbName } : { dbName: '' }),
});
};

const handleNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange({
dbType,
dbName: event.target.value,
});
};

return (
<div>
<FormControl fullWidth required={required} margin="normal">
<InputLabel>Database Type</InputLabel>
<Select value={dbType} onChange={handleTypeChange}>
<MenuItem value="none">No Database</MenuItem>
<MenuItem value="postgres">PostgreSQL</MenuItem>
</Select>
</FormControl>

{dbType === 'postgres' && (
<TextField
label="Database Name"
value={dbName}
onChange={handleNameChange}
fullWidth
margin="normal"
required
helperText="The name of the database to create (e.g., my_custom_db)"
error={rawErrors?.length > 0 && !dbName}
/>
)}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
import { createScaffolderFieldExtension } from '@backstage/plugin-scaffolder-react';
import { DatabasePicker } from './DatabasePicker';

export const DatabasePickerExtension = scaffolderPlugin.provide(
export const DatabasePickerExtension: any = scaffolderPlugin.provide(
createScaffolderFieldExtension({
name: 'DatabasePicker',
component: DatabasePicker,
validation: (value, validation, context) => {
// Todo: Implement validation logic
validation: (value: any, validation: any) => {
// Custom validation: If postgres is selected, dbName MUST be provided
if (value?.dbType === 'postgres') {
if (!value?.dbName) {
validation.addError('Database Name is required when PostgreSQL is selected');
}
}
},
}),
);
);
2 changes: 1 addition & 1 deletion apps/portal/packages/app/src/scaffolder/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './DatabasePickerExtension/index';
export { DatabasePickerExtension } from './DatabasePickerExtension/extension';