Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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.20.6-pre-31",
"version": "1.20.6-alpha-31",
"description": "Supporting common component library",
"type": "module",
"main": "dist/index.js",
Expand Down
6 changes: 6 additions & 0 deletions src/Assets/IconV2/ic-backup-color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/Assets/IconV2/ic-backup-schedule-color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/Assets/IconV2/ic-cloud-upload.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/Assets/IconV2/ic-pause.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 35 additions & 6 deletions src/Common/ClipboardButton/ClipboardButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
import { useEffect, useRef, useState } from 'react'

import Tooltip from '@Common/Tooltip/Tooltip'
import { Button, ButtonStyleType, ButtonVariantType } from '@Shared/Components/Button'

import { ReactComponent as Check } from '../../Assets/Icon/ic-check.svg'
import { ReactComponent as ICCopy } from '../../Assets/Icon/ic-copy.svg'
import { copyToClipboard, noop, stopPropagation } from '../Helper'
import ClipboardProps from './types'
import { ClipboardProps } from './types'

/**
* @param content - Content to be copied
Expand All @@ -40,6 +41,8 @@ export const ClipboardButton = ({
rootClassName = '',
iconSize = 16,
handleSuccess,
variant = 'default',
size,
}: ClipboardProps) => {
const [copied, setCopied] = useState<boolean>(false)
const setCopiedFalseTimeoutRef = useRef<ReturnType<typeof setTimeout>>(-1)
Expand Down Expand Up @@ -96,18 +99,44 @@ export const ClipboardButton = ({

const iconClassName = `icon-dim-${iconSize} dc__no-shrink`

const ariaLabel = `Copy ${content}`

const renderIcon = () => (
<div className="flex">
{copied ? <Check className={iconClassName} /> : <ICCopy className={iconClassName} />}
</div>
)

const tooltipContent = copied ? copiedTippyText : initialTippyText

if (variant === 'button--secondary') {
return (
<Button
variant={ButtonVariantType.secondary}
dataTestId="clippy-button"
icon={renderIcon()}
size={size}
onClick={handleCopyContent}
tooltipProps={{
content: tooltipContent,
}}
showTooltip
ariaLabel={ariaLabel}
style={ButtonStyleType.neutral}
/>
)
}

return (
<Tooltip content={copied ? copiedTippyText : initialTippyText} alwaysShowTippyOnHover>
<Tooltip content={tooltipContent} alwaysShowTippyOnHover>
{/* TODO: semantically buttons should not be nested; fix later */}
<button
type="button"
className={`dc__outline-none-imp p-0 flex dc__transparent--unstyled dc__no-border ${rootClassName}`}
aria-label={`Copy ${content}`}
aria-label={ariaLabel}
onClick={handleCopyContent}
>
<div className="flex">
{copied ? <Check className={iconClassName} /> : <ICCopy className={iconClassName} />}
</div>
{renderIcon()}
</button>
</Tooltip>
)
Expand Down
16 changes: 15 additions & 1 deletion src/Common/ClipboardButton/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,21 @@
* limitations under the License.
*/

