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: tooltip overlap pdf/text view #533

Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c992033
feat: text active color and PDF highlight/active colors
drdorianm Jun 13, 2023
8246966
feat: support active and highlight
drdorianm Jun 22, 2023
562fd17
Merge remote-tracking branch 'upstream/master' into feat/unique-highl…
drdorianm Jul 10, 2023
6359c1f
fix: tweak merge
drdorianm Jul 11, 2023
39e1bfc
fix: pr review
drdorianm Jul 19, 2023
62fe640
feat: pdf, single tooltip
drdorianm Jul 24, 2023
d559c8b
feat: pdf single tooltip
drdorianm Jul 24, 2023
2eda07b
fix: pdf active color, css !important
drdorianm Jul 24, 2023
dc78541
fix: rename css classes and other pr feedback
drdorianm Jul 26, 2023
4418d73
Merge branch 'feat/unique-highlight-style' into feat/enrich-single-to…
drdorianm Jul 26, 2023
8a48c60
fix: single line tooltip
drdorianm Jul 26, 2023
4073543
feat: add tooltip for text. Next, update tooltip content
drdorianm Jul 26, 2023
c4fcfcc
Merge remote-tracking branch 'upstream/master' into feat/enrich-singl…
drdorianm Jul 26, 2023
5d31f00
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Jul 26, 2023
00d0d31
feat: tooltip for text view
drdorianm Jul 27, 2023
1a1b46b
fix: remove debug msg and clean styles
drdorianm Jul 27, 2023
82df624
fix: refactor TooltipHighlight
drdorianm Jul 27, 2023
8cd713e
Merge remote-tracking branch 'upstream/master' into feat/enrich-singl…
drdorianm Jul 28, 2023
d092c58
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Jul 28, 2023
88d20ea
fix: do not display empty tooltips or duplicate tooltip content
drdorianm Aug 7, 2023
2a3af59
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Aug 8, 2023
149df19
fix: update text highlight style
drdorianm Aug 14, 2023
96b251c
fix: pr feedback
drdorianm Aug 14, 2023
cca368b
fix: tooltip content with table to match design
drdorianm Aug 16, 2023
89f07d9
fix: remove sample data for development
drdorianm Aug 16, 2023
ea83b5f
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Aug 16, 2023
7fb1412
fix: pr feedback
drdorianm Aug 17, 2023
34fba38
fix: move static text to messages
drdorianm Aug 17, 2023
978b6d7
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Aug 17, 2023
a9579fc
fix: text view, rename TooltipAction to TooltipShow
drdorianm Aug 17, 2023
93bc256
fix: pr feedback
drdorianm Aug 17, 2023
c9a5a23
feat: for tooltip, ellipsis in the middle of long text
drdorianm Aug 21, 2023
f9818de
fix: pr feedback
drdorianm Aug 22, 2023
29b1bff
fix: remove test data
drdorianm Aug 22, 2023
7821b9a
fix: add testid for cypress test
drdorianm Aug 23, 2023
f27d3fd
Merge branch 'feat/enrich-single-tooltip-pdf' into feat/enrich-single…
drdorianm Aug 23, 2023
cf2ee39
feat: take-in overlapInfoMap and pass to pdf and text views
drdorianm Aug 25, 2023
ee8208f
fix: add Keyword, create style, move MAX_CONTENT_LENGTH
drdorianm Aug 28, 2023
4262660
fix: hide tooltip sample data
drdorianm Aug 28, 2023
697eee1
fix: keyword case-insensitive
drdorianm Aug 28, 2023
e9c5875
Merge branch 'feat/enrich-single-tooltip-text' into feat/tooltip-over…
drdorianm Aug 28, 2023
636527e
feat: start support multiple mentions (ie overlap) in tooltip
drdorianm Aug 30, 2023
88b89e8
Merge remote-tracking branch 'upstream/master' into feat/tooltip-over…
drdorianm Aug 30, 2023
76768a7
feat: introduce OverlapMeta
drdorianm Sep 1, 2023
32b26cf
fix: update style for active enrichment in overlap
drdorianm Sep 5, 2023
72e1514
fix: active enrichment in overlap, show tooltip for overlap
drdorianm Sep 7, 2023
4bc000b
feat: track overlap for text view
drdorianm Sep 11, 2023
46a8e40
fix: make a unique ID for text enrichments (work in progress)
drdorianm Sep 19, 2023
196753f
feat: unique id for enrichments in text view, remove debug
drdorianm Sep 20, 2023
d350807
Merge remote-tracking branch 'upstream/master' into feat/tooltip-over…
drdorianm Sep 25, 2023
98a5513
fix: merge
drdorianm Sep 25, 2023
99cfbf4
fix: unit tests with new enrichment id
drdorianm Sep 26, 2023
4e43f5d
fix: some tests in CIDocument.spec.tsx by adding type
drdorianm Sep 27, 2023
f98c420
Revert "fix: some tests in CIDocument.spec.tsx by adding type"
drdorianm Sep 28, 2023
9b7b608
fix: getId for Section with and without facets
drdorianm Sep 28, 2023
bad8d1b
feat: add const OVERLAP_ID and function initOverlapMeta
drdorianm Oct 3, 2023
63a0568
fix: fail gracefully if facetId is invalid
drdorianm Oct 6, 2023
44867d2
fix: align color swatch in tooltip
drdorianm Oct 6, 2023
eb3c26c
fix: add comments based on pr feedback (and one rename)
drdorianm Oct 13, 2023
e08874c
fix: tweak text z-index for overlap
drdorianm Oct 13, 2023
c3781bb
fix: refactor styles for pdf highlight
drdorianm Oct 13, 2023
94b043e
fix: pr feedback
drdorianm Oct 16, 2023
9ceb7dc
feat: on active enrichment, tooltip displays overlap info
drdorianm Oct 17, 2023
572d1cb
fix: pr feedback
drdorianm Nov 3, 2023
04c473f
Merge remote-tracking branch 'upstream/master' into feat/tooltip-over…
drdorianm Nov 7, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { SkeletonText } from 'carbon-components-react';
import Section, { OnFieldClickFn } from '../Section/Section';
import VirtualScroll from '../VirtualScroll/VirtualScroll';
import { defaultTheme, Theme } from 'utils/theme';
import { SectionType, ItemMap, HighlightWithMeta } from 'components/CIDocument/types';
import { FacetInfoMap } from '../../../DocumentPreview/types';
import { SectionType, ItemMap, TextHighlightWithMeta } from 'components/CIDocument/types';
import { FacetInfoMap, initOverlapMeta, OverlapMeta } from '../../../DocumentPreview/types';
import { getId as getLocationId } from 'utils/document/idUtils';

