adress code rabbit feedback and add translations

This commit is contained in:
Johannes
2026-02-17 09:23:44 -03:00
parent ddb18fe2d4
commit 0433ac4680
17 changed files with 418 additions and 72 deletions

View File

@@ -0,0 +1,196 @@
import { describe, expect, test } from "vitest";
import { z } from "zod";
import { ZId } from "@formbricks/types/common";
const ZGetDisplaysWithContactAction = z.object({
surveyId: ZId,
limit: z.number().int().min(1),
offset: z.number().int().nonnegative(),
});
const mockSurveyId = "clqkr5smu000108jy50v6g5k4";
describe("ZGetDisplaysWithContactAction Schema Validation", () => {
describe("Happy Path", () => {
test("accepts valid positive limit and non-negative offset", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 10,
offset: 0,
});
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.limit).toBe(10);
expect(result.data.offset).toBe(0);
}
});
test("accepts limit of 1 and offset of 0", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 1,
offset: 0,
});
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.limit).toBe(1);
expect(result.data.offset).toBe(0);
}
});
test("accepts large positive values", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 100,
offset: 50,
});
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.limit).toBe(100);
expect(result.data.offset).toBe(50);
}
});
});
describe("Validation - Negative Values", () => {
test("rejects negative limit", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: -1,
offset: 0,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("limit");
expect(result.error.issues[0].message).toMatch(/greater than or equal to 1/i);
}
});
test("rejects negative offset", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 10,
offset: -5,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("offset");
expect(result.error.issues[0].message).toMatch(/greater than or equal to 0/i);
}
});
test("rejects both negative limit and offset", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: -10,
offset: -5,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues.length).toBeGreaterThanOrEqual(2);
const paths = result.error.issues.map((i) => i.path[0]);
expect(paths).toContain("limit");
expect(paths).toContain("offset");
}
});
test("rejects zero limit (must be at least 1)", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 0,
offset: 0,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("limit");
expect(result.error.issues[0].message).toMatch(/greater than or equal to 1/i);
}
});
});
describe("Validation - Non-Integer Values", () => {
test("rejects decimal limit", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 10.5,
offset: 0,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("limit");
expect(result.error.issues[0].message).toMatch(/integer/i);
}
});
test("rejects decimal offset", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 10,
offset: 5.7,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("offset");
expect(result.error.issues[0].message).toMatch(/integer/i);
}
});
test("rejects both decimal values", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 10.5,
offset: 5.7,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues.length).toBeGreaterThanOrEqual(2);
const paths = result.error.issues.map((i) => i.path[0]);
expect(paths).toContain("limit");
expect(paths).toContain("offset");
}
});
});
describe("Validation - Invalid surveyId", () => {
test("rejects invalid surveyId format", () => {
const result = ZGetDisplaysWithContactAction.safeParse({
surveyId: "invalid-id",
limit: 10,
offset: 0,
});
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("surveyId");
}
});
});
describe("Edge Cases", () => {
test("ensures Prisma skip/take receive valid integers", () => {
const validResult = ZGetDisplaysWithContactAction.safeParse({
surveyId: mockSurveyId,
limit: 15,
offset: 0,
});
expect(validResult.success).toBe(true);
if (validResult.success) {
expect(Number.isInteger(validResult.data.limit)).toBe(true);
expect(Number.isInteger(validResult.data.offset)).toBe(true);
expect(validResult.data.limit).toBeGreaterThan(0);
expect(validResult.data.offset).toBeGreaterThanOrEqual(0);
}
});
});
});

View File

@@ -110,8 +110,8 @@ export const getResponseCountAction = authenticatedActionClient
const ZGetDisplaysWithContactAction = z.object({
surveyId: ZId,
limit: z.number(),
offset: z.number(),
limit: z.number().int().min(1),
offset: z.number().int().nonnegative(),
});
export const getDisplaysWithContactAction = authenticatedActionClient

View File

