mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-26 10:19:14 -06:00
chore: removed environmentId from language services (#3070)
This commit is contained in:
committed by
GitHub
parent
3e79ec9a61
commit
14e0d57091
@@ -41,7 +41,7 @@ const Page = async ({ params }: { params: { environmentId: string } }) => {
|
||||
<SettingsCard
|
||||
title="Multi-language surveys"
|
||||
description="Add languages to create multi-language surveys.">
|
||||
<EditLanguage product={product} environmentId={params.environmentId} />
|
||||
<EditLanguage product={product} />
|
||||
</SettingsCard>
|
||||
</PageContentWrapper>
|
||||
);
|
||||
|
||||
@@ -214,7 +214,7 @@ export const createSurvey = async (page: Page, params: CreateSurveyParams) => {
|
||||
.filter({ hasText: new RegExp(`^${addQuestion}$`) })
|
||||
.nth(1)
|
||||
.click();
|
||||
await page.getByRole("button", { name: "Call-to-Action" }).click();
|
||||
await page.getByRole("button", { name: "Statement (Call to Action)" }).click();
|
||||
await page.getByPlaceholder("Your question here. Recall").fill(params.ctaQuestion.question);
|
||||
await page.getByPlaceholder("Finish").fill(params.ctaQuestion.buttonLabel);
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import { LanguageRow } from "./language-row";
|
||||
|
||||
interface EditLanguageProps {
|
||||
product: TProduct;
|
||||
environmentId: string;
|
||||
}
|
||||
|
||||
const checkIfDuplicateExists = (arr: string[]) => {
|
||||
@@ -67,7 +66,7 @@ const validateLanguages = (languages: TLanguage[]) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
export function EditLanguage({ product, environmentId }: EditLanguageProps) {
|
||||
export function EditLanguage({ product }: EditLanguageProps) {
|
||||
const [languages, setLanguages] = useState<TLanguage[]>(product.languages);
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [confirmationModal, setConfirmationModal] = useState({
|
||||
@@ -123,7 +122,7 @@ export function EditLanguage({ product, environmentId }: EditLanguageProps) {
|
||||
|
||||
const performLanguageDeletion = async (languageId: string) => {
|
||||
try {
|
||||
await deleteLanguageAction({ environmentId, languageId });
|
||||
await deleteLanguageAction({ languageId, productId: product.id });
|
||||
setLanguages((prev) => prev.filter((lang) => lang.id !== languageId));
|
||||
toast.success("Language deleted successfully.");
|
||||
// Close the modal after deletion
|
||||
@@ -145,11 +144,11 @@ export function EditLanguage({ product, environmentId }: EditLanguageProps) {
|
||||
languages.map((lang) => {
|
||||
return lang.id === "new"
|
||||
? createLanguageAction({
|
||||
environmentId,
|
||||
productId: product.id,
|
||||
languageInput: { code: lang.code, alias: lang.alias },
|
||||
})
|
||||
: updateLanguageAction({
|
||||
environmentId,
|
||||
productId: product.id,
|
||||
languageId: lang.id,
|
||||
languageInput: { code: lang.code, alias: lang.alias },
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import { z } from "zod";
|
||||
import { authenticatedActionClient } from "@formbricks/lib/actionClient";
|
||||
import { checkAuthorization } from "@formbricks/lib/actionClient/utils";
|
||||
import { getEnvironment } from "@formbricks/lib/environment/service";
|
||||
import {
|
||||
createLanguage,
|
||||
deleteLanguage,
|
||||
@@ -15,35 +14,30 @@ import {
|
||||
getOrganizationIdFromProductId,
|
||||
} from "@formbricks/lib/organization/utils";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
import { ZLanguageInput } from "@formbricks/types/product";
|
||||
|
||||
const ZCreateLanguageAction = z.object({
|
||||
environmentId: ZId,
|
||||
productId: ZId,
|
||||
languageInput: ZLanguageInput,
|
||||
});
|
||||
|
||||
export const createLanguageAction = authenticatedActionClient
|
||||
.schema(ZCreateLanguageAction)
|
||||
.action(async ({ ctx, parsedInput }) => {
|
||||
const environment = await getEnvironment(parsedInput.environmentId);
|
||||
if (!environment) {
|
||||
throw new ResourceNotFoundError("Environment", parsedInput.environmentId);
|
||||
}
|
||||
await checkAuthorization({
|
||||
data: parsedInput.languageInput,
|
||||
schema: ZLanguageInput,
|
||||
userId: ctx.user.id,
|
||||
organizationId: await getOrganizationIdFromProductId(environment.productId),
|
||||
organizationId: await getOrganizationIdFromProductId(parsedInput.productId),
|
||||
rules: ["language", "create"],
|
||||
});
|
||||
|
||||
return await createLanguage(environment.productId, parsedInput.environmentId, parsedInput.languageInput);
|
||||
return await createLanguage(parsedInput.productId, parsedInput.languageInput);
|
||||
});
|
||||
|
||||
const ZDeleteLanguageAction = z.object({
|
||||
environmentId: ZId,
|
||||
languageId: ZId,
|
||||
productId: ZId,
|
||||
});
|
||||
|
||||
export const deleteLanguageAction = authenticatedActionClient
|
||||
@@ -55,7 +49,7 @@ export const deleteLanguageAction = authenticatedActionClient
|
||||
rules: ["language", "delete"],
|
||||
});
|
||||
|
||||
return await deleteLanguage(parsedInput.environmentId, parsedInput.languageId);
|
||||
return await deleteLanguage(parsedInput.languageId, parsedInput.productId);
|
||||
});
|
||||
|
||||
const ZGetSurveysUsingGivenLanguageAction = z.object({
|
||||
@@ -75,7 +69,7 @@ export const getSurveysUsingGivenLanguageAction = authenticatedActionClient
|
||||
});
|
||||
|
||||
const ZUpdateLanguageAction = z.object({
|
||||
environmentId: ZId,
|
||||
productId: ZId,
|
||||
languageId: ZId,
|
||||
languageInput: ZLanguageInput,
|
||||
});
|
||||
@@ -91,5 +85,5 @@ export const updateLanguageAction = authenticatedActionClient
|
||||
rules: ["language", "update"],
|
||||
});
|
||||
|
||||
return await updateLanguage(parsedInput.environmentId, parsedInput.languageId, parsedInput.languageInput);
|
||||
return await updateLanguage(parsedInput.productId, parsedInput.languageId, parsedInput.languageInput);
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
ZLanguageUpdate,
|
||||
} from "@formbricks/types/product";
|
||||
import { productCache } from "../product/cache";
|
||||
import { getProduct } from "../product/service";
|
||||
import { surveyCache } from "../survey/cache";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
|
||||
@@ -48,11 +49,12 @@ export const getLanguage = async (languageId: string): Promise<TLanguage & { pro
|
||||
|
||||
export const createLanguage = async (
|
||||
productId: string,
|
||||
environmentId: string,
|
||||
languageInput: TLanguageInput
|
||||
): Promise<TLanguage> => {
|
||||
try {
|
||||
validateInputs([productId, ZId], [environmentId, ZId], [languageInput, ZLanguageInput]);
|
||||
validateInputs([productId, ZId], [languageInput, ZLanguageInput]);
|
||||
const product = await getProduct(productId);
|
||||
if (!product) throw new ResourceNotFoundError("Product not found", productId);
|
||||
if (!languageInput.code) {
|
||||
throw new ValidationError("Language code is required");
|
||||
}
|
||||
@@ -67,9 +69,10 @@ export const createLanguage = async (
|
||||
select: languageSelect,
|
||||
});
|
||||
|
||||
productCache.revalidate({
|
||||
id: productId,
|
||||
environmentId,
|
||||
product.environments.forEach((environment) => {
|
||||
productCache.revalidate({
|
||||
environmentId: environment.id,
|
||||
});
|
||||
});
|
||||
|
||||
return language;
|
||||
@@ -110,25 +113,20 @@ export const getSurveysUsingGivenLanguage = reactCache(async (languageId: string
|
||||
}
|
||||
});
|
||||
|
||||
export const deleteLanguage = async (environmentId: string, languageId: string): Promise<TLanguage> => {
|
||||
export const deleteLanguage = async (languageId: string, productId: string): Promise<TLanguage> => {
|
||||
try {
|
||||
validateInputs([languageId, ZId]);
|
||||
|
||||
validateInputs([languageId, ZId], [productId, ZId]);
|
||||
const product = await getProduct(productId);
|
||||
if (!product) throw new ResourceNotFoundError("Product not found", productId);
|
||||
const prismaLanguage = await prisma.language.delete({
|
||||
where: { id: languageId },
|
||||
select: { ...languageSelect, surveyLanguages: { select: { surveyId: true } } },
|
||||
});
|
||||
|
||||
productCache.revalidate({
|
||||
id: prismaLanguage.productId,
|
||||
environmentId,
|
||||
});
|
||||
|
||||
// revalidate cache of all connected surveys
|
||||
prismaLanguage.surveyLanguages.forEach((surveyLanguage) => {
|
||||
surveyCache.revalidate({
|
||||
id: surveyLanguage.surveyId,
|
||||
environmentId,
|
||||
product.environments.forEach((environment) => {
|
||||
productCache.revalidate({
|
||||
id: prismaLanguage.productId,
|
||||
environmentId: environment.id,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -146,29 +144,34 @@ export const deleteLanguage = async (environmentId: string, languageId: string):
|
||||
};
|
||||
|
||||
export const updateLanguage = async (
|
||||
environmentId: string,
|
||||
productId: string,
|
||||
languageId: string,
|
||||
languageInput: TLanguageUpdate
|
||||
): Promise<TLanguage> => {
|
||||
try {
|
||||
validateInputs([languageId, ZId], [languageInput, ZLanguageUpdate]);
|
||||
|
||||
validateInputs([languageId, ZId], [languageInput, ZLanguageUpdate], [productId, ZId]);
|
||||
const product = await getProduct(productId);
|
||||
if (!product) throw new ResourceNotFoundError("Product not found", productId);
|
||||
const prismaLanguage = await prisma.language.update({
|
||||
where: { id: languageId },
|
||||
data: { ...languageInput, updatedAt: new Date() },
|
||||
select: { ...languageSelect, surveyLanguages: { select: { surveyId: true } } },
|
||||
});
|
||||
|
||||
productCache.revalidate({
|
||||
id: prismaLanguage.productId,
|
||||
environmentId,
|
||||
product.environments.forEach((environment) => {
|
||||
productCache.revalidate({
|
||||
id: prismaLanguage.productId,
|
||||
environmentId: environment.id,
|
||||
});
|
||||
surveyCache.revalidate({
|
||||
environmentId: environment.id,
|
||||
});
|
||||
});
|
||||
|
||||
// revalidate cache of all connected surveys
|
||||
prismaLanguage.surveyLanguages.forEach((surveyLanguage) => {
|
||||
surveyCache.revalidate({
|
||||
id: surveyLanguage.surveyId,
|
||||
environmentId,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ describe("Tests for deleteLanguage", () => {
|
||||
it("Deletes a Language", async () => {
|
||||
prismaMock.language.delete.mockResolvedValue(mockLanguage);
|
||||
|
||||
const language = await deleteLanguage(mockEnvironmentId, mockLanguageId);
|
||||
const language = await deleteLanguage(mockLanguageId, mockProductId);
|
||||
expect(language).toEqual(mockLanguage);
|
||||
});
|
||||
});
|
||||
@@ -115,14 +115,14 @@ describe("Tests for deleteLanguage", () => {
|
||||
|
||||
prismaMock.language.delete.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(deleteLanguage(mockEnvironmentId, mockLanguageId)).rejects.toThrow(DatabaseError);
|
||||
await expect(deleteLanguage(mockLanguageId, mockProductId)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other exceptions", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.language.delete.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(deleteLanguage(mockEnvironmentId, mockLanguageId)).rejects.toThrow(Error);
|
||||
await expect(deleteLanguage(mockLanguageId, mockProductId)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user