forked from debezium/debezium-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DBZ-3696 Addition of Topic Groups to UI (debezium#396)
* DBZ-3696 Addition of Topic Groups * Add Topic Group Options section * using common name field and updates * Displays alert when topic creation feature disabled * Update card css, response flags * Utilize backend service
- Loading branch information
Showing
20 changed files
with
1,227 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
{ | ||
"defaults": [ | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": -1, | ||
"description": "Topic Replication Factor default value", | ||
"displayName": "Topic Replication Factor default", | ||
"isMandatory": false, | ||
"name": "topic.creation.default.replication.factor", | ||
"type": "INT" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": -1, | ||
"description": "Topic Partitions default value", | ||
"displayName": "Topic Partitions default", | ||
"isMandatory": false, | ||
"name": "topic.creation.default.partitions", | ||
"type": "INT" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": "delete", | ||
"allowedValues": ["compact", "delete"], | ||
"description": "Topic Cleanup Policy default value", | ||
"displayName": "Topic Cleanup Policy default", | ||
"isMandatory": false, | ||
"name": "topic.creation.default.cleanup.policy", | ||
"type": "STRING" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": "producer", | ||
"allowedValues": ["uncompressed", "zstd", "lz4", "snappy", "gzip", "producer"], | ||
"description": "Topic Compression Type default value", | ||
"displayName": "Topic Compression Type default", | ||
"isMandatory": false, | ||
"name": "topic.creation.default.compression.type", | ||
"type": "STRING" | ||
} | ||
], | ||
"groups": { | ||
"properties": [ | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"description": "Topic Creation Groups", | ||
"displayName": "Topic Creation Groups", | ||
"isMandatory": false, | ||
"name": "topic.creation.groups", | ||
"type": "STRING" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"description": "Topic Group includes", | ||
"displayName": "Topic includes", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).include", | ||
"type": "STRING" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"description": "Topic Group excludes", | ||
"displayName": "Topic excludes", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).exclude", | ||
"type": "STRING" | ||
} | ||
], | ||
"options": [ | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": -1, | ||
"description": "Topic Replication Factor value", | ||
"displayName": "Topic Replication Factor", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).replication.factor", | ||
"type": "INT" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": -1, | ||
"description": "Topic Partitions value", | ||
"displayName": "Topic Partitions", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).partitions", | ||
"type": "INT" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": "delete", | ||
"allowedValues": ["compact", "delete"], | ||
"description": "Topic Cleanup Policy value", | ||
"displayName": "Topic Cleanup Policy", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).cleanup.policy", | ||
"type": "STRING" | ||
}, | ||
{ | ||
"category": "TOPIC_CREATION", | ||
"defaultValue": "producer", | ||
"allowedValues": ["uncompressed", "zstd", "lz4", "snappy", "gzip", "producer"], | ||
"description": "Topic Compression Type value", | ||
"displayName": "Topic Compression Type", | ||
"isMandatory": false, | ||
"name": "topic.creation.(.+).compression.type", | ||
"type": "STRING" | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
ui/packages/ui/src/app/components/topicCreationHelpers/TopicDefaults.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { Form, Grid, GridItem } from '@patternfly/react-core'; | ||
import React from 'react'; | ||
import { FormComponent } from 'components'; | ||
import { Formik, useFormikContext } from 'formik'; | ||
import * as Yup from 'yup'; | ||
import _ from 'lodash'; | ||
import { formatPropertyDefinitions } from 'shared'; | ||
|
||
export interface ITopicDefaultsProps { | ||
topicDefaultProperties: any[]; | ||
topicDefaultValues?: any; | ||
updateTopicDefaults: (value: any) => void; | ||
setIsTopicCreationDirty: (data: boolean) => void; | ||
} | ||
|
||
const FormSubmit: React.FunctionComponent<any> = React.forwardRef((props, ref) => { | ||
const { dirty, submitForm, validateForm } = useFormikContext(); | ||
|
||
React.useImperativeHandle(ref, () => ({ | ||
validate() { | ||
validateForm(); | ||
submitForm(); | ||
} | ||
})); | ||
React.useEffect(() => { | ||
if (dirty) { | ||
props.setIsTopicCreationDirty(true); | ||
} | ||
}, [dirty]); | ||
return null; | ||
}); | ||
|
||
export const TopicDefaults: React.FunctionComponent<any> = React.forwardRef((props, ref) => { | ||
const getInitialValues = (properties: any) => { | ||
const combinedValues: any = {}; | ||
|
||
for (const prop of properties) { | ||
if (!combinedValues[prop.name]) { | ||
if (_.isEmpty(props.topicDefaultValues) || props.topicDefaultValues[prop.name] === undefined) { | ||
prop.defaultValue === undefined | ||
? (combinedValues[prop.name] = prop.type === 'INT' || prop.type === 'LONG' ? 0 : '') | ||
: (combinedValues[prop.name] = prop.defaultValue); | ||
} else { | ||
combinedValues[prop.name] = props.topicDefaultValues[prop.name]; | ||
} | ||
} | ||
} | ||
return combinedValues; | ||
}; | ||
|
||
const propList = formatPropertyDefinitions(props.topicDefaultProperties); | ||
|
||
const initialValues = getInitialValues(propList); | ||
|
||
const basicValidationSchema = {}; | ||
|
||
const topicDefaultList = [...propList]; | ||
|
||
topicDefaultList.map((key: any) => { | ||
if (key.type === 'STRING') { | ||
basicValidationSchema[key.name] = Yup.string(); | ||
} else if (key.type === 'PASSWORD') { | ||
basicValidationSchema[key.name] = Yup.string(); | ||
} else if (key.type === 'INT') { | ||
basicValidationSchema[key.name] = Yup.string(); | ||
} | ||
if (key.isMandatory) { | ||
basicValidationSchema[key.name] = basicValidationSchema[key.name].required(`${key.name} required`); | ||
} | ||
}); | ||
const validationSchema = Yup.object().shape({ ...basicValidationSchema }); | ||
|
||
const handleSubmit = (value: any) => { | ||
const newValues = {}; | ||
for (const prop of props.topicDefaultProperties) { | ||
const newValue = (prop.type === 'INT' || prop.type === 'LONG' || | ||
prop.type === 'NON-NEG-INT' || prop.type === 'NON-NEG-LONG' || | ||
prop.type === 'POS-INT') ? Number(value[prop.name]) : value[prop.name]; | ||
if (!prop.defaultValue || newValue !== prop.defaultValue) { | ||
newValues[prop.name] = newValue; | ||
} | ||
} | ||
props.updateTopicDefaults(newValues); | ||
props.setIsTopicCreationDirty(false); | ||
}; | ||
return ( | ||
<> | ||
<Formik | ||
initialValues={initialValues} | ||
validationSchema={validationSchema} | ||
onSubmit={values => { | ||
handleSubmit(values); | ||
}} | ||
enableReinitialize={true} | ||
> | ||
{({ errors, touched, setFieldValue }) => ( | ||
<Form className="pf-c-form"> | ||
<Grid hasGutter={true}> | ||
{propList.map((prop, index) => { | ||
return ( | ||
<GridItem key={index} lg={prop.gridWidthLg} sm={prop.gridWidthSm}> | ||
<FormComponent | ||
propertyDefinition={prop} | ||
// tslint:disable-next-line: no-empty | ||
propertyChange={() => {}} | ||
setFieldValue={setFieldValue} | ||
helperTextInvalid={errors[prop.name]} | ||
invalidMsg={[]} | ||
validated={errors[prop.name] && touched[prop.name] ? 'error' : 'default'} | ||
// tslint:disable-next-line: no-empty | ||
clearValidationError={() => {}} | ||
/> | ||
</GridItem> | ||
); | ||
})} | ||
</Grid> | ||
<FormSubmit ref={ref} setIsTopicCreationDirty={props.setIsTopicCreationDirty} /> | ||
</Form> | ||
)} | ||
</Formik> | ||
</> | ||
); | ||
}); |
5 changes: 5 additions & 0 deletions
5
ui/packages/ui/src/app/components/topicCreationHelpers/TopicGroupCard.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.topic-group-block { | ||
padding: 5px 0px 0px 5px; | ||
border: 1px solid var(--pf-global--BorderColor--100); | ||
border-radius: 5px; | ||
} |
91 changes: 91 additions & 0 deletions
91
ui/packages/ui/src/app/components/topicCreationHelpers/TopicGroupCard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { | ||
Button, | ||
Form, | ||
Grid, | ||
GridItem, | ||
Split, | ||
SplitItem, | ||
Title | ||
} from '@patternfly/react-core'; | ||
import { TrashIcon } from '@patternfly/react-icons'; | ||
import React from 'react'; | ||
import { NameInputField, TopicGroupConfig } from 'components'; | ||
import _ from 'lodash'; | ||
import { getFormattedTopicCreationProperties } from 'shared'; | ||
import { useTranslation } from 'react-i18next'; | ||
import './TopicGroupCard.css'; | ||
|
||
export interface ITopicGroupCardProps { | ||
topicGroupNo: number; | ||
topicGroupName: string; | ||
topicGroupNameList: string[]; | ||
topicGroupConfig: any; | ||
deleteTopicGroup: (order: number) => void; | ||
updateTopicGroup: (key: number, field: string, value: any) => void; | ||
topicGroupsData: any; | ||
topicGroupOptionsData: any; | ||
setIsTopicCreationDirty: (data: boolean) => void; | ||
} | ||
|
||
export const TopicGroupCard: React.FunctionComponent<any> = React.forwardRef((props, ref) => { | ||
const { t } = useTranslation(); | ||
const [nameIsValid, setNameIsValid] = React.useState<boolean>(true); | ||
|
||
const deleteCard = () => { | ||
props.deleteTopicGroup(props.topicGroupNo); | ||
}; | ||
|
||
const updateName = (value: string, field?: string) => { | ||
if (field) { | ||
value === '' || props.topicGroupNameList.includes(value) ? setNameIsValid(false) : setNameIsValid(true); | ||
props.updateTopicGroup(props.topicGroupNo, 'name', value); | ||
} | ||
}; | ||
|
||
return ( | ||
<Grid> | ||
<GridItem span={12}> | ||
<div className={'topic-group-block pf-u-mt-lg pf-u-p-sm pf-u-pb-lg'} id="topic-group-parent"> | ||
<Split> | ||
<SplitItem isFilled={true}> | ||
<Title headingLevel="h2"> | ||
Topic Group # {props.topicGroupNo} | ||
</Title> | ||
<Form> | ||
<Grid hasGutter={true}> | ||
<GridItem span={4}> | ||
<NameInputField | ||
label="Name" | ||
description="" | ||
fieldId="topic_group_name" | ||
isRequired={true} | ||
name="topic_group_name" | ||
placeholder="Name" | ||
inputType="text" | ||
value={props.topicGroupName} | ||
setFieldValue={updateName} | ||
isInvalid={!nameIsValid} | ||
invalidText={props.topicGroupName ? t('uniqueName') : t('nameRequired')} | ||
/> | ||
</GridItem> | ||
</Grid> | ||
</Form> | ||
<TopicGroupConfig | ||
ref={ref} | ||
topicGroupNo={props.topicGroupNo} | ||
topicGroupConfigProperties={getFormattedTopicCreationProperties(props.topicGroupsData)} | ||
topicGroupConfigValues={props.topicGroupConfig} | ||
topicGroupOptionProperties={getFormattedTopicCreationProperties(props.topicGroupOptionsData)} | ||
updateTopicGroup={props.updateTopicGroup} | ||
setIsTopicCreationDirty={props.setIsTopicCreationDirty} | ||
/> | ||
</SplitItem> | ||
<SplitItem> | ||
<Button variant="link" icon={<TrashIcon />} onClick={deleteCard} id='tooltip-selector' /> | ||
</SplitItem> | ||
</Split> | ||
</div> | ||
</GridItem> | ||
</Grid> | ||
); | ||
}); |
6 changes: 6 additions & 0 deletions
6
ui/packages/ui/src/app/components/topicCreationHelpers/TopicGroupConfig.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.topic-group-option-block { | ||
margin-left: 20px; | ||
padding: 5px 0px 0px 5px; | ||
border: 1px dashed var(--pf-global--BorderColor--100); | ||
border-radius: 5px; | ||
} |
Oops, something went wrong.