@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.
Files changed (32) hide show
  1. package/force-app/main/default/lwc/quanticFeedback/__tests__/quanticFeedback.test.js +11 -0
  2. package/force-app/main/default/lwc/quanticFeedback/quanticFeedback.html +6 -4
  3. package/force-app/main/default/lwc/quanticFeedback/quanticFeedback.js +8 -0
  4. package/force-app/main/default/lwc/quanticGeneratedAnswer/__tests__/quanticGeneratedAnswer.test.js +32 -3
  5. package/force-app/main/default/lwc/quanticGeneratedAnswer/quanticGeneratedAnswer.css +1 -8
  6. package/force-app/main/default/lwc/quanticGeneratedAnswer/quanticGeneratedAnswer.js +6 -28
  7. package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/generatedAnswer.css +0 -13
  8. package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/generatedAnswer.html +120 -93
  9. package/force-app/main/default/lwc/quanticGeneratedAnswer/templates/retryPrompt.html +24 -15
  10. package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/__tests__/quanticGeneratedAnswerCopyToClipboard.test.js +125 -0
  11. package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/quanticGeneratedAnswerCopyToClipboard.html +1 -1
  12. package/force-app/main/default/lwc/quanticGeneratedAnswerCopyToClipboard/quanticGeneratedAnswerCopyToClipboard.js +20 -1
  13. package/force-app/main/default/lwc/quanticThreadItem/__tests__/quanticThreadItem.test.js +176 -0
  14. package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.css +64 -0
  15. package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.html +48 -0
  16. package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.js +80 -0
  17. package/force-app/main/default/lwc/quanticThreadItem/quanticThreadItem.js-meta.xml +5 -0
  18. package/force-app/main/default/staticresources/coveoheadless/case-assist/headless.js +15 -15
  19. package/force-app/main/default/staticresources/coveoheadless/definitions/app/case-assist-engine/case-assist-engine-configuration.d.ts +1 -1
  20. package/force-app/main/default/staticresources/coveoheadless/definitions/app/insight-engine/insight-engine-configuration.d.ts +1 -1
  21. package/force-app/main/default/staticresources/coveoheadless/definitions/app/recommendation-engine/recommendation-engine-configuration.d.ts +1 -1
  22. package/force-app/main/default/staticresources/coveoheadless/definitions/app/search-engine/search-engine-configuration.d.ts +1 -1
  23. package/force-app/main/default/staticresources/coveoheadless/definitions/features/case-assist-configuration/case-assist-configuration-actions.d.ts +1 -1
  24. package/force-app/main/default/staticresources/coveoheadless/definitions/features/case-assist-configuration/case-assist-configuration-state.d.ts +1 -1
  25. package/force-app/main/default/staticresources/coveoheadless/definitions/features/configuration/configuration-actions.d.ts +1 -1
  26. package/force-app/main/default/staticresources/coveoheadless/definitions/features/configuration/configuration-state.d.ts +1 -1
  27. package/force-app/main/default/staticresources/coveoheadless/definitions/features/generated-answer/generated-answer-request.d.ts +2 -2
  28. package/force-app/main/default/staticresources/coveoheadless/headless.js +17 -17
  29. package/force-app/main/default/staticresources/coveoheadless/insight/headless.js +16 -16
  30. package/force-app/main/default/staticresources/coveoheadless/recommendation/headless.js +14 -14
  31. package/force-app/main/default/staticresources/dompurify/purify.min.js +2 -2
  32. 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
+ }
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <apiVersion>66.0</apiVersion>
4
+ <isExposed>false</isExposed>
5
+ </LightningComponentBundle>