Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:devtron-labs/devtron-fe-common-l…
Browse files Browse the repository at this point in the history
…ib into feat/bulk-trigger-deployment
  • Loading branch information
Elessar1802 committed Jan 8, 2025
2 parents 1344683 + b63105d commit 3bc1830
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 75 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@devtron-labs/devtron-fe-common-lib",
"version": "1.3.11",
"version": "1.4.0-beta-2",
"description": "Supporting common component library",
"type": "module",
"main": "dist/index.js",
Expand Down
39 changes: 34 additions & 5 deletions src/Common/Common.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { MutableRefObject } from 'react'
import moment from 'moment'
import { sanitizeApprovalConfigData, sanitizeUserApprovalList } from '@Shared/Helpers'
import { sanitizeApprovalConfigData, sanitizeUserApprovalList, stringComparatorBySortOrder } from '@Shared/Helpers'
import { PolicyBlockInfo, RuntimeParamsAPIResponseType, RuntimePluginVariables } from '@Shared/types'
import { get, post } from './Api'
import { GitProviderType, ROUTES } from './Constants'
Expand All @@ -42,7 +42,7 @@ import {
GlobalVariableOptionType,
} from './Types'
import { ApiResourceType, STAGE_MAP } from '../Pages'
import { RefVariableType } from './CIPipeline.Types'
import { RefVariableType, VariableTypeFormat } from './CIPipeline.Types'

export const getTeamListMin = (): Promise<TeamList> => {
// ignore active field
Expand Down Expand Up @@ -196,7 +196,7 @@ const cdMaterialListModal = ({
deploymentWindowArtifactMetadata: material.deploymentWindowArtifactMetadata ?? null,
configuredInReleases: material.configuredInReleases ?? [],
appWorkflowId: material.appWorkflowId ?? null,
deploymentBlockedState: sanitizeDeploymentBlockedState(material.deploymentBlockedState)
deploymentBlockedState: sanitizeDeploymentBlockedState(material.deploymentBlockedState),
}
})
return materials
Expand Down Expand Up @@ -237,8 +237,37 @@ const processCDMaterialsApprovalInfo = (enableApproval: boolean, cdMaterialsResu
}
}

export const parseRuntimeParams = (response: RuntimeParamsAPIResponseType): RuntimePluginVariables[] =>
(response?.runtimePluginVariables ?? []).map((variable) => ({ ...variable, defaultValue: variable.value }))
export const parseRuntimeParams = (response: RuntimeParamsAPIResponseType): RuntimePluginVariables[] => {
const envVariables = Object.entries(response?.envVariables || {}).map<RuntimePluginVariables>(
([key, value]) => ({
name: key,
value,
defaultValue: '',
format: VariableTypeFormat.STRING,
isRequired: false,
valueType: RefVariableType.NEW,
variableStepScope: RefVariableType.GLOBAL,
stepName: null,
stepType: null,
// TODO: (Rohit/Eshank) Replace this with getUniqueId (nanoId method)
stepVariableId: Math.floor(new Date().valueOf() * Math.random()),
valueConstraint: null,
description: null,
fileReferenceId: null,
fileMountDir: null,
}),
)

const runtimeParams = (response?.runtimePluginVariables ?? []).map<RuntimePluginVariables>((variable) => ({
...variable,
defaultValue: variable.value,
}))

runtimeParams.push(...envVariables)
runtimeParams.sort((a, b) => stringComparatorBySortOrder(a.name, b.name))

return runtimeParams
}

