Skip to content

Commit b88e8dd

Browse files
feat(Bulk import): bulk import UI improvements (#1695)
* Bulk import UI improvements * Hide Import Instructions section * Added Missing Configuration page if integration is not added * Disabled import checkbox for Waiting for PR pPR approval status also * fix(bulk-import): Fix sidebar icon visibility in light theme * Updated status values for scaffolder flow * feat(bulk-import): Hide status column * Revert "feat(bulk-import): Hide status column" This reverts commit 44b6eab. * feat(bulk-import): Show info bar for pull request flow, hide for scaffolder * feat: update bulk import sidebar icon to rotated Material Symbols publish icon * fix: hide instructions section when integrations are missing and update text * fix: resolve browser tab title showing [object Object] * fix: prevent status column shifting with fixed percentage widths' * refactor: replace useAsync with useQuery and implement granular invalidation --------- Co-authored-by: Mitesh Kumar <itsmiteshkumar98@gmail.com>
1 parent f66ba99 commit b88e8dd

42 files changed

Lines changed: 1184 additions & 817 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-bulk-import': minor
3+
---
4+
5+
Improve bulk import UI consistency and user experience
6+
7+
- Ensure "Bulk import" navigation in left sidebar takes users directly to Import page
8+
- Hide source control tool radio buttons when only one provider is configured
9+
- Remove Repository/Organization toggle buttons from Import page
10+
- Update empty state message for better user guidance
11+
- Show "Import to Red Hat Developer Hub" info bar for pull request flow, hide for scaffolder flow
12+
- Show "Choose a source control tool" step only when multiple approval tools are configured
13+
- Added "Missing Configuration" page that displays when no GitHub or GitLab integrations are configured
14+
- Show "Ready to import" instead of "Not generated" status in scaffolder flow
15+
- Remove "Preview file" button for selected repositories in scaffolder flow
16+
- Fix task status display to show status text + separate "View task" button

workspaces/bulk-import/plugins/bulk-import/report-alpha.api.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ readonly "table.headers.url": string;
1616
readonly "table.headers.repoUrl": string;
1717
readonly "table.headers.organizationGroup": string;
1818
readonly "table.headers.group": string;
19+
readonly "table.headers.taskStatus": string;
1920
readonly "table.headers.lastUpdated": string;
2021
readonly "table.headers.actions": string;
2122
readonly "table.headers.catalogInfoYaml": string;
@@ -32,11 +33,17 @@ readonly "status.alreadyImported": string;
3233
readonly "status.added": string;
3334
readonly "status.waitingForApproval": string;
3435
readonly "status.imported": string;
36+
readonly "status.readyToImport": string;
37+
readonly "status.waitingForPullRequestToStart": string;
38+
readonly "status.missingConfigurations": string;
39+
readonly "status.failedCreatingPR": string;
40+
readonly "status.pullRequestRejected": string;
3541
readonly "repositories.addedRepositories": string;
3642
readonly "repositories.importedEntities": string;
3743
readonly "repositories.addedRepositoriesCount": string;
3844
readonly "repositories.importedEntitiesCount": string;
3945
readonly "repositories.noRecordsFound": string;
46+
readonly "repositories.noProjectsFound": string;
4047
readonly "repositories.refresh": string;
4148
readonly "repositories.import": string;
4249
readonly "repositories.removing": string;
@@ -74,6 +81,8 @@ readonly "errors.catalogEntityConflict": string;
7481
readonly "errors.repoEmpty": string;
7582
readonly "errors.codeOwnersNotFound": string;
7683
readonly "errors.errorOccurred": string;
84+
readonly "errors.noIntegrationsConfigured": string;
85+
readonly "errors.addIntegrationsToConfig": string;
7786
readonly "validation.componentNameInvalid": string;
7887
readonly "validation.componentNameRequired": string;
7988
readonly "validation.entityOwnerRequired": string;
@@ -112,7 +121,6 @@ readonly "addRepositories.selectedCount": string;
112121
readonly "addRepositories.addSelected": string;
113122
readonly "addRepositories.preview": string;
114123
readonly "catalogInfo.status.generating": string;
115-
readonly "catalogInfo.status.notGenerated": string;
116124
readonly "common.select": string;
117125
readonly "common.filter": string;
118126
readonly "common.view": string;
@@ -121,13 +129,13 @@ readonly "common.add": string;
121129
readonly "common.cancel": string;
122130
readonly "common.close": string;
123131
readonly "common.delete": string;
132+
readonly "common.documentation": string;
124133
readonly "common.edit": string;
125134
readonly "common.remove": string;
126135
readonly "common.save": string;
127136
readonly "common.update": string;
128137
readonly "previewFile.preview": string;
129138
readonly "previewFile.previewFile": string;
130-
readonly "previewFile.readyToImport": string;
131139
readonly "previewFile.previewFiles": string;
132140
readonly "previewFile.failedToCreatePR": string;
133141
readonly "previewFile.prCreationUnsuccessful": string;
@@ -164,6 +172,7 @@ readonly "forms.footer.createServiceNowTicket": string;
164172
readonly "forms.footer.createServiceNowTickets": string;
165173
readonly "forms.footer.createPullRequest": string;
166174
readonly "forms.footer.createPullRequests": string;
175+
readonly "forms.footer.selectRepositoryTooltip": string;
167176
readonly "forms.footer.serviceNowTooltip": string;
168177
readonly "forms.footer.importTooltip": string;
169178
readonly "forms.footer.pullRequestTooltip": string;

workspaces/bulk-import/plugins/bulk-import/src/components/AddRepositories/AddRepositories.tsx

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,47 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { CodeSnippet, Link } from '@backstage/core-components';
18+
import { configApiRef, useApi } from '@backstage/core-plugin-api';
19+
20+
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
1721
import Alert from '@mui/material/Alert';
1822
import AlertTitle from '@mui/material/AlertTitle';
23+
import Box from '@mui/material/Box';
1924
import FormControl from '@mui/material/FormControl';
25+
import Typography from '@mui/material/Typography';
2026
import { useFormikContext } from 'formik';
2127

2228
import { useTranslation } from '../../hooks/useTranslation';
2329
import { AddRepositoriesFormValues, PullRequestPreviewData } from '../../types';
30+
import { getImageForIconClass } from '../../utils/icons';
2431
import { useDrawer } from '../DrawerContext';
2532
import { PreviewFileSidebar } from '../PreviewFile/PreviewFileSidebar';
2633
import { AddRepositoriesFormFooter } from './AddRepositoriesFormFooter';
2734
import { AddRepositoriesTable } from './AddRepositoriesTable';
2835

29-
export const AddRepositories = ({ error }: { error: any }) => {
36+
export const AddRepositories = ({ error }: { error?: any }) => {
3037
const { t } = useTranslation();
38+
const configApi = useApi(configApiRef);
3139
const { openDrawer, setOpenDrawer, drawerData } = useDrawer();
3240
const { setFieldValue, values } =
3341
useFormikContext<AddRepositoriesFormValues>();
42+
43+
// Check if integrations are configured
44+
const hasGitHubIntegration = configApi.has('integrations.github');
45+
const hasGitLabIntegration = configApi.has('integrations.gitlab');
46+
const hasMissingIntegrations = !hasGitHubIntegration && !hasGitLabIntegration;
47+
48+
// Parse error message if it exists and is valid JSON
49+
const errorMessage = (() => {
50+
try {
51+
return error?.error?.message ? JSON.parse(error.error.message) : null;
52+
} catch {
53+
// If parsing fails, return null and use the raw error message
54+
return null;
55+
}
56+
})();
57+
3458
const closeDrawer = () => {
3559
setOpenDrawer(false);
3660
};
@@ -45,7 +69,96 @@ export const AddRepositories = ({ error }: { error: any }) => {
4569
setOpenDrawer(false);
4670
};
4771

48-
const errorMessage = error?.error?.message && JSON.parse(error.error.message);
72+
// Show missing configuration page if no integrations are configured
73+
if (hasMissingIntegrations) {
74+
return (
75+
<Box
76+
sx={{ display: 'flex', minHeight: '50vh', padding: 3, paddingLeft: 6 }}
77+
>
78+
<Box sx={{ flex: 0.8, pr: 2, pt: 8, pl: 3 }}>
79+
<Box sx={{ mb: 2, pt: 12 }}>
80+
<Typography
81+
variant="h3"
82+
component="h1"
83+
sx={{
84+
fontSize: '2rem',
85+
fontWeight: 400,
86+
margin: '0 0 1rem 0',
87+
}}
88+
>
89+
{t('status.missingConfigurations')}
90+
</Typography>
91+
<Typography
92+
variant="body1"
93+
sx={{
94+
lineHeight: '1.5',
95+
margin: '0 0 1rem 0',
96+
}}
97+
>
98+
{t('errors.noIntegrationsConfigured')}
99+
</Typography>
100+
<Typography
101+
variant="body1"
102+
sx={{
103+
lineHeight: '1.5',
104+
margin: '0 0 2rem 0',
105+
}}
106+
>
107+
{t('errors.addIntegrationsToConfig')}
108+
</Typography>
109+
<CodeSnippet
110+
text={`integrations:
111+
github:
112+
- host: github.com
113+
token: \${GITHUB_TOKEN}
114+
# or
115+
gitlab:
116+
- host: gitlab.com
117+
token: \${GITLAB_TOKEN}`}
118+
language="yaml"
119+
showCopyCodeButton
120+
customStyle={{
121+
marginBottom: '1rem',
122+
fontSize: '0.875rem',
123+
}}
124+
/>
125+
<Link
126+
to="https://backstage.io/docs/integrations/#configuration"
127+
target="_blank"
128+
rel="noopener noreferrer"
129+
>
130+
{t('common.documentation')}
131+
<OpenInNewIcon
132+
style={{ verticalAlign: 'sub', paddingTop: '7px' }}
133+
/>
134+
</Link>
135+
</Box>
136+
</Box>
137+
138+
<Box
139+
sx={{
140+
flex: 1,
141+
display: 'flex',
142+
justifyContent: 'center',
143+
alignItems: 'center',
144+
}}
145+
>
146+
<img
147+
src={getImageForIconClass('missing-configuration')}
148+
alt="Missing configuration"
149+
style={{
150+
maxWidth: '100%',
151+
maxHeight: '100%',
152+
width: 'auto',
153+
height: 'auto',
154+
opacity: 0.8,
155+
objectFit: 'contain',
156+
}}
157+
/>
158+
</Box>
159+
</Box>
160+
);
161+
}
49162

50163
return (
51164
<>
@@ -62,9 +175,12 @@ export const AddRepositories = ({ error }: { error: any }) => {
62175
<AlertTitle>
63176
{errorMessage?.error?.name ??
64177
error?.error?.name ??
178+
error?.name ??
65179
t('errors.errorOccurred')}
66180
</AlertTitle>
67181
{errorMessage?.error?.message ??
182+
error?.error?.message ??
183+
error?.message ??
68184
error?.err ??
69185
t('errors.failedToCreatePullRequest')}
70186
</Alert>

0 commit comments

Comments
 (0)