Skip to content

Commit

Permalink
sync role for !IS_COMMUNITY && is_superadmin
Browse files Browse the repository at this point in the history
  • Loading branch information
himdel committed Dec 17, 2023
1 parent 4ca7493 commit cdf2823
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export { ImportAPI } from './import';
export { LegacyImportAPI } from './legacy-import';
export { LegacyNamespaceAPI } from './legacy-namespace';
export { LegacyRoleAPI } from './legacy-role';
export { LegacySyncAPI } from './legacy-sync';
export { MyDistributionAPI } from './my-distribution';
export { MyNamespaceAPI } from './my-namespace';
export { MySyncListAPI } from './my-synclist';
Expand Down
11 changes: 11 additions & 0 deletions src/api/legacy-sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { LegacyAPI } from './legacy';

export class API extends LegacyAPI {
apiPath = 'v1/sync/';

sync(data) {
return this.http.post(this.apiPath, data);
}
}

export const LegacySyncAPI = new API();
10 changes: 9 additions & 1 deletion src/components/ansible-role/role-import-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const RoleImportForm = ({ addAlert }: IProps) => {
Object.fromEntries(Object.entries(o).filter(([_k, v]) => v));

const onCancel = () => navigate(formatPath(Paths.standaloneRoles));

const onSaved = ({
data: {
results: [{ pulp_id }],
Expand All @@ -91,7 +92,8 @@ export const RoleImportForm = ({ addAlert }: IProps) => {
data.github_repo &&
`https://github.com/${data.github_user}/${data.github_repo}`;

const anyErrors = !!errors || requiredFields.some((k) => !data[k]);
const anyErrors =
!!Object.keys(errors || {}).length || requiredFields.some((k) => !data[k]);

const formSuffix = (
<>
Expand All @@ -116,6 +118,12 @@ export const RoleImportForm = ({ addAlert }: IProps) => {
const updateField = (k, v) => {
setData((data) => ({ ...data, [k]: v }));

setErrors((errors) => {
const e = { ...errors };
delete e[k];
return e;
});

if (requiredFields.includes(k) && !v) {
setErrors((errors) => ({ ...errors, [k]: t`Field is required.` }));
}
Expand Down
92 changes: 92 additions & 0 deletions src/components/ansible-role/role-sync-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Trans, t } from '@lingui/macro';
import { ActionGroup, Button } from '@patternfly/react-core';
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { LegacySyncAPI } from 'src/api';
import { AlertType, DataForm, ExternalLink } from 'src/components';
import { Paths, formatPath } from 'src/paths';
import { ErrorMessagesType, handleHttpError, taskAlert } from 'src/utilities';

interface IProps {
addAlert: (alert: AlertType) => void;
}

export const RoleSyncForm = ({ addAlert }: IProps) => {
const [data, setData] = useState<{
github_user: string;
role_name: string;
}>({ github_user: '', role_name: '' });
const [errors, setErrors] = useState<ErrorMessagesType>(null);
const navigate = useNavigate();

const formFields = [
{ id: 'github_user', title: t`GitHub user` },
{ id: 'role_name', title: t`Role name` },
];

const requiredFields = ['github_user', 'role_name'];

const onCancel = () => navigate(formatPath(Paths.standaloneRoles));

const onSaved = ({ data: { pulp_id } }) =>
addAlert(taskAlert(pulp_id, t`Sync started`));

const onSave = () =>
LegacySyncAPI.sync(data)
.then(onSaved)
.catch(handleHttpError(t`Failed to sync role`, null, addAlert));

const link =
data.github_user &&
data.role_name &&
`https://galaxy.ansible.com/ui/standalone/roles/${data.github_user}/${data.role_name}/`;

const anyErrors =
!!Object.keys(errors || {}).length || requiredFields.some((k) => !data[k]);

const formSuffix = (
<>
{link ? (
<div>
<Trans>
Will sync <ExternalLink href={link}>{link}</ExternalLink>
</Trans>
</div>
) : null}
<ActionGroup key='actions'>
<Button type='submit' isDisabled={anyErrors}>
{t`Sync`}
</Button>
<Button onClick={onCancel} variant='link'>
{t`Cancel`}
</Button>
</ActionGroup>
</>
);

const updateField = (k, v) => {
setData((data) => ({ ...data, [k]: v }));

setErrors((errors) => {
const e = { ...errors };
delete e[k];
return e;
});

if (requiredFields.includes(k) && !v) {
setErrors((errors) => ({ ...errors, [k]: t`Field is required.` }));
}
};

return (
<DataForm
errorMessages={errors || {}}
formFields={formFields}
formSuffix={formSuffix}
model={data}
requiredFields={requiredFields}
updateField={(v, e) => updateField(e.target.id, v)}
onSave={onSave}
/>
);
};
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { RoleImportForm } from './ansible-role/role-import-form';
export { LegacyRoleListItem } from './ansible-role/role-item';
export { RoleNamespaceEditModal } from './ansible-role/role-namespace-edit-modal';
export { RoleNamespaceModal } from './ansible-role/role-namespace-modal';
export { RoleSyncForm } from './ansible-role/role-sync-form';
export { ApprovalRow } from './approval/approval-row';
export { ApproveModal } from './approval/approve-modal';
export { CardListSwitcher } from './card-list-switcher/card-list-switcher';
Expand Down
9 changes: 9 additions & 0 deletions src/containers/ansible-role/role-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class AnsibleRoleList extends React.Component<RouteProps, RolesState> {
);

const canImport = user && !user.is_anonymous;
const canSync = user?.is_superuser && !IS_COMMUNITY;

return (
<div>
Expand All @@ -184,6 +185,14 @@ class AnsibleRoleList extends React.Component<RouteProps, RolesState> {
}
>{t`Import role`}</Button>
),
canSync && (
<Button
key='sync'
onClick={() =>
this.props.navigate(formatPath(Paths.standaloneRoleSync))
}
>{t`Sync role`}</Button>
),
].filter(Boolean)}
count={count}
filterConfig={filterConfig}
Expand Down
54 changes: 54 additions & 0 deletions src/containers/ansible-role/role-sync.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { t } from '@lingui/macro';
import React from 'react';
import {
AlertList,
AlertType,
BaseHeader,
Main,
RoleSyncForm,
closeAlertMixin,
} from 'src/components';
import { RouteProps, withRouter } from 'src/utilities';

interface RoleState {
alerts: AlertType[];
}

class AnsibleRoleSync extends React.Component<RouteProps, RoleState> {
constructor(props) {
super(props);
this.state = {
alerts: [],
};
}

private addAlert(alert: AlertType) {
this.setState({
alerts: [...this.state.alerts, alert],
});
}

private get closeAlert() {
return closeAlertMixin('alerts');
}

render() {
const { alerts } = this.state;
const addAlert = (alert) => this.addAlert(alert);
const closeAlert = (i) => this.closeAlert(i);

return (
<>
<AlertList alerts={alerts} closeAlert={closeAlert} />
<BaseHeader title={t`Sync role`} />
<Main>
<section className='body'>
<RoleSyncForm addAlert={addAlert} />
</section>
</Main>
</>
);
}
}

export default withRouter(AnsibleRoleSync);
1 change: 1 addition & 0 deletions src/containers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as AnsibleRoleNamespaceList } from './ansible-role/namespace-li
export { default as AnsibleRoleDetail } from './ansible-role/role-detail';
export { default as AnsibleRoleImport } from './ansible-role/role-import';
export { default as AnsibleRoleList } from './ansible-role/role-list';
export { default as AnsibleRoleSync } from './ansible-role/role-sync';
export { default as CertificationDashboard } from './certification-dashboard/certification-dashboard';
export { default as CollectionContent } from './collection-detail/collection-content';
export { default as CollectionDependencies } from './collection-detail/collection-dependencies';
Expand Down
2 changes: 2 additions & 0 deletions src/loaders/standalone/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
AnsibleRoleList,
AnsibleRoleNamespaceDetail,
AnsibleRoleNamespaceList,
AnsibleRoleSync,
CertificationDashboard,
CollectionContent,
CollectionDependencies,
Expand Down Expand Up @@ -218,6 +219,7 @@ export class StandaloneRoutes extends React.Component<IRoutesProps> {
{ component: AnsibleRoleNamespaceList, path: Paths.standaloneNamespaces },
{ component: AnsibleRoleDetail, path: Paths.standaloneRole },
{ component: AnsibleRoleImport, path: Paths.standaloneRoleImport },
{ component: AnsibleRoleSync, path: Paths.standaloneRoleSync },
{ component: AnsibleRoleList, path: Paths.standaloneRoles },
{
component: TaskListView,
Expand Down
1 change: 1 addition & 0 deletions src/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export enum Paths {
landingPage = '/',
standaloneRole = '/standalone/roles/:namespace/:name/:tab?',
standaloneRoleImport = '/standalone/roles/import',
standaloneRoleSync = '/standalone/roles/sync',
standaloneRoles = '/standalone/roles',
standaloneNamespace = '/standalone/namespaces/:namespaceid',
standaloneNamespaces = '/standalone/namespaces',
Expand Down

0 comments on commit cdf2823

Please sign in to comment.