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
26 changes: 18 additions & 8 deletions x-pack/plugins/cases/public/components/add_comment/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { TestProviders } from '../../common/mock';

import { CommentRequest, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common';
import { usePostComment } from '../../containers/use_post_comment';
import { AddComment, AddCommentRefObject } from '.';
import { AddComment, AddCommentProps, AddCommentRefObject } from '.';
import { CasesTimelineIntegrationProvider } from '../timeline_context';
import { timelineIntegrationMock } from '../__mock__/timeline';

Expand All @@ -25,10 +25,9 @@ const onCommentSaving = jest.fn();
const onCommentPosted = jest.fn();
const postComment = jest.fn();

const addCommentProps = {
const addCommentProps: AddCommentProps = {
caseId: '1234',
disabled: false,
insertQuote: null,
userCanCrud: true,
onCommentSaving,
onCommentPosted,
showLoading: false,
Expand Down Expand Up @@ -94,11 +93,11 @@ describe('AddComment ', () => {
).toBeTruthy();
});

it('should disable submit button when disabled prop passed', () => {
it('should disable submit button when isLoading is true', () => {
usePostCommentMock.mockImplementation(() => ({ ...defaultPostComment, isLoading: true }));
const wrapper = mount(
<TestProviders>
<AddComment {...{ ...addCommentProps, disabled: true }} />
<AddComment {...addCommentProps} />
</TestProviders>
);

Expand All @@ -107,12 +106,23 @@ describe('AddComment ', () => {
).toBeTruthy();
});

it('should hide the component when the user does not have crud permissions', () => {
usePostCommentMock.mockImplementation(() => ({ ...defaultPostComment, isLoading: true }));
const wrapper = mount(
<TestProviders>
<AddComment {...{ ...addCommentProps, userCanCrud: false }} />
</TestProviders>
);

expect(wrapper.find(`[data-test-subj="add-comment"]`).exists()).toBeFalsy();
});

it('should insert a quote', async () => {
const sampleQuote = 'what a cool quote';
const ref = React.createRef<AddCommentRefObject>();
const wrapper = mount(
<TestProviders>
<AddComment {...{ ...addCommentProps }} ref={ref} />
<AddComment {...addCommentProps} ref={ref} />
</TestProviders>
);

Expand Down Expand Up @@ -143,7 +153,7 @@ describe('AddComment ', () => {
const wrapper = mount(
<TestProviders>
<CasesTimelineIntegrationProvider timelineIntegration={mockTimelineIntegration}>
<AddComment {...{ ...addCommentProps }} />
<AddComment {...addCommentProps} />
</CasesTimelineIntegrationProvider>
</TestProviders>
);
Expand Down
58 changes: 30 additions & 28 deletions x-pack/plugins/cases/public/components/add_comment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export interface AddCommentRefObject {
addQuote: (quote: string) => void;
}

interface AddCommentProps {
export interface AddCommentProps {
caseId: string;
disabled?: boolean;
userCanCrud?: boolean;
onCommentSaving?: () => void;
onCommentPosted: (newCase: Case) => void;
showLoading?: boolean;
Expand All @@ -45,7 +45,7 @@ interface AddCommentProps {
export const AddComment = React.memo(
forwardRef<AddCommentRefObject, AddCommentProps>(
(
{ caseId, disabled, onCommentPosted, onCommentSaving, showLoading = true, subCaseId },
{ caseId, userCanCrud, onCommentPosted, onCommentSaving, showLoading = true, subCaseId },
ref
) => {
const owner = useOwnerContext();
Expand Down Expand Up @@ -91,31 +91,33 @@ export const AddComment = React.memo(
return (
<span id="add-comment-permLink">
{isLoading && showLoading && <MySpinner data-test-subj="loading-spinner" size="xl" />}
<Form form={form}>
<UseField
path={fieldName}
component={MarkdownEditorForm}
componentProps={{
idAria: 'caseComment',
isDisabled: isLoading,
dataTestSubj: 'add-comment',
placeholder: i18n.ADD_COMMENT_HELP_TEXT,
bottomRightContent: (
<EuiButton
data-test-subj="submit-comment"
iconType="plusInCircle"
isDisabled={isLoading || disabled}
isLoading={isLoading}
onClick={onSubmit}
size="s"
>
{i18n.ADD_COMMENT}
</EuiButton>
),
}}
/>
<InsertTimeline fieldName="comment" />
</Form>
{userCanCrud && (
<Form form={form}>
<UseField
path={fieldName}
component={MarkdownEditorForm}
componentProps={{
idAria: 'caseComment',
isDisabled: isLoading,
dataTestSubj: 'add-comment',
placeholder: i18n.ADD_COMMENT_HELP_TEXT,
bottomRightContent: (
<EuiButton
data-test-subj="submit-comment"
iconType="plusInCircle"
isDisabled={isLoading}
isLoading={isLoading}
onClick={onSubmit}
size="s"
>
{i18n.ADD_COMMENT}
</EuiButton>
),
}}
/>
<InsertTimeline fieldName="comment" />
</Form>
)}
</span>
);
}
Expand Down
32 changes: 21 additions & 11 deletions x-pack/plugins/cases/public/components/all_cases/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,27 @@ export const CasesTableHeader: FunctionComponent<Props> = ({
wrap={true}
data-test-subj="all-cases-header"
>
<FlexItemDivider grow={false}>
<Count refresh={refresh} />
</FlexItemDivider>
<EuiFlexItem grow={false}>
<NavButtons
actionsErrors={actionsErrors}
configureCasesNavigation={configureCasesNavigation}
createCaseNavigation={createCaseNavigation}
userCanCrud={userCanCrud}
/>
</EuiFlexItem>
{userCanCrud ? (
<>
<FlexItemDivider grow={false}>
<Count refresh={refresh} />
</FlexItemDivider>

<EuiFlexItem grow={false}>
<NavButtons
actionsErrors={actionsErrors}
configureCasesNavigation={configureCasesNavigation}
createCaseNavigation={createCaseNavigation}
/>
</EuiFlexItem>
</>
) : (
// doesn't include the horizontal bar that divides the buttons and other padding since we don't have any buttons
// to the right
<EuiFlexItem>
<Count refresh={refresh} />
</EuiFlexItem>
)}
</EuiFlexGroup>
</CaseHeaderPage>
);
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface OwnProps {
actionsErrors: ErrorMessage[];
configureCasesNavigation: CasesNavigation;
createCaseNavigation: CasesNavigation;
userCanCrud: boolean;
}

type Props = OwnProps;
Expand All @@ -26,22 +25,20 @@ export const NavButtons: FunctionComponent<Props> = ({
actionsErrors,
configureCasesNavigation,
createCaseNavigation,
userCanCrud,
}) => (
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<ConfigureCaseButton
configureCasesNavigation={configureCasesNavigation}
label={i18n.CONFIGURE_CASES_BUTTON}
isDisabled={!isEmpty(actionsErrors) || !userCanCrud}
isDisabled={!isEmpty(actionsErrors)}
showToolTip={!isEmpty(actionsErrors)}
msgTooltip={!isEmpty(actionsErrors) ? actionsErrors[0].description : <></>}
titleTooltip={!isEmpty(actionsErrors) ? actionsErrors[0].title : ''}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<LinkButton
isDisabled={!userCanCrud}
fill
onClick={createCaseNavigation.onClick}
href={createCaseNavigation.href}
Expand Down
26 changes: 14 additions & 12 deletions x-pack/plugins/cases/public/components/all_cases/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,21 @@ export const CasesTable: FunctionComponent<CasesTableProps> = ({
<EuiEmptyPrompt
title={<h3>{i18n.NO_CASES}</h3>}
titleSize="xs"
body={i18n.NO_CASES_BODY}
body={userCanCrud ? i18n.NO_CASES_BODY : i18n.NO_CASES_BODY_READ_ONLY}
actions={
<LinkButton
isDisabled={!userCanCrud}
fill
size="s"
onClick={goToCreateCase}
href={createCaseNavigation.href}
iconType="plusInCircle"
data-test-subj="cases-table-add-case"
>
{i18n.ADD_NEW_CASE}
</LinkButton>
userCanCrud && (
<LinkButton
isDisabled={!userCanCrud}
fill
size="s"
onClick={goToCreateCase}
href={createCaseNavigation.href}
iconType="plusInCircle"
data-test-subj="cases-table-add-case"
>
{i18n.ADD_NEW_CASE}
</LinkButton>
)
}
/>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,19 @@ export * from '../../common/translations';
export const NO_CASES = i18n.translate('xpack.cases.caseTable.noCases.title', {
defaultMessage: 'No Cases',
});

export const NO_CASES_BODY = i18n.translate('xpack.cases.caseTable.noCases.body', {
defaultMessage:
'There are no cases to display. Please create a new case or change your filter settings above.',
});

export const NO_CASES_BODY_READ_ONLY = i18n.translate(
'xpack.cases.caseTable.noCases.readonly.body',
{
defaultMessage: 'There are no cases to display. Please change your filter settings above.',
}
);

export const ADD_NEW_CASE = i18n.translate('xpack.cases.caseTable.addNewCase', {
defaultMessage: 'Add New Case',
});
Expand Down
11 changes: 0 additions & 11 deletions x-pack/plugins/cases/public/components/callout/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,7 @@
* 2.0.
*/

import React from 'react';
import md5 from 'md5';

import * as i18n from './translations';
import { ErrorMessage } from './types';

export const permissionsReadOnlyErrorMessage: ErrorMessage = {
id: 'read-only-privileges-error',
title: i18n.READ_ONLY_FEATURE_TITLE,
description: <>{i18n.READ_ONLY_FEATURE_MSG}</>,
errorType: 'warning',
};

export const createCalloutId = (ids: string[], delimiter: string = '|'): string =>
md5(ids.join(delimiter));
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,6 @@

import { i18n } from '@kbn/i18n';

export const READ_ONLY_FEATURE_TITLE = i18n.translate('xpack.cases.readOnlyFeatureTitle', {
defaultMessage: 'You cannot open new or update existing cases',
});

export const READ_ONLY_FEATURE_MSG = i18n.translate('xpack.cases.readOnlyFeatureDescription', {
defaultMessage:
'You only have privileges to view cases. If you need to open and update cases, contact your Kibana administrator.',
});

export const DISMISS_CALLOUT = i18n.translate('xpack.cases.dismissErrorsPushServiceCallOutTitle', {
defaultMessage: 'Dismiss',
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@ interface CaseViewActions {
allCasesNavigation: CasesNavigation;
caseData: Case;
currentExternalIncident: CaseService | null;
disabled?: boolean;
}

const ActionsComponent: React.FC<CaseViewActions> = ({
allCasesNavigation,
caseData,
currentExternalIncident,
disabled = false,
}) => {
// Delete case
const {
Expand All @@ -39,7 +37,6 @@ const ActionsComponent: React.FC<CaseViewActions> = ({
const propertyActions = useMemo(
() => [
{
disabled,
iconType: 'trash',
label: i18n.DELETE_CASE(),
onClick: handleToggleModal,
Expand All @@ -54,7 +51,7 @@ const ActionsComponent: React.FC<CaseViewActions> = ({
]
: []),
],
[disabled, handleToggleModal, currentExternalIncident]
[handleToggleModal, currentExternalIncident]
);

if (isDeleted) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe('CaseActionBar', () => {
onRefresh,
onUpdateField,
currentExternalIncident: null,
userCanCrud: true,
};

beforeEach(() => {
Expand Down
Loading