From 9bd0dbb67dac513fc1806e15bd19e6aaaa795612 Mon Sep 17 00:00:00 2001 From: Shailesh Parmar Date: Sat, 12 Nov 2022 19:23:52 +0530 Subject: [PATCH] Fixed Add Partition Setting in UI for Profiler #8624 (#8673) * Fixed Add Partition Setting in UI for Profiler #8624 * addressing comments --- .../Component/ProfilerSettingsModal.tsx | 275 +++++++++++++++--- .../ui/src/constants/profiler.constant.ts | 27 +- .../ui/src/locale/languages/en-us.json | 17 +- .../main/resources/ui/src/styles/spacing.less | 3 + 4 files changed, 275 insertions(+), 47 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ProfilerSettingsModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ProfilerSettingsModal.tsx index ab6aee6e3ed..c335a3ba728 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ProfilerSettingsModal.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/Component/ProfilerSettingsModal.tsx @@ -12,14 +12,23 @@ */ import { PlusOutlined } from '@ant-design/icons'; -import { Button, InputNumber, Modal, Select, Slider, TreeSelect } from 'antd'; +import { + Button, + InputNumber, + Modal, + Select, + Slider, + Space, + Switch, + TreeSelect, +} from 'antd'; import Form from 'antd/lib/form'; import { List } from 'antd/lib/form/Form'; import { Col, Row } from 'antd/lib/grid'; import { AxiosError } from 'axios'; import classNames from 'classnames'; import 'codemirror/addon/fold/foldgutter.css'; -import { isEmpty, isEqual, isUndefined, startCase } from 'lodash'; +import { isEmpty, isEqual, isUndefined, omit, startCase } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { Controlled as CodeMirror } from 'react-codemirror2'; import { useTranslation } from 'react-i18next'; @@ -30,10 +39,14 @@ import { import { codeMirrorOption, DEFAULT_INCLUDE_PROFILE, + INTERVAL_TYPE_OPTIONS, + INTERVAL_UNIT_OPTIONS, PROFILER_METRIC, + SUPPORTED_PARTITION_TYPE, } from '../../../constants/profiler.constant'; import { ColumnProfilerConfig, + PartitionProfilerConfig, TableProfilerConfig, } from '../../../generated/entity/data/table'; import jsonData from '../../../jsons/en'; @@ -59,6 +72,9 @@ const ProfilerSettingsModal: React.FC = ({ ); const [isLoading, setIsLoading] = useState(false); + const [enablePartition, setEnablePartition] = useState(false); + const [partitionData, setPartitionData] = useState(); + const selectOptions = useMemo(() => { return columns.map(({ name }) => ({ label: name, @@ -82,8 +98,30 @@ const ProfilerSettingsModal: React.FC = ({ return metricsOptions; }, [columns]); + const { partitionColumnOptions, isPartitionDisabled } = useMemo(() => { + const partitionColumnOptions = columns.reduce((result, column) => { + if (SUPPORTED_PARTITION_TYPE.includes(column.dataType)) { + return [ + ...result, + { + value: column.name, + label: column.name, + }, + ]; + } + + return result; + }, [] as { value: string; label: string }[]); + const isPartitionDisabled = partitionColumnOptions.length === 0; + + return { + partitionColumnOptions, + isPartitionDisabled, + }; + }, [columns]); + const updateInitialConfig = (tableProfilerConfig: TableProfilerConfig) => { - const { includeColumns } = tableProfilerConfig; + const { includeColumns, partitioning } = tableProfilerConfig; setSqlQuery(tableProfilerConfig.profileQuery || ''); setProfileSample(tableProfilerConfig.profileSample || 100); setExcludeCol(tableProfilerConfig.excludeColumns || []); @@ -101,6 +139,10 @@ const ProfilerSettingsModal: React.FC = ({ form.setFieldsValue({ includeColumns: includeColValue }); setIncludeCol(includeColValue); } + if (partitioning) { + setEnablePartition(partitioning.enablePartitioning || false); + form.setFieldsValue({ ...partitioning }); + } }; const fetchProfileConfig = async () => { @@ -151,8 +193,13 @@ const ProfilerSettingsModal: React.FC = ({ includeColumns: !isEqual(includeCol, DEFAULT_INCLUDE_PROFILE) ? getIncludesColumns() : undefined, + partitioning: enablePartition + ? { + ...partitionData, + enablePartitioning: enablePartition, + } + : undefined, }; - try { const data = await putTableProfileConfig(tableId, profileConfig); if (data) { @@ -186,6 +233,10 @@ const ProfilerSettingsModal: React.FC = ({ = ({ confirmLoading={isLoading} data-testid="profiler-settings-modal" maskClosable={false} + okButtonProps={{ + form: 'profiler-setting-form', + htmlType: 'submit', + }} okText={t('label.save')} title={t('label.settings')} visible={visible} width={630} - onCancel={handleCancel} - onOk={handleSave}> + onCancel={handleCancel}>

{t('label.profile-sample-percentage')}

@@ -271,13 +325,17 @@ const ProfilerSettingsModal: React.FC = ({
{ setIncludeCol(data.includeColumns); + setPartitionData(omit(data, 'includeColumns')); }}> {(fields, { add, remove }) => ( @@ -296,53 +354,182 @@ const ProfilerSettingsModal: React.FC = ({
1, + 'tw-max-h-40 tw-overflow-y-auto': includeCol.length > 1, })} data-testid="include-column-container"> {fields.map(({ key, name, ...restField }) => ( -
- - - } - type="text" - onClick={() => remove(name)} - /> -
+ + + + + + +
)}
+ + +

{t('label.enable-partition')}

+ setEnablePartition(value)} + /> +
+
+ + + {t('label.column-name')} + } + labelCol={{ + style: { + paddingBottom: 8, + }, + }} + name="partitionColumnName" + rules={[ + { + required: isPartitionDisabled || enablePartition, + message: t('message.column-name-required'), + }, + ]}> + + + + + {t('label.interval')}} + labelCol={{ + style: { + paddingBottom: 8, + }, + }} + name="partitionInterval" + rules={[ + { + required: isPartitionDisabled || enablePartition, + message: t('message.interval-required'), + }, + ]}> + + + + + {t('label.interval-unit')} + } + labelCol={{ + style: { + paddingBottom: 8, + }, + }} + name="partitionIntervalUnit" + rules={[ + { + required: isPartitionDisabled || enablePartition, + message: t('message.interval-unit-required'), + }, + ]}> +