Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for enforcement of approval policy in deployment and configuration change #2247

Merged
merged 63 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
2964232
feat: add route for approval policy in global configuration
eshankvaish Nov 21, 2024
ffa10f1
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Nov 26, 2024
0c41879
chore: bump common
eshankvaish Nov 26, 2024
b2dd1c1
refactor: comment out the to be removed code
eshankvaish Nov 26, 2024
377bdf8
feat: add approvalConfigData in cd pipeline
eshankvaish Nov 28, 2024
9671b8f
feat: add target id to workflow editor container
eshankvaish Nov 28, 2024
bc1c763
fix: parsing issue for approval config data
eshankvaish Nov 28, 2024
7f9889e
refactor: remove unused code
eshankvaish Nov 28, 2024
10d1215
refactor: decouple the isProtected for configurations
eshankvaish Nov 28, 2024
f4abdb3
refactor: rename isProtected to isApprovalApplicable
eshankvaish Nov 28, 2024
cda5da4
feat: add is approval policy configured in deployment config compare
eshankvaish Nov 28, 2024
0d0a7a5
refactor: fix the condition for isProtected
eshankvaish Nov 29, 2024
f51b0fd
feat: add approval info tippy
eshankvaish Nov 29, 2024
42adbcb
feat: add user approval meta data
eshankvaish Nov 29, 2024
2181b68
feat: add approved by you button
eshankvaish Nov 29, 2024
795918c
fix: position the approve button to the rightx
eshankvaish Nov 29, 2024
8250476
fix: unused import
eshankvaish Nov 29, 2024
6afd6d4
refactor: remove deprecated items
eshankvaish Nov 29, 2024
022a212
refactor: improve naming convention
eshankvaish Nov 29, 2024
59412f9
refactor: code clean up and refactoring
eshankvaish Nov 29, 2024
064e270
refactor: remove deprecated code
eshankvaish Nov 30, 2024
5200b0a
fix: approvalConfigMap
eshankvaish Nov 30, 2024
a390011
fix: column gap for image card
eshankvaish Dec 2, 2024
27e2be6
refactor: clean up renderNavItem
eshankvaish Dec 2, 2024
a2b2d01
refactor: code clean up
eshankvaish Dec 2, 2024
cd7c533
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 2, 2024
d6f1ccd
refactor: remove unused code
eshankvaish Dec 2, 2024
13b094e
fix: approval policy configured state on app details
eshankvaish Dec 2, 2024
92fe1dc
refactor: remove redundant code
eshankvaish Dec 2, 2024
6f6bffa
chore: bump common lib
eshankvaish Dec 3, 2024
d63ea24
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 5, 2024
0299ba5
chore: bump common
eshankvaish Dec 5, 2024
8069a16
refactor: code review comments
eshankvaish Dec 6, 2024
f298447
Merge branch 'develop' of github.com:devtron-labs/dashboard into fix/…
eshankvaish Dec 6, 2024
eb6de2e
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 6, 2024
8d613fe
Merge branch 'feat/approval-policy' of github.com:devtron-labs/dashbo…
eshankvaish Dec 6, 2024
98dc53c
fix: approval policy icon for base configuration
eshankvaish Dec 6, 2024
73dfbce
Merge pull request #2269 from devtron-labs/fix/approval-policy
eshankvaish Dec 6, 2024
2927982
fix: migrate to use isApprovalPolicyApplicable
eshankvaish Dec 6, 2024
ac95b53
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 10, 2024
1b03553
Merge branch 'feat/approval-policy' of github.com:devtron-labs/dashbo…
eshankvaish Dec 10, 2024
aa876bf
chore: version bump
eshankvaish Dec 10, 2024
9aee02e
fix: approval policy icon for base configurations
eshankvaish Dec 11, 2024
b4a338e
fix: check for base configurations
eshankvaish Dec 11, 2024
393b5dc
fix: icons for base configuration
eshankvaish Dec 12, 2024
9708082
fix: approve changes styling
eshankvaish Dec 12, 2024
b891099
Merge branch 'develop' of github.com:devtron-labs/dashboard into fix/…
eshankvaish Dec 12, 2024
f2a584f
fix: alignment for save changes button
eshankvaish Dec 12, 2024
c399204
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 12, 2024
a19a2cc
Merge branch 'feat/approval-policy' of github.com:devtron-labs/dashbo…
eshankvaish Dec 12, 2024
e1c7f4d
feat: add requestedUserId in config toolbar
eshankvaish Dec 13, 2024
9919454
Merge pull request #2270 from devtron-labs/fix/approval-policy
eshankvaish Dec 13, 2024
19f23bc
fix: edit file icon stroke effect
eshankvaish Dec 16, 2024
0f06f40
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 17, 2024
0678137
fix: icon color for approval pending
eshankvaish Dec 17, 2024
b245599
fix: alignment for save changes button
eshankvaish Dec 17, 2024
417bbd8
chore: version bump for common
eshankvaish Dec 18, 2024
7b2517d
Merge branch 'develop' into feat/approval-policy
eshankvaish Dec 19, 2024
997157c
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 19, 2024
b492486
refactor: remove unused css
eshankvaish Dec 24, 2024
4e9a833
Merge branch 'develop' of github.com:devtron-labs/dashboard into feat…
eshankvaish Dec 24, 2024
7cf83f6
Merge branch 'develop' into feat/approval-policy
AbhishekA1509 Dec 26, 2024
6186d35
chore: bump devtron-fe-common-lib version to 1.3.9
AbhishekA1509 Dec 27, 2024
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"homepage": "/dashboard",
"dependencies": {
"@devtron-labs/devtron-fe-common-lib": "1.3.0",
"@devtron-labs/devtron-fe-common-lib": "1.3.0-beta-4",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@rjsf/core": "^5.13.3",
"@rjsf/utils": "^5.13.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EnvResourceType } from '@devtron-labs/devtron-fe-common-lib'
import { BASE_CONFIGURATION_ENV_ID, EnvResourceType } from '@devtron-labs/devtron-fe-common-lib'

export const BASE_CONFIGURATIONS = {
id: -1,
id: BASE_CONFIGURATION_ENV_ID,
name: 'Base Configurations',
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
ResourceKindType,
ToastManager,
ToastVariantType,
ResourceIdToResourceApprovalPolicyConfigMapType,
} from '@devtron-labs/devtron-fe-common-lib'
import { URLS, getAppComposeURL, APP_COMPOSE_STAGE, ViewType } from '../../../../../config'
import { importComponentFromFELibrary } from '../../../../../components/common'
Expand All @@ -38,7 +39,6 @@ import {
AppStageUnlockedType,
STAGE_NAME,
DEFAULT_LANDING_STAGE,
ConfigProtection,
} from './AppConfig.types'
import { getUserRole } from '../../../../GlobalConfigurations/Authorization/authorization.service'
import { isCIPipelineCreated, isCDPipelineCreated, getNavItems, isUnlocked } from './AppConfig.utils'
Expand All @@ -47,13 +47,12 @@ import { UserRoleType } from '../../../../GlobalConfigurations/Authorization/con
import { AppNavigation } from './Navigation/AppNavigation'
import { AppConfigStatusItemType } from '../../service.types'
import { getAppConfigStatus, getEnvConfig } from '../../service'
import { AppOtherEnvironment } from '../../../../../services/service.types'
import { deleteApp } from './AppConfig.service'
import { AppConfigurationProvider } from './AppConfiguration.provider'
import { ENV_CONFIG_PATH_REG } from './AppConfig.constants'

const ConfigProtectionView = importComponentFromFELibrary('ConfigProtectionView')
const getConfigProtections = importComponentFromFELibrary('getConfigProtections', null, 'function')
const getApprovalPolicyConfigForApp: (appId: number) => Promise<ResourceIdToResourceApprovalPolicyConfigMapType> =
importComponentFromFELibrary('getApprovalPolicyConfigForApp', null, 'function')

export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigProps) => {
// HOOKS
Expand All @@ -79,8 +78,7 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
canDeleteApp: false,
workflowsRes: null,
environmentList: [],
isBaseConfigProtected: false,
configProtectionData: [],
envIdToEnvApprovalConfigurationMap: {} as ResourceIdToResourceApprovalPolicyConfigMapType,
envConfig: {
isLoading: true,
config: null,
Expand All @@ -98,55 +96,36 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
*
* The function performs the following steps:
* 1. Calls `getAppOtherEnvironmentMin` or `getJobOtherEnvironmentMin` (if resource kind is `job` (isJob)) with the application ID (`appId`) to fetch the environment configurations.
* 2. Calls `getConfigProtections` with the application ID (`appId`) if the function is defined and resource kind is `job` (isJob), to fetch configuration protections.
* 2. Calls `getApprovalPolicyConfigForApp` with the application ID (`appId`) if the function is defined and resource kind is `job` (isJob), to fetch configuration protections.
* 3. Creates a map (`envProtectMap`) to store protection states for each environment based on the configuration protections response.
* 4. Filters the environment configurations based on `filteredEnvIds`, if provided, and marks them as protected if they are found in the protection map.
* 5. Sorts the filtered and updated environments by their names.
* 6. Determines if base configuration protection is enabled by checking the protection map for the key `-1`.
*
* The promise resolves to an object with the following properties:
* - `updatedEnvs`: An array of updated environment configurations, each marked with a protection status.
* - `isBaseConfigProtectionEnabled`: A boolean flag indicating if the base configuration protection is enabled.
* - `configProtections`: An array of configuration protection objects.
*/
const fetchEnvironments = (): Promise<{
updatedEnvs: AppOtherEnvironment['result']
isBaseConfigProtectionEnabled: boolean
configProtections: ConfigProtection[]
updatedEnvs: AppConfigState['environmentList']
envIdToEnvApprovalConfigurationMap: ResourceIdToResourceApprovalPolicyConfigMapType
}> =>
Promise.all([
isJob ? getJobOtherEnvironmentMin(appId) : getAppOtherEnvironmentMin(appId),
typeof getConfigProtections === 'function' && !isJob ? getConfigProtections(Number(appId)) : null,
]).then(([envResult, configProtectionsResp]) => {
let envProtectMap: Record<number, boolean> = {}

if (configProtectionsResp?.result) {
envProtectMap = configProtectionsResp.result.reduce((acc, config) => {
acc[config.envId] = config.state === 1
return acc
}, {})
}

typeof getApprovalPolicyConfigForApp === 'function' && !isJob
? getApprovalPolicyConfigForApp(Number(appId))
: null,
]).then(([envResult, envIdToEnvApprovalConfigurationMap]) => {
const filteredEnvMap = filteredEnvIds?.split(',').reduce((agg, curr) => agg.set(+curr, true), new Map())

const updatedEnvs =
const updatedEnvs: AppConfigState['environmentList'] =
envResult.result
?.filter((env) => !filteredEnvMap || filteredEnvMap.get(env.environmentId))
.map((env) => {
const envData = { ...env, isProtected: false }
if (envProtectMap[env.environmentId]) {
envData.isProtected = true
}
return envData
})
?.sort((envA, envB) => envA.environmentName.localeCompare(envB.environmentName)) || []

const isBaseConfigProtectionEnabled = envProtectMap[-1] ?? false

return {
updatedEnvs,
isBaseConfigProtectionEnabled,
configProtections: configProtectionsResp?.result ?? [],
envIdToEnvApprovalConfigurationMap,
}
})

Expand Down Expand Up @@ -271,15 +250,24 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
}
}

