Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f958c5f
refactor: KeyValueTable - refactor component to use DynamicDataTable
RohitRaj011 Apr 11, 2025
fcf245a
refactor: update CMCS to use KeyValueTableData type instead of CMSecr…
RohitRaj011 Apr 11, 2025
d1589d6
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-l…
RohitRaj011 Apr 11, 2025
0e8816c
fix: KeyValueTable - fix sorting logic
RohitRaj011 Apr 15, 2025
a63823e
refactor: update FormType to use KeyValueTableData for args
RohitRaj011 Apr 21, 2025
a86a48e
refactor: KeyValueTable - move methods to utils and code optimization…
RohitRaj011 Apr 21, 2025
2007b0f
feat: add ConditionDetails interface and related error handling types
RohitRaj011 Apr 21, 2025
638af5a
fix: update error handling in DynamicDataTableRow for SelectPicker an…
RohitRaj011 Apr 21, 2025
3376c4b
refactor: types refactor
RohitRaj011 Apr 23, 2025
756104b
feat: add addBtnTooltip prop to DynamicDataTableHeader for customizab…
RohitRaj011 Apr 24, 2025
87c64be
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-l…
RohitRaj011 Apr 25, 2025
2090a19
chore(version): bump to 1.11.0-beta-10
RohitRaj011 Apr 25, 2025
453427d
feat: KeyValueTable - implement sorting functionality
RohitRaj011 Apr 28, 2025
96d1b4d
chore(version): bump to 1.12.0-beta-3
RohitRaj011 Apr 28, 2025
0ccf6ea
refactor: KeyValueTable - optimize sorting logic and improve performance
RohitRaj011 Apr 29, 2025
4950b1e
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-l…
RohitRaj011 Apr 29, 2025
39a264e
chore(version): bump to 1.12.0-pre-1
RohitRaj011 Apr 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 22 additions & 16 deletions src/Common/CIPipeline.Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { DynamicDataTableCellValidationState } from '@Shared/Components'
import { DynamicDataTableCellValidationState, KeyValueTableData } from '@Shared/Components'