@@ -1,8 +1,9 @@
"use client";
import { InfoIcon } from "lucide-react";
import { AlertCircleIcon, InfoIcon } from "lucide-react";
import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { TDisplayWithContact } from "@formbricks/types/displays";
import { TUserLocale } from "@formbricks/types/user";
@@ -23,38 +24,66 @@ export const SummaryImpressions = ({ surveyId, environmentId, locale }: SummaryI
const [displays, setDisplays] = useState<TDisplayWithContact[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [hasMore, setHasMore] = useState(true);
const [displaysError, setDisplaysError] = useState<string | null>(null);
const fetchDisplays = useCallback(
async (offset: number) => {
const response = await getDisplaysWithContactAction({
surveyId,
limit: DISPLAYS_PER_PAGE,
offset,
});
try {
const response = await getDisplaysWithContactAction({
surveyId,
limit: DISPLAYS_PER_PAGE,
offset,
});
if (response?.data) {
return response.data;
if (response?.serverError) {
const errorMessage = response.serverError || t("common.something_went_wrong");
throw new Error(errorMessage);
}
if (response?.data) {
return response.data;
}
return [];
} catch (error) {
const errorMessage = error instanceof Error ? error.message : t("common.something_went_wrong");
setDisplaysError(errorMessage);
toast.error(errorMessage);
throw error;
}
return [];
},
[surveyId]
[surveyId, t]
);
useEffect(() => {
const loadInitial = async () => {
setIsLoading(true);
const loadInitialDisplays = useCallback(async () => {
setIsLoading(true);
setDisplaysError(null);
try {
const data = await fetchDisplays(0);
setDisplays(data);
setHasMore(data.length === DISPLAYS_PER_PAGE);
} catch {
// Error is already handled in fetchDisplays
setDisplays([]);
setHasMore(false);
} finally {
setIsLoading(false);
};
loadInitial();
}
}, [fetchDisplays]);
useEffect(() => {
loadInitialDisplays();
}, [loadInitialDisplays]);
const handleLoadMore = async () => {
const data = await fetchDisplays(displays.length);
setDisplays((prev) => [...prev, ...data]);
setHasMore(data.length === DISPLAYS_PER_PAGE);
try {
const data = await fetchDisplays(displays.length);
setDisplays((prev) => [...prev, ...data]);
setHasMore(data.length === DISPLAYS_PER_PAGE);
} catch {
// Error is already handled in fetchDisplays
setHasMore(false);
}
};
const getDisplayContactIdentifier = (display: TDisplayWithContact): string => {
@@ -62,6 +91,73 @@ export const SummaryImpressions = ({ surveyId, environmentId, locale }: SummaryI
return display.contact.attributes?.email || display.contact.attributes?.userId || display.contact.id;
};
const renderContent = () => {
if (displaysError) {
return (
<div className="p-8">
<div className="flex flex-col items-center gap-4 text-center">
<div className="flex items-center gap-2 text-red-600">
<AlertCircleIcon className="h-5 w-5" />
<span className="text-sm font-medium">{t("common.error_loading_data")}</span>
</div>
<p className="text-sm text-slate-500">{displaysError}</p>
<Button onClick={loadInitialDisplays} variant="secondary" size="sm">
{t("common.try_again")}
</Button>
</div>
</div>
);
}
if (displays.length === 0) {
return (
<div className="p-8 text-center text-sm text-slate-500">
{t("environments.surveys.summary.no_identified_impressions")}
</div>
);
}
return (
<>
<div className="grid min-h-10 grid-cols-4 items-center border-b border-slate-200 bg-slate-100 text-sm font-semibold text-slate-600">
<div className="col-span-2 px-4 md:px-6">{t("common.user")}</div>
<div className="col-span-2 px-4 md:px-6">{t("environments.contacts.survey_viewed_at")}</div>
</div>
<div className="max-h-[62vh] overflow-y-auto">
{displays.map((display) => (
<div
key={display.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-xs text-slate-800 last:border-transparent md:text-sm">
<div className="col-span-2 pl-4 md:pl-6">
{display.contact ? (
<Link
className="ph-no-capture break-all text-slate-600 hover:underline"
href={`/environments/${environmentId}/contacts/${display.contact.id}`}>
{getDisplayContactIdentifier(display)}
</Link>
) : (
<span className="break-all text-slate-600">{t("common.anonymous")}</span>
)}
</div>
<div className="col-span-2 px-4 text-slate-500 md:px-6">
{timeSince(display.createdAt.toString(), locale)}
</div>
</div>
))}
</div>
{hasMore && (
<div className="flex justify-center border-t border-slate-100 py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
{t("common.load_more")}
</Button>
</div>
)}
</>
);
};
if (isLoading) {
return (
<div className="rounded-xl border border-slate-200 bg-white p-8 shadow-sm">
@@ -78,50 +174,7 @@ export const SummaryImpressions = ({ surveyId, environmentId, locale }: SummaryI
<InfoIcon className="h-4 w-4 shrink-0" />
<span>{t("environments.surveys.summary.impressions_identified_only")}</span>
</div>
{displays.length === 0 ? (
<div className="p-8 text-center text-sm text-slate-500">
{t("environments.surveys.summary.no_identified_impressions")}
</div>
) : (
<>
<div className="grid min-h-10 grid-cols-4 items-center border-b border-slate-200 bg-slate-100 text-sm font-semibold text-slate-600">
<div className="col-span-2 px-4 md:px-6">{t("common.user")}</div>
<div className="col-span-2 px-4 md:px-6">{t("environments.contacts.survey_viewed_at")}</div>
</div>
<div className="max-h-[62vh] overflow-y-auto">
{displays.map((display) => (
<div
key={display.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-xs text-slate-800 last:border-transparent md:text-sm">
<div className="col-span-2 pl-4 md:pl-6">
{display.contact ? (
<Link
className="ph-no-capture break-all text-slate-600 hover:underline"
href={`/environments/${environmentId}/contacts/${display.contact.id}`}>
{getDisplayContactIdentifier(display)}
</Link>
) : (
<span className="break-all text-slate-600">{t("common.anonymous")}</span>
)}
</div>
<div className="col-span-2 px-4 text-slate-500 md:px-6">
{timeSince(display.createdAt.toISOString(), locale)}
</div>
</div>
))}
</div>
{hasMore && (
<div className="flex justify-center border-t border-slate-100 py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
{t("common.load_more")}
</Button>
</div>
)}
</>
)}
{renderContent()}
</div>
);
};

View File

@@ -401,6 +401,7 @@ checksums:
common/top_right: 241f95c923846911aaf13af6109333e5
common/try_again: 33dd8820e743e35a66e6977f69e9d3b5
common/type: f04471a7ddac844b9ad145eb9911ef75
common/unknown_survey: dd8f6985e17ccf19fac1776e18b2c498
common/unlock_more_workspaces_with_a_higher_plan: fe1590075b855bb4306c9388b65143b0
common/update: 079fc039262fd31b10532929685c2d1b
common/updated: 8aa8ff2dc2977ca4b269e80a513100b4
@@ -620,6 +621,7 @@ checksums:
environments/contacts/delete_attribute_confirmation: 01d99b89eb3d27ff468d0db1b4aeb394
environments/contacts/delete_contact_confirmation: 2d45579e0bb4bc40fb1ee75b43c0e7a4
environments/contacts/delete_contact_confirmation_with_quotas: d3d17f13ae46ce04c126c82bf01299ac
environments/contacts/displays: fcc4527002bd045021882be463b8ac72
environments/contacts/edit_attribute: 92a83c96a5d850e7d39002e8fd5898f4
environments/contacts/edit_attribute_description: 073a3084bb2f3b34ed1320ed1cd6db3c
environments/contacts/edit_attribute_values: 44e4e7a661cc1b59200bb07c710072a7
@@ -631,6 +633,7 @@ checksums:
environments/contacts/invalid_csv_column_names: dcb8534e7d4c00b9ea7bdaf389f72328
environments/contacts/invalid_date_format: 5bad9730ac5a5bacd0792098f712b1c4
environments/contacts/invalid_number_format: bd0422507385f671c3046730a6febc64
environments/contacts/no_activity_yet: f88897ac05afd6bf8af0d4834ad24ffc
environments/contacts/no_published_link_surveys_available: 9c1abc5b21aba827443cdf87dd6c8bfe
environments/contacts/no_published_surveys: bd945b0e2e2328c17615c94143bdd62b
environments/contacts/no_responses_found: f10190cffdda4ca1bed479acbb89b13f
@@ -645,6 +648,8 @@ checksums:
environments/contacts/select_a_survey: 1f49086dfb874307aae1136e88c3d514
environments/contacts/select_attribute: d93fb60eb4fbb42bf13a22f6216fbd79
environments/contacts/select_attribute_key: 673a6683fab41b387d921841cded7e38
environments/contacts/survey_viewed: 646d413218626787b0373ffd71cb7451
environments/contacts/survey_viewed_at: 2ab535237af5c3c3f33acc792a7e70a4
environments/contacts/system_attributes: eadb6a8888c7b32c0e68881f945ae9b6
environments/contacts/unlock_contacts_description: c5572047f02b4c39e5109f9de715499d
environments/contacts/unlock_contacts_title: a8b3d7db03eb404d9267fd5cdd6d5ddb
@@ -1846,6 +1851,7 @@ checksums:
environments/surveys/summary/filtered_responses_excel: 06e57bae9e41979fd7fc4b8bfe3466f9
environments/surveys/summary/generating_qr_code: 5026d4a76f995db458195e5215d9bbd9
environments/surveys/summary/impressions: 7fe38d42d68a64d3fd8436a063751584
environments/surveys/summary/impressions_identified_only: 10f8c491463c73b8e6534314ee00d165
environments/surveys/summary/impressions_tooltip: 4d0823cbf360304770c7c5913e33fdc8
environments/surveys/summary/in_app/connection_description: 9710bbf8048a8a5c3b2b56db9d946b73
environments/surveys/summary/in_app/connection_title: 29e8a40ad6a7fdb5af5ee9451a70a9aa
@@ -1886,6 +1892,7 @@ checksums:
environments/surveys/summary/last_quarter: 2e565a81de9b3d7b1ee709ebb6f6eda1
environments/surveys/summary/last_year: fe7c268a48bf85bc40da000e6e437637
environments/surveys/summary/limit: 347051f1a068e01e8c4e4f6744d8e727
environments/surveys/summary/no_identified_impressions: c3bc42e6feb9010ced905ded51c5afc4
environments/surveys/summary/no_responses_found: f10190cffdda4ca1bed479acbb89b13f
environments/surveys/summary/other_values_found: 48a74ee68c05f7fb162072b50c683b6a
environments/surveys/summary/overall: 6c6d6533013d4739766af84b2871bca6

View File

@@ -428,6 +428,7 @@
"top_right": "Oben rechts",
"try_again": "Versuch's nochmal",
"type": "Typ",
"unknown_survey": "Unbekannte Umfrage",
"unlock_more_workspaces_with_a_higher_plan": "Schalten Sie mehr Projekte mit einem höheren Tarif frei.",
"update": "Aktualisierung",
"updated": "Aktualisiert",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Dadurch wird das ausgewählte Attribut gelöscht. Alle mit diesem Attribut verknüpften Kontaktdaten gehen verloren.} other {Dadurch werden die ausgewählten Attribute gelöscht. Alle mit diesen Attributen verknüpften Kontaktdaten gehen verloren.}}",
"delete_contact_confirmation": "Dies wird alle Umfrageantworten und Kontaktattribute löschen, die mit diesem Kontakt verbunden sind. Jegliche zielgerichtete Kommunikation und Personalisierung basierend auf den Daten dieses Kontakts gehen verloren.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Dies wird alle Umfrageantworten und Kontaktattribute löschen, die mit diesem Kontakt verbunden sind. Jegliche zielgerichtete Kommunikation und Personalisierung basierend auf den Daten dieses Kontakts gehen verloren. Wenn dieser Kontakt Antworten hat, die zu den Umfragequoten zählen, werden die Quotenstände reduziert, aber die Quotenlimits bleiben unverändert.} other {Dies wird alle Umfrageantworten und Kontaktattribute löschen, die mit diesen Kontakten verbunden sind. Jegliche zielgerichtete Kommunikation und Personalisierung basierend auf den Daten dieses Kontakts gehen verloren. Wenn diesen Kontakten Antworten haben, die zu den Umfragequoten zählen, werden die Quotenstände reduziert, aber die Quotenlimits bleiben unverändert.}}",
"displays": "Anzeigen",
"edit_attribute": "Attribut bearbeiten",
"edit_attribute_description": "Aktualisieren Sie die Bezeichnung und Beschreibung für dieses Attribut.",
"edit_attribute_values": "Attribute bearbeiten",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Ungültige CSV-Spaltennamen: {columns}. Spaltennamen, die zu neuen Attributen werden, dürfen nur Kleinbuchstaben, Zahlen und Unterstriche enthalten und müssen mit einem Buchstaben beginnen.",
"invalid_date_format": "Ungültiges Datumsformat. Bitte verwende ein gültiges Datum.",
"invalid_number_format": "Ungültiges Zahlenformat. Bitte gib eine gültige Zahl ein.",
"no_activity_yet": "Noch keine Aktivität",
"no_published_link_surveys_available": "Keine veröffentlichten Link-Umfragen verfügbar. Bitte veröffentliche zuerst eine Link-Umfrage.",
"no_published_surveys": "Keine veröffentlichten Umfragen",
"no_responses_found": "Keine Antworten gefunden",
@@ -681,6 +684,8 @@
"select_a_survey": "Wähle eine Umfrage aus",
"select_attribute": "Attribut auswählen",
"select_attribute_key": "Attributschlüssel auswählen",
"survey_viewed": "Umfrage angesehen",
"survey_viewed_at": "Angesehen am",
"system_attributes": "Systemattribute",
"unlock_contacts_description": "Verwalte Kontakte und sende gezielte Umfragen",
"unlock_contacts_title": "Kontakte mit einem höheren Plan freischalten",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Gefilterte Antworten (Excel)",
"generating_qr_code": "QR-Code wird generiert",
"impressions": "Eindrücke",
"impressions_identified_only": "Zeigt nur Impressionen von identifizierten Kontakten",
"impressions_tooltip": "Anzahl der Aufrufe der Umfrage.",
"in_app": {
"connection_description": "Die Umfrage wird den Nutzern Ihrer Website angezeigt, die den unten aufgeführten Kriterien entsprechen",
@@ -1989,6 +1995,7 @@
"last_quarter": "Letztes Quartal",
"last_year": "Letztes Jahr",
"limit": "Limit",
"no_identified_impressions": "Keine Impressionen von identifizierten Kontakten",
"no_responses_found": "Keine Antworten gefunden",
"other_values_found": "Andere Werte gefunden",
"overall": "Insgesamt",

View File

@@ -428,6 +428,7 @@
"top_right": "Superior derecha",
"try_again": "Intentar de nuevo",
"type": "Tipo",
"unknown_survey": "Encuesta desconocida",
"unlock_more_workspaces_with_a_higher_plan": "Desbloquea más proyectos con un plan superior.",
"update": "Actualizar",
"updated": "Actualizado",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Esto eliminará el atributo seleccionado. Se perderán todos los datos de contacto asociados con este atributo.} other {Esto eliminará los atributos seleccionados. Se perderán todos los datos de contacto asociados con estos atributos.}}",
"delete_contact_confirmation": "Esto eliminará todas las respuestas de encuestas y atributos de contacto asociados con este contacto. Cualquier segmentación y personalización basada en los datos de este contacto se perderá.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Esto eliminará todas las respuestas de encuestas y atributos de contacto asociados con este contacto. Cualquier segmentación y personalización basada en los datos de este contacto se perderá. Si este contacto tiene respuestas que cuentan para las cuotas de encuesta, los recuentos de cuota se reducirán pero los límites de cuota permanecerán sin cambios.} other {Esto eliminará todas las respuestas de encuestas y atributos de contacto asociados con estos contactos. Cualquier segmentación y personalización basada en los datos de estos contactos se perderá. Si estos contactos tienen respuestas que cuentan para las cuotas de encuesta, los recuentos de cuota se reducirán pero los límites de cuota permanecerán sin cambios.}}",
"displays": "Visualizaciones",
"edit_attribute": "Editar atributo",
"edit_attribute_description": "Actualiza la etiqueta y la descripción de este atributo.",
"edit_attribute_values": "Editar atributos",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Nombre(s) de columna CSV no válido(s): {columns}. Los nombres de columna que se convertirán en nuevos atributos solo deben contener letras minúsculas, números y guiones bajos, y deben comenzar con una letra.",
"invalid_date_format": "Formato de fecha no válido. Por favor, usa una fecha válida.",
"invalid_number_format": "Formato de número no válido. Por favor, introduce un número válido.",
"no_activity_yet": "Aún no hay actividad",
"no_published_link_surveys_available": "No hay encuestas de enlace publicadas disponibles. Por favor, publica primero una encuesta de enlace.",
"no_published_surveys": "No hay encuestas publicadas",
"no_responses_found": "No se encontraron respuestas",
@@ -681,6 +684,8 @@
"select_a_survey": "Selecciona una encuesta",
"select_attribute": "Seleccionar atributo",
"select_attribute_key": "Seleccionar clave de atributo",
"survey_viewed": "Encuesta vista",
"survey_viewed_at": "Vista el",
"system_attributes": "Atributos del sistema",
"unlock_contacts_description": "Gestiona contactos y envía encuestas dirigidas",
"unlock_contacts_title": "Desbloquea contactos con un plan superior",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Respuestas filtradas (Excel)",
"generating_qr_code": "Generando código QR",
"impressions": "Impresiones",
"impressions_identified_only": "Solo se muestran impresiones de contactos identificados",
"impressions_tooltip": "Número de veces que se ha visto la encuesta.",
"in_app": {
"connection_description": "La encuesta se mostrará a los usuarios de tu sitio web que cumplan con los criterios enumerados a continuación",
@@ -1989,6 +1995,7 @@
"last_quarter": "Último trimestre",
"last_year": "Último año",
"limit": "Límite",
"no_identified_impressions": "No hay impresiones de contactos identificados",
"no_responses_found": "No se han encontrado respuestas",
"other_values_found": "Otros valores encontrados",
"overall": "General",

View File

@@ -428,6 +428,7 @@
"top_right": "En haut à droite",
"try_again": "Réessayer",
"type": "Type",
"unknown_survey": "Enquête inconnue",
"unlock_more_workspaces_with_a_higher_plan": "Débloquez plus de projets avec un forfait supérieur.",
"update": "Mise à jour",
"updated": "Mise à jour",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Cela supprimera l'attribut sélectionné. Toutes les données de contact associées à cet attribut seront perdues.} other {Cela supprimera les attributs sélectionnés. Toutes les données de contact associées à ces attributs seront perdues.}}",
"delete_contact_confirmation": "Cela supprimera toutes les réponses aux enquêtes et les attributs de contact associés à ce contact. Toute la personnalisation et le ciblage basés sur les données de ce contact seront perdus.",
"delete_contact_confirmation_with_quotas": "{value, plural, other {Cela supprimera toutes les réponses aux enquêtes et les attributs de contact associés à ce contact. Toute la personnalisation et le ciblage basés sur les données de ce contact seront perdus. Si ce contact a des réponses qui comptent dans les quotas de l'enquête, les comptes de quotas seront réduits mais les limites de quota resteront inchangées.}}",
"displays": "Affichages",
"edit_attribute": "Modifier l'attribut",
"edit_attribute_description": "Mettez à jour l'étiquette et la description de cet attribut.",
"edit_attribute_values": "Modifier les attributs",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Nom(s) de colonne CSV invalide(s): {columns}. Les noms de colonnes qui deviendront de nouveaux attributs ne doivent contenir que des lettres minuscules, des chiffres et des underscores, et doivent commencer par une lettre.",
"invalid_date_format": "Format de date invalide. Merci d'utiliser une date valide.",
"invalid_number_format": "Format de nombre invalide. Veuillez saisir un nombre valide.",
"no_activity_yet": "Aucune activité pour le moment",
"no_published_link_surveys_available": "Aucune enquête par lien publiée n'est disponible. Veuillez d'abord publier une enquête par lien.",
"no_published_surveys": "Aucune enquête publiée",
"no_responses_found": "Aucune réponse trouvée",
@@ -681,6 +684,8 @@
"select_a_survey": "Sélectionner une enquête",
"select_attribute": "Sélectionner un attribut",
"select_attribute_key": "Sélectionner une clé d'attribut",
"survey_viewed": "Enquête consultée",
"survey_viewed_at": "Consultée le",
"system_attributes": "Attributs système",
"unlock_contacts_description": "Gérer les contacts et envoyer des enquêtes ciblées",
"unlock_contacts_title": "Débloquez des contacts avec un plan supérieur.",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Réponses filtrées (Excel)",
"generating_qr_code": "Génération du code QR",
"impressions": "Impressions",
"impressions_identified_only": "Affichage uniquement des impressions des contacts identifiés",
"impressions_tooltip": "Nombre de fois que l'enquête a été consultée.",
"in_app": {
"connection_description": "Le sondage sera affiché aux utilisateurs de votre site web, qui correspondent aux critères listés ci-dessous",
@@ -1989,6 +1995,7 @@
"last_quarter": "dernier trimestre",
"last_year": "l'année dernière",
"limit": "Limite",
"no_identified_impressions": "Aucune impression des contacts identifiés",
"no_responses_found": "Aucune réponse trouvée",
"other_values_found": "D'autres valeurs trouvées",
"overall": "Globalement",

View File

@@ -428,6 +428,7 @@
"top_right": "Jobbra fent",
"try_again": "Próbálja újra",
"type": "Típus",
"unknown_survey": "Ismeretlen kérdőív",
"unlock_more_workspaces_with_a_higher_plan": "Több munkaterület feloldása egy magasabb csomaggal.",
"update": "Frissítés",
"updated": "Frissítve",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Ez törölni fogja a kiválasztott attribútumot. Az ehhez az attribútumhoz hozzárendelt összes partneradat el fog veszni.} other {Ez törölni fogja a kiválasztott attribútumokat. Az ezekhez az attribútumokhoz hozzárendelt összes partneradat el fog veszni.}}",
"delete_contact_confirmation": "Ez törölni fogja az ehhez a partnerhez tartozó összes kérdőívválaszt és partnerattribútumot. A partner adatain alapuló bármilyen célzás és személyre szabás el fog veszni.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Ez törölni fogja az ehhez a partnerhez tartozó összes kérdőívválaszt és partnerattribútumot. A partner adatain alapuló bármilyen célzás és személyre szabás el fog veszni. Ha ez a partner olyan válaszokkal rendelkezik, amelyek a kérdőívkvótákba beletartoznak, akkor a kvóta számlálója csökkentve lesz, de a kvóta korlátai változatlanok maradnak.} other {Ez törölni fogja az ezekhez a partnerekhez tartozó összes kérdőívválaszt és partnerattribútumot. A partnerek adatain alapuló bármilyen célzás és személyre szabás el fog veszni. Ha ezek a partnerek olyan válaszokkal rendelkeznek, amelyek a kérdőívkvótákba beletartoznak, akkor a kvóta számlálója csökkentve lesz, de a kvóta korlátai változatlanok maradnak.}}",
"displays": "Megjelenítések",
"edit_attribute": "Attribútum szerkesztése",
"edit_attribute_description": "Az attribútum címkéjének és leírásának frissítése.",
"edit_attribute_values": "Attribútumok szerkesztése",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Érvénytelen CSV oszlopnév(nevek): {columns}. Az új attribútumokká váló oszlopnevek csak kisbetűket, számokat és aláhúzásjeleket tartalmazhatnak, és betűvel kell kezdődniük.",
"invalid_date_format": "Érvénytelen dátumformátum. Kérlek, adj meg egy érvényes dátumot.",
"invalid_number_format": "Érvénytelen számformátum. Kérlek, adj meg egy érvényes számot.",
"no_activity_yet": "Még nincs aktivitás",
"no_published_link_surveys_available": "Nem érhetők el közzétett hivatkozás-kérdőívek. Először tegyen közzé egy hivatkozás-kérdőívet.",
"no_published_surveys": "Nincsenek közzétett kérdőívek",
"no_responses_found": "Nem találhatók válaszok",
@@ -681,6 +684,8 @@
"select_a_survey": "Kérdőív kiválasztása",
"select_attribute": "Attribútum kiválasztása",
"select_attribute_key": "Attribútum kulcs kiválasztása",
"survey_viewed": "Kérdőív megtekintve",
"survey_viewed_at": "Megtekintve",
"system_attributes": "Rendszer attribútumok",
"unlock_contacts_description": "Partnerek kezelése és célzott kérdőívek kiküldése",
"unlock_contacts_title": "Partnerek feloldása egy magasabb csomaggal",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Szűrt válaszok (Excel)",
"generating_qr_code": "QR-kód előállítása",
"impressions": "Benyomások",
"impressions_identified_only": "Csak az azonosított kapcsolatok megjelenítései láthatók",
"impressions_tooltip": "A kérdőív megtekintési alkalmainak száma.",
"in_app": {
"connection_description": "A kérdőív a webhelye azon felhasználóinak lesz megjelenítve, akik megfelelnek az alább felsorolt feltételeknek",
@@ -1989,6 +1995,7 @@
"last_quarter": "Elmúlt negyedév",
"last_year": "Elmúlt év",
"limit": "Korlát",
"no_identified_impressions": "Nincsenek megjelenítések azonosított kapcsolatoktól",
"no_responses_found": "Nem találhatók válaszok",
"other_values_found": "Más értékek találhatók",
"overall": "Összesen",

View File

@@ -428,6 +428,7 @@
"top_right": "右上",
"try_again": "もう一度お試しください",
"type": "種類",
"unknown_survey": "不明なフォーム",
"unlock_more_workspaces_with_a_higher_plan": "上位プランでより多くのワークスペースを利用できます。",
"update": "更新",
"updated": "更新済み",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {選択した属性を削除します。この属性に関連付けられたすべてのコンタクトデータは失われます。} other {選択した属性を削除します。これらの属性に関連付けられたすべてのコンタクトデータは失われます。}}",
"delete_contact_confirmation": "これにより、この連絡先に関連付けられているすべてのフォーム回答と連絡先属性が削除されます。この連絡先のデータに基づいたターゲティングとパーソナライゼーションはすべて失われます。",
"delete_contact_confirmation_with_quotas": "{value, plural, one {これにより この連絡先に関連するすべてのアンケート応答と連絡先属性が削除されます。この連絡先のデータに基づくターゲティングとパーソナライゼーションが失われます。この連絡先がアンケートの割当量を考慮した回答を持っている場合、割当量カウントは減少しますが、割当量の制限は変更されません。} other {これにより これらの連絡先に関連するすべてのアンケート応答と連絡先属性が削除されます。これらの連絡先のデータに基づくターゲティングとパーソナライゼーションが失われます。これらの連絡先がアンケートの割当量を考慮した回答を持っている場合、割当量カウントは減少しますが、割当量の制限は変更されません。}}",
"displays": "表示回数",
"edit_attribute": "属性を編集",
"edit_attribute_description": "この属性のラベルと説明を更新します。",
"edit_attribute_values": "属性を編集",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "無効なCSV列名: {columns}。新しい属性となる列名は、小文字、数字、アンダースコアのみを含み、文字で始まる必要があります。",
"invalid_date_format": "無効な日付形式です。有効な日付を使用してください。",
"invalid_number_format": "無効な数値形式です。有効な数値を入力してください。",
"no_activity_yet": "まだアクティビティがありません",
"no_published_link_surveys_available": "公開されたリンクフォームはありません。まずリンクフォームを公開してください。",
"no_published_surveys": "公開されたフォームはありません",
"no_responses_found": "回答が見つかりません",
@@ -681,6 +684,8 @@
"select_a_survey": "フォームを選択",
"select_attribute": "属性を選択",
"select_attribute_key": "属性キーを選択",
"survey_viewed": "フォームを閲覧",
"survey_viewed_at": "閲覧日時",
"system_attributes": "システム属性",
"unlock_contacts_description": "連絡先を管理し、特定のフォームを送信します",
"unlock_contacts_title": "上位プランで連絡先をアンロック",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "フィルター済み回答 (Excel)",
"generating_qr_code": "QRコードを生成中",
"impressions": "表示回数",
"impressions_identified_only": "識別済みコンタクトからのインプレッションのみを表示しています",
"impressions_tooltip": "フォームが表示された回数。",
"in_app": {
"connection_description": "このフォームは、以下の条件に一致するあなたのウェブサイトのユーザーに表示されます",
@@ -1989,6 +1995,7 @@
"last_quarter": "前四半期",
"last_year": "昨年",
"limit": "制限",
"no_identified_impressions": "識別済みコンタクトからのインプレッションはありません",
"no_responses_found": "回答が見つかりません",
"other_values_found": "他の値が見つかりました",
"overall": "全体",

View File

@@ -428,6 +428,7 @@
"top_right": "Rechtsboven",
"try_again": "Probeer het opnieuw",
"type": "Type",
"unknown_survey": "Onbekende enquête",
"unlock_more_workspaces_with_a_higher_plan": "Ontgrendel meer werkruimtes met een hoger abonnement.",
"update": "Update",
"updated": "Bijgewerkt",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Dit verwijdert het geselecteerde attribuut. Alle contactgegevens die aan dit attribuut zijn gekoppeld, gaan verloren.} other {Dit verwijdert de geselecteerde attributen. Alle contactgegevens die aan deze attributen zijn gekoppeld, gaan verloren.}}",
"delete_contact_confirmation": "Hierdoor worden alle enquêtereacties en contactkenmerken verwijderd die aan dit contact zijn gekoppeld. Elke targeting en personalisatie op basis van de gegevens van dit contact gaat verloren.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Dit verwijdert alle enquêteresultaten en contactattributen die aan dit contact zijn gekoppeld. Alle targeting en personalisatie op basis van de gegevens van dit contact gaan verloren. Als dit contact reacties heeft die meetellen voor enquêtekvota, worden de quotawaarden verlaagd maar blijven de limieten ongewijzigd.} other {Dit verwijdert alle enquêteresultaten en contactattributen die aan deze contacten zijn gekoppeld. Alle targeting en personalisatie op basis van de gegevens van deze contacten gaan verloren. Als deze contacten reacties hebben die meetellen voor enquêtekvota, worden de quotawaarden verlaagd maar blijven de limieten ongewijzigd.}}",
"displays": "Weergaven",
"edit_attribute": "Attribuut bewerken",
"edit_attribute_description": "Werk het label en de beschrijving voor dit attribuut bij.",
"edit_attribute_values": "Attributen bewerken",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Ongeldige CSV-kolomna(a)m(en): {columns}. Kolomnamen die nieuwe kenmerken worden, mogen alleen kleine letters, cijfers en underscores bevatten en moeten beginnen met een letter.",
"invalid_date_format": "Ongeldig datumformaat. Gebruik een geldige datum.",
"invalid_number_format": "Ongeldig getalformaat. Voer een geldig getal in.",
"no_activity_yet": "Nog geen activiteit",
"no_published_link_surveys_available": "Geen gepubliceerde link-enquêtes beschikbaar. Publiceer eerst een link-enquête.",
"no_published_surveys": "Geen gepubliceerde enquêtes",
"no_responses_found": "Geen reacties gevonden",
@@ -681,6 +684,8 @@
"select_a_survey": "Selecteer een enquête",
"select_attribute": "Selecteer Kenmerk",
"select_attribute_key": "Selecteer kenmerksleutel",
"survey_viewed": "Enquête bekeken",
"survey_viewed_at": "Bekeken op",
"system_attributes": "Systeemkenmerken",
"unlock_contacts_description": "Beheer contacten en verstuur gerichte enquêtes",
"unlock_contacts_title": "Ontgrendel contacten met een hoger abonnement",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Gefilterde reacties (Excel)",
"generating_qr_code": "QR-code genereren",
"impressions": "Indrukken",
"impressions_identified_only": "Alleen weergaven van geïdentificeerde contacten worden getoond",
"impressions_tooltip": "Aantal keren dat de enquête is bekeken.",
"in_app": {
"connection_description": "De enquête wordt getoond aan gebruikers van uw website die voldoen aan de onderstaande criteria",
@@ -1989,6 +1995,7 @@
"last_quarter": "Laatste kwartaal",
"last_year": "Vorig jaar",
"limit": "Beperken",
"no_identified_impressions": "Geen weergaven van geïdentificeerde contacten",
"no_responses_found": "Geen reacties gevonden",
"other_values_found": "Andere waarden gevonden",
"overall": "Algemeen",

View File

@@ -428,6 +428,7 @@
"top_right": "Canto Superior Direito",
"try_again": "Tenta de novo",
"type": "Tipo",
"unknown_survey": "Pesquisa desconhecida",
"unlock_more_workspaces_with_a_higher_plan": "Desbloqueie mais projetos com um plano superior.",
"update": "atualizar",
"updated": "atualizado",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Isso excluirá o atributo selecionado. Todos os dados de contato associados a este atributo serão perdidos.} other {Isso excluirá os atributos selecionados. Todos os dados de contato associados a estes atributos serão perdidos.}}",
"delete_contact_confirmation": "Isso irá apagar todas as respostas da pesquisa e atributos de contato associados a este contato. Qualquer direcionamento e personalização baseados nos dados deste contato serão perdidos.",
"delete_contact_confirmation_with_quotas": "{value, plural, other {Isso irá apagar todas as respostas da pesquisa e atributos de contato associados a este contato. Qualquer direcionamento e personalização baseados nos dados deste contato serão perdidos. Se este contato tiver respostas que contam para cotas da pesquisa, as contagens das cotas serão reduzidas, mas os limites das cotas permanecerão inalterados.}}",
"displays": "Exibições",
"edit_attribute": "Editar atributo",
"edit_attribute_description": "Atualize a etiqueta e a descrição deste atributo.",
"edit_attribute_values": "Editar atributos",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Nome(s) de coluna CSV inválido(s): {columns}. Os nomes de colunas que se tornarão novos atributos devem conter apenas letras minúsculas, números e sublinhados, e devem começar com uma letra.",
"invalid_date_format": "Formato de data inválido. Por favor, use uma data válida.",
"invalid_number_format": "Formato de número inválido. Por favor, insira um número válido.",
"no_activity_yet": "Nenhuma atividade ainda",
"no_published_link_surveys_available": "Não há pesquisas de link publicadas disponíveis. Por favor, publique uma pesquisa de link primeiro.",
"no_published_surveys": "Sem pesquisas publicadas",
"no_responses_found": "Nenhuma resposta encontrada",
@@ -681,6 +684,8 @@
"select_a_survey": "Selecione uma pesquisa",
"select_attribute": "Selecionar Atributo",
"select_attribute_key": "Selecionar chave de atributo",
"survey_viewed": "Pesquisa visualizada",
"survey_viewed_at": "Visualizada em",
"system_attributes": "Atributos do sistema",
"unlock_contacts_description": "Gerencie contatos e envie pesquisas direcionadas",
"unlock_contacts_title": "Desbloqueie contatos com um plano superior",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Respostas filtradas (Excel)",
"generating_qr_code": "Gerando código QR",
"impressions": "Impressões",
"impressions_identified_only": "Mostrando apenas impressões de contatos identificados",
"impressions_tooltip": "Número de vezes que a pesquisa foi visualizada.",
"in_app": {
"connection_description": "A pesquisa será exibida para usuários do seu site, que atendam aos critérios listados abaixo",
@@ -1989,6 +1995,7 @@
"last_quarter": "Último trimestre",
"last_year": "Último ano",
"limit": "Limite",
"no_identified_impressions": "Nenhuma impressão de contatos identificados",
"no_responses_found": "Nenhuma resposta encontrada",
"other_values_found": "Outros valores encontrados",
"overall": "No geral",

View File

@@ -428,6 +428,7 @@
"top_right": "Superior Direito",
"try_again": "Tente novamente",
"type": "Tipo",
"unknown_survey": "Inquérito desconhecido",
"unlock_more_workspaces_with_a_higher_plan": "Desbloqueie mais projetos com um plano superior.",
"update": "Atualizar",
"updated": "Atualizado",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Isto irá eliminar o atributo selecionado. Todos os dados de contacto associados a este atributo serão perdidos.} other {Isto irá eliminar os atributos selecionados. Todos os dados de contacto associados a estes atributos serão perdidos.}}",
"delete_contact_confirmation": "Isto irá eliminar todas as respostas das pesquisas e os atributos de contato associados a este contato. Qualquer direcionamento e personalização baseados nos dados deste contato serão perdidos.",
"delete_contact_confirmation_with_quotas": "{value, plural, other {Isto irá eliminar todas as respostas das pesquisas e os atributos de contacto associados a este contacto. Qualquer segmentação e personalização baseados nos dados deste contacto serão perdidos. Se este contacto tiver respostas que contribuam para as quotas das pesquisas, as contagens de quotas serão reduzidas, mas os limites das quotas permanecerão inalterados.}}",
"displays": "Visualizações",
"edit_attribute": "Editar atributo",
"edit_attribute_description": "Atualize a etiqueta e a descrição deste atributo.",
"edit_attribute_values": "Editar atributos",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Nome(s) de coluna CSV inválido(s): {columns}. Os nomes de colunas que se tornarão novos atributos devem conter apenas letras minúsculas, números e underscores, e devem começar com uma letra.",
"invalid_date_format": "Formato de data inválido. Por favor, usa uma data válida.",
"invalid_number_format": "Formato de número inválido. Por favor, introduz um número válido.",
"no_activity_yet": "Ainda sem atividade",
"no_published_link_surveys_available": "Não existem inquéritos de link publicados disponíveis. Por favor, publique primeiro um inquérito de link.",
"no_published_surveys": "Sem inquéritos publicados",
"no_responses_found": "Nenhuma resposta encontrada",
@@ -681,6 +684,8 @@
"select_a_survey": "Selecione um inquérito",
"select_attribute": "Selecionar Atributo",
"select_attribute_key": "Selecionar chave de atributo",
"survey_viewed": "Inquérito visualizado",
"survey_viewed_at": "Visualizado em",
"system_attributes": "Atributos do sistema",
"unlock_contacts_description": "Gerir contactos e enviar inquéritos direcionados",
"unlock_contacts_title": "Desbloqueie os contactos com um plano superior",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Respostas filtradas (Excel)",
"generating_qr_code": "A gerar código QR",
"impressions": "Impressões",
"impressions_identified_only": "A mostrar apenas impressões de contactos identificados",
"impressions_tooltip": "Número de vezes que o inquérito foi visualizado.",
"in_app": {
"connection_description": "O questionário será exibido aos utilizadores do seu website que correspondam aos critérios listados abaixo",
@@ -1989,6 +1995,7 @@
"last_quarter": "Último trimestre",
"last_year": "Ano passado",
"limit": "Limite",
"no_identified_impressions": "Sem impressões de contactos identificados",
"no_responses_found": "Nenhuma resposta encontrada",
"other_values_found": "Outros valores encontrados",
"overall": "Geral",

View File

@@ -428,6 +428,7 @@
"top_right": "Dreapta Sus",
"try_again": "Încearcă din nou",
"type": "Tip",
"unknown_survey": "Chestionar necunoscut",
"unlock_more_workspaces_with_a_higher_plan": "Deblochează mai multe workspaces cu un plan superior.",
"update": "Actualizare",
"updated": "Actualizat",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Acest lucru va șterge atributul selectat. Orice date de contact asociate cu acest atribut vor fi pierdute.} few {Acest lucru va șterge atributele selectate. Orice date de contact asociate cu aceste atribute vor fi pierdute.} other {Acest lucru va șterge atributele selectate. Orice date de contact asociate cu aceste atribute vor fi pierdute.}}",
"delete_contact_confirmation": "Acest lucru va șterge toate răspunsurile la sondaj și atributele de contact asociate cu acest contact. Orice țintire și personalizare bazată pe datele acestui contact vor fi pierdute.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Această acțiune va șterge toate răspunsurile chestionarului și atributele de contact asociate cu acest contact. Orice țintire și personalizare bazată pe datele acestui contact vor fi pierdute. Dacă acest contact are răspunsuri care contează pentru cotele chestionarului, numărul cotelor va fi redus, dar limitele cotelor vor rămâne neschimbate.} other {Aceste acțiuni vor șterge toate răspunsurile chestionarului și atributele de contact asociate cu acești contacți. Orice țintire și personalizare bazată pe datele acestor contacți vor fi pierdute. Dacă acești contacți au răspunsuri care contează pentru cotele chestionarului, numărul cotelor va fi redus, dar limitele cotelor vor rămâne neschimbate.} }",
"displays": "Afișări",
"edit_attribute": "Editează atributul",
"edit_attribute_description": "Actualizează eticheta și descrierea acestui atribut.",
"edit_attribute_values": "Editează atributele",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Nume de coloană CSV nevalide: {columns}. Numele coloanelor care vor deveni atribute noi trebuie să conțină doar litere mici, cifre și caractere de subliniere și trebuie să înceapă cu o literă.",
"invalid_date_format": "Format de dată invalid. Te rugăm să folosești o dată validă.",
"invalid_number_format": "Format de număr invalid. Te rugăm să introduci un număr valid.",
"no_activity_yet": "Nicio activitate încă",
"no_published_link_surveys_available": "Nu există sondaje publicate pentru linkuri disponibile. Vă rugăm să publicați mai întâi un sondaj pentru linkuri.",
"no_published_surveys": "Nu există sondaje publicate",
"no_responses_found": "Nu s-au găsit răspunsuri",
@@ -681,6 +684,8 @@
"select_a_survey": "Selectați un sondaj",
"select_attribute": "Selectează atributul",
"select_attribute_key": "Selectează cheia atributului",
"survey_viewed": "Chestionar vizualizat",
"survey_viewed_at": "Vizualizat la",
"system_attributes": "Atribute de sistem",
"unlock_contacts_description": "Gestionează contactele și trimite sondaje țintite",
"unlock_contacts_title": "Deblocați contactele cu un plan superior.",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Răspunsuri filtrate (Excel)",
"generating_qr_code": "Se generează codul QR",
"impressions": "Impresii",
"impressions_identified_only": "Se afișează doar impresiile de la contactele identificate",
"impressions_tooltip": "Număr de ori când sondajul a fost vizualizat.",
"in_app": {
"connection_description": "Sondajul va fi afișat utilizatorilor site-ului dvs. web, care îndeplinesc criteriile enumerate mai jos",
@@ -1989,6 +1995,7 @@
"last_quarter": "Ultimul trimestru",
"last_year": "Anul trecut",
"limit": "Limită",
"no_identified_impressions": "Nicio impresie de la contactele identificate",
"no_responses_found": "Nu s-au găsit răspunsuri",
"other_values_found": "Alte valori găsite",
"overall": "General",

View File

@@ -428,6 +428,7 @@
"top_right": "Вверху справа",
"try_again": "Попробуйте ещё раз",
"type": "Тип",
"unknown_survey": "Неизвестный опрос",
"unlock_more_workspaces_with_a_higher_plan": "Откройте больше рабочих пространств с более высоким тарифом.",
"update": "Обновить",
"updated": "Обновлено",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Будет удалён выбранный атрибут. Все данные контактов, связанные с этим атрибутом, будут потеряны.} few {Будут удалены выбранные атрибуты. Все данные контактов, связанные с этими атрибутами, будут потеряны.} many {Будут удалены выбранные атрибуты. Все данные контактов, связанные с этими атрибутами, будут потеряны.} other {Будут удалены выбранные атрибуты. Все данные контактов, связанные с этими атрибутами, будут потеряны.}}",
"delete_contact_confirmation": "Это удалит все ответы на опросы и атрибуты контакта, связанные с этим контактом. Любая таргетинг и персонализация на основе данных этого контакта будут потеряны.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Это удалит все ответы на опросы и атрибуты контакта, связанные с этим контактом. Любая таргетинг и персонализация на основе данных этого контакта будут потеряны. Если у этого контакта есть ответы, которые учитываются в квотах опроса, количество по квотам будет уменьшено, но лимиты квот останутся без изменений.} few {Это удалит все ответы на опросы и атрибуты контактов, связанные с этими контактами. Любая таргетинг и персонализация на основе данных этих контактов будут потеряны. Если у этих контактов есть ответы, которые учитываются в квотах опроса, количество по квотам будет уменьшено, но лимиты квот останутся без изменений.} many {Это удалит все ответы на опросы и атрибуты контактов, связанные с этими контактами. Любая таргетинг и персонализация на основе данных этих контактов будут потеряны. Если у этих контактов есть ответы, которые учитываются в квотах опроса, количество по квотам будет уменьшено, но лимиты квот останутся без изменений.} other {Это удалит все ответы на опросы и атрибуты контактов, связанные с этими контактами. Любая таргетинг и персонализация на основе данных этих контактов будут потеряны. Если у этих контактов есть ответы, которые учитываются в квотах опроса, количество по квотам будет уменьшено, но лимиты квот останутся без изменений.}}",
"displays": "Показы",
"edit_attribute": "Редактировать атрибут",
"edit_attribute_description": "Обновите метку и описание для этого атрибута.",
"edit_attribute_values": "Редактировать атрибуты",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Недопустимые имена столбцов в CSV: {columns}. Имена столбцов, которые станут новыми атрибутами, должны содержать только строчные буквы, цифры и подчёркивания, а также начинаться с буквы.",
"invalid_date_format": "Неверный формат даты. Пожалуйста, используйте корректную дату.",
"invalid_number_format": "Неверный формат числа. Пожалуйста, введите корректное число.",
"no_activity_yet": "Пока нет активности",
"no_published_link_surveys_available": "Нет доступных опубликованных опросов-ссылок. Пожалуйста, сначала опубликуйте опрос-ссылку.",
"no_published_surveys": "Нет опубликованных опросов",
"no_responses_found": "Ответы не найдены",
@@ -681,6 +684,8 @@
"select_a_survey": "Выберите опрос",
"select_attribute": "Выберите атрибут",
"select_attribute_key": "Выберите ключ атрибута",
"survey_viewed": "Опрос просмотрен",
"survey_viewed_at": "Просмотрено",
"system_attributes": "Системные атрибуты",
"unlock_contacts_description": "Управляйте контактами и отправляйте целевые опросы",
"unlock_contacts_title": "Откройте доступ к контактам с более высоким тарифом",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Отфильтрованные ответы (Excel)",
"generating_qr_code": "Генерация QR-кода",
"impressions": "Просмотры",
"impressions_identified_only": "Показаны только показы от идентифицированных контактов",
"impressions_tooltip": "Количество раз, когда опрос был просмотрен.",
"in_app": {
"connection_description": "Опрос будет показан пользователям вашего сайта, которые соответствуют указанным ниже критериям",
@@ -1989,6 +1995,7 @@
"last_quarter": "Прошлый квартал",
"last_year": "Прошлый год",
"limit": "Лимит",
"no_identified_impressions": "Нет показов от идентифицированных контактов",
"no_responses_found": "Ответы не найдены",
"other_values_found": "Найдены другие значения",
"overall": "В целом",

View File

@@ -428,6 +428,7 @@
"top_right": "Övre höger",
"try_again": "Försök igen",
"type": "Typ",
"unknown_survey": "Okänd enkät",
"unlock_more_workspaces_with_a_higher_plan": "Lås upp fler arbetsytor med ett högre abonnemang.",
"update": "Uppdatera",
"updated": "Uppdaterad",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {Detta kommer att ta bort det valda attributet. All kontaktdata som är kopplad till detta attribut kommer att gå förlorad.} other {Detta kommer att ta bort de valda attributen. All kontaktdata som är kopplad till dessa attribut kommer att gå förlorad.}}",
"delete_contact_confirmation": "Detta kommer att ta bort alla enkätsvar och kontaktattribut som är kopplade till denna kontakt. All målgruppsinriktning och personalisering baserad på denna kontakts data kommer att gå förlorad.",
"delete_contact_confirmation_with_quotas": "{value, plural, one {Detta kommer att ta bort alla enkätsvar och kontaktattribut som är kopplade till denna kontakt. All målgruppsinriktning och personalisering baserad på denna kontakts data kommer att gå förlorad. Om denna kontakt har svar som räknas mot enkätkvoter, kommer kvotantalet att minskas men kvotgränserna förblir oförändrade.} other {Detta kommer att ta bort alla enkätsvar och kontaktattribut som är kopplade till dessa kontakter. All målgruppsinriktning och personalisering baserad på dessa kontakters data kommer att gå förlorad. Om dessa kontakter har svar som räknas mot enkätkvoter, kommer kvotantalet att minskas men kvotgränserna förblir oförändrade.}}",
"displays": "Visningar",
"edit_attribute": "Redigera attribut",
"edit_attribute_description": "Uppdatera etikett och beskrivning för detta attribut.",
"edit_attribute_values": "Redigera attribut",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "Ogiltiga CSV-kolumnnamn: {columns}. Kolumnnamn som ska bli nya attribut får bara innehålla små bokstäver, siffror och understreck, och måste börja med en bokstav.",
"invalid_date_format": "Ogiltigt datumformat. Ange ett giltigt datum.",
"invalid_number_format": "Ogiltigt nummerformat. Ange ett giltigt nummer.",
"no_activity_yet": "Ingen aktivitet än",
"no_published_link_surveys_available": "Inga publicerade länkenkäter tillgängliga. Vänligen publicera en länkenkät först.",
"no_published_surveys": "Inga publicerade enkäter",
"no_responses_found": "Inga svar hittades",
@@ -681,6 +684,8 @@
"select_a_survey": "Välj en enkät",
"select_attribute": "Välj attribut",
"select_attribute_key": "Välj attributnyckel",
"survey_viewed": "Enkät visad",
"survey_viewed_at": "Visad kl.",
"system_attributes": "Systemattribut",
"unlock_contacts_description": "Hantera kontakter och skicka ut riktade enkäter",
"unlock_contacts_title": "Lås upp kontakter med en högre plan",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "Filtrerade svar (Excel)",
"generating_qr_code": "Genererar QR-kod",
"impressions": "Visningar",
"impressions_identified_only": "Visar bara visningar från identifierade kontakter",
"impressions_tooltip": "Antal gånger enkäten har visats.",
"in_app": {
"connection_description": "Enkäten kommer att visas för användare på din webbplats som matchar kriterierna nedan",
@@ -1989,6 +1995,7 @@
"last_quarter": "Senaste kvartalet",
"last_year": "Senaste året",
"limit": "Gräns",
"no_identified_impressions": "Inga visningar från identifierade kontakter",
"no_responses_found": "Inga svar hittades",
"other_values_found": "Andra värden hittades",
"overall": "Övergripande",

View File

@@ -428,6 +428,7 @@
"top_right": "右上",
"try_again": "再試一次",
"type": "類型",
"unknown_survey": "未知問卷",
"unlock_more_workspaces_with_a_higher_plan": "升級方案以解鎖更多工作區。",
"update": "更新",
"updated": "已更新",
@@ -656,6 +657,7 @@
"delete_attribute_confirmation": "{value, plural, one {這將刪除所選屬性。與此屬性相關的聯絡人資料將會遺失。} other {這將刪除所選屬性。與這些屬性相關的聯絡人資料將會遺失。}}",
"delete_contact_confirmation": "這將刪除與此聯繫人相關的所有調查回應和聯繫屬性。任何基於此聯繫人數據的定位和個性化將會丟失。",
"delete_contact_confirmation_with_quotas": "{value, plural, one {這將刪除與這個 contact 相關的所有調查響應和聯繫人屬性。基於這個 contact 數據的任何定向和個性化功能將會丟失。如果這個 contact 有作為調查配額依據的響應,配額計數將會減少,但配額限制將保持不變。} other {這將刪除與這些 contacts 相關的所有調查響應和聯繫人屬性。基於這些 contacts 數據的任何定向和個性化功能將會丟失。如果這些 contacts 有作為調查配額依據的響應,配額計數將會減少,但配額限制將保持不變。}}",
"displays": "顯示次數",
"edit_attribute": "編輯屬性",
"edit_attribute_description": "更新此屬性的標籤與描述。",
"edit_attribute_values": "編輯屬性",
@@ -667,6 +669,7 @@
"invalid_csv_column_names": "無效的 CSV 欄位名稱:{columns}。作為新屬性的欄位名稱只能包含小寫字母、數字和底線,且必須以字母開頭。",
"invalid_date_format": "日期格式無效。請使用有效的日期。",
"invalid_number_format": "數字格式無效。請輸入有效的數字。",
"no_activity_yet": "尚無活動",
"no_published_link_surveys_available": "沒有可用的已發佈連結問卷。請先發佈一個連結問卷。",
"no_published_surveys": "沒有已發佈的問卷",
"no_responses_found": "找不到回應",
@@ -681,6 +684,8 @@
"select_a_survey": "選擇問卷",
"select_attribute": "選取屬性",
"select_attribute_key": "選取屬性鍵值",
"survey_viewed": "已查看問卷",
"survey_viewed_at": "查看時間",
"system_attributes": "系統屬性",
"unlock_contacts_description": "管理聯絡人並發送目標問卷",
"unlock_contacts_title": "使用更高等級的方案解鎖聯絡人",
@@ -1947,6 +1952,7 @@
"filtered_responses_excel": "篩選回應 (Excel)",
"generating_qr_code": "正在生成 QR code",
"impressions": "曝光數",
"impressions_identified_only": "僅顯示已識別聯絡人的曝光次數",
"impressions_tooltip": "問卷已檢視的次數。",
"in_app": {
"connection_description": "調查將顯示給符合以下列出條件的網站用戶",
@@ -1989,6 +1995,7 @@
"last_quarter": "上一季",
"last_year": "去年",
"limit": "限制",
"no_identified_impressions": "沒有來自已識別聯絡人的曝光次數",
"no_responses_found": "找不到回應",
"other_values_found": "找到其他值",
"overall": "整體",

View File

@@ -48,6 +48,16 @@ export const ActivityTimeline = ({
const [responses, setResponses] = useState(initialResponses);
const [isReversed, setIsReversed] = useState(false);
// Fetch membership role once for the environment
const { membershipRole } = useMembershipRole(environment.id, user.id);
// Compute isReadOnly once for all responses
const isReadOnly = useMemo(() => {
const { isMember } = getAccessFlags(membershipRole);
const { hasReadAccess } = getTeamPermissionFlags(projectPermission);
return isMember && hasReadAccess;
}, [membershipRole, projectPermission]);
useEffect(() => {
setResponses(initialResponses);
}, [initialResponses]);
@@ -121,7 +131,7 @@ export const ActivityTimeline = ({
updateResponseList={updateResponseList}
updateResponse={updateResponse}
locale={locale}
projectPermission={projectPermission}
isReadOnly={isReadOnly}
/>
)
)}
@@ -164,7 +174,7 @@ const DisplayCard = ({
)}
</div>
</div>
<span className="text-sm text-slate-500">{timeSince(display.createdAt.toISOString(), locale)}</span>
<span className="text-sm text-slate-500">{timeSince(display.createdAt.toString(), locale)}</span>
</div>
);
};
@@ -178,7 +188,7 @@ const ResponseSurveyCard = ({
updateResponseList,
updateResponse,
locale,
projectPermission,
isReadOnly,
}: {
response: TResponseWithQuotas;
surveys: TSurvey[];
@@ -188,13 +198,9 @@ const ResponseSurveyCard = ({
updateResponseList: (responseIds: string[]) => void;
updateResponse: (responseId: string, response: TResponseWithQuotas) => void;
locale: TUserLocale;
projectPermission: TTeamPermission | null;
isReadOnly: boolean;
}) => {
const survey = surveys.find((s) => s.id === response.surveyId);
const { membershipRole } = useMembershipRole(survey?.environmentId || "", user.id);
const { isMember } = getAccessFlags(membershipRole);
const { hasReadAccess } = getTeamPermissionFlags(projectPermission);
const isReadOnly = isMember && hasReadAccess;
if (!survey) return null;