export default interface ClipboardProps {
import { ComponentSizeType } from '@Shared/constants'

export type ClipboardProps = (
| {
/**
* @default 'default'
*/
variant?: 'default'
size?: never
}
| {
variant: 'button--secondary'
size: ComponentSizeType
}
) & {
content: string
/**
* tippy text before copying
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export const URLS = {
DATA_PROTECTION: DATA_PROTECTION_ROOT,
DATA_PROTECTION_OVERVIEW: `${DATA_PROTECTION_ROOT}/overview`,
DATA_PROTECTION_BACKUP_AND_SCHEDULE,
DATA_PROTECTION_BACKUP_AND_SCHEDULE_DETAIL: `${DATA_PROTECTION_BACKUP_AND_SCHEDULE}/:name`,
DATA_PROTECTION_BACKUP_AND_SCHEDULE_DETAIL: `${DATA_PROTECTION_BACKUP_AND_SCHEDULE}/detail/:id`,
DATA_PROTECTION_RESTORES: `${DATA_PROTECTION_ROOT}/restores`,
DATA_PROTECTION_RESTORES_DETAIL: `${DATA_PROTECTION_ROOT}/restores/:restoreId`,
DATA_PROTECTION_BACKUP_LOCATIONS: `${DATA_PROTECTION_ROOT}/backup-locations/:type(${Object.values(BackupLocationsTypes).join('|')})`,
Expand Down
8 changes: 8 additions & 0 deletions src/Shared/Components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import { ReactComponent as ICAwsCodecommit } from '@IconsV2/ic-aws-codecommit.sv
import { ReactComponent as ICAzure } from '@IconsV2/ic-azure.svg'
import { ReactComponent as ICAzureAks } from '@IconsV2/ic-azure-aks.svg'
import { ReactComponent as ICBackupAndSchedule } from '@IconsV2/ic-backup-and-schedule.svg'
import { ReactComponent as ICBackupColor } from '@IconsV2/ic-backup-color.svg'
import { ReactComponent as ICBackupLocation } from '@IconsV2/ic-backup-location.svg'
import { ReactComponent as ICBackupScheduleColor } from '@IconsV2/ic-backup-schedule-color.svg'
import { ReactComponent as ICBgBuild } from '@IconsV2/ic-bg-build.svg'
import { ReactComponent as ICBgCluster } from '@IconsV2/ic-bg-cluster.svg'
import { ReactComponent as ICBgCpu } from '@IconsV2/ic-bg-cpu.svg'
Expand Down Expand Up @@ -71,6 +73,7 @@ import { ReactComponent as ICClock } from '@IconsV2/ic-clock.svg'
import { ReactComponent as ICClockCounterclockwise } from '@IconsV2/ic-clock-counterclockwise.svg'
import { ReactComponent as ICCloseLarge } from '@IconsV2/ic-close-large.svg'
import { ReactComponent as ICCloseSmall } from '@IconsV2/ic-close-small.svg'
import { ReactComponent as ICCloudUpload } from '@IconsV2/ic-cloud-upload.svg'
import { ReactComponent as ICCloudVms } from '@IconsV2/ic-cloud-vms.svg'
import { ReactComponent as ICCluster } from '@IconsV2/ic-cluster.svg'
import { ReactComponent as ICClusterIsolated } from '@IconsV2/ic-cluster-isolated.svg'
Expand Down Expand Up @@ -216,6 +219,7 @@ import { ReactComponent as ICPaperPlane } from '@IconsV2/ic-paper-plane.svg'
import { ReactComponent as ICPaperPlaneColor } from '@IconsV2/ic-paper-plane-color.svg'
import { ReactComponent as ICParty } from '@IconsV2/ic-party.svg'
import { ReactComponent as ICPath } from '@IconsV2/ic-path.svg'
import { ReactComponent as ICPause } from '@IconsV2/ic-pause.svg'
import { ReactComponent as ICPauseCircle } from '@IconsV2/ic-pause-circle.svg'
import { ReactComponent as ICPencil } from '@IconsV2/ic-pencil.svg'
import { ReactComponent as ICPlayOutline } from '@IconsV2/ic-play-outline.svg'
Expand Down Expand Up @@ -324,7 +328,9 @@ export const iconMap = {
'ic-azure-aks': ICAzureAks,
'ic-azure': ICAzure,
'ic-backup-and-schedule': ICBackupAndSchedule,
'ic-backup-color': ICBackupColor,
'ic-backup-location': ICBackupLocation,
'ic-backup-schedule-color': ICBackupScheduleColor,
'ic-bg-build': ICBgBuild,
'ic-bg-cluster': ICBgCluster,
'ic-bg-cpu': ICBgCpu,
Expand Down Expand Up @@ -368,6 +374,7 @@ export const iconMap = {
'ic-clock': ICClock,
'ic-close-large': ICCloseLarge,
'ic-close-small': ICCloseSmall,
'ic-cloud-upload': ICCloudUpload,
'ic-cloud-vms': ICCloudVms,
'ic-cluster-isolated': ICClusterIsolated,
'ic-cluster': ICCluster,
Expand Down Expand Up @@ -514,6 +521,7 @@ export const iconMap = {
'ic-party': ICParty,
'ic-path': ICPath,
'ic-pause-circle': ICPauseCircle,
'ic-pause': ICPause,
'ic-pencil': ICPencil,
'ic-play-outline': ICPlayOutline,
'ic-priority-medium-fill': ICPriorityMediumFill,
Expand Down
29 changes: 29 additions & 0 deletions src/Shared/validations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -545,3 +545,32 @@ export const getIsRegexValid = (regexString: string): ValidationResponseType =>
}
}
}

export const validateCronExpression = (cron: string): ValidationResponseType => {
// Basic cron validation - 5 parts separated by spaces
const parts = cron.trim().split(/\s+/)
if (parts.length !== 5) {
return { isValid: false, message: 'Cron expression must have 5 parts separated by spaces' }
}

const isValid = parts.every((part) => {
if (part === '*') return true
if (/^\d+$/.test(part)) return true
if (/^\d+-\d+$/.test(part)) return true
if (/^\*\/\d+$/.test(part)) return true
if (/^(\d+,)+\d+$/.test(part)) return true
return false
})

// Basic validation - each part should be either * or a number or a range
if (isValid) {
return {
isValid,
}
}

return {
isValid: false,
message: 'Invalid cron expression format',
}
}