@coveo/quantic 3.37.10 → 3.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/force-app/main/default/lwc/quanticFeedback/__tests__/quanticFeedback.test.js +11 -0
- package/force-app/main/default/lwc/quanticFeedback/quanticFeedback.html +6 -4
- package/force-app/main/default/lwc/quanticFeedback/quanticFeedback.js +8 -0
- package/force-app/main/default/lwc/quanticGeneratedAnswer/__tests__/quanticGeneratedAnswer.test.js +32 -3
- package/force-app/main/default/lwc/quanticGeneratedAnswer/quanticGeneratedAnswer.css +1 -8
- package/force-app/main/default/lwc/quanticGeneratedAnswer/quanticGeneratedAnswer.js +6 -28
- package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/generatedAnswer.css +0 -13
- package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/generatedAnswer.html +120 -93
- package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/retryPrompt.html +24 -15
- package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/__tests__/quanticGeneratedAnswerCopyToClipboard.test.js +125 -0
- package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/quanticGeneratedAnswerCopyToClipboard.html +1 -1
- package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/quanticGeneratedAnswerCopyToClipboard.js +20 -1
- package/force-app/main/default/lwc/quanticThreadItem/__tests__/quanticThreadItem.test.js +176 -0
- package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.css +64 -0
- package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.html +48 -0
- package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.js +80 -0
- package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.js-meta.xml +5 -0
- package/force-app/main/default/staticresources/coveoheadless/case-assist/headless.js +15 -15
- package/force-app/main/default/staticresources/coveoheadless/definitions/app/case-assist-engine/case-assist-engine-configuration.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/app/insight-engine/insight-engine-configuration.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/app/recommendation-engine/recommendation-engine-configuration.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/app/search-engine/search-engine-configuration.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/case-assist-configuration/case-assist-configuration-actions.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/case-assist-configuration/case-assist-configuration-state.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/configuration/configuration-actions.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/configuration/configuration-state.d.ts +1 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/generated-answer/generated-answer-request.d.ts +2 -2
- package/force-app/main/default/staticresources/coveoheadless/headless.js +17 -17
- package/force-app/main/default/staticresources/coveoheadless/insight/headless.js +16 -16
- package/force-app/main/default/staticresources/coveoheadless/recommendation/headless.js +14 -14
- package/force-app/main/default/staticresources/dompurify/purify.min.js +2 -2
- package/package.json +4 -4
|
@@ -12,8 +12,27 @@ import {LightningElement, api} from 'lwc';
|
|
|
12
12
|
export default class QuanticGeneratedAnswerCopyToClipboard extends LightningElement {
|
|
13
13
|
/**
|
|
14
14
|
* The answer to copy
|
|
15
|
+
* @type {string}
|
|
15
16
|
*/
|
|
16
|
-
@api answer;
|
|
17
|
+
@api answer = '';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The size of the copy icon.
|
|
21
|
+
* @api
|
|
22
|
+
* @type {'xx-small' | 'x-small' | 'small' | 'medium' | 'large'}
|
|
23
|
+
*/
|
|
24
|
+
@api
|
|
25
|
+
get size() {
|
|
26
|
+
return this._size;
|
|
27
|
+
}
|
|
28
|
+
set size(value) {
|
|
29
|
+
if (['xx-small', 'x-small', 'small', 'medium', 'large'].includes(value)) {
|
|
30
|
+
this._size = value;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @type {'xx-small' | 'x-small' | 'small' | 'medium' | 'large'} */
|
|
35
|
+
_size = 'xx-small';
|
|
17
36
|
|
|
18
37
|
labels = {
|
|
19
38
|
copy,
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import QuanticThreadItem from '../quanticThreadItem';
|
|
3
|
+
import {buildCreateTestComponent, cleanup, flushPromises} from 'c/testUtils';
|
|
4
|
+
|
|
5
|
+
const selectors = {
|
|
6
|
+
titleButton: '[data-testid="thread-item-title-button"]',
|
|
7
|
+
titleSpan: '[data-testid="thread-item-title-static"]',
|
|
8
|
+
boldTitle: '.slds-text-title_bold',
|
|
9
|
+
contentWrapper: '[data-testid="thread-item-content"]',
|
|
10
|
+
visibleContent: '[data-testid="thread-item-content"] > div:not([hidden])',
|
|
11
|
+
line: '[data-testid="thread-item-line"]',
|
|
12
|
+
dot: '[data-testid="thread-item-dot"]',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createTestComponent = buildCreateTestComponent(
|
|
16
|
+
QuanticThreadItem,
|
|
17
|
+
'c-quantic-thread-item',
|
|
18
|
+
{
|
|
19
|
+
title: 'Test title',
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
describe('c-quantic-thread-item', () => {
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
cleanup();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('initial rendering', () => {
|
|
29
|
+
it('renders a button when collapse is enabled', async () => {
|
|
30
|
+
const element = createTestComponent();
|
|
31
|
+
await flushPromises();
|
|
32
|
+
|
|
33
|
+
const button = element.shadowRoot.querySelector(selectors.titleButton);
|
|
34
|
+
expect(button).not.toBeNull();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('renders a span instead of a button when disableCollapse is true', async () => {
|
|
38
|
+
const element = createTestComponent({disableCollapse: true});
|
|
39
|
+
await flushPromises();
|
|
40
|
+
|
|
41
|
+
const button = element.shadowRoot.querySelector(selectors.titleButton);
|
|
42
|
+
const span = element.shadowRoot.querySelector(selectors.titleSpan);
|
|
43
|
+
expect(button).toBeNull();
|
|
44
|
+
expect(span).not.toBeNull();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('renders the timeline line by default', async () => {
|
|
48
|
+
const element = createTestComponent();
|
|
49
|
+
await flushPromises();
|
|
50
|
+
|
|
51
|
+
const line = element.shadowRoot.querySelector(selectors.line);
|
|
52
|
+
expect(line).not.toBeNull();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('hides the timeline line when hideLine is true', async () => {
|
|
56
|
+
const element = createTestComponent({hideLine: true});
|
|
57
|
+
await flushPromises();
|
|
58
|
+
|
|
59
|
+
const line = element.shadowRoot.querySelector(selectors.line);
|
|
60
|
+
expect(line).toBeNull();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('collapsed state', () => {
|
|
65
|
+
it('does not render the content by default', async () => {
|
|
66
|
+
const element = createTestComponent();
|
|
67
|
+
await flushPromises();
|
|
68
|
+
|
|
69
|
+
const content = element.shadowRoot.querySelector(
|
|
70
|
+
selectors.visibleContent
|
|
71
|
+
);
|
|
72
|
+
expect(content).toBeNull();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('button has aria-expanded set to false when collapsed', async () => {
|
|
76
|
+
const element = createTestComponent();
|
|
77
|
+
await flushPromises();
|
|
78
|
+
|
|
79
|
+
const button = element.shadowRoot.querySelector(selectors.titleButton);
|
|
80
|
+
expect(button.getAttribute('aria-expanded')).toBe('false');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('dot does not have expanded class when collapsed', async () => {
|
|
84
|
+
const element = createTestComponent();
|
|
85
|
+
await flushPromises();
|
|
86
|
+
|
|
87
|
+
const dot = element.shadowRoot.querySelector(selectors.dot);
|
|
88
|
+
expect(dot.className).not.toContain('thread-item__dot--expanded');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('expanded state', () => {
|
|
93
|
+
it('renders the content when isExpanded is true', async () => {
|
|
94
|
+
const element = createTestComponent({isExpanded: true});
|
|
95
|
+
await flushPromises();
|
|
96
|
+
|
|
97
|
+
const content = element.shadowRoot.querySelector(
|
|
98
|
+
selectors.visibleContent
|
|
99
|
+
);
|
|
100
|
+
expect(content).not.toBeNull();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('button has aria-expanded set to true when expanded', async () => {
|
|
104
|
+
const element = createTestComponent({isExpanded: true});
|
|
105
|
+
await flushPromises();
|
|
106
|
+
|
|
107
|
+
const button = element.shadowRoot.querySelector(selectors.titleButton);
|
|
108
|
+
expect(button.getAttribute('aria-expanded')).toBe('true');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('dot has expanded class when expanded', async () => {
|
|
112
|
+
const element = createTestComponent({isExpanded: true});
|
|
113
|
+
await flushPromises();
|
|
114
|
+
|
|
115
|
+
const dot = element.shadowRoot.querySelector(selectors.dot);
|
|
116
|
+
expect(dot.className).toContain('thread-item__dot--expanded');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('toggle interaction', () => {
|
|
121
|
+
it('renders the content when the button is clicked while collapsed', async () => {
|
|
122
|
+
const element = createTestComponent();
|
|
123
|
+
await flushPromises();
|
|
124
|
+
|
|
125
|
+
element.shadowRoot.querySelector(selectors.titleButton).click();
|
|
126
|
+
await flushPromises();
|
|
127
|
+
|
|
128
|
+
const content = element.shadowRoot.querySelector(
|
|
129
|
+
selectors.visibleContent
|
|
130
|
+
);
|
|
131
|
+
expect(content).not.toBeNull();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('does not render the content when the button is clicked while expanded', async () => {
|
|
135
|
+
const element = createTestComponent({isExpanded: true});
|
|
136
|
+
await flushPromises();
|
|
137
|
+
|
|
138
|
+
element.shadowRoot.querySelector(selectors.titleButton).click();
|
|
139
|
+
await flushPromises();
|
|
140
|
+
|
|
141
|
+
const content = element.shadowRoot.querySelector(
|
|
142
|
+
selectors.visibleContent
|
|
143
|
+
);
|
|
144
|
+
expect(content).toBeNull();
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('disableCollapse', () => {
|
|
149
|
+
it('forces item to be expanded regardless of isExpanded prop', async () => {
|
|
150
|
+
const element = createTestComponent({
|
|
151
|
+
disableCollapse: true,
|
|
152
|
+
isExpanded: false,
|
|
153
|
+
});
|
|
154
|
+
await flushPromises();
|
|
155
|
+
|
|
156
|
+
const content = element.shadowRoot.querySelector(
|
|
157
|
+
selectors.visibleContent
|
|
158
|
+
);
|
|
159
|
+
expect(content).not.toBeNull();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('renders a bold title when collapse is disabled', async () => {
|
|
163
|
+
const element = createTestComponent({
|
|
164
|
+
disableCollapse: true,
|
|
165
|
+
isExpanded: false,
|
|
166
|
+
});
|
|
167
|
+
await flushPromises();
|
|
168
|
+
|
|
169
|
+
const title = element.shadowRoot.querySelector(selectors.titleSpan);
|
|
170
|
+
expect(title.className).toContain('slds-text-title_bold');
|
|
171
|
+
expect(
|
|
172
|
+
element.shadowRoot.querySelector(selectors.boldTitle)
|
|
173
|
+
).not.toBeNull();
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.thread-item {
|
|
2
|
+
list-style: none;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.thread-item__dot-column,
|
|
6
|
+
.thread-item__line-column {
|
|
7
|
+
width: 10px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.thread-item__line-column {
|
|
11
|
+
align-items: stretch;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.thread-item__dot {
|
|
15
|
+
height: 8px;
|
|
16
|
+
width: 8px;
|
|
17
|
+
border-radius: 50%;
|
|
18
|
+
background-color: var(--lwc-colorBorder, #dddbda);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.thread-item__dot--expanded {
|
|
22
|
+
background-color: var(--lwc-colorTextDefault, #080707);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.thread-item__line {
|
|
26
|
+
position: relative;
|
|
27
|
+
width: 1px;
|
|
28
|
+
height: 100%;
|
|
29
|
+
background-color: var(--lwc-colorBorder, #dddbda);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.thread-item__line::before,
|
|
33
|
+
.thread-item__line::after {
|
|
34
|
+
content: '';
|
|
35
|
+
position: absolute;
|
|
36
|
+
left: 0;
|
|
37
|
+
width: 1px;
|
|
38
|
+
height: 8px;
|
|
39
|
+
background-color: var(--lwc-colorBorder, #dddbda);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.thread-item__line::before {
|
|
43
|
+
top: -8px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.thread-item__line::after {
|
|
47
|
+
bottom: -8px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.thread-item__clamped-text {
|
|
51
|
+
display: -webkit-box;
|
|
52
|
+
-webkit-line-clamp: 3;
|
|
53
|
+
-webkit-box-orient: vertical;
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.thread-item__title-button {
|
|
58
|
+
width: fit-content;
|
|
59
|
+
border-radius: var(--slds-g-radius-border-2, 4px);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.thread-item__title-button:hover {
|
|
63
|
+
background-color: var(--lwc-colorBackgroundRowHover, #f3f2f2);
|
|
64
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li class="thread-item">
|
|
3
|
+
<div class="slds-grid slds-grid_vertical-align-center">
|
|
4
|
+
<div
|
|
5
|
+
class="slds-grid slds-grid_align-center slds-grid_vertical-align-center slds-shrink-none slds-m-right_x-small thread-item__dot-column"
|
|
6
|
+
>
|
|
7
|
+
<span class={dotClass} data-testid="thread-item-dot"></span>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="slds-col slds-has-flexi-truncate">
|
|
10
|
+
<template lwc:if={disableCollapse}>
|
|
11
|
+
<span class={titleClass} data-testid="thread-item-title-static"
|
|
12
|
+
>{title}</span
|
|
13
|
+
>
|
|
14
|
+
</template>
|
|
15
|
+
<template lwc:else>
|
|
16
|
+
<button
|
|
17
|
+
type="button"
|
|
18
|
+
class={titleButtonClass}
|
|
19
|
+
aria-expanded={isExpanded}
|
|
20
|
+
data-testid="thread-item-title-button"
|
|
21
|
+
onclick={handleTitleClick}
|
|
22
|
+
aria-controls="thread-item-content"
|
|
23
|
+
>
|
|
24
|
+
{title}
|
|
25
|
+
</button>
|
|
26
|
+
</template>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="slds-grid">
|
|
30
|
+
<div
|
|
31
|
+
class="slds-grid slds-grid_align-center slds-shrink-none thread-item__line-column slds-m-right_x-small"
|
|
32
|
+
>
|
|
33
|
+
<template lwc:if={shouldDisplayLine}>
|
|
34
|
+
<span class="thread-item__line" data-testid="thread-item-line"></span>
|
|
35
|
+
</template>
|
|
36
|
+
</div>
|
|
37
|
+
<div
|
|
38
|
+
id="thread-item-content"
|
|
39
|
+
class="slds-col slds-p-left_x-small slds-p-vertical_xx-small"
|
|
40
|
+
data-testid="thread-item-content"
|
|
41
|
+
>
|
|
42
|
+
<div hidden={contentHidden}>
|
|
43
|
+
<slot></slot>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</li>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {LightningElement, api} from 'lwc';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `QuanticThreadItem` component renders a thread item with timeline visuals and collapsible content.
|
|
5
|
+
* @category Internal
|
|
6
|
+
* @example
|
|
7
|
+
* <c-quantic-thread-item title="Step title" hide-line is-expanded></c-quantic-thread-item>
|
|
8
|
+
*/
|
|
9
|
+
export default class QuanticThreadItem extends LightningElement {
|
|
10
|
+
/**
|
|
11
|
+
* The title displayed for the thread item.
|
|
12
|
+
* @api
|
|
13
|
+
* @type {string}
|
|
14
|
+
*/
|
|
15
|
+
@api title = '';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Whether the thread item can be expanded or collapsed.
|
|
19
|
+
* @api
|
|
20
|
+
* @type {boolean}
|
|
21
|
+
* @defaultValue `false`
|
|
22
|
+
*/
|
|
23
|
+
@api disableCollapse = false;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Whether the timeline line should be hidden.
|
|
27
|
+
* @api
|
|
28
|
+
* @type {boolean}
|
|
29
|
+
* @defaultValue `false`
|
|
30
|
+
*/
|
|
31
|
+
@api hideLine = false;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether the thread item is expanded.
|
|
35
|
+
* @api
|
|
36
|
+
* @type {boolean}
|
|
37
|
+
* @defaultValue `false`
|
|
38
|
+
*/
|
|
39
|
+
@api
|
|
40
|
+
get isExpanded() {
|
|
41
|
+
return this._isExpanded;
|
|
42
|
+
}
|
|
43
|
+
set isExpanded(value) {
|
|
44
|
+
this._isExpanded = value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** @type {boolean} */
|
|
48
|
+
_isExpanded = false;
|
|
49
|
+
|
|
50
|
+
connectedCallback() {
|
|
51
|
+
this._isExpanded = this.disableCollapse ? true : this.isExpanded;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
handleTitleClick() {
|
|
55
|
+
if (this.disableCollapse) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
this._isExpanded = !this._isExpanded;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get shouldDisplayLine() {
|
|
62
|
+
return !this.hideLine;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get contentHidden() {
|
|
66
|
+
return !this._isExpanded;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get titleClass() {
|
|
70
|
+
return `thread-item__clamped-text slds-text-body_regular slds-p-horizontal_x-small slds-p-vertical_xx-small${this._isExpanded ? ' slds-text-title_bold' : ''}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get titleButtonClass() {
|
|
74
|
+
return `slds-button_reset slds-p-horizontal_x-small slds-p-vertical_xx-small thread-item__title-button thread-item__clamped-text${this._isExpanded ? ' slds-text-title_bold' : ''}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get dotClass() {
|
|
78
|
+
return `thread-item__dot${this._isExpanded ? ' thread-item__dot--expanded' : ''}`;
|
|
79
|
+
}
|
|
80
|
+
}
|