import classnames from 'classnames'; import React from 'react'; import { Illustration } from '@spinnaker/presentation'; import { ApplicationQueryError } from '../ApplicationQueryError'; import { DeliveryConfig } from './DeliveryConfig'; import { GitIntegration } from './GitIntegration'; import { UnmanagedMessage } from '../UnmanagedMessage'; import { SETTINGS } from '../../config/settings'; import { FetchApplicationManagementDataDocument, useFetchApplicationManagementDataQuery, useToggleManagementMutation, } from '../graphql/graphql-sdk'; import { Messages } from '../messages/Messages'; import { showModal, useApplicationContextSafe } from '../../presentation'; import type { IArtifactActionModalProps } from '../utils/ActionModal'; import { ActionModal } from '../utils/ActionModal'; import { getIsDebugMode } from '../utils/debugMode'; import { getDocsUrl, MODAL_MAX_WIDTH, spinnerProps } from '../utils/defaults'; import { useLogEvent } from '../utils/logging'; import { useNotifyOnError } from '../utils/useNotifyOnError.hook'; import { Spinner } from '../../widgets'; const BTN_CLASSNAMES = 'btn md-btn'; const managementStatusToContent = { PAUSED: { title: 'Application management is disabled', btnText: 'Resume management...', btnClassName: 'md-btn-success', }, ENABLED: { title: 'Application is managed by Spinnaker 🙌', btnText: 'Disable management...', btnClassName: 'md-btn-danger', }, }; export const Configuration = () => { const appName = useApplicationContextSafe().name; const { data, error, loading } = useFetchApplicationManagementDataQuery({ variables: { appName }, errorPolicy: 'all', }); const logError = useLogEvent('DeliveryConfig'); React.useEffect(() => { if (error) { logError({ action: 'LoadingFailed', data: { error } }); } }, [error, logError]); if (loading || !data) { return ; } if (error && !Boolean(data?.application)) { return ; } const gitIntegration = data.application?.gitIntegration; const isDebug = getIsDebugMode(); const config = data.application?.config; return (
{error && } {SETTINGS.feature.mdGitIntegration && gitIntegration && } {isDebug && }
); }; interface IManagementToggleProps { isPaused?: boolean; } const ManagementToggle = ({ isPaused }: IManagementToggleProps) => { const appName = useApplicationContextSafe().name; const logEvent = useLogEvent('Management'); const [toggleManagement, { loading: mutationInFlight, error }] = useToggleManagementMutation({ refetchQueries: [{ query: FetchApplicationManagementDataDocument, variables: { appName } }], }); useNotifyOnError({ key: 'toggleManagement', content: `Failed to ${isPaused ? 'enable' : 'disable'} management`, error, }); const onShowToggleManagementModal = React.useCallback((shouldPause: boolean) => { logEvent({ action: 'OpenModal', data: { shouldPause } }); showModal( shouldPause ? DisableManagementModal : ResumeManagementModal, { application: appName, onAction: async () => { toggleManagement({ variables: { application: appName, isPaused: shouldPause } }); }, logCategory: 'Management', withComment: false, }, { maxWidth: MODAL_MAX_WIDTH }, ); }, []); const state = managementStatusToContent[isPaused ? 'PAUSED' : 'ENABLED']; return (

Management

{state.title}
{mutationInFlight && ( )}
); }; type InternalModalProps = Omit & { application: string }; export const ResumeManagementModal = ({ application, ...props }: InternalModalProps) => { return (

You’re about to resume management for this application. The latest good version approved for deployment will be deployed to each environment, and any configuration changes made while disabled will take effect.

); }; export const DisableManagementModal = ({ application, ...props }: InternalModalProps) => { return (

Careful! You’re about to stop Spinnaker from managing all resources in your application. This feature should only be used if management is not working properly and manual intervention is required.{' '} Check our documentation for more information .

Need to rollback?{' '} Try pinning a version instead .

); };