export interface MaterialType {
name: string
Expand Down Expand Up @@ -158,7 +158,7 @@ export interface PortMapType {
portOnLocal: number
portOnContainer: number
}
interface ConditionDetails {
export interface ConditionDetails {
Comment thread
vivek-devtron marked this conversation as resolved.
id: number
conditionOnVariable: string
conditionOperator: string
Expand Down Expand Up @@ -266,7 +266,7 @@ export enum WORKFLOW_CACHE_CONFIG_ENUM {

export interface FormType {
name: string
args: { key: string; value: string }[]
args: KeyValueTableData[]
materials: MaterialType[]
gitHost: Githost
webhookEvents: WebhookEvent[]
Expand Down Expand Up @@ -314,23 +314,29 @@ export enum InputOutputVariablesHeaderKeys {
VALUE = 'val',
}

export type InputOutputVariablesErrorObj = Record<InputOutputVariablesHeaderKeys, DynamicDataTableCellValidationState>
export enum ConditionDataTableHeaderKeys {
VARIABLE = 'variable',
OPERATOR = 'operator',
VALUE = 'val',
}

type InputOutputVariablesErrorObj = Record<InputOutputVariablesHeaderKeys, DynamicDataTableCellValidationState>
type ConditionDetailsErrorObj = Record<ConditionDataTableHeaderKeys, DynamicDataTableCellValidationState>

interface StepDetailTaskErrorObj {
inputVariables?: Record<number, InputOutputVariablesErrorObj>
outputVariables?: Record<number, InputOutputVariablesErrorObj>
isInputVariablesValid?: boolean
isOutputVariablesValid?: boolean
conditionDetails?: Record<number, ConditionDetailsErrorObj>
isConditionDetailsValid?: boolean
}

export interface TaskErrorObj {
isValid: boolean
name: ErrorObj
inlineStepDetail?: {
inputVariables?: Record<number, InputOutputVariablesErrorObj>
outputVariables?: Record<number, InputOutputVariablesErrorObj>
isInputVariablesValid?: boolean
isOutputVariablesValid?: boolean
}
pluginRefStepDetail?: {
inputVariables?: Record<number, InputOutputVariablesErrorObj>
outputVariables?: Record<number, InputOutputVariablesErrorObj>
isInputVariablesValid?: boolean
isOutputVariablesValid?: boolean
}
inlineStepDetail?: StepDetailTaskErrorObj
pluginRefStepDetail?: StepDetailTaskErrorObj
}
export interface FormErrorObjectType {
name: ErrorObj
Expand Down
5 changes: 3 additions & 2 deletions src/Shared/Components/CMCS/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
* limitations under the License.
*/

import { CMSecretExternalType, CMSecretYamlData } from '@Shared/Services'
import { CMSecretExternalType } from '@Shared/Services'

import { KeyValueTableData } from '../KeyValueTable'
import { ConfigMapSecretDataTypeOptionType } from './types'

export const CONFIG_MAP_SECRET_YAML_PARSE_ERROR = 'Please provide valid YAML'
Expand All @@ -33,7 +34,7 @@ export const configMapDataTypeOptions: ConfigMapSecretDataTypeOptionType[] = [
{ value: CMSecretExternalType.KubernetesConfigMap, label: 'Kubernetes External ConfigMap' },
]

export const CONFIG_MAP_SECRET_DEFAULT_CURRENT_DATA: CMSecretYamlData[] = [{ k: '', v: '', id: 0 }]
export const CONFIG_MAP_SECRET_DEFAULT_CURRENT_DATA: KeyValueTableData[] = [{ key: '', value: '', id: 0 }]

export const configMapSecretMountDataMap = {
environment: { title: 'Environment Variable', value: 'environment' },
Expand Down
35 changes: 18 additions & 17 deletions src/Shared/Components/CMCS/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
CMSecretConfigData,
CMSecretExternalType,
CMSecretPayloadType,
CMSecretYamlData,
CODE_EDITOR_RADIO_STATE,
ConfigDatum,
ConfigMapSecretUseFormProps,
Expand All @@ -36,6 +35,7 @@ import {
} from '@Shared/Services'
import { hasESO, OverrideMergeStrategyType } from '@Pages/index'

import { KeyValueTableData } from '../KeyValueTable'
import { getSelectPickerOptionByValue } from '../SelectPicker'
import {
CONFIG_MAP_SECRET_DEFAULT_CURRENT_DATA,
Expand Down Expand Up @@ -93,7 +93,7 @@ export const getSecretDataTypeOptions = (
return isJob ? kubernetesOptions : [...kubernetesOptions, ...esoOptions, ...(isHashiOrAWS ? kesOptions : [])]
}

const secureValues = (data: Record<string, string>, decodeData: boolean): CMSecretYamlData[] => {
const secureValues = (data: Record<string, string>, decodeData: boolean): KeyValueTableData[] => {
let decodedData = data || DEFAULT_SECRET_PLACEHOLDER

if (decodeData) {
Expand All @@ -104,9 +104,9 @@ const secureValues = (data: Record<string, string>, decodeData: boolean): CMSecr
}
}

return Object.keys(decodedData).map((k, id) => ({
k,
v: typeof decodedData[k] === 'object' ? YAMLStringify(decodedData[k]) : decodedData[k],
return Object.keys(decodedData).map((key, id) => ({
key,
value: typeof decodedData[key] === 'object' ? YAMLStringify(decodedData[key]) : decodedData[key],
id,
}))
}
Expand Down Expand Up @@ -150,8 +150,8 @@ const processExternalSubPathValues = ({
return ''
}

export const convertKeyValuePairToYAML = (currentData: CMSecretYamlData[]) =>
currentData.length ? YAMLStringify(currentData.reduce((agg, { k, v }) => ({ ...agg, [k]: v }), {})) : ''
export const convertKeyValuePairToYAML = (currentData: KeyValueTableData[]) =>
currentData.length ? YAMLStringify(currentData.reduce((agg, { key, value }) => ({ ...agg, [key]: value }), {})) : ''

const getSecretDataFromConfigData = ({
secretData,
Expand Down Expand Up @@ -368,29 +368,30 @@ export const getConfigMapSecretReadOnlyValues = ({
? [
{
displayName: 'Keys',
value: currentData?.length > 0 ? currentData.map((d) => d.k).join(', ') : 'No keys available',
value:
currentData?.length > 0 ? currentData.map((d) => d.key).join(', ') : 'No keys available',
key: 'keys',
},
]
: []),
],
data: !mountExistingExternal ? (currentData?.[0]?.k && yaml) || esoSecretYaml || secretDataYaml : null,
data: !mountExistingExternal ? (currentData?.[0]?.key && yaml) || esoSecretYaml || secretDataYaml : null,
}
}

export const convertYAMLToKeyValuePair = (yaml: string): CMSecretYamlData[] => {
export const convertYAMLToKeyValuePair = (yaml: string): KeyValueTableData[] => {
try {
const obj = yaml && YAML.parse(yaml)
if (typeof obj !== 'object') {
throw new Error()
}
const keyValueArray: CMSecretYamlData[] = Object.keys(obj).reduce((agg, k, id) => {
if (!k && !obj[k]) {
const keyValueArray = Object.keys(obj).reduce<KeyValueTableData[]>((agg, key, id) => {
if (!key && !obj[key]) {
return CONFIG_MAP_SECRET_DEFAULT_CURRENT_DATA
}
const v = obj[k] && typeof obj[k] === 'object' ? YAMLStringify(obj[k]) : obj[k].toString()
const value = obj[key] && typeof obj[key] === 'object' ? YAMLStringify(obj[key]) : obj[key].toString()

return [...agg, { k, v: v ?? '', id }]
return [...agg, { key, value: value ?? '', id }]
}, [])
return keyValueArray
} catch {
Expand Down Expand Up @@ -449,14 +450,14 @@ export const getConfigMapSecretPayload = ({
const isESO = isSecret && hasESO(externalType)
const _currentData = yamlMode ? convertYAMLToKeyValuePair(yaml) : currentData
const data = _currentData.reduce((acc, curr) => {
if (!curr.k) {
if (!curr.key) {
return acc
}
const value = curr.v ?? ''
const value = curr.value ?? ''

return {
...acc,
[curr.k]: isSecret && externalType === '' ? btoa(value) : value,
[curr.key]: isSecret && externalType === '' ? btoa(value) : value,
}
}, {})

Expand Down
5 changes: 3 additions & 2 deletions src/Shared/Components/CMCS/validations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import YAML from 'yaml'
import { PATTERNS } from '@Common/Constants'
import { YAMLStringify } from '@Common/Helper'
import { UseFormValidation, UseFormValidations } from '@Shared/Hooks'
import { CMSecretExternalType, CMSecretYamlData, ConfigMapSecretUseFormProps } from '@Shared/Services'
import { CMSecretExternalType, ConfigMapSecretUseFormProps } from '@Shared/Services'
import { validateCMVolumeMountPath } from '@Shared/validations'
import { hasESO } from '@Pages/index'

import { KeyValueTableData } from '../KeyValueTable'
import { CONFIG_MAP_SECRET_YAML_PARSE_ERROR, SECRET_TOAST_INFO } from './constants'
import { getESOSecretDataFromYAML } from './utils'

Expand Down Expand Up @@ -310,7 +311,7 @@ export const getConfigMapSecretFormValidations: UseFormValidations<ConfigMapSecr
},
currentData: {
custom: {
isValid: (value: CMSecretYamlData[]) => !!value.filter(({ k }) => !!k).length,
isValid: (value: KeyValueTableData[]) => !!value.filter(({ key }) => !!key).length,
message: 'This is a required field',
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const DynamicDataTableHeader = <K extends string, CustomStateType = Recor
headers,
rows,
sortingConfig,
addBtnTooltip,
onRowAdd,
readOnly,
isAdditionNotAllowed,
Expand Down Expand Up @@ -89,12 +90,11 @@ export const DynamicDataTableHeader = <K extends string, CustomStateType = Recor
{shouldRenderAddRowButton && (
<Button
dataTestId="data-table-add-row-button"
ariaLabel="Add"
ariaLabel={addBtnTooltip}
onClick={onRowAdd}
icon={<ICAdd />}
variant={ButtonVariantType.borderLess}
size={ComponentSizeType.xs}
showAriaLabelInTippy={false}
/>
)}
{key === lastHeaderKey && headerComponent}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,18 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
? cellError[row.id][key]
: { isValid: true, errorMessages: [] }

const isSelectText = row.data[key].type === DynamicDataTableRowDataType.SELECT_TEXT
const isDropdown =
row.data[key].type === DynamicDataTableRowDataType.SELECT_TEXT ||
row.data[key].type === DynamicDataTableRowDataType.DROPDOWN

if (isValid) {
return null
}

// Adding 'no-error' class to hide error when SelectPickerTextArea is focused.
// Adding 'no-error' class to hide error when SelectPicker or SelectPickerTextArea is focused.
return (
<div
className={`dynamic-data-table__error bg__primary dc__border br-4 py-7 px-8 flexbox-col dc__gap-4 ${isSelectText ? 'no-error' : ''}`}
className={`dynamic-data-table__error bg__primary dc__border br-4 py-7 px-8 flexbox-col dc__gap-4 ${isDropdown ? 'no-error' : ''}`}
>
{errorMessages.map((error) => renderErrorMessage(error))}
</div>
Expand Down
5 changes: 5 additions & 0 deletions src/Shared/Components/DynamicDataTable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ export type DynamicDataTableProps<K extends string, CustomStateType = Record<str
isDeletionNotAllowed?: boolean
/** When true, data add or update is disabled. */
readOnly?: boolean
/** Tooltip for add button.
* @default 'Add'
*/
addBtnTooltip?: string
/** Function to handle the addition of a new row to the table. */
onRowAdd: () => void
/**
Expand Down Expand Up @@ -233,6 +237,7 @@ export interface DynamicDataTableHeaderProps<K extends string, CustomStateType =
| 'rows'
| 'headerComponent'
| 'sortingConfig'
| 'addBtnTooltip'
| 'onRowAdd'
| 'readOnly'
| 'isAdditionNotAllowed'
Expand Down
Loading
Loading