Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 12 additions & 19 deletions packages/browser-sdk/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
Feedback,
feedback,
FeedbackOptions,
handleDeprecatedFeedbackOptions,
RequestFeedbackData,
RequestFeedbackOptions,
} from "./feedback/feedback";
Expand Down Expand Up @@ -384,11 +383,9 @@ export class BucketClient {
enableTracking: opts?.enableTracking ?? defaultConfig.enableTracking,
};

const feedbackOpts = handleDeprecatedFeedbackOptions(opts?.feedback);

this.requestFeedbackOptions = {
position: feedbackOpts?.ui?.position,
translations: feedbackOpts?.ui?.translations,
position: opts?.feedback?.ui?.position,
translations: opts?.feedback?.ui?.translations,
};

this.httpClient = new HttpClient(this.publishableKey, {
Expand Down Expand Up @@ -416,7 +413,7 @@ export class BucketClient {
if (
this.context?.user &&
!isNode && // do not prompt on server-side
feedbackOpts?.enableAutoFeedback !== false // default to on
opts?.feedback?.enableAutoFeedback !== false // default to on
) {
if (isMobile) {
this.logger.warn(
Expand All @@ -427,18 +424,18 @@ export class BucketClient {
this.config.sseBaseUrl,
this.logger,
this.httpClient,
feedbackOpts?.autoFeedbackHandler,
opts?.feedback?.autoFeedbackHandler,
String(this.context.user?.id),
feedbackOpts?.ui?.position,
feedbackOpts?.ui?.translations,
opts?.feedback?.ui?.position,
opts?.feedback?.ui?.translations,
);
}
}

if (shouldShowToolbar(opts)) {
this.logger.info("opening toolbar toggler");
showToolbarToggle({
bucketClient: this as unknown as BucketClient,
bucketClient: this,
position:
typeof opts.toolbar === "object" ? opts.toolbar.position : undefined,
});
Expand Down Expand Up @@ -621,32 +618,28 @@ export class BucketClient {
return;
}

const featureId = "featureId" in options ? options.featureId : undefined;
const featureKey = "featureKey" in options ? options.featureKey : undefined;

if (!featureId && !featureKey) {
if (!options.featureKey) {
this.logger.error(
"`requestFeedback` call ignored. No `featureId` or `featureKey` provided",
"`requestFeedback` call ignored. No `featureKey` provided",
);
return;
}

const feedbackData = {
featureId,
featureKey,
featureKey: options.featureKey,
companyId:
options.companyId ||
(this.context.company?.id
? String(this.context.company?.id)
: undefined),
source: "widget" as const,
} as Feedback;
} satisfies Feedback;

// Wait a tick before opening the feedback form,
// to prevent the same click from closing it.
setTimeout(() => {
feedbackLib.openFeedbackForm({
key: (featureKey || featureId)!,
key: options.featureKey,
title: options.title,
position: options.position || this.requestFeedbackOptions.position,
translations:
Expand Down
63 changes: 21 additions & 42 deletions packages/browser-sdk/src/feedback/feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,46 +45,8 @@ export type FeedbackOptions = {
*/
translations?: Partial<FeedbackTranslations>;
};

/**
* @deprecated Use `enableAutoFeedback` instead
*/
enableLiveSatisfaction?: boolean;

/**
* @deprecated Use `autoFeedbackHandler` instead
*/
liveSatisfactionHandler?: FeedbackPromptHandler;
};

export function handleDeprecatedFeedbackOptions(
opts?: FeedbackOptions,
): FeedbackOptions {
return {
...opts,
enableAutoFeedback:
opts?.enableAutoFeedback ?? opts?.enableLiveSatisfaction,
autoFeedbackHandler:
opts?.autoFeedbackHandler ?? opts?.liveSatisfactionHandler,
};
}

type FeatureIdentifier =
| {
/**
* Bucket feature ID.
*
* @deprecated use `feedbackId` instead.
*/
featureId: string;
}
| {
/**
* Bucket feature key.
*/
featureKey: string;
};

export type RequestFeedbackData = Omit<
OpenFeedbackFormOptions,
"key" | "onSubmit"
Expand All @@ -105,7 +67,12 @@ export type RequestFeedbackData = Omit<
* @param data.
*/
onAfterSubmit?: (data: FeedbackSubmission) => void;
} & FeatureIdentifier;

/**
* Bucket feature key.
*/
featureKey: string;
};

export type RequestFeedbackOptions = RequestFeedbackData & {
/**
Expand All @@ -115,6 +82,11 @@ export type RequestFeedbackOptions = RequestFeedbackData & {
};

export type UnassignedFeedback = {
/**
* Bucket feature key.
*/
featureKey: string;

/**
* Bucket feedback ID
*/
Expand Down Expand Up @@ -159,7 +131,7 @@ export type UnassignedFeedback = {
* - `sdk` - Feedback submitted via `feedback`
*/
source?: "prompt" | "sdk" | "widget";
} & FeatureIdentifier;
};

export type Feedback = UnassignedFeedback & {
/**
Expand Down Expand Up @@ -242,10 +214,17 @@ export const DEFAULT_FEEDBACK_CONFIG = {
autoFeedbackEnabled: true,
};

// Payload can include featureId or featureKey, but the public API only exposes featureKey
// We use featureId internally because prompting is based on featureId
type FeedbackPayload = Omit<Feedback, "featureKey"> & {
featureId?: string;
featureKey?: string;
};

export async function feedback(
httpClient: HttpClient,
logger: Logger,
payload: Feedback,
payload: FeedbackPayload,
) {
if (!payload.score && !payload.comment) {
logger.error(
Expand Down Expand Up @@ -435,7 +414,7 @@ export class AutoFeedback {
question: reply.question,
promptedQuestion: message.question,
source: "prompt",
} satisfies Feedback;
} satisfies FeedbackPayload;

const response = await feedback(
this.httpClient,
Expand Down
2 changes: 0 additions & 2 deletions packages/browser-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// import "preact/debug";

export type { Feature, InitOptions, ToolbarOptions } from "./client";
export { BucketClient } from "./client";
export type { BucketContext, CompanyContext, UserContext } from "./context";
Expand Down
10 changes: 5 additions & 5 deletions packages/browser-sdk/test/e2e/feedback-widget.browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async function getOpenedWidgetContainer(
const bucket = new BucketClient({publishableKey: "${KEY}", user: {id: "foo"}, company: {id: "bar"}, ...${JSON.stringify(initOptions ?? {})}});
await bucket.initialize();
await bucket.requestFeedback({
featureId: "featureId1",
featureKey: "feature1",
title: "baz",
});
})()
Expand Down Expand Up @@ -90,7 +90,7 @@ async function getGiveFeedbackPageContainer(
document.querySelector("#give-feedback-button")?.addEventListener("click", () => {
console.log("cliked!");
bucket.requestFeedback({
featureId: "featureId1",
featureKey: "feature1",
title: "baz",
});
});
Expand Down Expand Up @@ -250,7 +250,7 @@ test("Sends a request when choosing a score immediately", async ({ page }) => {
.poll(() => sentJSON)
.toEqual({
companyId: "bar",
featureId: "featureId1",
key: "feature1",
score: expectedScore,
question: "baz",
userId: "foo",
Expand Down Expand Up @@ -309,7 +309,7 @@ test("Updates the score on every change", async ({ page }) => {
.toEqual({
feedbackId: "123",
companyId: "bar",
featureId: "featureId1",
key: "feature1",
question: "baz",
score: 3,
userId: "foo",
Expand Down Expand Up @@ -369,7 +369,7 @@ test("Sends a request with both the score and comment when submitting", async ({
score: expectedScore,
companyId: "bar",
question: "baz",
featureId: "featureId1",
key: "feature1",
feedbackId: "123",
userId: "foo",
source: "widget",
Expand Down
14 changes: 7 additions & 7 deletions packages/browser-sdk/test/mocks/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const handlers = [
!data["userId"] ||
!data["attributes"]
) {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand All @@ -106,7 +106,7 @@ export const handlers = [
!data["companyId"] ||
!data["attributes"]
) {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand All @@ -118,7 +118,7 @@ export const handlers = [
const data = await request.json();

if (typeof data !== "object" || !data || !data["userId"]) {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand All @@ -130,7 +130,7 @@ export const handlers = [
const data = await request.json();

if (typeof data !== "object" || !data || !data["userId"]) {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand All @@ -145,9 +145,9 @@ export const handlers = [
!data ||
!data["userId"] ||
typeof data["score"] !== "number" ||
(!data["featureId"] && !data["featureKey"])
(!data["featureId"] && !data["key"])
) {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand All @@ -173,7 +173,7 @@ export const handlers = [
async ({ request }) => {
const data = await request.json();
if (typeof data !== "object") {
return new HttpResponse(null, { status: 400 });
return HttpResponse.error();
}

return HttpResponse.json({
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-sdk/test/usage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe("usage", () => {
await bucketInstance.track("baz", { baz: true });

await bucketInstance.feedback({
featureId: "featureId1",
featureKey: "huddles",
score: 5,
comment: "Sunt bine!",
question: "Cum esti?",
Expand Down
4 changes: 2 additions & 2 deletions packages/react-sdk/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export function useTrack() {
* ```ts
* const requestFeedback = useRequestFeedback();
* bucket.requestFeedback({
* featureId: "bucket-feature-id",
* featureKey: "file-uploads",
* title: "How satisfied are you with file uploads?",
* });
* ```
Expand All @@ -269,7 +269,7 @@ export function useRequestFeedback() {
* ```ts
* const sendFeedback = useSendFeedback();
* sendFeedback({
* featureId: "fe2323223";;
* featureKey: "huddle";
* question: "How did you like the new huddle feature?";
* score: 5;
* comment: "I loved it!";
Expand Down
4 changes: 2 additions & 2 deletions packages/react-sdk/test/usage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,15 @@ describe("useRequestFeedback", () => {

await waitFor(async () => {
result.current({
featureId: "123",
featureKey: "huddles",
title: "Test question",
companyId: "456",
});

expect(requestFeedback).toHaveBeenCalledOnce();
expect(requestFeedback).toHaveBeenCalledWith({
featureKey: "huddles",
companyId: "456",
featureId: "123",
title: "Test question",
});
});
Expand Down