Skip to content

Commit

Permalink
[8.8] [Cases] Fix lens visualization in comment and description markd…
Browse files Browse the repository at this point in the history
…own (#155897) (#156189)

# Backport

This will backport the following commits from `main` to `8.8`:
- [[Cases] Fix lens visualization in comment and description markdown
(#155897)](#155897)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Janki
Salvi","email":"117571355+js-jankisalvi@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-04-28T15:21:00Z","message":"[Cases]
Fix lens visualization in comment and description markdown
(#155897)\n\n## Summary\r\n\r\nThis PR fixes issues with lens
visualization in case view page for\r\ncomment and
description.\r\n\r\nFixes:
#155631\r\n\r\n**Description:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234856964-52bc479e-73bb-48d1-9b23-9e78e3452f00.mov\r\n\r\n**Comment:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234858215-feaac6c7-5579-4a00-bb97-00e0b23f5cfe.mov\r\n\r\n###
Checklist\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n**Flakey Test
runner:**\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2182\r\n\r\nNext
one after
update:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2183\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"0c0e02277f6c0d52dd4906e7421edcbd4c0dd962","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:ResponseOps","Feature:Cases","v8.7.0","v8.8.0","v8.9.0"],"number":155897,"url":"https://github.com/elastic/kibana/pull/155897","mergeCommit":{"message":"[Cases]
Fix lens visualization in comment and description markdown
(#155897)\n\n## Summary\r\n\r\nThis PR fixes issues with lens
visualization in case view page for\r\ncomment and
description.\r\n\r\nFixes:
#155631\r\n\r\n**Description:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234856964-52bc479e-73bb-48d1-9b23-9e78e3452f00.mov\r\n\r\n**Comment:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234858215-feaac6c7-5579-4a00-bb97-00e0b23f5cfe.mov\r\n\r\n###
Checklist\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n**Flakey Test
runner:**\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2182\r\n\r\nNext
one after
update:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2183\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"0c0e02277f6c0d52dd4906e7421edcbd4c0dd962"}},"sourceBranch":"main","suggestedTargetBranches":["8.7","8.8"],"targetPullRequestStates":[{"branch":"8.7","label":"v8.7.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.8","label":"v8.8.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/155897","number":155897,"mergeCommit":{"message":"[Cases]
Fix lens visualization in comment and description markdown
(#155897)\n\n## Summary\r\n\r\nThis PR fixes issues with lens
visualization in case view page for\r\ncomment and
description.\r\n\r\nFixes:
#155631\r\n\r\n**Description:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234856964-52bc479e-73bb-48d1-9b23-9e78e3452f00.mov\r\n\r\n**Comment:**\r\n\r\n\r\nhttps://user-images.githubusercontent.com/117571355/234858215-feaac6c7-5579-4a00-bb97-00e0b23f5cfe.mov\r\n\r\n###
Checklist\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n\r\n**Flakey Test
runner:**\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2182\r\n\r\nNext
one after
update:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2183\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"0c0e02277f6c0d52dd4906e7421edcbd4c0dd962"}}]}]
BACKPORT-->

Co-authored-by: Janki Salvi <117571355+js-jankisalvi@users.noreply.github.com>
Co-authored-by: Lisa Cawley <lcawley@elastic.co>
  • Loading branch information
3 people authored May 2, 2023
1 parent edd78ba commit 52c7918
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import { schema } from './schema';
import type { AppMockRenderer } from '../../common/mock';
import { createAppMockRenderer } from '../../common/mock';

jest.mock('../markdown_editor/plugins/lens/use_lens_draft_comment');

describe('Description', () => {
let globalForm: FormHook;
let appMockRender: AppMockRenderer;
Expand Down
32 changes: 2 additions & 30 deletions x-pack/plugins/cases/public/components/create/description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@
* 2.0.
*/

import React, { memo, useEffect, useRef } from 'react';
import {
UseField,
useFormContext,
useFormData,
} from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib';
import React, { memo, useRef } from 'react';
import { UseField, useFormData } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib';
import { MarkdownEditorForm } from '../markdown_editor';
import { useLensDraftComment } from '../markdown_editor/plugins/lens/use_lens_draft_comment';
import { ID as LensPluginId } from '../markdown_editor/plugins/lens/constants';

interface Props {
Expand All @@ -23,33 +18,10 @@ interface Props {
export const fieldName = 'description';

const DescriptionComponent: React.FC<Props> = ({ isLoading, draftStorageKey }) => {
const { draftComment, hasIncomingLensState, openLensModal, clearDraftComment } =
useLensDraftComment();
const { setFieldValue } = useFormContext();
const [{ title, tags }] = useFormData({ watch: ['title', 'tags'] });
const editorRef = useRef<Record<string, unknown>>();
const disabledUiPlugins = [LensPluginId];

useEffect(() => {
if (draftComment?.commentId === fieldName && editorRef.current) {
setFieldValue(fieldName, draftComment.comment);

if (draftComment.caseTitle) {
setFieldValue('title', draftComment.caseTitle);
}

if (draftComment.caseTags && draftComment.caseTags.length > 0) {
setFieldValue('tags', draftComment.caseTags);
}

if (hasIncomingLensState) {
openLensModal({ editorRef: editorRef.current });
} else {
clearDraftComment();
}
}
}, [clearDraftComment, draftComment, hasIncomingLensState, openLensModal, setFieldValue]);

return (
<UseField
path={fieldName}
Expand Down
34 changes: 33 additions & 1 deletion x-pack/plugins/cases/public/components/description/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import React, { useCallback, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { css } from '@emotion/react';
import {
Expand All @@ -21,12 +21,17 @@ import { getMarkdownEditorStorageKey } from '../markdown_editor/utils';
import * as i18n from '../user_actions/translations';
import { useCasesContext } from '../cases_context/use_cases_context';
import { useLensDraftComment } from '../markdown_editor/plugins/lens/use_lens_draft_comment';
import type { EditableMarkdownRefObject, EuiMarkdownEditorRef } from '../markdown_editor';
import { EditableMarkdown, ScrollableMarkdown } from '../markdown_editor';
import type { Case } from '../../containers/types';
import type { OnUpdateFields } from '../case_view/types';
import { schema } from './schema';

const DESCRIPTION_ID = 'description';

export interface DescriptionMarkdownRefObject extends EditableMarkdownRefObject {
editor: EuiMarkdownEditorRef | null;
}
export interface DescriptionProps {
caseData: Case;
isLoadingDescription: boolean;
Expand Down Expand Up @@ -73,6 +78,13 @@ const getDraftDescription = (
return sessionStorage.getItem(draftStorageKey);
};

const isCommentRef = (
ref: EditableMarkdownRefObject | null | undefined
): ref is EditableMarkdownRefObject => {
const commentRef = ref as EditableMarkdownRefObject;
return commentRef?.setComment != null;
};

export const Description = ({
caseData,
onUpdateField,
Expand All @@ -82,13 +94,16 @@ export const Description = ({
const [isEditable, setIsEditable] = useState<boolean>(false);

const descriptionRef = useRef(null);
const descriptionMarkdownRef = useRef<DescriptionMarkdownRefObject | null>(null);

const { euiTheme } = useEuiTheme();
const { appId, permissions } = useCasesContext();

const {
clearDraftComment: clearLensDraftComment,
draftComment: lensDraftComment,
hasIncomingLensState,
openLensModal,
} = useLensDraftComment();

const handleOnChangeEditable = useCallback(() => {
Expand Down Expand Up @@ -117,6 +132,22 @@ export const Description = ({
setIsEditable(true);
}

useEffect(() => {
if (
isCommentRef(descriptionMarkdownRef.current) &&
descriptionMarkdownRef.current.editor?.textarea &&
lensDraftComment &&
lensDraftComment.commentId === DESCRIPTION_ID
) {
descriptionMarkdownRef.current.setComment(lensDraftComment.comment);
if (hasIncomingLensState) {
openLensModal({ editorRef: descriptionMarkdownRef.current.editor });
} else {
clearLensDraftComment();
}
}
}, [clearLensDraftComment, lensDraftComment, hasIncomingLensState, openLensModal]);

const hasUnsavedChanges =
draftDescription && draftDescription !== caseData.description && !isLoadingDescription;

Expand All @@ -131,6 +162,7 @@ export const Description = ({
editorRef={descriptionRef}
fieldName="content"
formSchema={schema}
ref={descriptionMarkdownRef}
/>
) : (
<Panel hasShadow={false} hasBorder={true} data-test-subj="description">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,17 @@ const MyEuiCommentFooter = styled(EuiText)`
`}
`;

const hasDraftComment = (appId = '', caseId: string, commentId: string): boolean => {
const draftStorageKey = getMarkdownEditorStorageKey(appId, caseId, commentId);
const hasDraftComment = (
applicationId = '',
caseId: string,
commentId: string,
comment: string
): boolean => {
const draftStorageKey = getMarkdownEditorStorageKey(applicationId, caseId, commentId);

return Boolean(sessionStorage.getItem(draftStorageKey));
const sessionValue = sessionStorage.getItem(draftStorageKey);

return Boolean(sessionValue && sessionValue !== comment);
};

export const createUserAttachmentUserActionBuilder = ({
Expand Down Expand Up @@ -78,7 +85,8 @@ export const createUserAttachmentUserActionBuilder = ({
className: classNames('userAction__comment', {
outlined,
isEdit,
draftFooter: !isEdit && !isLoading && hasDraftComment(appId, caseId, comment.id),
draftFooter:
!isEdit && !isLoading && hasDraftComment(appId, caseId, comment.id, comment.comment),
}),
children: (
<>
Expand All @@ -95,7 +103,7 @@ export const createUserAttachmentUserActionBuilder = ({
version: comment.version,
})}
/>
{!isEdit && !isLoading && hasDraftComment(appId, caseId, comment.id) ? (
{!isEdit && !isLoading && hasDraftComment(appId, caseId, comment.id, comment.comment) ? (
<MyEuiCommentFooter>
<EuiText color="subdued" size="xs" data-test-subj="user-action-comment-unsaved-draft">
{i18n.UNSAVED_DRAFT_COMMENT}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ const isAddCommentRef = (
return commentRef?.addQuote != null;
};

const isSetCommentRef = (
ref: AddCommentRefObject | UserActionMarkdownRefObject | null | undefined
): ref is AddCommentRefObject => {
const commentRef = ref as UserActionMarkdownRefObject;
return commentRef?.setComment != null;
};

export const useUserActionsHandler = (): UseUserActionsHandler => {
const { detailName: caseId } = useCaseViewParams();
const { clearDraftComment, draftComment, hasIncomingLensState, openLensModal } =
Expand Down Expand Up @@ -122,7 +129,7 @@ export const useUserActionsHandler = (): UseUserActionsHandler => {
);

useEffect(() => {
if (draftComment?.commentId) {
if (draftComment?.commentId && draftComment?.commentId !== 'description') {
setManageMarkdownEditIds((prevManageMarkdownEditIds) => {
if (
NEW_COMMENT_ID !== draftComment?.commentId &&
Expand All @@ -135,7 +142,7 @@ export const useUserActionsHandler = (): UseUserActionsHandler => {

const ref = commentRefs?.current?.[draftComment.commentId];

if (isAddCommentRef(ref) && ref.editor?.textarea) {
if (isSetCommentRef(ref) && ref.editor?.textarea) {
ref.setComment(draftComment.comment);
if (hasIncomingLensState) {
openLensModal({ editorRef: ref.editor });
Expand Down
15 changes: 11 additions & 4 deletions x-pack/test/functional/services/cases/single_case_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft
},

async getCommentCount(): Promise<number> {
const commentsContainer = await testSubjects.find('user-actions');
const commentsContainer = await testSubjects.find('user-actions-list');
const comments = await commentsContainer.findAllByClassName('euiComment');
return comments.length - 1; // don't count the element for adding a new comment
},
Expand All @@ -58,13 +58,22 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft
});
},

async addVisualization(visName: string) {
async addVisualizationToNewComment(visName: string) {
// open saved object finder
const addCommentElement = await testSubjects.find('add-comment');
const addVisualizationButton = await addCommentElement.findByCssSelector(
'[data-test-subj="euiMarkdownEditorToolbarButton"][aria-label="Visualization"]'
);
await addVisualizationButton.click();

await this.findAndSaveVisualization(visName);

await testSubjects.existOrFail('cases-app', { timeout: 10 * 1000 });

await this.submitComment();
},

async findAndSaveVisualization(visName: string) {
await testSubjects.existOrFail('savedObjectsFinderTable', { timeout: 10 * 1000 });

// select visualization
Expand All @@ -78,8 +87,6 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft

// save and return to cases app, add comment
await lensPage.saveAndReturn();
await testSubjects.existOrFail('cases-app', { timeout: 10 * 1000 });
await this.submitComment();
},

async openVisualizationButtonTooltip() {
Expand Down
110 changes: 100 additions & 10 deletions x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,6 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});

it('shows unsaved comment message when page is refreshed', async () => {
const commentArea = await find.byCssSelector(
'[data-test-subj="add-comment"] textarea.euiMarkdownEditorTextArea'
);
await commentArea.focus();
await commentArea.type('Test comment from automation');

await testSubjects.click('submit-comment');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('property-actions-user-action-ellipses');

await header.waitUntilLoadingHasFinished();
Expand All @@ -299,6 +289,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
await editCommentTextArea.focus();
await editCommentTextArea.type('Edited comment');

await header.waitUntilLoadingHasFinished();

await browser.refresh();

await header.waitUntilLoadingHasFinished();
Expand Down Expand Up @@ -341,6 +333,104 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
});
});

describe('Lens visualization', () => {
before(async () => {
await cases.testResources.installKibanaSampleData('logs');
});

after(async () => {
await cases.testResources.removeKibanaSampleData('logs');
});

createOneCaseBeforeDeleteAllAfter(getPageObject, getService);

it('adds lens visualization in description', async () => {
await testSubjects.click('description-edit-icon');

await header.waitUntilLoadingHasFinished();

const editCommentTextArea = await find.byCssSelector(
'[data-test-subj*="editable-markdown-form"] textarea.euiMarkdownEditorTextArea'
);

await header.waitUntilLoadingHasFinished();

await editCommentTextArea.focus();

const editableDescription = await testSubjects.find('editable-markdown-form');

const addVisualizationButton = await editableDescription.findByCssSelector(
'[data-test-subj="euiMarkdownEditorToolbarButton"][aria-label="Visualization"]'
);
await addVisualizationButton.click();

await cases.singleCase.findAndSaveVisualization('[Logs] Bytes distribution');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('editable-save-markdown');

await header.waitUntilLoadingHasFinished();

const description = await find.byCssSelector('[data-test-subj="description"]');

await description.findByCssSelector('[data-test-subj="xyVisChart"]');
});

it('adds lens visualization in existing comment', async () => {
const commentArea = await find.byCssSelector(
'[data-test-subj="add-comment"] textarea.euiMarkdownEditorTextArea'
);
await commentArea.focus();
await commentArea.type('Test comment from automation');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('submit-comment');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('property-actions-user-action-ellipses');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('property-actions-user-action-pencil');

await header.waitUntilLoadingHasFinished();

const editComment = await find.byCssSelector('[data-test-subj*="editable-markdown-form"]');

const addVisualizationButton = await editComment.findByCssSelector(
'[data-test-subj="euiMarkdownEditorToolbarButton"][aria-label="Visualization"]'
);
await addVisualizationButton.click();

await cases.singleCase.findAndSaveVisualization('[Logs] Bytes distribution');

await header.waitUntilLoadingHasFinished();

await testSubjects.click('editable-save-markdown');

await header.waitUntilLoadingHasFinished();

const createdComment = await find.byCssSelector(
'[data-test-subj*="comment-create-action"] [data-test-subj="scrollable-markdown"]'
);

await createdComment.findByCssSelector('[data-test-subj="xyVisChart"]');
});

it('adds lens visualization in new comment', async () => {
await cases.singleCase.addVisualizationToNewComment('[Logs] Bytes distribution');

await header.waitUntilLoadingHasFinished();

const newComment = await find.byCssSelector('[data-test-subj*="comment-create-action"]');

await newComment.findByCssSelector('[data-test-subj="xyVisChart"]');
});
});

describe('Severity field', () => {
createOneCaseBeforeDeleteAllAfter(getPageObject, getService);

Expand Down
Loading

0 comments on commit 52c7918

Please sign in to comment.