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
16 changes: 6 additions & 10 deletions src/components/ApplicationGroup/AppGroup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ export interface BulkCDDetailTypeResponse {
uniqueReleaseTags: string[]
}

export interface BulkCDDetailType extends BulkTriggerAppDetailType, Pick<CDMaterialProps, 'isTriggerBlockedDueToPlugin' | 'configurePluginURL' | 'consequence'>, Partial<Pick<CommonNodeAttr, 'showPluginWarning'>> {
export interface BulkCDDetailType
extends BulkTriggerAppDetailType,
Pick<CDMaterialProps, 'isTriggerBlockedDueToPlugin' | 'configurePluginURL' | 'consequence'>,
Partial<Pick<CommonNodeAttr, 'showPluginWarning'>> {
cdPipelineName?: string
cdPipelineId?: string
stageType?: DeploymentNodeType
Expand Down Expand Up @@ -316,7 +319,7 @@ export interface AppGroupDetailDefaultType {
isVirtualEnv?: boolean
envName?: string
description?: string
getAppListData?: () => Promise<void>
getAppListData?: () => Promise<OptionType[]>
handleSaveDescription?: (description: string) => Promise<void>
}

Expand Down Expand Up @@ -609,11 +612,4 @@ export enum AppGroupUrlFilters {

export interface AppGroupUrlFiltersType extends Record<AppGroupUrlFilters, string[]> {}

export interface SetFiltersInLocalStorageParamsType {
filterParentType: FilterParentType,
resourceId: string,
resourceList: MultiValue<OptionType>,
groupList: MultiValue<GroupOptionType>,
}

export type AppEnvLocalStorageKeyType = `${string}__filter`
export type AppEnvLocalStorageKeyType = `${string}__filter`
25 changes: 0 additions & 25 deletions src/components/ApplicationGroup/AppGroup.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ import {
CDWorkflowStatusType,
CIWorkflowStatusType,
ProcessWorkFlowStatusType,
FilterParentType,
SetFiltersInLocalStorageParamsType,
AppEnvLocalStorageKeyType,
} from './AppGroup.types'
import { getParsedBranchValuesForPlugin } from '@Components/common'
import { APP_GROUP_LOCAL_STORAGE_KEY, ENV_GROUP_LOCAL_STORAGE_KEY } from './Constants'

let timeoutId

Expand Down Expand Up @@ -296,24 +292,3 @@ export const processConsequenceData = (data: BlockedStateData): ConsequenceType
export const parseSearchParams = (searchParams: URLSearchParams) => ({
[AppGroupUrlFilters.cluster]: searchParams.getAll(AppGroupUrlFilters.cluster),
})

export const getAppFilterLocalStorageKey = (filterParentType: FilterParentType): AppEnvLocalStorageKeyType =>
filterParentType === FilterParentType.app ? ENV_GROUP_LOCAL_STORAGE_KEY : APP_GROUP_LOCAL_STORAGE_KEY

export const setFilterInLocalStorage = ({
filterParentType,
resourceId,
resourceList,
groupList,
}: SetFiltersInLocalStorageParamsType) => {
const localStorageKey = getAppFilterLocalStorageKey(filterParentType)
try {
const localStorageValue = localStorage.getItem(localStorageKey)
const localStoredMap = new Map(localStorageValue ? JSON.parse(localStorageValue) : null)
localStoredMap.set(resourceId, [resourceList, groupList])
// Set filter in local storage as Array from Map of resourceId vs [selectedAppList, selectedGroupFilter]
localStorage.setItem(localStorageKey, JSON.stringify(Array.from(localStoredMap)))
} catch {
localStorage.setItem(localStorageKey, '')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { components } from 'react-select'
import { ComponentSizeType, ConditionalWrap, TabGroup } from '@devtron-labs/devtron-fe-common-lib'
import Tippy from '@tippyjs/react'
import { useAppGroupAppFilterContext } from './AppGroupDetailsRoute'
import { getOptionBGClass, setFilterInLocalStorage } from './AppGroup.utils'
import { getOptionBGClass } from './AppGroup.utils'
import { ReactComponent as ShowIconFilter } from '../../assets/icons/ic-group-filter.svg'
import { ReactComponent as ShowIconFilterApplied } from '../../assets/icons/ic-group-filter-applied.svg'
import { ReactComponent as Search } from '../../assets/icons/ic-search.svg'
Expand All @@ -31,6 +31,7 @@ import { ReactComponent as CheckIcon } from '../../assets/icons/ic-check.svg'
import { AppGroupAppFilterContextType, FilterParentType } from './AppGroup.types'
import { AppFilterTabs } from './Constants'
import { ShortcutKeyBadge } from '@Components/common/formFields/Widgets/Widgets'
import { setAppGroupFilterInLocalStorage } from '@Components/common'

export const ValueContainer = (props): JSX.Element => {
const {
Expand Down Expand Up @@ -183,7 +184,7 @@ export const MenuList = (props: any): JSX.Element => {
const clearSelection = (): void => {
setSelectedAppList([])
setSelectedGroupFilter([])
setFilterInLocalStorage({ filterParentType, resourceId, resourceList: [], groupList: [] })
setAppGroupFilterInLocalStorage({ filterParentType, resourceId, resourceList: [], groupList: [] })
}
const onTabChange = (e): void => {
setSelectedFilterTab(e.currentTarget.dataset.selectedTab)
Expand Down
59 changes: 9 additions & 50 deletions src/components/ApplicationGroup/AppGroupAppFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
import { useEffect, useRef, useState } from 'react'
import ReactSelect, { SelectInstance } from 'react-select'
import { useAppGroupAppFilterContext } from './AppGroupDetailsRoute'
import { appGroupAppSelectorStyle, getAppFilterLocalStorageKey, setFilterInLocalStorage } from './AppGroup.utils'
import { appGroupAppSelectorStyle } from './AppGroup.utils'
import { AppGroupAppFilterContextType, FilterParentType } from './AppGroup.types'
import { AppFilterTabs } from './Constants'
import { MenuList, Option, ValueContainer } from './AppGroupAppFilter.components'
import { OptionType, ReactSelectInputAction, useRegisterShortcut } from '@devtron-labs/devtron-fe-common-lib'
import { setAppGroupFilterInLocalStorage } from '@Components/common'

export default function AppGroupAppFilter() {
const {
Expand Down Expand Up @@ -88,14 +89,19 @@ export default function AppGroupAppFilter() {
if (selectedFilterTab === AppFilterTabs.APP_FILTER) {
setSelectedAppList(selectedValue)
setSelectedGroupFilter([])
setFilterInLocalStorage({ filterParentType, resourceId, resourceList: selectedValue, groupList: [] })
setAppGroupFilterInLocalStorage({
filterParentType,
resourceId,
resourceList: selectedValue,
groupList: [],
})
} else {
const _selectedGroup = selectedValue.pop()
setSelectedGroupFilter([_selectedGroup])
if (_selectedGroup) {
const updatedAppList = appListOptions.filter((app) => _selectedGroup.appIds.indexOf(+app.value) >= 0)
setSelectedAppList(updatedAppList)
setFilterInLocalStorage({
setAppGroupFilterInLocalStorage({
filterParentType,
resourceId,
resourceList: updatedAppList,
Expand All @@ -117,53 +123,6 @@ export default function AppGroupAppFilter() {
appGroupFilterRef.current.onMenuOpen()
}

const getAndSetItem = () => {
const localStorageKey = getAppFilterLocalStorageKey(filterParentType)

const localStorageValue = localStorage.getItem(localStorageKey)
if (!localStorageValue) {
return
}
try {
const valueForCurrentResource = new Map(JSON.parse(localStorageValue)).get(resourceId)
// local storage value for app list/ env list
const localStorageResourceList = valueForCurrentResource?.[0] || []
// local storage value for group filter
const localStorageGroupList = valueForCurrentResource?.[1] || []

const appListOptionsMap = appListOptions.reduce<Record<string, true>>((agg, curr) => {
agg[curr.value] = true
return agg
}, {})

const groupFilterOptionsMap = groupFilterOptions.reduce<Record<string, true>>((agg, curr) => {
agg[curr.value] = true
return agg
}, {})

// filtering local storage lists acc to new appList/ envList or groupFilterList as local values might be deleted or does not exist anymore
const filteredLocalStorageResourceList = localStorageResourceList.filter(
({ value }) => appListOptionsMap[value],
)
const filteredLocalStorageGroupList = localStorageGroupList.filter(
({ value }) => groupFilterOptionsMap[value],
)

setSelectedAppList(filteredLocalStorageResourceList)
setSelectedGroupFilter(filteredLocalStorageGroupList)
} catch {
localStorage.setItem(localStorageKey, '')
}
}

useEffect(() => {
if (!appListOptions || !groupFilterOptions) {
return
}

getAndSetItem()
}, [appListOptions, groupFilterOptions])

useEffect(() => {
registerShortcut({ keys: ['F'], callback: handleFilterFocus })

Expand Down
78 changes: 55 additions & 23 deletions src/components/ApplicationGroup/AppGroupDetailsRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ import {
} from '@devtron-labs/devtron-fe-common-lib'
import ReactGA from 'react-ga4'
import { MultiValue } from 'react-select'
import { ErrorBoundary, sortOptionsByLabel, useAppContext } from '../common'
import {
ErrorBoundary,
getAndSetAppGroupFilters,
setAppGroupFilterInLocalStorage,
sortOptionsByLabel,
useAppContext,
} from '../common'
import { URLS } from '../../config'
import EnvTriggerView from './Details/TriggerView/EnvTriggerView'
import EnvConfig from './Details/EnvironmentConfig/EnvConfig'
Expand Down Expand Up @@ -112,6 +118,9 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
const [description, setDescription] = useState<string>(
appGroupListData?.description ? appGroupListData?.description : '',
)
const [initLoading, setInitLoading] = useState<boolean>(false)

const filterParentType = FilterParentType.env

useEffect(() => {
if (envList?.result) {
Expand All @@ -124,8 +133,22 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType

useEffect(() => {
if (envId && !showEmpty) {
getSavedFilterData()
getAppListData()
setInitLoading(true)

Promise.all([getSavedFilterData(), getAppListData()]).then((response) => {
const groupFilterOptionsList = response[0]
const appListOptionsList = response[1]

getAndSetAppGroupFilters({
filterParentType,
appListOptions: appListOptionsList,
groupFilterOptions: groupFilterOptionsList,
resourceId: envId,
setSelectedAppList,
setSelectedGroupFilter,
})
})
setInitLoading(false)
}
return () => {
setSelectedAppList([])
Expand All @@ -136,13 +159,13 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
}
}, [envId])

const getSavedFilterData = async (groupId?: number): Promise<void> => {
const getSavedFilterData = async (groupId?: number): Promise<GroupOptionType[]> => {
setSelectedAppList([])
setAppListLoading(true)
const { result } = await getEnvGroupList(+envId)

const _groupFilterOption = []
if (result) {
const _groupFilterOption = []
let _selectedGroup
for (const group of result) {
const processedGroupData = {
Expand All @@ -162,8 +185,15 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
for (const appId of groupAppIds) {
selectedAppsMap[appId] = true
}
setSelectedAppList(appListOptions.filter((app) => selectedAppsMap[app.value]))
const filteredAppList = appListOptions.filter((app) => selectedAppsMap[app.value])
setSelectedAppList(filteredAppList)
setSelectedGroupFilter([_selectedGroup])
setAppGroupFilterInLocalStorage({
filterParentType,
resourceId: envId,
resourceList: filteredAppList,
groupList: [_selectedGroup],
})
} else {
setSelectedAppList([])
setSelectedGroupFilter([])
Expand All @@ -172,6 +202,7 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
setGroupFilterOptions(_groupFilterOption)
}
setAppListLoading(false)
return _groupFilterOption
}

const handleSaveDescription = async (value: string) => {
Expand All @@ -197,28 +228,29 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
}
}

const getAppListData = async (): Promise<void> => {
const getAppListData = async (): Promise<OptionType[]> => {
setSelectedAppList([])
setAppListLoading(true)
const { result } = await getAppGroupList(+envId)
setAppGroupListData(result)
setDescription(result.description)
if (result.apps?.length) {
const _appListOptions = result.apps
.map((app): OptionType => {
return {
value: `${app.appId}`,
label: app.appName,
}
})
.sort(sortOptionsByLabel)

setAppListOptions(_appListOptions)
if (selectedGroupFilter.length) {
setSelectedAppList(_appListOptions.filter((app) => selectedGroupFilter[0].appIds.includes(+app.value)))
}
const _appListOptions = result.apps?.length
? result.apps
.map((app): OptionType => {
return {
value: `${app.appId}`,
label: app.appName,
}
})
.sort(sortOptionsByLabel)
: []

setAppListOptions(_appListOptions)
if (selectedGroupFilter.length) {
setSelectedAppList(_appListOptions.filter((app) => selectedGroupFilter[0].appIds.includes(+app.value)))
}
setAppListLoading(false)
return _appListOptions
}

const handleToast = (action: string) => {
Expand Down Expand Up @@ -391,7 +423,7 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
}, [selectedAppList, appGroupListData?.apps, appGroupListData?.description])

const renderRoute = () => {
if (loading || appListLoading) {
if (initLoading || loading || appListLoading) {
return <Progressing pageLoader />
}
if (showEmpty) {
Expand Down Expand Up @@ -462,7 +494,7 @@ export default function AppGroupDetailsRoute({ isSuperAdmin }: AppGroupAdminType
appList={allAppsList}
selectedAppGroup={clickedGroup}
closePopup={closeCreateGroup}
filterParentType={FilterParentType.env}
filterParentType={filterParentType}
/>
)}
{showDeleteGroup && isPopupBox && (
Expand Down
Loading
Loading