makethisbetter 1.9.0 → 1.9.2
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/dist/i18n/de.d.ts +1 -0
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/en.d.ts +1 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/es.d.ts +1 -0
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/fr.d.ts +1 -0
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/ja.d.ts +1 -0
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ko.d.ts +1 -0
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/zh-CN.d.ts +1 -0
- package/dist/i18n/zh-CN.d.ts.map +1 -1
- package/dist/makethisbetter.cjs +25 -17
- package/dist/makethisbetter.cjs.map +1 -1
- package/dist/makethisbetter.esm.js +418 -384
- package/dist/makethisbetter.esm.js.map +1 -1
- package/dist/makethisbetter.js +25 -17
- package/dist/makethisbetter.js.map +1 -1
- package/dist/popup/clarify.d.ts +3 -1
- package/dist/popup/clarify.d.ts.map +1 -1
- package/dist/popup/comment.d.ts +2 -0
- package/dist/popup/comment.d.ts.map +1 -1
- package/dist/widget/controller.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/i18n/de.ts +1 -0
- package/src/i18n/en.ts +1 -0
- package/src/i18n/es.ts +1 -0
- package/src/i18n/fr.ts +1 -0
- package/src/i18n/ja.ts +1 -0
- package/src/i18n/ko.ts +1 -0
- package/src/i18n/zh-CN.ts +1 -0
- package/src/popup/clarify.test.ts +90 -23
- package/src/popup/clarify.ts +40 -20
- package/src/popup/comment.test.ts +38 -0
- package/src/popup/comment.ts +15 -8
- package/src/styles/widget.css +64 -34
- package/src/widget/controller.test.ts +38 -9
- package/src/widget/controller.ts +16 -15
package/dist/popup/clarify.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ interface ClarifyCardOptions {
|
|
|
7
7
|
apiClient: ApiClient;
|
|
8
8
|
messages: I18nMessages;
|
|
9
9
|
onFinalize: () => Promise<void> | void;
|
|
10
|
+
element?: HTMLDivElement;
|
|
11
|
+
position?: 'left' | 'right';
|
|
10
12
|
x?: number;
|
|
11
13
|
y?: number;
|
|
12
14
|
preloadedResult?: ClarifyStreamResult;
|
|
@@ -49,7 +51,7 @@ export declare class ClarifyCard {
|
|
|
49
51
|
private stopPolling;
|
|
50
52
|
private poll;
|
|
51
53
|
private handleDone;
|
|
52
|
-
private
|
|
54
|
+
private showFinalizeButton;
|
|
53
55
|
private finalize;
|
|
54
56
|
private showRetryButton;
|
|
55
57
|
private renderConversation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clarify.d.ts","sourceRoot":"","sources":["../../src/popup/clarify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AASnE,UAAU,kBAAkB;IAC1B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,SAAS,CAAA;IACpB,QAAQ,EAAE,YAAY,CAAA;IACtB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtC,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,eAAe,CAAC,EAAE,mBAAmB,CAAA;IACrC,oBAAoB,CAAC,EAAE,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;CAC3D;AAKD,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,eAAe,CAAC,CAAqB;IAC7C,OAAO,CAAC,oBAAoB,CAAC,CAAqC;gBAEtD,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,kBAAkB;
|
|
1
|
+
{"version":3,"file":"clarify.d.ts","sourceRoot":"","sources":["../../src/popup/clarify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AASnE,UAAU,kBAAkB;IAC1B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,eAAe,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,SAAS,CAAA;IACpB,QAAQ,EAAE,YAAY,CAAA;IACtB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtC,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,eAAe,CAAC,EAAE,mBAAmB,CAAA;IACrC,oBAAoB,CAAC,EAAE,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;CAC3D;AAKD,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,mBAAmB,CAAQ;IACnC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,eAAe,CAAC,CAAqB;IAC7C,OAAO,CAAC,oBAAoB,CAAC,CAAqC;gBAEtD,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,kBAAkB;IA4B7D,OAAO,CAAC,YAAY;IA+BpB,OAAO,CAAC,SAAS;IAmCjB,OAAO,CAAC,UAAU;YAuBJ,iBAAiB;YA8BjB,WAAW;YA+BX,cAAc;YAmBd,wBAAwB;YAgBxB,aAAa;IAY3B,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;YAOL,IAAI;IAwBlB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,kBAAkB;YAgBZ,QAAQ;IAgBtB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,cAAc;IAItB,OAAO,IAAI,IAAI;CAKhB"}
|
package/dist/popup/comment.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface PopupOptions {
|
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
onMyFeedback?: () => void;
|
|
12
12
|
messages: I18nMessages;
|
|
13
|
+
position?: 'left' | 'right';
|
|
13
14
|
}
|
|
14
15
|
export declare class CommentPopup {
|
|
15
16
|
private el;
|
|
@@ -29,6 +30,7 @@ export declare class CommentPopup {
|
|
|
29
30
|
private submit;
|
|
30
31
|
setLoading(loading: boolean): void;
|
|
31
32
|
setError(message: string): void;
|
|
33
|
+
releaseElement(): HTMLDivElement;
|
|
32
34
|
destroy(): void;
|
|
33
35
|
}
|
|
34
36
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/popup/comment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,UAAU,YAAY;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,QAAQ,EAAE,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/popup/comment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,UAAU,YAAY;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,QAAQ,EAAE,YAAY,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAC5B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAc;gBAElB,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY;IAqBvD,OAAO,CAAC,SAAS;IA6CjB,OAAO,CAAC,aAAa;IAwCrB,OAAO,CAAC,UAAU;IA2BlB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,MAAM;IAMd,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAclC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK/B,cAAc,IAAI,cAAc;IAIhC,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/widget/controller.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,oBAAoB,EAAqD,MAAM,UAAU,CAAA;AAYvG,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,gBAAgB,CAAgC;IACxD,OAAO,CAAC,gBAAgB,CAAyC;IACjE,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,WAAW,CAAyE;IAC5F,OAAO,CAAC,0BAA0B,CAAQ;gBAE9B,MAAM,EAAE,oBAAoB;IAoBxC,OAAO,CAAC,aAAa,CAuBpB;IAED,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,uBAAuB;IA+B/B,OAAO,CAAC,gBAAgB,CAKvB;IAED,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/widget/controller.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,oBAAoB,EAAqD,MAAM,UAAU,CAAA;AAYvG,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,gBAAgB,CAAgC;IACxD,OAAO,CAAC,gBAAgB,CAAyC;IACjE,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,WAAW,CAAyE;IAC5F,OAAO,CAAC,0BAA0B,CAAQ;gBAE9B,MAAM,EAAE,oBAAoB;IAoBxC,OAAO,CAAC,aAAa,CAuBpB;IAED,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,uBAAuB;IA+B/B,OAAO,CAAC,gBAAgB,CAKvB;IAED,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,SAAS;IAyBjB,OAAO,CAAC,sBAAsB;YAYhB,YAAY;YAyCZ,kBAAkB;IAqChC,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,WAAW;YA0BL,kBAAkB;IAsBhC,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,OAAO;IA4Bf,OAAO,IAAI,IAAI;CAahB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makethisbetter",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
4
4
|
"description": "Make This Better JS Widget SDK — embed user feedback collection in any website",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/makethisbetter.cjs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"homepage": "https://makethisbetter.dev",
|
|
61
61
|
"repository": {
|
|
62
62
|
"type": "git",
|
|
63
|
-
"url": "https://github.com/makethisbetter/makethisbetter-js.git"
|
|
63
|
+
"url": "git+https://github.com/makethisbetter/makethisbetter-js.git"
|
|
64
64
|
},
|
|
65
65
|
"license": "MIT"
|
|
66
66
|
}
|
package/src/i18n/de.ts
CHANGED
package/src/i18n/en.ts
CHANGED
package/src/i18n/es.ts
CHANGED
package/src/i18n/fr.ts
CHANGED
package/src/i18n/ja.ts
CHANGED
package/src/i18n/ko.ts
CHANGED
package/src/i18n/zh-CN.ts
CHANGED
|
@@ -65,6 +65,38 @@ describe('ClarifyCard', () => {
|
|
|
65
65
|
shadow.destroy()
|
|
66
66
|
})
|
|
67
67
|
|
|
68
|
+
it('reuses the current popup element without moving or replaying its entrance', async () => {
|
|
69
|
+
const shadow = new ShadowContainer()
|
|
70
|
+
const element = shadow.el<HTMLDivElement>('div', 'mtb-popup')
|
|
71
|
+
element.style.left = '40px'
|
|
72
|
+
element.style.top = '60px'
|
|
73
|
+
shadow.append(element)
|
|
74
|
+
|
|
75
|
+
const apiClient = mockApiClient()
|
|
76
|
+
const card = new ClarifyCard(shadow, {
|
|
77
|
+
submissionSessionId: 'submission_123',
|
|
78
|
+
submissionToken: 'submission-secret',
|
|
79
|
+
apiClient,
|
|
80
|
+
messages: getMessages('en'),
|
|
81
|
+
onFinalize: vi.fn(),
|
|
82
|
+
element,
|
|
83
|
+
x: 400,
|
|
84
|
+
y: 300,
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
await vi.waitFor(() => {
|
|
88
|
+
expect(apiClient.startClarification).toHaveBeenCalled()
|
|
89
|
+
})
|
|
90
|
+
expect(shadow.root.querySelector('.mtb-clarify')).toBe(element)
|
|
91
|
+
expect(element.className).toBe('mtb-clarify mtb-clarify-continuation')
|
|
92
|
+
expect(element.style.left).toBe('40px')
|
|
93
|
+
expect(element.style.top).toBe('60px')
|
|
94
|
+
expect(shadow.root.children).toHaveLength(2)
|
|
95
|
+
|
|
96
|
+
card.destroy()
|
|
97
|
+
shadow.destroy()
|
|
98
|
+
})
|
|
99
|
+
|
|
68
100
|
it('renders header with skip button', async () => {
|
|
69
101
|
const { shadow, card, messages, apiClient } = setupCard()
|
|
70
102
|
await vi.waitFor(() => {
|
|
@@ -98,7 +130,7 @@ describe('ClarifyCard', () => {
|
|
|
98
130
|
const el = shadow.root.querySelector<HTMLDivElement>('.mtb-clarify')!
|
|
99
131
|
const left = parseInt(el.style.left, 10)
|
|
100
132
|
const top = parseInt(el.style.top, 10)
|
|
101
|
-
expect(left + 346).toBeLessThanOrEqual(1024)
|
|
133
|
+
expect(left + 346).toBeLessThanOrEqual(1024 - 44)
|
|
102
134
|
expect(top).toBeGreaterThanOrEqual(12)
|
|
103
135
|
expect(top).toBeLessThanOrEqual(768 - 12)
|
|
104
136
|
|
|
@@ -106,6 +138,26 @@ describe('ClarifyCard', () => {
|
|
|
106
138
|
shadow.destroy()
|
|
107
139
|
})
|
|
108
140
|
|
|
141
|
+
it('leaves room for a left-side feedback tab', async () => {
|
|
142
|
+
const shadow = new ShadowContainer()
|
|
143
|
+
const card = new ClarifyCard(shadow, {
|
|
144
|
+
submissionSessionId: 'submission_123',
|
|
145
|
+
submissionToken: 'submission-secret',
|
|
146
|
+
apiClient: mockApiClient(),
|
|
147
|
+
messages: getMessages('en'),
|
|
148
|
+
onFinalize: vi.fn(),
|
|
149
|
+
position: 'left',
|
|
150
|
+
x: 0,
|
|
151
|
+
y: 300,
|
|
152
|
+
})
|
|
153
|
+
const element = shadow.root.querySelector<HTMLDivElement>('.mtb-clarify')!
|
|
154
|
+
|
|
155
|
+
expect(Number.parseFloat(element.style.left)).toBeGreaterThanOrEqual(44)
|
|
156
|
+
|
|
157
|
+
card.destroy()
|
|
158
|
+
shadow.destroy()
|
|
159
|
+
})
|
|
160
|
+
|
|
109
161
|
it('renders the redesigned header title and subtitle', async () => {
|
|
110
162
|
const { shadow, card, messages } = setupCard()
|
|
111
163
|
expect(shadow.root.querySelector('.mtb-clarify-title')?.textContent).toBe(messages.clarify.title)
|
|
@@ -253,9 +305,12 @@ describe('ClarifyCard', () => {
|
|
|
253
305
|
expect(startClarification).toHaveBeenCalledTimes(2)
|
|
254
306
|
})
|
|
255
307
|
expect(startClarification).toHaveBeenCalledWith('submission_123', 'submission-secret', 'Button does nothing')
|
|
308
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
256
309
|
await vi.waitFor(() => {
|
|
257
|
-
expect(
|
|
310
|
+
expect(shadow.root.querySelector('.mtb-clarify-send-feedback')).toBeTruthy()
|
|
258
311
|
})
|
|
312
|
+
shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!.click()
|
|
313
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
259
314
|
|
|
260
315
|
card.destroy()
|
|
261
316
|
shadow.destroy()
|
|
@@ -382,7 +437,7 @@ describe('ClarifyCard', () => {
|
|
|
382
437
|
shadow.destroy()
|
|
383
438
|
})
|
|
384
439
|
|
|
385
|
-
it('
|
|
440
|
+
it('waits for Send feedback when done=true from start', async () => {
|
|
386
441
|
const startClarification = vi.fn().mockResolvedValue({
|
|
387
442
|
status: 'complete',
|
|
388
443
|
messages: [{ role: 'assistant', content: 'All clear, thanks!' }],
|
|
@@ -395,15 +450,19 @@ describe('ClarifyCard', () => {
|
|
|
395
450
|
})
|
|
396
451
|
await vi.advanceTimersByTimeAsync(0)
|
|
397
452
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
453
|
+
expect(shadow.root.querySelector('.mtb-clarify-ai')?.textContent).toBe('All clear, thanks!')
|
|
454
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
455
|
+
|
|
456
|
+
const sendFeedback = shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!
|
|
457
|
+
expect(sendFeedback).toBeTruthy()
|
|
458
|
+
sendFeedback.click()
|
|
459
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
401
460
|
|
|
402
461
|
card.destroy()
|
|
403
462
|
shadow.destroy()
|
|
404
463
|
})
|
|
405
464
|
|
|
406
|
-
it('
|
|
465
|
+
it('waits for confirmation when polling returns done=true', async () => {
|
|
407
466
|
const getClarification = vi.fn().mockResolvedValueOnce({
|
|
408
467
|
status: 'complete',
|
|
409
468
|
messages: [{ role: 'assistant', content: 'Done' }],
|
|
@@ -422,15 +481,17 @@ describe('ClarifyCard', () => {
|
|
|
422
481
|
})
|
|
423
482
|
await vi.advanceTimersByTimeAsync(0)
|
|
424
483
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
484
|
+
const sendFeedback = shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!
|
|
485
|
+
expect(sendFeedback).toBeTruthy()
|
|
486
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
487
|
+
sendFeedback.click()
|
|
488
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
428
489
|
|
|
429
490
|
card.destroy()
|
|
430
491
|
shadow.destroy()
|
|
431
492
|
})
|
|
432
493
|
|
|
433
|
-
it('
|
|
494
|
+
it('waits for confirmation on startClarification error', async () => {
|
|
434
495
|
const startClarification = vi.fn().mockRejectedValue(new Error('Network error'))
|
|
435
496
|
|
|
436
497
|
const { shadow, card, onFinalize } = setupCard({ startClarification })
|
|
@@ -439,9 +500,11 @@ describe('ClarifyCard', () => {
|
|
|
439
500
|
})
|
|
440
501
|
await vi.advanceTimersByTimeAsync(0)
|
|
441
502
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
503
|
+
const sendFeedback = shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!
|
|
504
|
+
expect(sendFeedback).toBeTruthy()
|
|
505
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
506
|
+
sendFeedback.click()
|
|
507
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
445
508
|
|
|
446
509
|
card.destroy()
|
|
447
510
|
shadow.destroy()
|
|
@@ -588,7 +651,7 @@ describe('ClarifyCard', () => {
|
|
|
588
651
|
shadow.destroy()
|
|
589
652
|
})
|
|
590
653
|
|
|
591
|
-
it('
|
|
654
|
+
it('waits for confirmation after streaming completes without polling', async () => {
|
|
592
655
|
const streamClarification = vi.fn().mockResolvedValue({
|
|
593
656
|
messages: [{ role: 'assistant', content: 'All clear, thanks!' }],
|
|
594
657
|
done: true,
|
|
@@ -603,15 +666,17 @@ describe('ClarifyCard', () => {
|
|
|
603
666
|
|
|
604
667
|
await vi.advanceTimersByTimeAsync(2000)
|
|
605
668
|
expect(getClarification).not.toHaveBeenCalled()
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
669
|
+
const sendFeedback = shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!
|
|
670
|
+
expect(sendFeedback).toBeTruthy()
|
|
671
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
672
|
+
sendFeedback.click()
|
|
673
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
609
674
|
|
|
610
675
|
card.destroy()
|
|
611
676
|
shadow.destroy()
|
|
612
677
|
})
|
|
613
678
|
|
|
614
|
-
it('
|
|
679
|
+
it('waits for confirmation when polling exceeds the timeout with no reply', async () => {
|
|
615
680
|
const getClarification = vi.fn().mockResolvedValue({
|
|
616
681
|
status: 'pending',
|
|
617
682
|
messages: [],
|
|
@@ -624,11 +689,13 @@ describe('ClarifyCard', () => {
|
|
|
624
689
|
})
|
|
625
690
|
await vi.advanceTimersByTimeAsync(0)
|
|
626
691
|
|
|
627
|
-
// Poll past the 45s deadline; the card should give up and
|
|
692
|
+
// Poll past the 45s deadline; the card should give up and let the reporter confirm.
|
|
628
693
|
await vi.advanceTimersByTimeAsync(48000)
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
694
|
+
const sendFeedback = shadow.root.querySelector<HTMLButtonElement>('.mtb-clarify-send-feedback')!
|
|
695
|
+
expect(sendFeedback).toBeTruthy()
|
|
696
|
+
expect(onFinalize).not.toHaveBeenCalled()
|
|
697
|
+
sendFeedback.click()
|
|
698
|
+
expect(onFinalize).toHaveBeenCalledOnce()
|
|
632
699
|
|
|
633
700
|
card.destroy()
|
|
634
701
|
shadow.destroy()
|
package/src/popup/clarify.ts
CHANGED
|
@@ -15,6 +15,8 @@ interface ClarifyCardOptions {
|
|
|
15
15
|
apiClient: ApiClient
|
|
16
16
|
messages: I18nMessages
|
|
17
17
|
onFinalize: () => Promise<void> | void
|
|
18
|
+
element?: HTMLDivElement
|
|
19
|
+
position?: 'left' | 'right'
|
|
18
20
|
x?: number
|
|
19
21
|
y?: number
|
|
20
22
|
preloadedResult?: ClarifyStreamResult
|
|
@@ -22,7 +24,7 @@ interface ClarifyCardOptions {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const CARD_WIDTH = 346
|
|
25
|
-
const CARD_HEIGHT =
|
|
27
|
+
const CARD_HEIGHT = 270
|
|
26
28
|
|
|
27
29
|
export class ClarifyCard {
|
|
28
30
|
private el: HTMLDivElement
|
|
@@ -55,10 +57,14 @@ export class ClarifyCard {
|
|
|
55
57
|
this.preloadedResult = opts.preloadedResult
|
|
56
58
|
this.pendingClarification = opts.pendingClarification
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
const existingElement = opts.element
|
|
61
|
+
this.el = existingElement ?? shadow.el<HTMLDivElement>('div', 'mtb-clarify')
|
|
62
|
+
this.el.className = existingElement ? 'mtb-clarify mtb-clarify-continuation' : 'mtb-clarify'
|
|
59
63
|
this.el.innerHTML = this.buildHTML(opts.messages)
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
if (!existingElement) {
|
|
65
|
+
shadow.append(this.el)
|
|
66
|
+
this.positionCard(opts.x, opts.y, opts.position ?? 'right')
|
|
67
|
+
}
|
|
62
68
|
|
|
63
69
|
this.messagesEl = this.el.querySelector('.mtb-clarify-messages')!
|
|
64
70
|
this.inputEl = this.el.querySelector('.mtb-clarify-input')!
|
|
@@ -70,15 +76,19 @@ export class ClarifyCard {
|
|
|
70
76
|
|
|
71
77
|
// Anchors the card near the annotation point, clamped to the viewport so it
|
|
72
78
|
// never overflows a screen edge (mirrors CommentPopup.positionPopup).
|
|
73
|
-
private positionCard(x
|
|
74
|
-
const cardW = CARD_WIDTH
|
|
75
|
-
const cardH = this.el.offsetHeight || CARD_HEIGHT
|
|
79
|
+
private positionCard(x: number | undefined, y: number | undefined, tabPosition: 'left' | 'right'): void {
|
|
76
80
|
const vw = window.innerWidth
|
|
77
81
|
const vh = window.innerHeight
|
|
78
82
|
const margin = 12
|
|
83
|
+
const tabWidth = 32
|
|
84
|
+
const cardW = Math.min(CARD_WIDTH, vw - 2 * margin - tabWidth)
|
|
85
|
+
const cardH = this.el.offsetHeight || CARD_HEIGHT
|
|
86
|
+
const minLeft = margin + (tabPosition === 'left' ? tabWidth : 0)
|
|
87
|
+
const maxRight = vw - margin - (tabPosition === 'right' ? tabWidth : 0)
|
|
79
88
|
|
|
80
89
|
if (x === undefined || y === undefined) {
|
|
81
|
-
|
|
90
|
+
const centeredLeft = Math.max(minLeft, (vw - cardW) / 2)
|
|
91
|
+
this.el.style.left = `${Math.min(centeredLeft, maxRight - cardW)}px`
|
|
82
92
|
this.el.style.top = `${Math.max(margin, (vh - cardH) / 2)}px`
|
|
83
93
|
this.el.style.maxHeight = `${vh - 2 * margin}px`
|
|
84
94
|
return
|
|
@@ -86,8 +96,9 @@ export class ClarifyCard {
|
|
|
86
96
|
|
|
87
97
|
let left = x + 12
|
|
88
98
|
let top = y + 12
|
|
89
|
-
if (left + cardW >
|
|
90
|
-
if (left
|
|
99
|
+
if (left + cardW > maxRight) left = x - cardW - 12
|
|
100
|
+
if (left + cardW > maxRight) left = maxRight - cardW
|
|
101
|
+
if (left < minLeft) left = minLeft
|
|
91
102
|
if (top + cardH > vh - margin) top = vh - cardH - margin
|
|
92
103
|
if (top < margin) top = margin
|
|
93
104
|
|
|
@@ -100,7 +111,7 @@ export class ClarifyCard {
|
|
|
100
111
|
return `
|
|
101
112
|
<div class="mtb-clarify-header">
|
|
102
113
|
<span class="mtb-clarify-icon">
|
|
103
|
-
<svg width="
|
|
114
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round">
|
|
104
115
|
<path d="M12 3l1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6L12 3z"/>
|
|
105
116
|
</svg>
|
|
106
117
|
</span>
|
|
@@ -109,18 +120,18 @@ export class ClarifyCard {
|
|
|
109
120
|
<div class="mtb-clarify-subtitle">${escapeHtml(m.clarify.subtitle)}</div>
|
|
110
121
|
</div>
|
|
111
122
|
<button class="mtb-clarify-close" type="button" title="${escapeHtml(m.clarify.skip)}" aria-label="${escapeHtml(m.clarify.skip)}">
|
|
112
|
-
<svg width="
|
|
123
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
113
124
|
<path d="M18 6L6 18M6 6l12 12"/>
|
|
114
125
|
</svg>
|
|
115
126
|
</button>
|
|
116
127
|
</div>
|
|
117
128
|
<div class="mtb-clarify-messages"></div>
|
|
118
129
|
<div class="mtb-clarify-footer">
|
|
119
|
-
<textarea class="mtb-clarify-input" rows="
|
|
130
|
+
<textarea class="mtb-clarify-input" rows="1" placeholder="${escapeHtml(m.clarify.placeholder)}"></textarea>
|
|
120
131
|
<div class="mtb-clarify-actions">
|
|
121
132
|
<button class="mtb-clarify-skip" type="button">${escapeHtml(m.clarify.skip)}</button>
|
|
122
133
|
<button class="mtb-clarify-send" type="button" disabled>
|
|
123
|
-
<svg width="
|
|
134
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
124
135
|
<line x1="22" y1="2" x2="11" y2="13"/>
|
|
125
136
|
<polygon points="22 2 15 22 11 13 2 9 22 2"/>
|
|
126
137
|
</svg>
|
|
@@ -331,13 +342,23 @@ export class ClarifyCard {
|
|
|
331
342
|
this.done = true
|
|
332
343
|
this.stopPolling()
|
|
333
344
|
this.removeThinking()
|
|
334
|
-
this.
|
|
335
|
-
void this.finalize()
|
|
345
|
+
this.showFinalizeButton()
|
|
336
346
|
}
|
|
337
347
|
|
|
338
|
-
private
|
|
339
|
-
this.
|
|
340
|
-
|
|
348
|
+
private showFinalizeButton(): void {
|
|
349
|
+
const footer = this.el.querySelector('.mtb-clarify-footer')!
|
|
350
|
+
footer.innerHTML = `
|
|
351
|
+
<button class="mtb-clarify-send-feedback" type="button">
|
|
352
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
353
|
+
<line x1="22" y1="2" x2="11" y2="13"/>
|
|
354
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2"/>
|
|
355
|
+
</svg>
|
|
356
|
+
<span>${escapeHtml(this.i18n.clarify.send_feedback)}</span>
|
|
357
|
+
</button>
|
|
358
|
+
`
|
|
359
|
+
footer.querySelector('.mtb-clarify-send-feedback')!.addEventListener('click', () => {
|
|
360
|
+
if (!this.destroyed) void this.finalize()
|
|
361
|
+
})
|
|
341
362
|
}
|
|
342
363
|
|
|
343
364
|
private async finalize(): Promise<void> {
|
|
@@ -406,4 +427,3 @@ export class ClarifyCard {
|
|
|
406
427
|
this.el.remove()
|
|
407
428
|
}
|
|
408
429
|
}
|
|
409
|
-
|
|
@@ -127,4 +127,42 @@ describe('CommentPopup', () => {
|
|
|
127
127
|
popup.destroy()
|
|
128
128
|
shadow.destroy()
|
|
129
129
|
})
|
|
130
|
+
|
|
131
|
+
it('leaves room for the right-side feedback tab', () => {
|
|
132
|
+
const shadow = new ShadowContainer()
|
|
133
|
+
const popup = new CommentPopup(shadow, {
|
|
134
|
+
targetName: 'Export PDF',
|
|
135
|
+
x: window.innerWidth,
|
|
136
|
+
y: 120,
|
|
137
|
+
messages: getMessages('en'),
|
|
138
|
+
onSubmit: vi.fn(),
|
|
139
|
+
onClose: vi.fn(),
|
|
140
|
+
position: 'right',
|
|
141
|
+
})
|
|
142
|
+
const element = shadow.root.querySelector<HTMLElement>('.mtb-popup')!
|
|
143
|
+
|
|
144
|
+
expect(Number.parseFloat(element.style.left) + 320).toBeLessThanOrEqual(window.innerWidth - 44)
|
|
145
|
+
|
|
146
|
+
popup.destroy()
|
|
147
|
+
shadow.destroy()
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('leaves room for the left-side feedback tab', () => {
|
|
151
|
+
const shadow = new ShadowContainer()
|
|
152
|
+
const popup = new CommentPopup(shadow, {
|
|
153
|
+
targetName: 'Export PDF',
|
|
154
|
+
x: 0,
|
|
155
|
+
y: 120,
|
|
156
|
+
messages: getMessages('en'),
|
|
157
|
+
onSubmit: vi.fn(),
|
|
158
|
+
onClose: vi.fn(),
|
|
159
|
+
position: 'left',
|
|
160
|
+
})
|
|
161
|
+
const element = shadow.root.querySelector<HTMLElement>('.mtb-popup')!
|
|
162
|
+
|
|
163
|
+
expect(Number.parseFloat(element.style.left)).toBeGreaterThanOrEqual(44)
|
|
164
|
+
|
|
165
|
+
popup.destroy()
|
|
166
|
+
shadow.destroy()
|
|
167
|
+
})
|
|
130
168
|
})
|
package/src/popup/comment.ts
CHANGED
|
@@ -12,6 +12,7 @@ interface PopupOptions {
|
|
|
12
12
|
onClose: () => void
|
|
13
13
|
onMyFeedback?: () => void
|
|
14
14
|
messages: I18nMessages
|
|
15
|
+
position?: 'left' | 'right'
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export class CommentPopup {
|
|
@@ -38,7 +39,7 @@ export class CommentPopup {
|
|
|
38
39
|
this.textarea = this.el.querySelector('.mtb-textarea')!
|
|
39
40
|
this.submitBtn = this.el.querySelector('.mtb-submit-btn')!
|
|
40
41
|
|
|
41
|
-
this.positionPopup(opts.x, opts.y, opts.targetRect)
|
|
42
|
+
this.positionPopup(opts.x, opts.y, opts.targetRect, opts.position ?? 'right')
|
|
42
43
|
this.bindEvents(opts.messages)
|
|
43
44
|
if (opts.onMyFeedback) {
|
|
44
45
|
this.el.querySelector('.mtb-my-feedback')!.addEventListener('click', opts.onMyFeedback)
|
|
@@ -91,13 +92,16 @@ export class CommentPopup {
|
|
|
91
92
|
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
private positionPopup(x: number, y: number, targetRect
|
|
95
|
-
const popupW = 320
|
|
96
|
-
const popupH = this.el.offsetHeight || 260
|
|
95
|
+
private positionPopup(x: number, y: number, targetRect: TargetRect | undefined, tabPosition: 'left' | 'right'): void {
|
|
97
96
|
const vw = window.innerWidth
|
|
98
97
|
const vh = window.innerHeight
|
|
99
98
|
const margin = 12
|
|
100
99
|
const gap = 8
|
|
100
|
+
const tabWidth = 32
|
|
101
|
+
const popupW = Math.min(320, vw - 2 * margin - tabWidth)
|
|
102
|
+
const popupH = this.el.offsetHeight || 260
|
|
103
|
+
const minLeft = margin + (tabPosition === 'left' ? tabWidth : 0)
|
|
104
|
+
const maxRight = vw - margin - (tabPosition === 'right' ? tabWidth : 0)
|
|
101
105
|
|
|
102
106
|
let left: number
|
|
103
107
|
let top: number
|
|
@@ -117,10 +121,10 @@ export class CommentPopup {
|
|
|
117
121
|
top = y + 12
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
if (left + popupW >
|
|
121
|
-
left =
|
|
124
|
+
if (left + popupW > maxRight) {
|
|
125
|
+
left = maxRight - popupW
|
|
122
126
|
}
|
|
123
|
-
if (left <
|
|
127
|
+
if (left < minLeft) left = minLeft
|
|
124
128
|
if (top < margin) top = margin
|
|
125
129
|
|
|
126
130
|
this.el.style.left = `${left}px`
|
|
@@ -188,6 +192,10 @@ export class CommentPopup {
|
|
|
188
192
|
this.errorEl.hidden = false
|
|
189
193
|
}
|
|
190
194
|
|
|
195
|
+
releaseElement(): HTMLDivElement {
|
|
196
|
+
return this.el
|
|
197
|
+
}
|
|
198
|
+
|
|
191
199
|
destroy(): void {
|
|
192
200
|
this.el.remove()
|
|
193
201
|
}
|
|
@@ -199,4 +207,3 @@ function formatDuration(seconds: number): string {
|
|
|
199
207
|
const ss = String(total % 60).padStart(2, '0')
|
|
200
208
|
return `${mm}:${ss}`
|
|
201
209
|
}
|
|
202
|
-
|