const baseClassName = `${settings.prefix}--ci-doc-content`;
Expand All @@ -31,11 +31,19 @@ export interface CIDocumentContentProps {
theme?: Theme;
documentId?: string;
onItemClick?: OnFieldClickFn;
combinedHighlights?: HighlightWithMeta[];
combinedHighlights?: TextHighlightWithMeta[];
facetInfoMap?: FacetInfoMap;
overlapMeta?: OverlapMeta;
activeColor?: string | null;
}

// Explicit control of elements to accomplish mouse interaction with overlap
// Enrichment with highest z-index is content of overlap tooltip
// Fields are transparent, now on-top of text, makes debug in browser inspect easier.
const ZINDEX_BASE = 10;
const ZINDEX_OVERLAP = 20;
const ZINDEX_ACTIVE = 30;

const CIDocumentContent: FC<CIDocumentContentProps> = ({
className,
sections = [],
Expand All @@ -53,6 +61,7 @@ const CIDocumentContent: FC<CIDocumentContentProps> = ({
onItemClick = (): void => {},
combinedHighlights,
facetInfoMap,
overlapMeta = initOverlapMeta(),
activeColor
}) => {
const virtualScrollRef = useRef<any>();
Expand Down Expand Up @@ -83,19 +92,20 @@ const CIDocumentContent: FC<CIDocumentContentProps> = ({
<style>
{createStyleRules(highlightedIds, [
backgroundColorRule(theme.highlightBackground),
// Set z-index to -1 in order to push non-active fields back
zIndexRule(-1)
zIndexRule(ZINDEX_BASE)
])}
</style>
)}
{activeIds && activeIds.length > 0 && (
<>
<style>
{/*Set z-index to 0 to pull active element in front of overlapping fields */}
{/*Set z-index to pull active element in front of overlapping fields */}
{createStyleRules(activeIds, [
backgroundColorRule(theme.activeHighlightBackground),
outlineRule(activeColor || theme.highlightBackground),
zIndexRule(0)
zIndexRule(ZINDEX_ACTIVE),
activeEnrichmentInOverlapRule(activeIds, overlapMeta),
opacityRule(100)
])}
</style>
</>
Expand Down Expand Up @@ -132,6 +142,7 @@ const CIDocumentContent: FC<CIDocumentContentProps> = ({
section={sections[index]}
onFieldClick={onItemClick}
facetInfoMap={facetInfoMap}
overlapMeta={overlapMeta}
/>
)}
</VirtualScroll>
Expand All @@ -143,16 +154,21 @@ const CIDocumentContent: FC<CIDocumentContentProps> = ({
};

function createStyleRules(idList: string[], rules: string[]): string {
// remove empty strings
return idList
.filter(item => item.localeCompare('') !== 0)
.map(id => `.${baseClassName} .field[data-field-id="${id}"] > *`)
.join(',')
.concat(`{${rules.join(';')}}`);
}

function highlightColoringFullArray(combinedHighlightsWithMeta: HighlightWithMeta[]) {
return combinedHighlightsWithMeta.map(highlightWithMeta => {
const locationId = getHighlightLocationId(highlightWithMeta);
const rules = `.${baseClassName} .field[data-field-id="${locationId}"] > * {background-color: ${highlightWithMeta.color}; border: 2px solid ${highlightWithMeta.color};}`;
function highlightColoringFullArray(combinedHighlightsWithMeta: TextHighlightWithMeta[]) {
return combinedHighlightsWithMeta.map(textHighlightWithMeta => {
const locationId = getHighlightLocationId(textHighlightWithMeta);
const zIndexValue = textHighlightWithMeta.isOverlap ? ZINDEX_OVERLAP : ZINDEX_BASE;
const rules = `.${baseClassName} .field[data-field-id="${locationId}"] > * {background-color: ${
textHighlightWithMeta.color
}; border: 2px solid ${textHighlightWithMeta.color}; ${zIndexRule(zIndexValue)};}`;
return rules;
});
}
Expand All @@ -165,6 +181,20 @@ function zIndexRule(value: number): string {
return `z-index: ${value}`;
}

function activeEnrichmentInOverlapRule(activeIds: string[], overlapMeta: OverlapMeta): string {
// Case: Enrichment in overlap, tooltip should show the overlap info.
// Enrichment element is on top to visually draw the border, but the mouse event must pass through.
if (activeIds.length > 0 && overlapMeta.fieldIdWithOverlap.has(activeIds[0])) {
return 'pointer-events: none';
} else {
return '';
}
}

function opacityRule(value: number): string {
return `opacity: ${value}`;
}

function outlineRule(color: string): string {
return `border: ${color} solid 2px`;
}
Expand All @@ -184,11 +214,12 @@ function scrollToActiveItem(
);
}

function getHighlightLocationId(highlightWithMeta: HighlightWithMeta): string {
function getHighlightLocationId(textHighlightWithMeta: TextHighlightWithMeta): string {
return getLocationId({
facetId: textHighlightWithMeta.facetId,
location: {
begin: highlightWithMeta.begin,
end: highlightWithMeta.end
begin: textHighlightWithMeta.begin,
end: textHighlightWithMeta.end
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('<MetadataPane />', () => {
text_normalized: '2008-12-22'
}
],
metadataId: '2533_2549',
metadataId: 'DEFAULT_F_2533_2549',
metadataType: 'effective_dates'
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { createFieldRects, findOffsetInDOM } from 'utils/document/documentUtils'
import { clearNodeChildren } from 'utils/dom';
import elementFromPoint from 'components/CIDocument/utils/elementFromPoint';
import { SectionType, Field, Item } from 'components/CIDocument/types';
import { FacetInfoMap } from '../../../DocumentPreview/types';
import { FacetInfoMap, initOverlapMeta, OverlapMeta } from '../../../DocumentPreview/types';
import { TooltipAction, TooltipEvent, OnTooltipShowFn } from '../../../TooltipHighlight/types';
import { TooltipHighlight, calcToolTipContent } from '../../../TooltipHighlight/TooltipHighlight';

Expand All @@ -31,22 +31,22 @@ export type OnFieldClickFn = (field: Field) => void;
const baseClassName = `${settings.prefix}--ci-doc-section`;

interface SectionProps {
/**
* Section to display in this component
*/
// Section to display in this component
section: SectionType;
/**
* Function to call when a field is clicked
*/
// Function to call when a field is clicked
onFieldClick?: OnFieldClickFn;

/**
* Meta-data on facets
*/
// Meta-data on facets
facetInfoMap?: FacetInfoMap;
// Overlap information used by tooltip
overlapMeta?: OverlapMeta;
}

export const Section: FC<SectionProps> = ({ section, onFieldClick, facetInfoMap = {} }) => {
export const Section: FC<SectionProps> = ({
section,
onFieldClick,
facetInfoMap = {},
overlapMeta = initOverlapMeta()
}) => {
const { html } = section;

const [hoveredField, setHoveredField] = useState<HTMLElement | null>(null);
Expand All @@ -57,7 +57,13 @@ export const Section: FC<SectionProps> = ({ section, onFieldClick, facetInfoMap

const createSectionFields = (): void => {
try {
renderSectionFields(section, sectionNode.current, contentNode.current, fieldsNode.current);
renderSectionFields(
section,
sectionNode.current,
contentNode.current,
fieldsNode.current,
facetInfoMap
);
} catch (err) {
// eslint-disable-next-line no-console
console.error('Failed to create section fields:', err);
Expand Down Expand Up @@ -100,7 +106,13 @@ export const Section: FC<SectionProps> = ({ section, onFieldClick, facetInfoMap
<div
className={cx(`${baseClassName}`, { hasTable: hasTable(html) })}
ref={sectionNode}
onMouseMove={mouseMoveListener(hoveredField, setHoveredField, onTooltipAction, facetInfoMap)}
onMouseMove={mouseMoveListener(
hoveredField,
setHoveredField,
onTooltipAction,
facetInfoMap,
overlapMeta
)}
onMouseLeave={mouseLeaveListener(hoveredField, setHoveredField, onTooltipAction)}
onClick={mouseClickListener(onFieldClick)}
>
Expand All @@ -120,7 +132,8 @@ function mouseMoveListener(
hoveredField: HTMLElement | null,
setHoveredField: Dispatch<SetStateAction<HTMLElement | null>>,
onTooltipShow: OnTooltipShowFn,
facetInfoMap: FacetInfoMap
facetInfoMap: FacetInfoMap,
overlapMeta: OverlapMeta
) {
return function _mouseMoveListener(event: MouseEvent): void {
const fieldRect = elementFromPoint(
Expand Down Expand Up @@ -149,8 +162,16 @@ function mouseMoveListener(
if (fieldNode) {
fieldNode.classList.add('hover');
const enrichValue = fieldNode.getAttribute('data-field-value') || '';
// In the case of overlap, data-field-value is used for Overlap ID
const enrichFieldId = fieldNode.getAttribute('data-field-value') || '';
const enrichFacetId = fieldNode.getAttribute('data-field-type') || '';
const tooltipContent = calcToolTipContent(facetInfoMap, enrichFacetId, enrichValue);
const tooltipContent = calcToolTipContent(
facetInfoMap,
overlapMeta,
enrichFacetId,
enrichValue,
enrichFieldId
);
const fieldNodeContent = fieldNode?.firstElementChild;
onTooltipShow({
...{
Expand Down Expand Up @@ -209,7 +230,8 @@ function renderSectionFields(
section: SectionType,
sectionNode: HTMLElement | null,
contentNode: HTMLElement | null,
fieldsNode: HTMLElement | null
fieldsNode: HTMLElement | null,
facetInfoMap: FacetInfoMap
): void {
if (!sectionNode || !contentNode || !fieldsNode) {
return;
Expand Down Expand Up @@ -243,12 +265,19 @@ function renderSectionFields(

const offsets = findOffsetInDOM(contentNode, begin, end);

// Field ID
// 1. W/O Facets: regular ID
// 2: With Facets: __type is same as facetId and is included in ID to distiguish overlap
// Note: FacetID defaults to {}, otherwise facets enabled
const fieldForId =
Object.keys(facetInfoMap).length === 0 ? field : { ...field, facetId: fieldType };

createFieldRects({
fragment,
parentRect: sectionRect as DOMRect,
fieldType,
fieldValue,
fieldId: getId(field as unknown as Item),
fieldId: getId(fieldForId as unknown as Item),
...offsets
});
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ export interface Location {
}

// TODO better name
// Some code-flow to Item use either __type or facetId
// facetId: Used when facets with colors are defined
// __type: Used when raw data from discovery query is processed
export interface Item {
id?: string;
__type?: string;
facetId?: string;
dorianmiller marked this conversation as resolved.
Show resolved Hide resolved
location: Location;
}

Expand Down Expand Up @@ -109,10 +114,10 @@ export type HighlightFacetMentions = {
className?: string;
};

export type HighlightWithMeta = {
facetIds: string[];
mentions: HighlightFacetMentions[];
export type TextHighlightWithMeta = {
begin: number;
end: number;
facetId: string;
color: string;
isOverlap: boolean;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { QueryResultPassage, QueryTableResult } from 'ibm-watson/discovery/v2';
import { ProcessedDoc } from 'utils/document';
import { Location } from 'utils/document/processDoc';
import { Location } from '../../../types';
import { getHighlightedTable } from '../tables';
import { isTable } from '../typeUtils';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import { QueryResult, QueryResultPassage, QueryTableResult } from 'ibm-watson/di
import DOMPurify from 'dompurify';
import get from 'lodash/get';
import flatMap from 'lodash/flatMap';
import { processDoc, ProcessedDoc, ProcessedBbox, Location } from 'utils/document/processDoc';
import { processDoc, ProcessedDoc, ProcessedBbox } from 'utils/document/processDoc';
import { findMatchingBbox } from 'components/DocumentPreview/utils/box';
import { findOffsetInDOM, createFieldRects } from 'utils/document/documentUtils';
import { clearNodeChildren } from 'utils/dom';
import { getTextMappings } from 'components/DocumentPreview/utils/documentData';
import { getPassagePageInfo } from '../Highlight/passages';
import { isPassage } from '../Highlight/typeUtils';
import { QueryResultWithOptionalMetadata } from 'components/DocumentPreview/types';
import { QueryResultWithOptionalMetadata, Location } from 'components/DocumentPreview/types';

interface Props extends HTMLAttributes<HTMLElement> {
/**
Expand Down
Loading