const processConfigStatusData = (configStatusRes: AppConfigStatusItemType[]) => {
const processConfigStatusData = (
configStatusRes: AppConfigStatusItemType[],
envIdToEnvApprovalConfigurationMap: AppConfigState['envIdToEnvApprovalConfigurationMap'],
) => {
const _isGitOpsConfigurationRequired = configStatusRes.find(
({ stageName }) => stageName === STAGE_NAME.GITOPS_CONFIG,
)?.required
const { configs, lastConfiguredStage } = getUnlockedConfigsAndLastStage(
configStatusRes,
_isGitOpsConfigurationRequired,
)
const { navItems } = getNavItems(configs, appId, resourceKind, _isGitOpsConfigurationRequired)
const { navItems } = getNavItems({
_isUnlocked: configs,
appId,
resourceKind,
isGitOpsConfigurationRequired: _isGitOpsConfigurationRequired,
envIdToEnvApprovalConfigurationMap,
})
// Finding index of navItem which is locked and is not of alternate nav menu (nav-item rendering on different path)
let index = navItems.findIndex((item) => !item.altNavKey && item.isLocked)
if (index < 0) {
Expand All @@ -294,10 +282,9 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
useEffect(() => {
if (appConfigData) {
// SET APP CONFIG DATA IN STATE
const [configStatusRes, workflowRes, { updatedEnvs, configProtections, isBaseConfigProtectionEnabled }] =
appConfigData
const [configStatusRes, workflowRes, { updatedEnvs, envIdToEnvApprovalConfigurationMap }] = appConfigData
const { navItems, isCDPipeline, isCiPipeline, configs, redirectUrl, lastConfiguredStage } =
processConfigStatusData(configStatusRes.result)
processConfigStatusData(configStatusRes.result, envIdToEnvApprovalConfigurationMap)

setState({
...state,
Expand All @@ -314,8 +301,7 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
canDeleteApp: workflowRes.result.workflows.length === 0,
workflowsRes: workflowRes.result,
environmentList: updatedEnvs,
isBaseConfigProtected: isBaseConfigProtectionEnabled,
configProtectionData: configProtections,
envIdToEnvApprovalConfigurationMap,
})
if (location.pathname === match.url) {
history.replace(redirectUrl)
Expand Down Expand Up @@ -370,6 +356,7 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
.then((configStatusRes) => {
const { navItems, isCDPipeline, isCiPipeline, configs, redirectUrl } = processConfigStatusData(
configStatusRes.result,
state.envIdToEnvApprovalConfigurationMap,
)
setState((prevState) => ({
...prevState,
Expand All @@ -394,12 +381,11 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr

const reloadEnvironments = () => {
fetchEnvironments()
.then(({ updatedEnvs, isBaseConfigProtectionEnabled, configProtections }) => {
.then(({ updatedEnvs, envIdToEnvApprovalConfigurationMap }) => {
setState((prevState) => ({
...prevState,
environmentList: updatedEnvs,
isBaseConfigProtected: isBaseConfigProtectionEnabled,
configProtectionData: configProtections,
envIdToEnvApprovalConfigurationMap,
}))
})
.catch((errors) => {
Expand Down Expand Up @@ -477,9 +463,7 @@ export const AppConfig = ({ appName, resourceKind, filteredEnvIds }: AppConfigPr
: 'app-compose-with-no-gitops-config__nav'
} ${isJob ? 'job-compose__side-nav' : ''} ${
!showCannotDeleteTooltip ? 'dc__position-rel' : ''
} ${hideConfigHelp ? 'hide-app-config-help' : ''} ${!canShowExternalLinks ? 'hide-external-links' : ''} ${
state.isUnlocked.workflowEditor && ConfigProtectionView && !isJob ? 'config-protection__side-nav' : ''
}`
} ${hideConfigHelp ? 'hide-app-config-help' : ''} ${!canShowExternalLinks ? 'hide-external-links' : ''}`
}

const toggleRepoSelectionTippy = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
AppEnvDeploymentConfigType,
EnvResourceType,
AppEnvironment,
ResourceIdToResourceApprovalPolicyConfigMapType,
} from '@devtron-labs/devtron-fe-common-lib'

import { ViewType } from '@Config/constants'
Expand All @@ -43,7 +44,6 @@ export enum STAGE_NAME {
SECRETS = 'SECRETS',
ENV_OVERRIDE = 'ENV_OVERRIDE',
EXTERNAL_LINKS = 'EXTERNAL_LINKS',
PROTECT_CONFIGURATION = 'PROTECT_CONFIGURATION',
REDIRECT_ITEM = 'REDIRECT_ITEM',
}

Expand Down Expand Up @@ -92,10 +92,7 @@ export interface AppConfigState {
workflowsRes?: WorkflowResult
/** Array containing environments data. */
environmentList?: AppEnvironment[]
/** Boolean indicating if the base configuration is protected. */
isBaseConfigProtected?: boolean
/** Array of configuration protection data which denotes which env is in protected state. */
configProtectionData?: ConfigProtection[]
envIdToEnvApprovalConfigurationMap: ResourceIdToResourceApprovalPolicyConfigMapType
/** The environment config containing the loading state, configState and title of deployment template, configmaps & secrets. */
envConfig: EnvConfigurationState
}
Expand Down Expand Up @@ -140,17 +137,6 @@ export interface NextButtonProps {
isDisabled: boolean
}

export enum ProtectionState {
ENABLED = 1,
DISABLED = 2,
}

export type ConfigProtection = {
appId: number
envId: number
state: ProtectionState
}

interface CommonAppConfigurationProps {
appId: string
resourceKind: Extract<ResourceKindType, ResourceKindType.devtronApplication | ResourceKindType.job>
Expand All @@ -169,17 +155,18 @@ interface CommonAppConfigurationProps {
fetchEnvConfig: (envId: number) => void
}

export interface AppConfigurationContextType extends CommonAppConfigurationProps {
export interface AppConfigurationContextType
extends CommonAppConfigurationProps,
Pick<AppConfigState, 'envIdToEnvApprovalConfigurationMap'> {
isUnlocked: AppStageUnlockedType
navItems: CustomNavItemsType[]
isCiPipeline: boolean
isCDPipeline: boolean
environments: AppEnvironment[]
environments: AppConfigState['environmentList']
workflowsRes: WorkflowResult
setRepoState: React.Dispatch<React.SetStateAction<string>>
isJobView: boolean
isBaseConfigProtected: boolean
configProtectionData: ConfigProtection[]
envIdToEnvApprovalConfigurationMap: ResourceIdToResourceApprovalPolicyConfigMapType
lastUnlockedStage: string
isWorkflowEditorUnlocked: boolean
getRepo: string
Expand Down Expand Up @@ -214,13 +201,11 @@ export enum EnvConfigObjectKey {
export interface EnvironmentOptionType {
name: string
id: number
isProtected?: boolean
}

export interface EnvConfigurationsNavProps {
export interface EnvConfigurationsNavProps extends Pick<AppConfigState, 'envIdToEnvApprovalConfigurationMap'> {
envConfig: EnvConfigurationState
fetchEnvConfig: (envId: number) => void
isBaseConfigProtected?: boolean
environments: EnvironmentOptionType[]
paramToCheck?: 'appId' | 'envId'
goBackURL: string
Expand Down Expand Up @@ -259,9 +244,9 @@ export interface DeploymentConfigParams {
}

export type DeploymentConfigCompareProps = {
appOrEnvIdToResourceApprovalConfigurationMap: AppConfigState['envIdToEnvApprovalConfigurationMap']
environments: EnvironmentOptionType[]
goBackURL?: string
isBaseConfigProtected?: boolean
getNavItemHref: (resourceType: EnvResourceType, resourceName: string) => string
overwriteNavHeading?: string
} & (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@
* limitations under the License.
*/

import { ResourceKindType, stringComparatorBySortOrder, ConfigResourceType } from '@devtron-labs/devtron-fe-common-lib'
import {
ResourceKindType,
stringComparatorBySortOrder,
ConfigResourceType,
BASE_CONFIGURATION_ENV_ID,
} from '@devtron-labs/devtron-fe-common-lib'

import { URLS, DOCUMENTATION } from '@Config/index'
import { DOCUMENTATION } from '@Config/index'

import { AppConfigStatusItemType, EnvConfigDTO } from '../../service.types'
import { AppStageUnlockedType, CustomNavItemsType, EnvConfigType, STAGE_NAME } from './AppConfig.types'
import { AppConfigState, AppStageUnlockedType, CustomNavItemsType, EnvConfigType, STAGE_NAME } from './AppConfig.types'

// stage: last configured stage
const isCommonUnlocked = (stage, isGitOpsConfigurationRequired) =>
Expand Down Expand Up @@ -92,12 +97,18 @@ export const getCompletedStep = (
return 0
}

export const getNavItems = (
_isUnlocked: AppStageUnlockedType,
appId: string,
resourceKind: ResourceKindType,
isGitOpsConfigurationRequired: boolean,
): { navItems: CustomNavItemsType[] } => {
export const getNavItems = ({
_isUnlocked,
appId,
resourceKind,
isGitOpsConfigurationRequired,
envIdToEnvApprovalConfigurationMap,
}: Pick<AppConfigState, 'envIdToEnvApprovalConfigurationMap'> & {
_isUnlocked: AppStageUnlockedType
appId: string
resourceKind: ResourceKindType
isGitOpsConfigurationRequired: boolean
}): { navItems: CustomNavItemsType[] } => {
const completedSteps = getCompletedStep(
_isUnlocked,
resourceKind === ResourceKindType.job,
Expand Down Expand Up @@ -203,7 +214,8 @@ export const getNavItems = (
href: `/app/${appId}/edit/deployment-template`,
stage: STAGE_NAME.REDIRECT_ITEM,
isLocked: !_isUnlocked.deploymentTemplate,
isProtectionAllowed: true,
isProtectionAllowed:
envIdToEnvApprovalConfigurationMap?.[BASE_CONFIGURATION_ENV_ID]?.isApprovalApplicable,
required: true,
},
{
Expand Down Expand Up @@ -270,12 +282,6 @@ export const getNavItems = (
flowCompletionPercent: completedPercent,
currentStep: completedSteps,
},
{
title: 'Protect Configuration',
href: `/app/${appId}/edit/${URLS.APP_CONFIG_PROTECTION}`,
stage: STAGE_NAME.PROTECT_CONFIGURATION,
isLocked: false,
},
{
title: 'Environment Override',
href: `/app/${appId}/edit/env-override`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export const AppConfigurationProvider = (props: AppConfigurationProviderProps) =
hideConfigHelp,
workflowsRes: state.workflowsRes,
getWorkflows,
isBaseConfigProtected: state.isBaseConfigProtected,
reloadEnvironments,
isGitOpsConfigurationRequired,
isUnlocked: state.isUnlocked,
Expand All @@ -69,7 +68,7 @@ export const AppConfigurationProvider = (props: AppConfigurationProviderProps) =
environments: state.environmentList,
userRole,
setRepoState: setShowRepoOnDelete,
configProtectionData: state.configProtectionData,
envIdToEnvApprovalConfigurationMap: state.envIdToEnvApprovalConfigurationMap,
filteredEnvIds,
reloadAppConfig,
lastUnlockedStage: state.redirectionUrl,
Expand Down
Loading
Loading