From 83ebc358083ac9bd044695f5e0a5c83ff539a9bd Mon Sep 17 00:00:00 2001 From: balaji-jr Date: Tue, 14 May 2024 15:21:52 +0530 Subject: [PATCH 1/3] added custom partition field to the form --- src/pages/Home/CreateStreamModal.tsx | 74 ++++++++++++++++++++++++++- src/pages/Home/index.tsx | 8 +-- src/pages/Home/styles/Home.module.css | 15 ++++++ 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/pages/Home/CreateStreamModal.tsx b/src/pages/Home/CreateStreamModal.tsx index 0f9961f6..0a6d26ee 100644 --- a/src/pages/Home/CreateStreamModal.tsx +++ b/src/pages/Home/CreateStreamModal.tsx @@ -6,6 +6,7 @@ import { Modal, Select, Stack, + TagsInput, Text, TextInput, ThemeIcon, @@ -98,7 +99,8 @@ const AddFieldButton = ({ onClick }: { onClick: () => void }) => { } - onClick={onClick}> + onClick={onClick} + style={{ padding: 12, fontSize: '0.8rem' }}> Add Field @@ -176,6 +178,49 @@ const PartitionField = (props: { ); }; +const CustomPartitionField = (props: { + partitionFields: string[]; + onChangeValue: (key: string, field: string[]) => void; + isStaticSchema: boolean; + error: string; + value: string[]; +}) => { + const shouldDisable = _.isEmpty(props.partitionFields); + + return ( + + + + Custom Partition Field + + + + + Upto 3 columns + + props.onChangeValue('customPartitionFields', val)} + maxTags={3} + error={props.error} + /> + + ); +}; + type FieldType = { data_type: string; name: string; @@ -197,6 +242,7 @@ const useCreateStreamForm = () => { fields: [defaultFieldValue], schemaType: dynamicType, partitionField: defaultPartitionField, + customPartitionFields: [], }, validate: { name: (value) => isValidStreamName(value), @@ -217,6 +263,15 @@ const useCreateStreamForm = () => { return schemaType === staticType && !_.includes(allStringFieldNames, val) ? 'Unknown Field' : null; }, schemaType: (val) => (_.includes([dynamicType, staticType], val) ? null : 'Choose either Dynamic or Static'), + customPartitionFields: (val, allValues) => { + if (_.isEmpty(val) || allValues.schemaType !== staticType) { + return null; + } else { + const allFieldNames = _.map(allValues.fields, (field) => field.name); + const invalidColumnNames = _.difference(val, allFieldNames); + return !_.isEmpty(invalidColumnNames) ? 'Unknown Field Included' : null; + } + }, }, validateInputOnChange: true, validateInputOnBlur: true, @@ -238,6 +293,7 @@ const useCreateStreamForm = () => { const onChangeValue = useCallback((key: string, value: any) => { form.setFieldValue(key, value); + form.validateField(key); }, []); return { form, onAddField, onRemoveField, onChangeValue }; @@ -248,6 +304,12 @@ const CreateStreamForm = (props: { toggleModal: () => void }) => { const stringFields = getStringFieldNames(form.values.fields); const isStaticSchema = form.values.schemaType === staticType; const partitionFields = [defaultPartitionField, ...(isStaticSchema ? stringFields : [])]; + const customPartitionFields = !isStaticSchema + ? [] + : _.chain(form.values.fields) + .map((field) => field.name) + .compact() + .value(); const { createLogStreamMutation } = useLogStream(); const { getLogStreamListRefetch } = useLogStream(); const onSuccessCallback = useCallback(() => { @@ -257,13 +319,14 @@ const CreateStreamForm = (props: { toggleModal: () => void }) => { const onSubmit = useCallback(() => { const { hasErrors } = form.validate(); - const { schemaType, fields, partitionField } = form.values; + const { schemaType, fields, partitionField, customPartitionFields } = form.values; const isStatic = schemaType === staticType; if (hasErrors || (isStatic && _.isEmpty(fields))) return; const headers = { ...(partitionField !== defaultPartitionField ? { 'X-P-Time-Partition': partitionField } : {}), ...(isStatic ? { 'X-P-Static-Schema-Flag': true } : {}), + ...(_.isEmpty(customPartitionFields) ? {} : { 'X-P-Custom-Partition': _.join(customPartitionFields, ',') }), }; const schmaFields = isStatic ? fields : {}; createLogStreamMutation({ @@ -305,6 +368,13 @@ const CreateStreamForm = (props: { toggleModal: () => void }) => { value={form.values.partitionField} error={_.toString(form.errors.partitionField)} /> + diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 2ffc2eff..bba92ad7 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -36,11 +36,11 @@ const EmptyStreamsView: FC = () => { const Home: FC = () => { useDocumentTitle('Parseable | Streams'); const classes = homeStyles; - const { container } = classes; + const { container, createStreamButton } = classes; const navigate = useNavigate(); const { getStreamMetadata, metaData } = useGetStreamMetadata(); const [userSpecificStreams, setAppStore] = useAppStore((store) => store.userSpecificStreams); - const [userAccessMap] = useAppStore((store) => store.userAccessMap); + const [userAccessMap] = useAppStore((store) => store.userAccessMap); useEffect(() => { if (!Array.isArray(userSpecificStreams) || userSpecificStreams.length === 0) return; @@ -54,7 +54,7 @@ const Home: FC = () => { const displayEmptyPlaceholder = Array.isArray(userSpecificStreams) && userSpecificStreams.length === 0; const openCreateStreamModal = useCallback(() => { - setAppStore(store => toggleCreateStreamModal(store)) + setAppStore((store) => toggleCreateStreamModal(store)); }, []); return ( @@ -74,7 +74,7 @@ const Home: FC = () => { {userAccessMap.hasCreateStreamAccess && (