Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
dd454fe
feat: add base AppStatusModal
AbhishekA1509 Apr 16, 2025
7218d58
feat: implement AppStatusBody component and integrate into AppStatusM…
AbhishekA1509 Apr 16, 2025
b1322a3
refactor: optimize ErrorBar component by replacing useEffect with use…
AbhishekA1509 Apr 16, 2025
04f7d19
feat: enhance AppStatusModal by adding ErrorBar component and refacto…
AbhishekA1509 Apr 16, 2025
6ad2556
chore: deprecated mark
AbhishekA1509 Apr 17, 2025
59627db
feat: enhance AppStatusModal with ConfigDrift functionality and refac…
AbhishekA1509 Apr 21, 2025
502fbf5
feat: add app detail fetching and enhance AppStatusModal with improve…
AbhishekA1509 Apr 22, 2025
c853b01
feat: enhance SegmentedControl by adding unique input IDs and improvi…
AbhishekA1509 Apr 22, 2025
0995322
feat: refactor AppStatusModal components for improved layout and acce…
AbhishekA1509 Apr 22, 2025
f3f4846
feat: add utility functions for app status management and update AppS…
AbhishekA1509 Apr 23, 2025
c1493b2
refactor: update AppStatusModal components for improved layout and st…
AbhishekA1509 Apr 23, 2025
b31ee60
refactor: remove CONFIG_DRIFT constant, update ConfigDriftModalProps …
AbhishekA1509 Apr 23, 2025
53de3f0
feat: add AppStatusContent component with styling for improved layout…
AbhishekA1509 Apr 23, 2025
43c4cc1
refactor: update AppStatusModal components to improve error handling …
AbhishekA1509 Apr 23, 2025
92dfeaf
refactor: simplify AppStatusModal components by removing unnecessary …
AbhishekA1509 Apr 23, 2025
4e7c1bd
feat: add new expand small icon and update constants for tenant insta…
AbhishekA1509 Apr 28, 2025
e609822
feat: add intermediate state to Toggle component with corresponding s…
AbhishekA1509 Apr 28, 2025
7395c1a
feat: enhance Toggle component to support controlled state management
AbhishekA1509 Apr 28, 2025
b1521b7
feat: deprecate debounce function and introduce useDebounce hook for …
AbhishekA1509 Apr 29, 2025
c1e1bd1
fix: update useRef type in useDebounce hook for better type safety
AbhishekA1509 Apr 29, 2025
64723a9
Merge branch 'develop' into feat/app-status-modal
AbhishekA1509 Apr 29, 2025
89bc6bb
refactor: streamline Drawer exports and enhance AppStatusModal title …
AbhishekA1509 Apr 29, 2025
7c19ab7
Merge pull request #717 from devtron-labs/feat/release-tenant-mapping
AbhishekA1509 Apr 29, 2025
054c9ee
fix: correct API endpoint formatting in AppStatusModal service
AbhishekA1509 Apr 29, 2025
efc5c03
fix: review comments
AbhishekA1509 Apr 29, 2025
0e7e4d6
refactor: reorganize EmptyState exports and enhance AppStatusModal co…
AbhishekA1509 Apr 29, 2025
9b253e0
fix: improve cleanup logic in AppStatusModal and handle missing statu…
AbhishekA1509 Apr 29, 2025
5e0d7a0
refactor: update SegmentedControl dependencies and improve StatusFilt…
AbhishekA1509 Apr 29, 2025
9e4f3dc
fix: ShowMoreText component usage in AppStatusModal
AbhishekA1509 Apr 29, 2025
c1b619e
feat: add buttonPadding prop to InfoIconTippy for customizable button…
AbhishekA1509 Apr 30, 2025
2ebf878
feat: add styles and update StatusFilterButtonComponent for improved UI
AbhishekA1509 Apr 30, 2025
eabc1f0
refactor: optimize SegmentedControl dependencies and enhance StatusFi…
AbhishekA1509 Apr 30, 2025
7785d2d
Merge branch 'develop' of https://github.com/devtron-labs/devtron-fe-…
AbhishekA1509 Apr 30, 2025
2697181
chore: update version to 1.12.0-beta-4 in package.json and package-lo…
AbhishekA1509 Apr 30, 2025
22011fc
refactor: simplify key generation in StatusFilterButtonComponent
AbhishekA1509 Apr 30, 2025
60dcf5d
chore: update version to 1.12.0-beta-5 in package.json and package-lo…
AbhishekA1509 Apr 30, 2025
4f56e28
Merge branch 'develop' of https://github.com/devtron-labs/devtron-fe-…
AbhishekA1509 May 9, 2025
69a523c
Merge branch 'develop' of https://github.com/devtron-labs/devtron-fe-…
AbhishekA1509 May 13, 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
3 changes: 3 additions & 0 deletions src/Assets/IconV2/ic-expand-sm.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: 2 additions & 1 deletion src/Common/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const DOCUMENTATION = {
GLOBAL_CONFIG_BUILD_INFRA: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/global-configurations/build-infra`,
ENTERPRISE_LICENSE: `${DOCUMENTATION_HOME_PAGE}/enterprise-license`,
KUBE_CONFIG: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/resource-browser#running-kubectl-commands-locally`,
TENANT_INSTALLATION: `${DOCUMENTATION_HOME_PAGE}${DOCUMENTATION_VERSION}/usage/software-distribution-hub/tenants`,
}