const processCDMaterialsMetaInfo = (cdMaterialsResult): CDMaterialsMetaInfo => {
if (!cdMaterialsResult) {
Expand Down
3 changes: 2 additions & 1 deletion src/Common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export const DOCUMENTATION = {
export const PATTERNS = {
STRING: /^[a-zA-Z0-9_]+$/,
DECIMAL_NUMBERS: /^-?\d*\.?\d*$/,
NATURAL_NUMBERS: /^\d*\.?\d*$/,
POSITIVE_DECIMAL_NUMBERS: /^\d*\.?\d*$/,
NATURAL_NUMBERS: /^[1-9]\d*$/,
KUBERNETES_KEY_PREFIX: /^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/,
KUBERNETES_KEY_NAME: /^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$/,
START_END_ALPHANUMERIC: /^(([A-Za-z0-9].*[A-Za-z0-9])|[A-Za-z0-9])$/,
Expand Down
6 changes: 3 additions & 3 deletions src/Shared/Components/CICDHistory/LogStageAccordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ const LogStageAccordion = ({
>
<span
ref={scrollIntoView}
className="cn-4 col-2 lh-20 dc__text-align-end dc__word-break mono fs-14"
className="cn-4 col-2 lh-20 dc__text-align-end dc__word-break mono fs-14 dc__user-select-none"
data-contains-match={doesLineContainSearchMatch}
>
{logsIndex + 1}
</span>
<p
className="mono fs-14 mb-0-imp cn-0 dc__word-break lh-20"
<pre
className="mono fs-14 mb-0-imp cn-0 dc__word-break lh-20 dc__unset-pre"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(log),
Expand Down
3 changes: 1 addition & 2 deletions src/Shared/Components/CICDHistory/LogsRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ const LogsRenderer = ({ triggerDetails, isBlobStorageConfigured, parentType, ful

const { registerShortcut, unregisterShortcut } = useRegisterShortcut()

const areStagesAvailable =
(window._env_.FEATURE_STEP_WISE_LOGS_ENABLE && streamDataList[0]?.startsWith(LOGS_STAGE_IDENTIFIER)) || false
const areStagesAvailable = streamDataList[0]?.startsWith(LOGS_STAGE_IDENTIFIER) || false

function createMarkup({
log,
Expand Down
36 changes: 26 additions & 10 deletions src/Shared/Components/DynamicDataTable/DynamicDataTableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { createElement, createRef, Fragment, ReactElement, RefObject, useEffect, useRef, useState } from 'react'
import {
createElement,
createRef,
Fragment,
ReactElement,
RefObject,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
// eslint-disable-next-line import/no-extraneous-dependencies
import { followCursor } from 'tippy.js'

Expand Down Expand Up @@ -74,10 +84,10 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
{},
)
}
const rowIds = useMemo(() => rows.map(({ id }) => id), [rows])

useEffect(() => {
setIsRowAdded(rows.length > 0 && Object.keys(cellRef.current).length < rows.length)
const rowIds = rows.map(({ id }) => id)

const updatedCellRef = rowIds.reduce((acc, curr) => {
if (cellRef.current[curr]) {
Expand All @@ -89,14 +99,16 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
}, {})

cellRef.current = updatedCellRef
}, [rows.length])
}, [JSON.stringify(rowIds)])

useEffect(() => {
// Using the below logic to ensure the cell is focused after row addition.
const cell = cellRef.current[rows[0].id][focusableFieldKey || headers[0].key].current
if (isRowAdded && cell) {
cell.focus()
setIsRowAdded(false)
if (isRowAdded) {
// Using the below logic to ensure the cell is focused after row addition.
const cell = cellRef.current[rows[0].id][focusableFieldKey || headers[0].key].current
if (cell) {
cell.focus()
setIsRowAdded(false)
}
}
}, [isRowAdded])

Expand Down Expand Up @@ -164,8 +176,10 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
isClearable
{...props}
variant={SelectPickerVariantType.BORDER_LESS}
classNamePrefix="dynamic-data-table__cell__select-picker"
classNamePrefix="dynamic-data-table__cell__select-picker-text-area"
inputId={`data-table-${row.id}-${key}-cell`}
minHeight={20}
maxHeight={160}
value={getSelectPickerOptionByValue(
props?.options,
value,
Expand All @@ -174,6 +188,8 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
onChange={onChange(row, key)}
isDisabled={isDisabled}
formatCreateLabel={(input) => `Use ${input}`}
refVar={cellRef?.current?.[row.id]?.[key]}
dependentRefs={cellRef?.current?.[row.id]}
fullWidth
/>
</div>
Expand Down Expand Up @@ -287,7 +303,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
plugins={[followCursor]}
>
<div
className={`dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${isDisabled ? 'dc__disabled no-hover' : ''} ${!isDisabled && hasError ? 'dynamic-data-table__cell--error no-hover' : ''} ${!rowTypeHasInputField(row.data[key].type) ? 'no-hover no-focus' : ''}`}
className={`dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${isDisabled ? 'cursor-not-allowed no-hover' : ''} ${!isDisabled && hasError ? 'dynamic-data-table__cell--error no-hover' : ''} ${!rowTypeHasInputField(row.data[key].type) ? 'no-hover no-focus' : ''}`}
>
{renderCellIcon(row, key, true)}
{renderCellContent(row, key)}
Expand Down
32 changes: 32 additions & 0 deletions src/Shared/Components/DynamicDataTable/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,38 @@
max-height: 160px !important;
}

&__select-picker-text-area {
&__control {
padding: 0 !important;
max-height: 160px !important;
}

&__placeholder {
align-self: start;
padding: 8px 50px 8px 8px;
}

&__indicators {
position: absolute;
top: 10px;
right: 8px;
}

&__input-container {
display: flex !important;
width: 100%;

&::after {
content: none !important;
}
}

&__input {
flex-grow: 1;
padding: 8px 50px 8px 8px !important;
}
}

&:hover:not(:focus-within):not(.no-hover) {
outline: 1px solid var(--N200);
}
Expand Down
13 changes: 12 additions & 1 deletion src/Shared/Components/DynamicDataTable/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,25 @@ export type DynamicDataTableCellPropsMap = {
| 'disableOnBlurResizeToMinHeight'
| 'refVar'
| 'dependentRef'
| 'dependentRefs'
>
[DynamicDataTableRowDataType.DROPDOWN]: Omit<
SelectPickerProps<string, false>,
'inputId' | 'value' | 'onChange' | 'fullWidth' | 'isDisabled'
>
[DynamicDataTableRowDataType.SELECT_TEXT]: Omit<
SelectPickerTextAreaProps,
'inputId' | 'value' | 'onChange' | 'fullWidth' | 'isDisabled' | 'variant' | 'formatCreateLabel'
| 'inputId'
| 'value'
| 'onChange'
| 'fullWidth'
| 'isDisabled'
| 'variant'
| 'formatCreateLabel'
| 'minHeight'
| 'maxHeight'
| 'refVar'
| 'dependentRefs'
>
[DynamicDataTableRowDataType.BUTTON]: Pick<
DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
Expand Down
8 changes: 3 additions & 5 deletions src/Shared/Components/SelectPicker/SelectPicker.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import {
SelectPickerOption,
SelectPickerValueContainer,
SelectPickerInput,
SelectPickerIndicatorsContainer,
} from './common'
import { SelectPickerOptionType, SelectPickerProps, SelectPickerVariantType } from './type'
import { GenericSectionErrorState } from '../GenericSectionErrorState'
Expand Down Expand Up @@ -285,10 +284,9 @@ const SelectPicker = <OptionValue, IsMulti extends boolean>({
{...valueContainerProps}
showSelectedOptionsCount={showSelectedOptionsCount}
customSelectedOptionsCount={customSelectedOptionsCount}
isFocussed={isFocussed}
/>
),
[showSelectedOptionsCount, customSelectedOptionsCount, isFocussed],
[showSelectedOptionsCount, customSelectedOptionsCount],
)

const renderOption = useCallback(
Expand Down Expand Up @@ -441,7 +439,6 @@ const SelectPicker = <OptionValue, IsMulti extends boolean>({
Control: SelectPickerControl,
Option: renderOption,
MenuList: SelectPickerMenuList,
IndicatorsContainer: SelectPickerIndicatorsContainer,
ClearIndicator: SelectPickerClearIndicator,
ValueContainer: renderValueContainer,
MultiValueLabel: renderMultiValueLabel,
Expand All @@ -467,10 +464,11 @@ const SelectPicker = <OptionValue, IsMulti extends boolean>({
onKeyDown={handleKeyDown}
shouldRenderTextArea={shouldRenderTextArea}
customDisplayText={customDisplayText}
onFocus={handleFocus}
{...(!shouldRenderTextArea ? { onFocus: handleFocus } : {})}
onBlur={handleBlur}
onChange={handleChange}
controlShouldRenderValue={controlShouldRenderValue}
isFocussed={isFocussed}
/>
</div>
</ConditionalWrap>
Expand Down
Loading

0 comments on commit 3bc1830

Please sign in to comment.