From 03d065b17b21bf97c8639585d460f9c11d0ee56c Mon Sep 17 00:00:00 2001 From: Jihan el medini <119955059+jelmedini@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:35:00 -0400 Subject: [PATCH 1/3] feat(genqa): add rephrase buttons as an option (#4246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SVCC-4005](https://coveord.atlassian.net/browse/SVCC-4005) - Add rephrase buttons as an option. - By default `withRephraseButtons` is set at `false`. - When `withRephraseButtons` is set to `true`, we show the rephrase buttons. By default: Screenshot 2024-08-01 at 3 14 46 PM When `withRephraseButtons` is set to `true`: Screenshot 2024-08-01 at 3 15 08 PM [SVCC-4005]: https://coveord.atlassian.net/browse/SVCC-4005?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../src/lib/stencil-generated/components.ts | 4 ++-- .../cypress/e2e/generated-answer.cypress.ts | 5 ++++- packages/atomic/src/components.d.ts | 20 +++++++++++++++++++ .../generated-answer-common.tsx | 7 +++++-- .../atomic-insight-generated-answer.tsx | 7 +++++++ .../atomic-generated-answer.tsx | 7 +++++++ 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts index 759a27e5b19..f24b1448d19 100644 --- a/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts +++ b/packages/atomic-angular/projects/atomic-angular/src/lib/stencil-generated/components.ts @@ -671,14 +671,14 @@ export declare interface AtomicFrequentlyBoughtTogether extends Components.Atomi @ProxyCmp({ - inputs: ['answerStyle', 'collapsible', 'withToggle'] + inputs: ['answerStyle', 'collapsible', 'withRephraseButtons', 'withToggle'] }) @Component({ selector: 'atomic-generated-answer', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['answerStyle', 'collapsible', 'withToggle'], + inputs: ['answerStyle', 'collapsible', 'withRephraseButtons', 'withToggle'], }) export class AtomicGeneratedAnswer { protected el: HTMLElement; diff --git a/packages/atomic/cypress/e2e/generated-answer.cypress.ts b/packages/atomic/cypress/e2e/generated-answer.cypress.ts index b37e76765d6..4cc10c193a3 100644 --- a/packages/atomic/cypress/e2e/generated-answer.cypress.ts +++ b/packages/atomic/cypress/e2e/generated-answer.cypress.ts @@ -93,6 +93,7 @@ describe('Generated Answer Test Suites', () => { mockStreamResponse(streamId, testMessagePayload); setupGeneratedAnswerWithoutFirstIntercept(streamId, { 'answer-style': answerStyle.value, + 'with-rephrase-buttons': true, }); }); @@ -344,7 +345,9 @@ describe('Generated Answer Test Suites', () => { beforeEach(() => { mockStreamResponse(streamId, testMessagePayload); - setupGeneratedAnswer(streamId); + setupGeneratedAnswer(streamId, { + 'with-rephrase-buttons': true, + }); cy.wait(getStreamInterceptAlias(streamId)); }); diff --git a/packages/atomic/src/components.d.ts b/packages/atomic/src/components.d.ts index d6961586dd2..3bddd49eee6 100644 --- a/packages/atomic/src/components.d.ts +++ b/packages/atomic/src/components.d.ts @@ -1057,6 +1057,11 @@ export namespace Components { * @default false */ "collapsible"?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + "withRephraseButtons"?: boolean; /** * Whether to render a toggle button that lets the user hide or show the answer. * @default false @@ -1198,6 +1203,11 @@ export namespace Components { * @default false */ "collapsible"?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + "withRephraseButtons"?: boolean; /** * Whether to render a toggle button that lets the user hide or show the answer. * @default false @@ -6711,6 +6721,11 @@ declare namespace LocalJSX { * @default false */ "collapsible"?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + "withRephraseButtons"?: boolean; /** * Whether to render a toggle button that lets the user hide or show the answer. * @default false @@ -6849,6 +6864,11 @@ declare namespace LocalJSX { * @default false */ "collapsible"?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + "withRephraseButtons"?: boolean; /** * Whether to render a toggle button that lets the user hide or show the answer. * @default false diff --git a/packages/atomic/src/components/common/generated-answer/generated-answer-common.tsx b/packages/atomic/src/components/common/generated-answer/generated-answer-common.tsx index fb27866d6d0..5a3a101af1f 100644 --- a/packages/atomic/src/components/common/generated-answer/generated-answer-common.tsx +++ b/packages/atomic/src/components/common/generated-answer/generated-answer-common.tsx @@ -28,6 +28,7 @@ interface GeneratedAnswerCommonOptions { host: HTMLElement; withToggle?: boolean; collapsible?: boolean; + withRephraseButtons?: boolean; getGeneratedAnswer: () => GeneratedAnswer | undefined; getGeneratedAnswerState: () => GeneratedAnswerState | undefined; getSearchStatusState: () => SearchStatusState | undefined; @@ -311,12 +312,14 @@ export class GeneratedAnswerCommon { } private renderRephraseButtons() { - const {getGeneratedAnswerState, getBindings} = this.props; + const {getGeneratedAnswerState, getBindings, withRephraseButtons} = + this.props; const {i18n} = getBindings(); const {isStreaming, responseFormat} = getGeneratedAnswerState() ?? {}; const {answerStyle} = responseFormat ?? {}; + const canRender = withRephraseButtons && !isStreaming; - if (isStreaming) { + if (!canRender) { return null; } return ( diff --git a/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx b/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx index 3a755d4224b..38ecf0941e5 100644 --- a/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx +++ b/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx @@ -118,6 +118,12 @@ export class AtomicInsightGeneratedAnswer */ @Prop() collapsible?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + @Prop() withRephraseButtons?: boolean; + @AriaLiveRegion('generated-answer') protected ariaMessage!: string; @@ -130,6 +136,7 @@ export class AtomicInsightGeneratedAnswer host: this.host, withToggle: this.withToggle, collapsible: this.collapsible, + withRephraseButtons: this.withRephraseButtons, getGeneratedAnswer: () => this.generatedAnswer, getGeneratedAnswerState: () => this.generatedAnswerState, getSearchStatusState: () => this.searchStatusState, diff --git a/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx b/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx index a46c3067ee2..078e45effe7 100644 --- a/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx +++ b/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx @@ -115,6 +115,12 @@ export class AtomicGeneratedAnswer implements InitializableComponent { */ @Prop() collapsible?: boolean; + /** + * Whether to render the rephrase buttons that lets the user rephrase the answer. + * @default false + */ + @Prop() withRephraseButtons?: boolean; + /** * @internal * The unique identifier of the answer configuration to use to generate the answer. @@ -133,6 +139,7 @@ export class AtomicGeneratedAnswer implements InitializableComponent { host: this.host, withToggle: this.withToggle, collapsible: this.collapsible, + withRephraseButtons: this.withRephraseButtons, getGeneratedAnswer: () => this.generatedAnswer, getGeneratedAnswerState: () => this.generatedAnswerState, getSearchStatusState: () => this.searchStatusState, From 7f04f7349ad2f25a7100d7d537686a3a06a25188 Mon Sep 17 00:00:00 2001 From: Jihan el medini <119955059+jelmedini@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:58:31 -0400 Subject: [PATCH 2/3] feat(genqa): filter citations that points to same document (#4250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SVCC-4029](https://coveord.atlassian.net/browse/SVCC-4029) - Filter citations that points to same documents. Before: Screenshot 2024-08-01 at 3 14 46 PM After: Screenshot 2024-08-02 at 3 11 39 PM [SVCC-4029]: https://coveord.atlassian.net/browse/SVCC-4029?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../generated-answer-slice.test.ts | 25 +++++++++++++++++++ .../generated-answer-slice.ts | 9 ++++++- .../generated-answer.cypress.ts | 4 +-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/headless/src/features/generated-answer/generated-answer-slice.test.ts b/packages/headless/src/features/generated-answer/generated-answer-slice.test.ts index 3f82512608f..d76cacd88b3 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-slice.test.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-slice.test.ts @@ -80,6 +80,7 @@ describe('generated answer slice', () => { const newCitations = [ buildMockCitation({ id: 'some-other-id', + uri: 'my-uri', }), ]; const finalState = generatedAnswerReducer( @@ -95,6 +96,30 @@ describe('generated answer slice', () => { ...newCitations, ]); }); + + it('Shows only citations that have different Uris', () => { + const existingCitations = [ + buildMockCitation({ + id: 'current-id', + uri: 'my-uri', + }), + ]; + const newCitations = [ + buildMockCitation({ + id: 'some-other-id', + uri: 'my-uri', + }), + ]; + const finalState = generatedAnswerReducer( + { + ...getGeneratedAnswerInitialState(), + citations: existingCitations, + }, + updateCitations({citations: newCitations}) + ); + + expect(finalState.citations).toEqual([...newCitations]); + }); }); describe('#updateError', () => { diff --git a/packages/headless/src/features/generated-answer/generated-answer-slice.ts b/packages/headless/src/features/generated-answer/generated-answer-slice.ts index f1935d3b59a..3da7d303558 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-slice.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-slice.ts @@ -1,5 +1,6 @@ import {createReducer} from '@reduxjs/toolkit'; import {RETRYABLE_STREAM_ERROR_CODE} from '../../api/generated-answer/generated-answer-client'; +import {GeneratedAnswerCitation} from '../../api/generated-answer/generated-answer-event-payload'; import { closeGeneratedAnswerFeedbackModal, dislikeGeneratedAnswer, @@ -47,7 +48,13 @@ export const generatedAnswerReducer = createReducer( .addCase(updateCitations, (state, {payload}) => { state.isLoading = false; state.isStreaming = true; - state.citations = state.citations.concat(payload.citations); + const citationMap = new Map(); + for (const citationCollection of [state.citations, payload.citations]) { + for (const citation of citationCollection) { + citationMap.set(citation.uri, citation); + } + } + state.citations = Array.from(citationMap.values()); delete state.error; }) .addCase(updateError, (state, {payload}) => { diff --git a/packages/quantic/cypress/e2e/default-2/generatedAnswer/generated-answer.cypress.ts b/packages/quantic/cypress/e2e/default-2/generatedAnswer/generated-answer.cypress.ts index 3f37d68135b..4d61a6cf336 100644 --- a/packages/quantic/cypress/e2e/default-2/generatedAnswer/generated-answer.cypress.ts +++ b/packages/quantic/cypress/e2e/default-2/generatedAnswer/generated-answer.cypress.ts @@ -1124,7 +1124,7 @@ describe('quantic-generated-answer', () => { const firstTestCitation = { id: 'some-id-1', title: 'Some Title 1', - uri: 'https://www.coveo.com', + uri: 'https://www.coveo1.com', permanentid: 'some-permanent-id-1', clickUri: exampleLinkUrl, text: 'example text 1', @@ -1132,7 +1132,7 @@ describe('quantic-generated-answer', () => { const secondTestCitation = { id: 'some-id-2', title: 'Some Title 2', - uri: 'https://www.coveo.com', + uri: 'https://www.coveo2.com', permanentid: 'some-permanent-id-2', clickUri: exampleLinkUrl, text: 'example text 2', From 54948d800c1b77bd0edce8fd297d5d7aa03a7733 Mon Sep 17 00:00:00 2001 From: Jihan el medini <119955059+jelmedini@users.noreply.github.com> Date: Fri, 9 Aug 2024 11:58:04 -0400 Subject: [PATCH 3/3] feat(genqa): update citations (#4243) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [SVCC-3999](https://coveord.atlassian.net/browse/SVCC-3999) Improve CRGA citations: - Remove numbered citations. Before: ![Screenshot 2024-07-31 at 2 34 39 PM](https://github.com/user-attachments/assets/08e5f5c8-cbb5-4459-8a17-1e1cf2ae2faf) After: ![Screenshot 2024-07-31 at 2 54 26 PM](https://github.com/user-attachments/assets/b26cf9df-74f3-4a86-af4c-c7ab91055779) [SVCC-3999]: https://coveord.atlassian.net/browse/SVCC-3999?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- packages/atomic/cypress/e2e/generated-answer-selectors.ts | 2 -- packages/atomic/cypress/e2e/generated-answer.cypress.ts | 1 - .../generated-answer/atomic-citation/atomic-citation.pcss | 5 ----- .../generated-answer/atomic-citation/atomic-citation.tsx | 6 ------ .../atomic-insight-generated-answer.tsx | 1 - .../atomic-generated-answer/atomic-generated-answer.tsx | 1 - 6 files changed, 16 deletions(-) diff --git a/packages/atomic/cypress/e2e/generated-answer-selectors.ts b/packages/atomic/cypress/e2e/generated-answer-selectors.ts index d6b7cd1f5a2..485f33ad164 100644 --- a/packages/atomic/cypress/e2e/generated-answer-selectors.ts +++ b/packages/atomic/cypress/e2e/generated-answer-selectors.ts @@ -20,8 +20,6 @@ export const GeneratedAnswerSelectors = { GeneratedAnswerSelectors.shadow().find('[part="citations-label"]'), citationTitle: () => GeneratedAnswerSelectors.citation().find('.citation-title'), - citationIndex: () => - GeneratedAnswerSelectors.citation().find('[part="citation-index"]'), citationCard: () => GeneratedAnswerSelectors.shadow().find('[part="citation-popover"]'), loader: () => GeneratedAnswerSelectors.shadow().find('.typing-indicator'), diff --git a/packages/atomic/cypress/e2e/generated-answer.cypress.ts b/packages/atomic/cypress/e2e/generated-answer.cypress.ts index 4cc10c193a3..832157a8d87 100644 --- a/packages/atomic/cypress/e2e/generated-answer.cypress.ts +++ b/packages/atomic/cypress/e2e/generated-answer.cypress.ts @@ -464,7 +464,6 @@ describe('Generated Answer Test Suites', () => { 'have.text', testCitation.title ); - GeneratedAnswerSelectors.citationIndex().should('have.text', '1'); GeneratedAnswerSelectors.citation().should( 'have.attr', 'href', diff --git a/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.pcss b/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.pcss index 215d9094757..25b5002bcd2 100644 --- a/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.pcss +++ b/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.pcss @@ -10,11 +10,6 @@ height: var(--height); } -[part='citation-index'] { - height: var(--index-height); - width: var(--index-height); -} - [part='citation-popover'] { --popover-width: 350px; diff --git a/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.tsx b/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.tsx index a234b80c742..eded75469bf 100644 --- a/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.tsx +++ b/packages/atomic/src/components/common/generated-answer/atomic-citation/atomic-citation.tsx @@ -158,12 +158,6 @@ export class AtomicCitation { onFocus={this.openPopover} onBlur={this.closePopover} > -
-
{this.index + 1}
-
{this.citation.title} diff --git a/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx b/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx index 38ecf0941e5..8bae8d40862 100644 --- a/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx +++ b/packages/atomic/src/components/insight/atomic-insight-generated-answer/atomic-insight-generated-answer.tsx @@ -60,7 +60,6 @@ import {InsightBindings} from '../atomic-insight-interface/atomic-insight-interf * * @part citation - The link that allows the user to navigate to the item. * @part citation-popover - The pop-up that shows an item preview when the user hovers over the citation. - * @part citation-index - The content of the citation item. */ @Component({ tag: 'atomic-insight-generated-answer', diff --git a/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx b/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx index 078e45effe7..e9fce7c0f92 100644 --- a/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx +++ b/packages/atomic/src/components/search/atomic-generated-answer/atomic-generated-answer.tsx @@ -59,7 +59,6 @@ import {Bindings} from '../atomic-search-interface/atomic-search-interface'; * * @part citation - The link that allows the user to navigate to the item. * @part citation-popover - The pop-up that shows an item preview when the user hovers over the citation. - * @part citation-index - The content of the citation item. */ @Component({ tag: 'atomic-generated-answer',