export const PATTERNS = {
Expand Down Expand Up @@ -86,7 +87,6 @@ export const URLS = {
COMPARE_CLUSTERS: '/compare-clusters',
APP_CONFIG: 'edit',
GLOBAL_CONFIG: '/global-config',
CONFIG_DRIFT: 'config-drift',
GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP,
GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP_CREATE: `${GLOBAL_CONFIG_TEMPLATES_DEVTRON_APP}/create`,
// NOTE: using appId since we are re-using AppConfig component
Expand Down Expand Up @@ -135,6 +135,7 @@ export const ROUTES = {
ATTRIBUTES_CREATE: 'attributes/create',
ATTRIBUTES_UPDATE: 'attributes/update',
APP_LIST_MIN: 'app/min',
APP_DETAIL: 'app/detail',
CLUSTER_LIST_MIN: 'cluster/autocomplete',
CLUSTER_LIST_RAW: 'k8s/capacity/cluster/list/raw',
PLUGIN_GLOBAL_LIST_DETAIL_V2: 'plugin/global/list/detail/v2',
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import React, { useRef, useEffect } from 'react'
import { useRef, useEffect } from 'react'
import { preventBodyScroll } from '../../Shared'
import { VisibleModal } from '../Modals/VisibleModal'
import './Drawer.scss'
Expand Down
1 change: 1 addition & 0 deletions src/Common/Drawer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Drawer'
12 changes: 12 additions & 0 deletions src/Common/Helper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@ export const applyCompareDiffOnUneditedDocument = (uneditedDocument: object, edi

/**
* Returns a debounced variant of the function
* @deprecated - It should use useRef instead, pls use useDebounce
*/
export const debounce = (func, timeout = 500) => {
let timer
Expand All @@ -693,6 +694,17 @@ export const debounce = (func, timeout = 500) => {
}
}

export const useDebounce = <Callback extends (...args: any[]) => void>(cb: Callback, delay: number) => {
const timeoutId = useRef<ReturnType<typeof setTimeout>>(null)

return (...args: Parameters<Callback>) => {
if (timeoutId.current) {
clearTimeout(timeoutId.current)
}
timeoutId.current = setTimeout(() => cb(...args), delay)
}
}

/**
* Returns a capitalized string with first letter in uppercase and rest in lowercase
*/
Expand Down
11 changes: 7 additions & 4 deletions src/Common/SegmentedControl/Segment.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ReactElement } from 'react'
import { ReactElement, useMemo } from 'react'

import { Tooltip } from '@Common/Tooltip'
import { Icon } from '@Shared/Components'
import { ComponentSizeType } from '@Shared/constants'
import { getUniqueId } from '@Shared/Helpers'

import { ConditionalWrap } from '../Helper'
import { COMPONENT_SIZE_TO_ICON_CLASS_MAP, COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP } from './constants'
Expand All @@ -24,6 +25,8 @@ const Segment = ({
size,
disabled,
}: SegmentProps) => {
const inputId = useMemo(getUniqueId, [])

const { value, icon, isError, label, tooltipProps, ariaLabel } = segment
const handleChange = () => {
onChange(segment)
Expand All @@ -32,13 +35,13 @@ const Segment = ({
return (
<ConditionalWrap key={value} condition={!!tooltipProps?.content} wrap={wrapWithTooltip(tooltipProps)}>
<div
className={`dc__position-rel dc__text-center ${fullWidth ? 'flex-grow-1' : ''}`}
className={`dc__position-rel dc__text-center dc__no-shrink ${fullWidth ? 'flex-grow-1' : ''}`}
ref={selectedSegmentRef}
>
<input
type="radio"
value={value}
id={`${name}-${value}`}
id={inputId}
name={name}
onChange={handleChange}
checked={isSelected}
Expand All @@ -47,7 +50,7 @@ const Segment = ({
/>

<label
htmlFor={`${name}-${value}`}
htmlFor={inputId}
className={`pointer m-0 flex ${!fullWidth ? 'left' : ''} dc__gap-4 br-4 segmented-control__segment segmented-control__segment--${size} ${isSelected ? 'fw-6 segmented-control__segment--selected' : 'fw-4'} ${segment.isError ? 'cr-5' : 'cn-9'} ${disabled ? 'cursor-not-allowed' : ''} ${COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP[size]}`}
aria-label={ariaLabel}
>
Expand Down
6 changes: 6 additions & 0 deletions src/Common/Toggle/Toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@
background-color: var(--white);
transition: all 0.4s ease;
}

&.intermediate::before {
width: 0px;
height: 0px;
}

&.with-icon {
background-color: var(--bg-primary) !important;
svg {
Expand Down
38 changes: 33 additions & 5 deletions src/Common/Toggle/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import React, { SyntheticEvent, useCallback } from 'react'
import { Icon as IconComponent } from '@Shared/Components'
import { throttle, useEffectAfterMount } from '../Helper'
import { CHECKBOX_VALUE } from '@Common/Types'
import './Toggle.scss'

const Toggle = ({
Expand All @@ -31,12 +32,14 @@ const Toggle = ({
throttleOnChange = false,
shouldToggleValueOnLabelClick = false,
isLoading = false,
value = CHECKBOX_VALUE.CHECKED,
isControlled = false,
...props
}) => {
const [active, setActive] = React.useState(selected)

useEffectAfterMount(() => {
if (typeof onSelect === 'function') {
if (typeof onSelect === 'function' && !isControlled) {
if (active !== selected) {
onSelect(active)
}
Expand All @@ -49,7 +52,11 @@ const Toggle = ({

function handleClick() {
if (!disabled) {
setActive((active) => !active)
if (isControlled) {
onSelect(!active)
} else {
setActive((active) => !active)
}
}
}

Expand All @@ -70,8 +77,26 @@ const Toggle = ({
}
}

const isIntermediateView = selected && value === CHECKBOX_VALUE.INTERMEDIATE

const renderIcon = () => {
if (isIntermediateView) {
return (
<div className="w-100 h-100 dc__position-abs flex">
<div className="w-8 h-2 br-4 dc__no-shrink bg__white" />
</div>
)
}

if (Icon) {
return <Icon className={`icon-dim-20 br-4 p-2 ${iconClass}`} />
}

return null
}

return isLoading ? (
<IconComponent name='ic-circle-loader' color='B500' size={20} />
<IconComponent name="ic-circle-loader" color="B500" size={20} />
) : (
<label
{...props}
Expand All @@ -80,8 +105,11 @@ const Toggle = ({
{...(shouldToggleValueOnLabelClick ? { onClick: handleLabelClick } : {})}
>
<input type="checkbox" checked={!!active} onChange={handleChange} className="toggle__input" />
<span className={`toggle__slider ${Icon ? 'with-icon br-4 dc__border' : 'round'}`} data-testid={dataTestId}>
{Icon && <Icon className={`icon-dim-20 br-4 p-2 ${iconClass}`} />}
<span
className={`toggle__slider ${isIntermediateView ? 'intermediate' : ''} ${Icon ? 'with-icon br-4 dc__border' : 'round'}`}
data-testid={dataTestId}
>
{renderIcon()}
</span>
</label>
)
Expand Down
2 changes: 1 addition & 1 deletion src/Common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export { default as DevtronCopyright } from './DevtronCopyright'
export * from './DevtronProgressing'
export * from './Dialogs'
export * from './DraggableWrapper'
export * from './Drawer/Drawer'
export * from './Drawer'
export { default as GenericEmptyState } from './EmptyState/GenericEmptyState'
export { default as GenericFilterEmptyState } from './EmptyState/GenericFilterEmptyState'
export { default as ErrorScreenManager } from './ErrorScreenManager'
Expand Down
84 changes: 84 additions & 0 deletions src/Shared/Components/AppStatusModal/AppStatusBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { ComponentProps, ReactNode } from 'react'

import { Tooltip } from '@Common/Tooltip'

import { ErrorBar } from '../Error'
import { ShowMoreText } from '../ShowMoreText'
import { AppStatus } from '../StatusComponent'
import AppStatusContent from './AppStatusContent'
import { APP_STATUS_CUSTOM_MESSAGES } from './constants'
import { AppStatusBodyProps } from './types'
import { getAppStatusMessageFromAppDetails } from './utils'

const InfoCardItem = ({ heading, value, isLast = false }: { heading: string; value: ReactNode; isLast?: boolean }) => (
<div
className={`py-12 px-16 dc__grid dc__column-gap-16 info-card-item ${!isLast ? 'border__secondary--bottom' : ''}`}
>
<Tooltip content={heading}>
<h3 className="cn-9 fs-13 fw-4 lh-1-5 dc__truncate m-0 dc__no-shrink">{heading}</h3>
</Tooltip>

{typeof value === 'string' ? (
<ShowMoreText key={`show-more-text-${value}`} textClass="cn-9 fs-13 fw-4 lh-1-5" text={value} />
) : (
value
)}
</div>
)

export const AppStatusBody = ({ appDetails, type, handleShowConfigDriftModal }: AppStatusBodyProps) => {
const appStatus = appDetails.resourceTree?.status?.toUpperCase() || appDetails.appStatus
const message = getAppStatusMessageFromAppDetails(appDetails)
const customMessage =
type === 'stack-manager'
? 'The installation will complete when status for all the below resources become HEALTHY.'
: APP_STATUS_CUSTOM_MESSAGES[appDetails.resourceTree?.status?.toUpperCase()]
Comment thread
AbhishekA1509 marked this conversation as resolved.
Outdated

const infoCardItems: (Omit<ComponentProps<typeof InfoCardItem>, 'isLast'> & { id: number })[] = [
{
id: 1,
heading: type !== 'stack-manager' ? 'Application Status' : 'Status',
value: appStatus ? <AppStatus status={appStatus} /> : '--',
},
...(message
? [
{
id: 2,
heading: 'Message',
value: message,
},
]
: []),
...(customMessage
? [
{
id: 3,
heading: 'Message',
value: customMessage,
},
]
: []),
]

return (
<div className="flexbox-col px-20 dc__gap-16 dc__overflow-auto">
{/* Info card */}
<div className="flexbox-col pt-20">
<div className="flexbox-col br-8 border__primary bg__primary shadow__card--secondary">
{infoCardItems.map((item, index) => (
<InfoCardItem
key={item.id}
heading={item.heading}
value={item.value}
isLast={index === infoCardItems.length - 1}
/>
))}
</div>
</div>

<ErrorBar appDetails={appDetails} useParentMargin={false} />

<AppStatusContent appDetails={appDetails} handleShowConfigDriftModal={handleShowConfigDriftModal} />
</div>
)
}
7 changes: 7 additions & 0 deletions src/Shared/Components/AppStatusModal/AppStatusContent.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.app-status-content {
.app-status-content {
&__row {
grid-template-columns: 150px 200px 100px auto;
}
}
}
Loading