Skip to content

Commit

Permalink
feat: Added stop/re-run button in experiment dashboard table and righ…
Browse files Browse the repository at this point in the history
…t sidebar (#4255)

* feat: Added stop experiment run feature in FE

Signed-off-by: Hrishav <[email protected]>

* chore: Updated manifest link

Signed-off-by: Hrishav <[email protected]>

* fix: Fixed add probe button shrinking issue

Signed-off-by: Hrishav <[email protected]>

* chore: removed propreitary message

Signed-off-by: Hrishav <[email protected]>

---------

Signed-off-by: Hrishav <[email protected]>
  • Loading branch information
hrishavjha authored Nov 3, 2023
1 parent 304d32e commit 11f97f6
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 63 deletions.
2 changes: 1 addition & 1 deletion chaoscenter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ helm install my-release bitnami/mongodb --values mongo-values.yml -n <NAMESPACE>
Applying the manifest file will install all the required service account configuration and ChaosCenter in cluster scope.

```shell
kubectl apply -f https://github.com/litmuschaos/litmus/blob/master/mkdocs/docs/3.0.0/litmus-cluster-scope-3.0.0.yaml
kubectl apply -f https://raw.githubusercontent.com/litmuschaos/litmus/master/mkdocs/docs/3.0.0/litmus-cluster-scope-3.0.0.yaml
```
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func (c *ChaosExperimentRunHandler) GetExperimentRun(ctx context.Context, projec
{"$project", bson.D{
{"name", 1},
{"is_custom_experiment", 1},
{"experiment_type", 1},
{"revision", bson.D{{
"$filter", bson.D{
{"input", "$revision"},
Expand Down Expand Up @@ -229,10 +230,13 @@ func (c *ChaosExperimentRunHandler) GetExperimentRun(ctx context.Context, projec
}
}

expType := string(wfRun.ExperimentDetails[0].ExperimentType)

expRunResponse = &model.ExperimentRun{
ExperimentName: wfRun.ExperimentDetails[0].ExperimentName,
ExperimentID: wfRun.ExperimentID,
ExperimentRunID: wfRun.ExperimentRunID,
ExperimentType: &expType,
NotifyID: wfRun.NotifyID,
Weightages: weightages,
ExperimentManifest: workflowRunManifest,
Expand Down
15 changes: 0 additions & 15 deletions chaoscenter/web/src/api/core/experiments/stopWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,3 @@ export function stopExperimentRun(

return [stopExperimentRunMutation, result];
}

export function stopAllExperiments(
options?: GqlAPIMutationRequest<StopAllExperimentResponse, StopAllExperimentRequest>
): GqlAPIMutationResponse<StopAllExperimentResponse, StopAllExperimentRequest> {
const [stopAllExperimentsMutation, result] = useMutation<StopAllExperimentResponse, StopAllExperimentRequest>(
gql`
mutation stopAllExperimentRuns($projectID: ID!) {
stopAllExperimentRuns(projectID: $projectID)
}
`,
options
);

return [stopAllExperimentsMutation, result];
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import React from 'react';
import { Color, PopoverProps } from '@harnessio/design-system';
import { useToaster, ButtonVariation, ButtonProps } from '@harnessio/uicore';
import {
useToaster,
ButtonVariation,
ButtonProps,
ConfirmationDialog,
ConfirmationDialogProps,
useToggleOpen
} from '@harnessio/uicore';
import cx from 'classnames';
import { Position } from '@blueprintjs/core';
import { Intent, Position } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import { parse } from 'yaml';
import { useStrings } from '@strings';
import { listExperiment, runChaosExperiment } from '@api/core';
import { listExperiment, runChaosExperiment, stopExperiment, stopExperimentRun } from '@api/core';
import { useRouteWithBaseUrl } from '@hooks';
import type { RefetchExperiments } from '@controllers/ExperimentDashboardV2';
import type { RefetchExperimentRuns, RefetchExperiments } from '@controllers/ExperimentDashboardV2';
import { PermissionGroup, StudioTabs } from '@models';
import RbacButton from '@components/RbacButton';
import { downloadYamlAsFile, getScope, yamlStringify } from '@utils';
import type { InfrastructureType } from '@api/entities';
import css from './ExperimentActionButton.module.scss';

interface ActionButtonProps {
Expand All @@ -24,6 +32,12 @@ interface RunExperimentButtonProps extends ActionButtonProps, Partial<RefetchExp
disabled?: boolean;
}

interface StopExperimentButtonProps extends ActionButtonProps, Partial<RefetchExperiments> {
buttonProps?: ButtonProps;
infrastructureType: InfrastructureType | undefined;
disabled?: boolean;
}

export const RunExperimentButton = ({
experimentID,
tooltipProps,
Expand Down Expand Up @@ -70,13 +84,6 @@ export const RunExperimentButton = ({
withoutCurrentColor
variation={ButtonVariation.ICON}
permission={PermissionGroup.EDITOR}
// permission={{
// resourceScope: scope,
// resource: {
// resourceType: ResourceType.CHAOS_EXPERIMENT
// },
// permission: PermissionIdentifier.EXECUTE_CHAOS_EXPERIMENT
// }}
onClick={() => {
runChaosExperimentMutation({
variables: { projectID: scope.projectID, experimentID: experimentID }
Expand All @@ -88,6 +95,154 @@ export const RunExperimentButton = ({
);
};

export const StopExperimentButton = ({
experimentID,
tooltipProps,
refetchExperiments,
disabled
}: StopExperimentButtonProps): React.ReactElement => {
const scope = getScope();
const { getString } = useStrings();
const { showSuccess, showError } = useToaster();
const {
isOpen: isOpenStopExperimentDialog,
open: openStopExperimentDialog,
close: closeStopExperimentDialog
} = useToggleOpen();

const [stopExperimentMutation] = stopExperiment({
onCompleted: () => {
showSuccess(getString('experimentStopSuccessMessage'));
refetchExperiments?.();
},
onError: err => showError(err.message)
});

const stopExperimentDialogProps: ConfirmationDialogProps = {
isOpen: isOpenStopExperimentDialog,
contentText: getString('stopExperimentDesc'),
titleText: getString('stopExperimentHeading'),
cancelButtonText: getString('cancel'),
confirmButtonText: getString('confirm'),
intent: Intent.DANGER,
buttonIntent: Intent.DANGER,
onClose: (isConfirmed: boolean) => {
if (isConfirmed) {
stopExperimentMutation({
variables: {
projectID: scope.projectID,
experimentID
}
});
}
closeStopExperimentDialog();
}
};

const stopExperimentDialog = <ConfirmationDialog {...stopExperimentDialogProps} />;

return (
<div className={cx(css.actionButtons, css.withBg, css.hoverRed)}>
<div>
<RbacButton
tooltip={getString('stopExpRuns')}
iconProps={{ size: 18 }}
withoutCurrentColor
disabled={disabled}
tooltipProps={{
position: Position.TOP,
usePortal: true,
isDark: true,
...tooltipProps
}}
permission={PermissionGroup.EDITOR}
variation={ButtonVariation.ICON}
icon={'stop'}
onClick={openStopExperimentDialog}
/>
</div>
{stopExperimentDialog}
</div>
);
};

interface StopExperimentRunButtonProps extends ActionButtonProps, Partial<RefetchExperimentRuns> {
experimentRunID?: string;
notifyID?: string;
infrastructureType: InfrastructureType | undefined;
}

export const StopExperimentRunButton = ({
experimentID,
experimentRunID,
tooltipProps,
refetchExperimentRuns
}: StopExperimentRunButtonProps): React.ReactElement => {
const scope = getScope();
const { getString } = useStrings();
const { showSuccess, showError } = useToaster();
const {
isOpen: isOpenStopExperimentRunModal,
open: openStopExperimentRunDialog,
close: closeStopExperimentRunDialog
} = useToggleOpen();

const [stopExperimentRunMutation] = stopExperimentRun({
onCompleted: () => {
showSuccess(getString('experimentStopSuccessMessage'));
refetchExperimentRuns?.();
},
onError: err => showError(err.message)
});

const stopExperimentRunDialogProps: ConfirmationDialogProps = {
isOpen: isOpenStopExperimentRunModal,
contentText: getString('stopExpRunDesc'),
titleText: `${getString('stopExpRun')}?`,
cancelButtonText: getString('cancel'),
confirmButtonText: getString('confirm'),
intent: Intent.DANGER,
buttonIntent: Intent.DANGER,
onClose: (isConfirmed: boolean) => {
if (isConfirmed) {
stopExperimentRunMutation({
variables: {
experimentID,
projectID: scope.projectID,
experimentRunID
}
});
}
closeStopExperimentRunDialog();
}
};

const stopExperimentRunDialog = <ConfirmationDialog {...stopExperimentRunDialogProps} />;

return (
<div className={cx(css.actionButtons, css.withBg, css.hoverRed)}>
<div>
<RbacButton
tooltip={getString('stopExpRun')}
iconProps={{ size: 18 }}
withoutCurrentColor
tooltipProps={{
position: Position.TOP,
usePortal: true,
isDark: true,
...tooltipProps
}}
variation={ButtonVariation.ICON}
icon={'stop'}
permission={PermissionGroup.EDITOR}
onClick={openStopExperimentRunDialog}
/>
</div>
{stopExperimentRunDialog}
</div>
);
};

export const EditExperimentButton = ({ experimentID, tooltipProps }: ActionButtonProps): React.ReactElement => {
const history = useHistory();
const paths = useRouteWithBaseUrl();
Expand Down
Loading

0 comments on commit 11f97f6

Please sign in to comment.