Skip to content

Commit

Permalink
feat: adds support tp move sink for eventSource
Browse files Browse the repository at this point in the history
  • Loading branch information
invincibleJai committed Mar 31, 2020
1 parent 87db3e7 commit f37ecef
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ interface ResourceDropdownProps {
selectedKey: string;
autoSelect?: boolean;
resourceFilter?: (resource: K8sResourceKind) => boolean;
onChange?: (key: string, name?: string, isListEmpty?: boolean) => void;
onChange?: (key: string, name?: string | object, isListEmpty?: boolean) => void;
onLoad?: (items: { [key: string]: string }) => void;
showBadge?: boolean;
autocompleteFilter?: (strText: string, item: object) => boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface ResourceDropdownFieldProps extends DropdownFieldProps {
resources: FirehoseResource[];
showBadge?: boolean;
onLoad?: (items: { [key: string]: string }) => void;
onChange?: (key: string, name?: string | object) => void;
resourceFilter?: (resource: K8sResourceKind) => boolean;
autoSelect?: boolean;
placeholder?: string;
Expand Down Expand Up @@ -55,8 +56,8 @@ const ResourceDropdownField: React.FC<ResourceDropdownFieldProps> = ({
dropDownClassName={cx({ 'dropdown--full-width': fullWidth })}
onLoad={onLoad}
resourceFilter={resourceFilter}
onChange={(value: string) => {
props.onChange && props.onChange(value);
onChange={(value: string, name) => {
props.onChange && props.onChange(value, name);
setFieldValue(props.name, value);
setFieldTouched(props.name, true);
}}
Expand Down
20 changes: 20 additions & 0 deletions frontend/packages/knative-plugin/src/actions/sink-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { KebabOption } from '@console/internal/components/utils';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { setSinkSourceModal } from '../components/modals';

export const setSinkSource = (model: K8sKind, obj: K8sResourceKind): KebabOption => {
return {
label: 'Move Sink',
callback: () =>
setSinkSourceModal({
obj,
}),
accessReview: {
group: model.apiGroup,
resource: model.plural,
name: obj.metadata.name,
namespace: obj.metadata.namespace,
verb: 'update',
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ export const setTrafficDistributionModal = (props) =>
import(
'../traffic-splitting/TrafficSplittingController' /* webpackChunkName: "set-traffic-splitting" */
).then((m) => m.trafficModalLauncher(props));

export const setSinkSourceModal = (props) =>
import('../sink-source/SinkSourceController' /* webpackChunkName: "sink-source" */).then((m) =>
m.sinkModalLauncher(props),
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as React from 'react';
import { Formik, FormikValues, FormikHelpers } from 'formik';
import { K8sResourceKind, k8sUpdate, referenceFor, modelFor } from '@console/internal/module/k8s';
import SinkSourceModal from './SinkSourceModal';

export interface SinkSourceProps {
source: K8sResourceKind;
cancel?: () => void;
close?: () => void;
}

const SinkSource: React.FC<SinkSourceProps> = ({ source, cancel, close }) => {
const {
metadata: { namespace, name },
spec: {
sink: {
ref: { name: sinkName },
},
},
} = source;

const initialValues = {
sink: {
ref: {
apiVersion: '',
kind: '',
name: sinkName || '',
},
},
};
const handleSubmit = (values: FormikValues, action: FormikHelpers<FormikValues>) => {
const updatePayload = {
...source,
spec: { ...source.spec, ...values },
};
k8sUpdate(modelFor(referenceFor(source)), updatePayload)
.then(() => {
action.setSubmitting(false);
action.setStatus({ error: '' });
close();
})
.catch((err) => {
action.setStatus({ error: err.message || 'An error occurred. Please try again' });
});
};

return (
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
onReset={cancel}
initialStatus={{ error: '' }}
>
{(props) => (
<SinkSourceModal {...props} namespace={namespace} resourceName={name} cancel={cancel} />
)}
</Formik>
);
};

export default SinkSource;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { K8sResourceKind } from '@console/internal/module/k8s';
import { createModalLauncher, ModalComponentProps } from '@console/internal/components/factory';
import SinkSource from './SinkSource';

type SinkSourceControllerProps = {
obj: K8sResourceKind;
};

const SinkSourceController: React.FC<SinkSourceControllerProps> = (props) => {
const { obj } = props;
return <SinkSource {...props} source={obj} />;
};

type Props = SinkSourceControllerProps & ModalComponentProps;

export const sinkModalLauncher = createModalLauncher<Props>(SinkSourceController);

export default SinkSourceController;
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as React from 'react';
import * as fuzzy from 'fuzzysearch';
import { FormikProps, FormikValues } from 'formik';
import {
ModalTitle,
ModalBody,
ModalSubmitFooter,
} from '@console/internal/components/factory/modal';
import { ResourceDropdownField } from '@console/shared';
import FormSection from '@console/dev-console/src/components/import/section/FormSection';
import { knativeServingResourcesServices } from '../../utils/create-knative-utils';

export interface SinkSourceModalProps {
namespace: string;
resourceName: string;
cancel?: () => void;
}

type Props = FormikProps<FormikValues> & SinkSourceModalProps;

const SinkSourceModal: React.FC<Props> = ({
namespace,
resourceName,
handleSubmit,
cancel,
isSubmitting,
status,
setFieldValue,
setFieldTouched,
validateForm,
values,
}) => {
const autocompleteFilter = (strText, item): boolean => fuzzy(strText, item?.props?.name);
const onSinkChange = React.useCallback(
(selectedValue, target) => {
const {
props: { model },
} = target;
if (selectedValue) {
setFieldTouched('sink.ref.name', true);
setFieldValue('sink.ref.name', selectedValue);
if (model) {
const sinkApiversion = `${model?.apiGroup}/${model?.apiVersion}`;
setFieldValue('sink.ref.apiVersion', sinkApiversion);
setFieldTouched('sink.ref.apiVersion', true);
setFieldValue('sink.ref.kind', model?.kind);
setFieldTouched('sink.ref.kind', true);
}
validateForm();
}
},
[setFieldValue, setFieldTouched, validateForm],
);
return (
<form className="modal-content modal-content--no-inner-scroll" onSubmit={handleSubmit}>
<ModalTitle>Move Sink</ModalTitle>
<ModalBody>
<p>
Select a sink to move the event source
<strong>{` ${resourceName} `}</strong>
to
</p>
<FormSection fullWidth>
<ResourceDropdownField
name="sink.ref.name"
resources={knativeServingResourcesServices(namespace)}
dataSelector={['metadata', 'name']}
fullWidth
required
placeholder="Select a sink"
showBadge
autocompleteFilter={autocompleteFilter}
onChange={onSinkChange}
autoSelect
selectedKey={values.sink.ref.name}
/>
</FormSection>
</ModalBody>
<ModalSubmitFooter
inProgress={isSubmitting}
submitText="Save"
cancel={cancel}
errorMessage={status.error}
/>
</form>
);
};

export default SinkSourceModal;
8 changes: 6 additions & 2 deletions frontend/packages/knative-plugin/src/utils/kebab-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
EditApplication,
} from '@console/dev-console/src/actions/modify-application';
import { setTrafficDistribution } from '../actions/traffic-splitting';
import { setSinkSource } from '../actions/sink-source';
import {
EventSourceApiServerModel,
EventSourceCamelModel,
Expand All @@ -16,15 +17,15 @@ import {
ServiceModel,
} from '../models';

const modifyApplicationRefs = [
const eventSourceModelrefs = [
referenceForModel(EventSourceApiServerModel),
referenceForModel(EventSourceContainerModel),
referenceForModel(EventSourceCronJobModel),
referenceForModel(EventSourceCamelModel),
referenceForModel(EventSourceKafkaModel),
referenceForModel(EventSourceSinkBindingModel),
referenceForModel(ServiceModel),
];
const modifyApplicationRefs = [...eventSourceModelrefs, referenceForModel(ServiceModel)];

export const getKebabActionsForKind = (resourceKind: K8sKind): KebabAction[] => {
const menuActions: KebabAction[] = [];
Expand All @@ -35,6 +36,9 @@ export const getKebabActionsForKind = (resourceKind: K8sKind): KebabAction[] =>
if (referenceForModel(resourceKind) === referenceForModel(ServiceModel)) {
menuActions.push(setTrafficDistribution, EditApplication);
}
if (_.includes(eventSourceModelrefs, referenceForModel(resourceKind))) {
menuActions.push(setSinkSource, EditApplication);
}
}
return menuActions;
};

0 comments on commit f37ecef

Please sign in to comment.