feat: similar feedback preview (#7917)

Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
This commit is contained in:
Johannes
2026-05-05 11:28:08 +02:00
committed by GitHub
parent f376c620ab
commit 74dd778630
28 changed files with 878 additions and 171 deletions
@@ -31,10 +31,10 @@ export const UnifyConfigNavigation = ({
label: (
<span className="inline-flex items-center gap-2">
{t("workspace.unify.topics_and_subtopics")}
<Badge text={t("common.soon")} type="gray" size="tiny" />
<Badge text={t("common.preview")} type="gray" size="tiny" />
</span>
),
disabled: true,
href: `${baseHref}/topics-subtopics`,
},
];
@@ -0,0 +1,121 @@
"use server";
import { z } from "zod";
import { ZId } from "@formbricks/types/common";
import { authenticatedActionClient } from "@/lib/utils/action-client";
import { checkAuthorizationUpdated } from "@/lib/utils/action-client/action-client-middleware";
import { AuthenticatedActionClientCtx } from "@/lib/utils/action-client/types/context";
import { getOrganizationIdFromWorkspaceId } from "@/lib/utils/helper";
import { getFeedbackDirectoriesByWorkspaceId } from "@/modules/ee/feedback-directory/lib/feedback-directory";
import { semanticSearchFeedbackRecords } from "@/modules/hub/service";
import type { SemanticSearchResultItem } from "@/modules/hub/types";
const TOPICS_PREVIEW_LIMIT = 10;
const SEARCH_CONCURRENCY = 4;
const ZSemanticSearchFeedbackRecordsAction = z.object({
workspaceId: ZId,
query: z.string().trim().min(1).max(500),
limit: z.number().min(1).max(50).optional(),
minScore: z.number().min(0).max(1).optional(),
});
export type TTopicsPreviewSearchResult = SemanticSearchResultItem & {
tenant_id: string;
directory_name: string;
};
export type TTopicsPreviewSearchActionResult = {
results: TTopicsPreviewSearchResult[];
unavailable: boolean;
unavailableMessage?: string;
};
const ensureReadAccess = async (userId: string, workspaceId: string): Promise<void> => {
const organizationId = await getOrganizationIdFromWorkspaceId(workspaceId);
await checkAuthorizationUpdated({
userId,
organizationId,
access: [
{
type: "organization",
roles: ["owner", "manager"],
},
{
type: "workspaceTeam",
minPermission: "read",
workspaceId,
},
],
});
};
export const semanticSearchFeedbackRecordsAction = authenticatedActionClient
.inputSchema(ZSemanticSearchFeedbackRecordsAction)
.action(
async ({
ctx,
parsedInput,
}: {
ctx: AuthenticatedActionClientCtx;
parsedInput: z.infer<typeof ZSemanticSearchFeedbackRecordsAction>;
}): Promise<TTopicsPreviewSearchActionResult> => {
await ensureReadAccess(ctx.user.id, parsedInput.workspaceId);
const directories = await getFeedbackDirectoriesByWorkspaceId(parsedInput.workspaceId);
if (directories.length === 0) {
return { results: [], unavailable: false };
}
const limit = parsedInput.limit ?? TOPICS_PREVIEW_LIMIT;
const searches: {
directory: (typeof directories)[number];
result: Awaited<ReturnType<typeof semanticSearchFeedbackRecords>>;
}[] = [];
for (let i = 0; i < directories.length; i += SEARCH_CONCURRENCY) {
const chunk = directories.slice(i, i + SEARCH_CONCURRENCY);
const chunkResults = await Promise.all(
chunk.map(async (directory) => {
const result = await semanticSearchFeedbackRecords({
tenant_id: directory.id,
query: parsedInput.query,
limit,
min_score: parsedInput.minScore,
});
return { directory, result };
})
);
searches.push(...chunkResults);
}
const successfulResults = searches.flatMap(({ directory, result }) =>
(result.data?.data ?? []).map((item) => ({
...item,
tenant_id: directory.id,
directory_name: directory.name,
}))
);
if (successfulResults.length > 0) {
return {
results: successfulResults.toSorted((a, b) => b.score - a.score).slice(0, limit),
unavailable: false,
};
}
const firstError = searches.find(({ result }) => result.error)?.result.error;
if (firstError?.status === 0 || firstError?.status === 503) {
return {
results: [],
unavailable: true,
unavailableMessage: firstError.message,
};
}
if (firstError) {
throw new Error(firstError.message);
}
return { results: [], unavailable: false };
}
);
@@ -0,0 +1,192 @@
"use client";
import { SearchIcon, SparklesIcon } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { getFormattedErrorMessage } from "@/lib/utils/helper";
import { Badge } from "@/modules/ui/components/badge";
import { Button } from "@/modules/ui/components/button";
import { Input } from "@/modules/ui/components/input";
import { PageContentWrapper } from "@/modules/ui/components/page-content-wrapper";
import { PageHeader } from "@/modules/ui/components/page-header";
import { UnifyConfigNavigation } from "../../components/UnifyConfigNavigation";
import { semanticSearchFeedbackRecordsAction } from "../actions";
import type { TTopicsPreviewSearchResult } from "../actions";
interface TopicsSubtopicsPreviewProps {
workspaceId: string;
directoryMap: Record<string, string>;
}
export const TopicsSubtopicsPreview = ({
workspaceId,
directoryMap,
}: Readonly<TopicsSubtopicsPreviewProps>) => {
const { t } = useTranslation();
const [query, setQuery] = useState("");
const [results, setResults] = useState<TTopicsPreviewSearchResult[]>([]);
const [hasSearched, setHasSearched] = useState(false);
const [isSearching, setIsSearching] = useState(false);
const [error, setError] = useState<string | null>(null);
const [unavailableMessage, setUnavailableMessage] = useState<string | null>(null);
const hasDirectories = Object.keys(directoryMap).length > 0;
const exampleSearches = [
t("workspace.unify.semantic_topics_example_slow_checkout"),
t("workspace.unify.semantic_topics_example_pricing_complaints"),
t("workspace.unify.semantic_topics_example_confusing_onboarding"),
];
const runSearch = async (searchQuery: string) => {
const trimmedQuery = searchQuery.trim();
if (!trimmedQuery || isSearching) return;
setQuery(trimmedQuery);
setIsSearching(true);
setHasSearched(true);
setError(null);
setUnavailableMessage(null);
try {
const response = await semanticSearchFeedbackRecordsAction({
workspaceId,
query: trimmedQuery,
limit: 10,
minScore: 0.7,
});
if (response?.data) {
setResults(response.data.results);
setUnavailableMessage(response.data.unavailable ? (response.data.unavailableMessage ?? "") : null);
} else {
setResults([]);
setError(getFormattedErrorMessage(response) ?? t("workspace.unify.semantic_search_failed"));
}
} catch {
setResults([]);
setError(t("workspace.unify.semantic_search_failed"));
} finally {
setIsSearching(false);
}
};
const handleSubmit = async (event: { preventDefault: () => void }) => {
event.preventDefault();
await runSearch(query);
};
return (
<PageContentWrapper>
<PageHeader pageTitle={t("workspace.unify.feedback_records")}>
<UnifyConfigNavigation workspaceId={workspaceId} activeId="topics-subtopics" />
</PageHeader>
<div className="space-y-4">
<div className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm">
<div className="flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
<div className="max-w-2xl space-y-2">
<div className="flex items-center gap-2">
<SparklesIcon className="h-5 w-5 text-slate-500" aria-hidden="true" />
<h2 className="text-lg font-semibold text-slate-900">
{t("workspace.unify.semantic_topics_preview_title")}
</h2>
<Badge text={t("common.preview")} type="gray" size="tiny" />
</div>
<p className="text-sm text-slate-600">
{t("workspace.unify.semantic_topics_preview_description")}
</p>
</div>
</div>
<form className="mt-5 flex flex-col gap-3 sm:flex-row" onSubmit={handleSubmit}>
<Input
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder={t("workspace.unify.semantic_search_placeholder")}
disabled={!hasDirectories || isSearching}
aria-label={t("workspace.unify.semantic_search_input_label")}
/>
<Button type="submit" disabled={!query.trim() || !hasDirectories} loading={isSearching}>
<SearchIcon className="h-4 w-4" aria-hidden="true" />
{t("workspace.unify.search_feedback")}
</Button>
</form>
<div className="mt-4 flex flex-wrap items-center gap-2">
<span className="text-xs text-slate-500">{t("workspace.unify.try_searching_for")}</span>
{exampleSearches.map((label) => (
<Button
key={label}
type="button"
size="sm"
variant="secondary"
disabled={!hasDirectories || isSearching}
onClick={() => runSearch(label)}>
{label}
</Button>
))}
</div>
</div>
{!hasDirectories && (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-center shadow-sm">
<p className="text-sm text-slate-600">{t("workspace.unify.semantic_search_no_directories")}</p>
<Button className="mt-4" size="sm" asChild>
<Link href={`/workspaces/${workspaceId}/feedback-sources`}>
{t("workspace.unify.manage_feedback_sources")}
</Link>
</Button>
</div>
)}
{error && (
<div className="rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-700">{error}</div>
)}
{unavailableMessage !== null && (
<div className="rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-800">
{t("workspace.unify.semantic_search_unavailable")}
</div>
)}
{hasSearched && !isSearching && !error && unavailableMessage === null && results.length === 0 && (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-center shadow-sm">
<p className="text-sm text-slate-600">{t("workspace.unify.semantic_search_no_results")}</p>
</div>
)}
{results.length > 0 && (
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
<div className="border-b border-slate-200 px-4 py-3">
<p className="text-sm font-medium text-slate-900">
{t("workspace.unify.semantic_search_results_count", { count: results.length })}
</p>
</div>
<div className="divide-y divide-slate-100">
{results.map((result) => (
<div key={`${result.tenant_id}-${result.feedback_record_id}`} className="space-y-2 p-4">
<div className="flex flex-wrap items-center gap-2">
<Badge text={result.directory_name} type="gray" size="tiny" />
<span className="text-xs text-slate-500">
{t("workspace.unify.semantic_search_relevance", {
score: Math.round(result.score * 100),
})}
</span>
</div>
<p className="text-sm font-medium text-slate-900">
{result.field_label || t("workspace.unify.field_label")}
</p>
<p className="whitespace-pre-wrap text-sm text-slate-700">
{result.value_text || t("workspace.unify.semantic_search_missing_text")}
</p>
</div>
))}
</div>
</div>
)}
</div>
</PageContentWrapper>
);
};
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { getTranslate } from "@/lingodotdev/server";
import { getFeedbackDirectoriesByWorkspaceId } from "@/modules/ee/feedback-directory/lib/feedback-directory";
import { getWorkspaceAuth } from "@/modules/workspaces/lib/utils";
import { TopicsSubtopicsPreview } from "./components/topics-subtopics-preview";
export default async function UnifyTopicsSubtopicsPage(
props: Readonly<{ params: Promise<{ workspaceId: string }> }>
) {
const t = await getTranslate();
const params = await props.params;
const { isOwner, isManager, hasReadAccess, hasReadWriteAccess, hasManageAccess, session } =
await getWorkspaceAuth(params.workspaceId);
if (!session) {
throw new Error(t("common.session_not_found"));
}
const hasAccess = isOwner || isManager || hasReadAccess || hasReadWriteAccess || hasManageAccess;
if (!hasAccess) {
return notFound();
}
const directories = await getFeedbackDirectoriesByWorkspaceId(params.workspaceId);
const directoryMap = Object.fromEntries(directories.map((directory) => [directory.id, directory.name]));
return <TopicsSubtopicsPreview workspaceId={params.workspaceId} directoryMap={directoryMap} />;
}
+1 -1
View File
@@ -5,7 +5,6 @@ import { TAuthenticationApiKey } from "@formbricks/types/auth";
import { authenticateRequest } from "@/app/api/v1/auth";
import { reportApiError } from "@/app/lib/api/api-error-reporter";
import { responses } from "@/app/lib/api/response";
import { getApiKeyFromHeaders } from "@/modules/api/lib/api-key-auth";
import {
AuthenticationMethod,
isClientSideApiRoute,
@@ -13,6 +12,7 @@ import {
isManagementApiRoute,
} from "@/app/middleware/endpoint-validator";
import { AUDIT_LOG_ENABLED } from "@/lib/constants";
import { getApiKeyFromHeaders } from "@/modules/api/lib/api-key-auth";
import { authOptions } from "@/modules/auth/lib/authOptions";
import {
TEnvoyRateLimitAuthType,
+29 -14
View File
@@ -407,7 +407,6 @@ checksums:
common/some_files_failed_to_upload: a0e26efeb29ae905257ecf93b112dff0
common/something_went_wrong: a3cd2f01c073f1f5ff436d4b132d39cf
common/something_went_wrong_please_try_again: c62a7718d9a1e9c4ffb707807550f836
common/soon: b12e79beb0aef9414a445a1b95dd4322
common/sort_by: 8adf3dbc5668379558957662f0c43563
common/start_free_trial: e346e4ed7d138dcc873db187922369da
common/status: 4e1fcce15854d824919b4a582c697c90
@@ -1681,7 +1680,7 @@ checksums:
workspace/analysis/charts/filter_data: 05cc68ed2896feef60bbe3829cd9063d
workspace/analysis/charts/filters: acf5accc113ff3c1992688058576732c
workspace/analysis/charts/filters_toggle_description: ea18bdb212a6a85620125cab89a4b1c1
workspace/analysis/charts/go_to_feedback_directories: 1aa0516beef8adbd330cffdcab8b521f
workspace/analysis/charts/go_to_feedback_directories: b19da1bfdf0a7d457c7e53532b871f60
workspace/analysis/charts/granularity: 9eb09aef092e7803ce4acb7965cbbaa9
workspace/analysis/charts/granularity_day: 47648cd60fc313bc3f05b70357a1d675
workspace/analysis/charts/granularity_hour: ec3113f22fc51d01f0c615c5496f8f87
@@ -1705,7 +1704,7 @@ checksums:
workspace/analysis/charts/no_data_available: fe1d34a45e22b5611d255b84b2d67232
workspace/analysis/charts/no_data_returned: 683acf7b4f3b32aa85fa26f1bb948d4f
workspace/analysis/charts/no_data_returned_for_chart: b9ff6c85697c683f40b3d0c05eeb2046
workspace/analysis/charts/no_data_source_available: 48179160e288de4a9e00f0bf110a5ced
workspace/analysis/charts/no_data_source_available: 17e92fdef044caf6d3bb36f834b9f977
workspace/analysis/charts/no_grouping: e3a6943e61407600cae057e0833a482d
workspace/analysis/charts/no_valid_data_to_display: d1ba2b0686520c0a2c62ee73daa1c9c9
workspace/analysis/charts/not_contains: 5894f5474271b8902d7892e43500d227
@@ -1779,10 +1778,10 @@ checksums:
workspace/api_keys/api_key_updated: 0e03754eb33742b4ee8d5fdad64c9b3f
workspace/api_keys/delete_api_key_confirmation: b2f0342d4e55f0cb244fe121eeeb10a3
workspace/api_keys/duplicate_access: 7ac7ac5ba755ce94e6fc81afa5a21997
workspace/api_keys/duplicate_directory_access: e112b756627f0b5e2551451274c3781f
workspace/api_keys/feedback_directory_access: 51babe735cb94388f68108555814b4f6
workspace/api_keys/duplicate_directory_access: 4230950c0bf6ebf23410b04627fb7bd3
workspace/api_keys/feedback_directory_access: 6de029dfe5192496d06a7bbf0f52effd
workspace/api_keys/no_api_keys_yet: 58593ed9f7e507dcd7ca7fe069add599
workspace/api_keys/no_directory_permissions_found: ae55b273dd4c71d8431d64d99b39c59f
workspace/api_keys/no_directory_permissions_found: 8296e96142af0f8b98ff62535f42fc5c
workspace/api_keys/no_workspace_permissions_found: 1d719624828a9d3e433cdf6b387549f3
workspace/api_keys/organization_access: 96a92fa907b15e0c0e47e33cac15be88
workspace/api_keys/organization_access_description: 773dfeaf6ffbf34dd9a0a3d656a6d83c
@@ -2435,10 +2434,10 @@ checksums:
workspace/settings/feedback_directories/archive_directory: 1114a8e1c5c5af3d30a174b28582f424
workspace/settings/feedback_directories/archive_not_allowed: 3ffe3336572a633406858887de60a470
workspace/settings/feedback_directories/are_you_sure_you_want_to_archive: d249e6e8bc0345835a13f70856eb1c30
workspace/settings/feedback_directories/assign_workspaces_description: 6c3f0bbf3bd7744bb313f4cd7886e184
workspace/settings/feedback_directories/assign_workspaces_description: 182522a7d2eedb04b2770b1555adfb41
workspace/settings/feedback_directories/connectors_description: 6efec0b94291db18124e8bfb1ced7e89
workspace/settings/feedback_directories/create_feedback_directory: c178dd6dbd702398df3ac08a9fa43324
workspace/settings/feedback_directories/description: 8f56b169cb38d8c7b2697bf3a3ed7a61
workspace/settings/feedback_directories/description: 2054e053da5c3708388aa538a7bcb180
workspace/settings/feedback_directories/directory_archived_successfully: fba5b99ced59d0546c8f2241c092a5dd
workspace/settings/feedback_directories/directory_created_successfully: 5db20153b840d91842543f71cdd91043
workspace/settings/feedback_directories/directory_id: 933a1376d7d8a8dc41ded90ef1c0f619
@@ -2447,20 +2446,20 @@ checksums:
workspace/settings/feedback_directories/directory_settings_title: c32af860e3254dea9dfaeefc7cd92d49
workspace/settings/feedback_directories/directory_unarchived_successfully: 08d56e260decc62fe664b50ab774b728
workspace/settings/feedback_directories/directory_updated_successfully: 638cb6c92f535328d809274cf2be4d7d
workspace/settings/feedback_directories/empty_state: 665593dcb7cfa081a3e719677d0f6b0d
workspace/settings/feedback_directories/empty_state: 5c78f7469c3730895735e00b008df2d3
workspace/settings/feedback_directories/error_directory_has_connectors: 792ca3a69d639f4fb602dd72daf5a806
workspace/settings/feedback_directories/error_directory_name_duplicate: 349d650f562cff96b084787126323ca2
workspace/settings/feedback_directories/error_directory_name_duplicate: 723aeaee8d7fc94ee5f6bb7157208058
workspace/settings/feedback_directories/error_directory_name_required: 0f42d7292979006a1069063ab213b8e3
workspace/settings/feedback_directories/error_directory_workspaces_invalid_org: 477b5c1a466c4194668544ffd42ec9bf
workspace/settings/feedback_directories/error_workspace_already_assigned: 6f851ad28a4e91e48fe13da917ea1ae0
workspace/settings/feedback_directories/nav_label: cf9a57b3cbac0f04b98e06fb693e986e
workspace/settings/feedback_directories/no_access: cc3385cd01a11e3949003a2cc6fb5b31
workspace/settings/feedback_directories/no_access: 707627df25fbaa28f18aa0f0d03dcb81
workspace/settings/feedback_directories/no_connectors: b1becb4fe4e2ba7c5d277db149f092ff
workspace/settings/feedback_directories/pause_connectors_confirmation_description: a3c2c56daed9f2a9e6a853cb8b924bad
workspace/settings/feedback_directories/pause_connectors_confirmation_title: 09041363c55fb2686f8115df6fa2afc1
workspace/settings/feedback_directories/select_workspaces_placeholder: 7d8c8f5910b264525f73bd32107765db
workspace/settings/feedback_directories/show_archived: c4c1c3bbddc1bb1540c079b589a2d3de
workspace/settings/feedback_directories/title: e3d425c27f80162f29ce094e31a3fd8f
workspace/settings/feedback_directories/title: cf9a57b3cbac0f04b98e06fb693e986e
workspace/settings/feedback_directories/unarchive: 671fc7e9d7c8cb4d182a25a46551c168
workspace/settings/feedback_directories/unarchive_workspace_conflict: 82f4b8ebaf41589cfb96e6398dafcc76
workspace/settings/feedback_directories/workspace_access: 32407b39cf878fb579559c1ed3660892
@@ -3520,10 +3519,10 @@ checksums:
workspace/unify/enum: 96fc644f35edd6b1c09d1d503f078acc
workspace/unify/failed_to_load_feedback_records: 57f6c8c5fa524d7c2d8777315e5036c8
workspace/unify/feedback_date: ddba5d3270d4a6394d29721025a04400
workspace/unify/feedback_directory: 156fa9957e1ee5eadf1f44226a2365e4
workspace/unify/feedback_record_created_successfully: 0ff30472085f1313a5ad53837c83e7c1
workspace/unify/feedback_record_details: 823f3353db049a9d263ef31405054cda
workspace/unify/feedback_record_details_description: 0b6f908154161241ce6bdeb4a2acaecd
workspace/unify/feedback_directory: 89a08a540d1c6eb9f0b1a4b8f56e8aca
workspace/unify/feedback_record_fields: 88c0f13afeb88fe751f85e79b0f73064
workspace/unify/feedback_record_mcp: cdddbef2944489820fd7f376a49c2803
workspace/unify/feedback_record_updated_successfully: cb40ef4b924e21fa627ebe6809d1d826
@@ -3560,7 +3559,7 @@ checksums:
workspace/unify/metadata_read_only_entries: 1934fee46c0a117f4926b61cc3d2d602
workspace/unify/metadata_value: 8d69be1f5a20d9473a33c35670dff216
workspace/unify/missing_feedback_source_title: 9ab1b8d54b4da72dd00ce03fe3b698b5
workspace/unify/no_feedback_directory_available: b8126ef5d6276d9655a9b27ffcaca824
workspace/unify/no_feedback_directory_available: b9854a7e35eb20c157f994d23149f36c
workspace/unify/no_feedback_records: 16a905c40f6d47a5e8f93b3d8c6f6693
workspace/unify/no_source_fields_loaded: a597b1d16262cbe897001046eb3ff640
workspace/unify/no_sources_connected: 0e8a5612530bfc82091091f40f95012f
@@ -3572,6 +3571,7 @@ checksums:
workspace/unify/request_feedback_source: 51045caa2c81dee971d23a1841d19a7e
workspace/unify/required: 04d7fb6f37ffe0a6ca97d49e2a8b6eb5
workspace/unify/save_changes: 53dd9f4f0a4accc822fa5c1f2f6d118a
workspace/unify/search_feedback: db1e8dd05944bb928b96e3822aee3379
workspace/unify/select_a_survey_to_see_questions: 792eba3d2f6d210231a2266401111a20
workspace/unify/select_a_value: 115002bf2d9eec536165a7b7efc62862
workspace/unify/select_feedback_directory: 88afbf2c2a322249908ee5d00ec5f65d
@@ -3581,6 +3581,20 @@ checksums:
workspace/unify/select_survey: bac52e59c7847417bef6fe7b7096b475
workspace/unify/select_survey_and_questions: 53914988a2f48caecea23f3b3b868b9f
workspace/unify/select_survey_questions_description: 3386ed56085eabebefa3cc453269fc5b
workspace/unify/semantic_search_failed: 6adf5f85d453ef2923861ad7b188787a
workspace/unify/semantic_search_input_label: 3b8af322b080da8b8cb4fcce6c3f3d1e
workspace/unify/semantic_search_missing_text: e1ad1ba8f3ab2e05f4f73732543d0ed5
workspace/unify/semantic_search_no_directories: 2bcebe10f5898f5422ee17ed66295044
workspace/unify/semantic_search_no_results: 50f0572ad7584c91af5a0a28523f40f2
workspace/unify/semantic_search_placeholder: b5dbff2cdd334d7b86f18a12c56ffbb1
workspace/unify/semantic_search_relevance: ddd1a91cd29944d5af7b899168b988a2
workspace/unify/semantic_search_results_count: 199b822e4f709787b79dd42ccd70e58f
workspace/unify/semantic_search_unavailable: eb66fd42fc327627e74fe54a76f33b16
workspace/unify/semantic_topics_example_confusing_onboarding: ac612953829e6a7f58e34796a472ca71
workspace/unify/semantic_topics_example_pricing_complaints: fdf96d24d56620f79c31de48e6c1936b
workspace/unify/semantic_topics_example_slow_checkout: 42579a662e637ffe40de7078def55805
workspace/unify/semantic_topics_preview_description: 330871cf6f36128bfdbc7d9d20c500a4
workspace/unify/semantic_topics_preview_title: 2d59d672921b4807a40770e5d40b485e
workspace/unify/set_value: b8a86f8da957ebd599ece4b1b1936a78
workspace/unify/setup_connection: cce7d9c488d737d04e70bed929a46f8a
workspace/unify/showing_count_loaded: f443aae08223b65fbd5521d6e69534a4
@@ -3608,6 +3622,7 @@ checksums:
workspace/unify/submission_id: 02edf76883b47079dbe20f3f36b7c1a7
workspace/unify/survey_has_no_questions: c08514b6bce5eb464a4492239be5934d
workspace/unify/topics_and_subtopics: 1148eca01a1993fadca932efcdea7641
workspace/unify/try_searching_for: 8bc02885a2efdc53d7323aac26ae1110
workspace/unify/unify_feedback: cd68c8ce0445767e7dcfb4de789903d5
workspace/unify/update_mapping_description: 58d5966c0c9b406c037dff3aa8bcb396
workspace/unify/updated_at: 8fdb85248e591254973403755dcc3724
+4 -4
View File
@@ -3,17 +3,17 @@ import { beforeEach, describe, expect, test, vi } from "vitest";
import { prisma } from "@formbricks/database";
import * as crypto from "@/lib/crypto";
import {
createGatewayServiceToken,
createFeedbackRecordsGatewayToken,
createEmailChangeToken,
createEmailToken,
createFeedbackRecordsGatewayToken,
createGatewayServiceToken,
createInviteToken,
createToken,
createTokenForLinkSurvey,
getEmailFromEmailToken,
verifyGatewayServiceToken,
verifyFeedbackRecordsGatewayToken,
verifyEmailChangeToken,
verifyFeedbackRecordsGatewayToken,
verifyGatewayServiceToken,
verifyInviteToken,
verifyToken,
verifyTokenForLinkSurvey,
+9 -3
View File
@@ -3,7 +3,7 @@ import { prisma } from "@formbricks/database";
import { logger } from "@formbricks/logger";
import { ENCRYPTION_KEY, NEXTAUTH_SECRET } from "@/lib/constants";
import { symmetricDecrypt, symmetricEncrypt } from "@/lib/crypto";
import { getGatewayAuthServiceTokenPurpose, TGatewayAuthService } from "@/modules/gateway-auth/lib/service";
import { TGatewayAuthService, getGatewayAuthServiceTokenPurpose } from "@/modules/gateway-auth/lib/service";
const FEEDBACK_RECORDS_GATEWAY_TOKEN_TTL_SECONDS = 60 * 10;
@@ -29,7 +29,10 @@ export const createToken = (userId: string, options = {}): string => {
return jwt.sign({ id: encryptedUserId }, NEXTAUTH_SECRET, options);
};
export const createGatewayServiceToken = (userId: string, service: TGatewayAuthService): {
export const createGatewayServiceToken = (
userId: string,
service: TGatewayAuthService
): {
token: string;
expiresAt: string;
} => {
@@ -104,7 +107,10 @@ export const verifyEmailChangeToken = async (token: string): Promise<{ id: strin
};
};
export const verifyGatewayServiceToken = (token: string, service: TGatewayAuthService): {
export const verifyGatewayServiceToken = (
token: string,
service: TGatewayAuthService
): {
userId: string;
} => {
if (!NEXTAUTH_SECRET) {
+23 -8
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Einige Dateien konnten nicht hochgeladen werden",
"something_went_wrong": "Etwas ist schiefgelaufen",
"something_went_wrong_please_try_again": "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
"soon": "Bald",
"sort_by": "Sortieren nach",
"start_free_trial": "Kostenlose Testversion starten",
"status": "Status",
@@ -1746,7 +1745,7 @@
"filter_data": "Daten filtern",
"filters": "Filter",
"filters_toggle_description": "Nur Daten einbeziehen, die die folgenden Bedingungen erfüllen.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Zu Feedback-Verzeichnissen gehen",
"granularity": "Granularität",
"granularity_day": "Tag",
"granularity_hour": "Stunde",
@@ -1770,7 +1769,7 @@
"no_data_available": "Keine Daten verfügbar",
"no_data_returned": "Keine Daten von der Abfrage zurückgegeben",
"no_data_returned_for_chart": "Keine Daten für Diagramm zurückgegeben",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Diesem Workspace ist kein Feedback-Verzeichnis zugewiesen.",
"no_grouping": "Keine (nur Filter)",
"no_valid_data_to_display": "Keine gültigen Daten zur Anzeige",
"not_contains": "enthält nicht",
@@ -1850,9 +1849,9 @@
"delete_api_key_confirmation": "Alle Anwendungen, die diesen Schlüssel verwenden, können nicht mehr auf deine Formbricks-Daten zugreifen.",
"duplicate_access": "Doppelter Workspace-Zugriff ist nicht erlaubt",
"duplicate_directory_access": "Doppelter Zugriff auf Feedback-Verzeichnis nicht erlaubt",
"feedback_directory_access": "Zugriff auf Feedback-Verzeichnis",
"feedback_directory_access": "Feedback-Verzeichnis-Zugriff",
"no_api_keys_yet": "Du hast noch keine API-Schlüssel",
"no_directory_permissions_found": "Keine Berechtigungen für Feedback-Verzeichnis gefunden",
"no_directory_permissions_found": "Keine Berechtigungen für Feedback-Verzeichnisse gefunden",
"no_workspace_permissions_found": "Keine Workspace-Berechtigungen gefunden",
"organization_access": "Organisations-Zugriff",
"organization_access_description": "Wähle Lese- oder Schreibrechte für organisationsweite Ressourcen aus.",
@@ -2542,10 +2541,10 @@
"archive_directory": "Verzeichnis archivieren",
"archive_not_allowed": "Du darfst dieses Verzeichnis nicht archivieren.",
"are_you_sure_you_want_to_archive": "Bist du sicher, dass du dieses Verzeichnis archivieren möchtest? Workspaces haben dann keinen Zugriff mehr darauf.",
"assign_workspaces_description": "Lege fest, welche Workspaces auf dieses Feedback-Verzeichnis zugreifen können.",
"assign_workspaces_description": "Steuere, welche Workspaces auf dieses Feedback-Verzeichnis zugreifen können.",
"connectors_description": "Connectoren, die Feedback-Datensätze an dieses Verzeichnis senden.",
"create_feedback_directory": "Feedback-Verzeichnis erstellen",
"description": "Verwalte Feedback-Verzeichnisse und ihre Workspace-Zuordnungen.",
"description": "Verwalte Feedback-Verzeichnisse und ihre Workspace-Zuweisungen.",
"directory_archived_successfully": "Verzeichnis erfolgreich archiviert",
"directory_created_successfully": "Verzeichnis erfolgreich erstellt",
"directory_id": "Verzeichnis-ID",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Schreibgeschützte Metadatenwerte (keine Zeichenfolge)",
"metadata_value": "Metadatenwert",
"missing_feedback_source_title": "Feedback-Quelle fehlt?",
"no_feedback_directory_available": "Diesem Workspace ist kein Feedback-Verzeichnis zugewiesen. Erstelle oder weise zuerst eines zu.",
"no_feedback_directory_available": "Diesem Workspace ist kein Feedback-Verzeichnis zugewiesen. Erstelle oder weise zuerst eins zu.",
"no_feedback_records": "Noch keine Feedback-Einträge vorhanden. Einträge erscheinen hier, sobald deine Konnektoren Daten senden.",
"no_source_fields_loaded": "Noch keine Quellfelder geladen",
"no_sources_connected": "Noch keine Quellen verbunden. Füge eine Quelle hinzu, um loszulegen.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Quellen-Integration anfragen",
"required": "Erforderlich",
"save_changes": "Änderungen speichern",
"search_feedback": "Feedback durchsuchen",
"select_a_survey_to_see_questions": "Wähle eine Umfrage aus, um ihre Fragen zu sehen",
"select_a_value": "Wähle einen Wert aus...",
"select_feedback_directory": "Verzeichnis auswählen",
@@ -3741,6 +3741,20 @@
"select_survey": "Umfrage auswählen",
"select_survey_and_questions": "Umfrage & Fragen auswählen",
"select_survey_questions_description": "Wähle aus, welche Umfragefragen FeedbackRecords erstellen sollen.",
"semantic_search_failed": "Suche nach Feedback-Einträgen fehlgeschlagen",
"semantic_search_input_label": "Feedback-Einträge nach Thema durchsuchen",
"semantic_search_missing_text": "Dieser Feedback-Eintrag hat keinen anzuzeigenden Text.",
"semantic_search_no_directories": "Diesem Workspace ist noch kein Feedback-Verzeichnis zugewiesen. Füge eine Feedback-Quelle hinzu, um Feedback nach Bedeutung zu durchsuchen.",
"semantic_search_no_results": "Keine passenden Feedback-Einträge gefunden. Versuche ein breiteres Thema oder eine andere Formulierung.",
"semantic_search_placeholder": "Suche nach einem Thema, z. B. Preisbeschwerden",
"semantic_search_relevance": "{score} % Relevanz",
"semantic_search_results_count": "{count, plural, one {# passender Feedback-Eintrag} other {# passende Feedback-Einträge}}",
"semantic_search_unavailable": "Semantische Suche ist noch nicht verfügbar. Konfiguriere Hub-Embeddings, um diese Vorschau zu nutzen.",
"semantic_topics_example_confusing_onboarding": "verwirrende Einführung",
"semantic_topics_example_pricing_complaints": "Preisbeschwerden",
"semantic_topics_example_slow_checkout": "langsamer Checkout",
"semantic_topics_preview_description": "Gib ein Thema oder einen Begriff ein, um Feedback-Einträge nach Bedeutung zu finden. Dies ist eine frühe Vorschau auf zukünftige Themen & Unterthemen.",
"semantic_topics_preview_title": "Feedback nach Thema durchsuchen",
"set_value": "Wert festlegen",
"setup_connection": "Verbindung einrichten",
"showing_count_loaded": "{count} Datensätze werden angezeigt",
@@ -3768,6 +3782,7 @@
"submission_id": "Einreichungs-ID",
"survey_has_no_questions": "Diese Umfrage hat keine Fragen",
"topics_and_subtopics": "Themen & Unterthemen",
"try_searching_for": "Versuche zu suchen nach",
"unify_feedback": "Feedback vereinheitlichen",
"update_mapping_description": "Aktualisiere die Zuordnungskonfiguration für diese Quelle.",
"updated_at": "Aktualisiert am",
+16 -1
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Some files failed to upload",
"something_went_wrong": "Something went wrong",
"something_went_wrong_please_try_again": "Something went wrong. Please try again.",
"soon": "Soon",
"sort_by": "Sort by",
"start_free_trial": "Start free trial",
"status": "Status",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Request source integration",
"required": "Required",
"save_changes": "Save changes",
"search_feedback": "Search feedback",
"select_a_survey_to_see_questions": "Select a survey to see its questions",
"select_a_value": "Select a value...",
"select_feedback_directory": "Select a directory",
@@ -3741,6 +3741,20 @@
"select_survey": "Select Survey",
"select_survey_and_questions": "Select Survey & Questions",
"select_survey_questions_description": "Choose which survey questions should create FeedbackRecords.",
"semantic_search_failed": "Failed to search feedback records",
"semantic_search_input_label": "Search feedback records by topic",
"semantic_search_missing_text": "This feedback record has no text to display.",
"semantic_search_no_directories": "No feedback record directory is assigned to this workspace yet. Add a feedback source to start searching feedback by meaning.",
"semantic_search_no_results": "No matching feedback records found. Try a broader topic or a different phrase.",
"semantic_search_placeholder": "Search for a topic, e.g. pricing complaints",
"semantic_search_relevance": "{score}% relevance",
"semantic_search_results_count": "{count, plural, one {# matching feedback record} other {# matching feedback records}}",
"semantic_search_unavailable": "Semantic search is not available yet. Configure Hub embeddings to use this preview.",
"semantic_topics_example_confusing_onboarding": "confusing onboarding",
"semantic_topics_example_pricing_complaints": "pricing complaints",
"semantic_topics_example_slow_checkout": "slow checkout",
"semantic_topics_preview_description": "Enter a topic or phrase to surface feedback records by meaning. This is an early preview of future Topics & Subtopics.",
"semantic_topics_preview_title": "Search feedback by topic",
"set_value": "set value",
"setup_connection": "Setup connection",
"showing_count_loaded": "Showing {count} records",
@@ -3768,6 +3782,7 @@
"submission_id": "Submission ID",
"survey_has_no_questions": "This survey has no questions",
"topics_and_subtopics": "Topics & Subtopics",
"try_searching_for": "Try searching for",
"unify_feedback": "Unify Feedback",
"update_mapping_description": "Update the mapping configuration for this source.",
"updated_at": "Updated at",
+24 -9
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Algunos archivos no se han podido subir",
"something_went_wrong": "Algo ha salido mal",
"something_went_wrong_please_try_again": "Algo ha salido mal. Por favor, inténtalo de nuevo.",
"soon": "Próximamente",
"sort_by": "Ordenar por",
"start_free_trial": "Iniciar prueba gratuita",
"status": "Estado",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrar datos",
"filters": "Filtros",
"filters_toggle_description": "Incluye solo los datos que cumplan las siguientes condiciones.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Ir a directorios de feedback",
"granularity": "Granularidad",
"granularity_day": "Día",
"granularity_hour": "Hora",
@@ -1770,7 +1769,7 @@
"no_data_available": "No hay datos disponibles",
"no_data_returned": "La consulta no ha devuelto datos",
"no_data_returned_for_chart": "No se han devuelto datos para el gráfico",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "No hay ningún directorio de feedback asignado a este espacio de trabajo.",
"no_grouping": "Ninguno (solo filtro)",
"no_valid_data_to_display": "No hay datos válidos para mostrar",
"not_contains": "no contiene",
@@ -1850,9 +1849,9 @@
"delete_api_key_confirmation": "Cualquier aplicación que use esta clave ya no podrá acceder a tus datos de Formbricks.",
"duplicate_access": "No se permite el acceso duplicado al espacio de trabajo",
"duplicate_directory_access": "No se permite el acceso duplicado al directorio de feedback",
"feedback_directory_access": "Acceso al Directorio de Feedback",
"feedback_directory_access": "Acceso al directorio de feedback",
"no_api_keys_yet": "Aún no tienes ninguna clave API",
"no_directory_permissions_found": "No se encontraron permisos de directorio de feedback",
"no_directory_permissions_found": "No se encontraron permisos para el directorio de feedback",
"no_workspace_permissions_found": "No se encontraron permisos del espacio de trabajo",
"organization_access": "Acceso a la organización",
"organization_access_description": "Selecciona privilegios de lectura o escritura para recursos de toda la organización.",
@@ -2561,13 +2560,13 @@
"error_directory_workspaces_invalid_org": "Algunos de los espacios de trabajo especificados no pertenecen a esta organización.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Directorios de Feedback",
"no_access": "No tienes permiso para gestionar los directorios de feedback.",
"no_access": "No tienes permiso para gestionar directorios de feedback.",
"no_connectors": "Aún no hay conectores vinculados a este directorio.",
"pause_connectors_confirmation_description": "Si pausas estos conectores, no se añadirán nuevos registros.",
"pause_connectors_confirmation_title": "¿Pausar conectores vinculados?",
"select_workspaces_placeholder": "Selecciona espacios de trabajo...",
"show_archived": "Mostrar archivados",
"title": "Directorios de Feedback",
"title": "Directorios de feedback",
"unarchive": "Desarchivar",
"unarchive_workspace_conflict": "No se puede desarchivar este directorio porque uno o más espacios de trabajo asignados están archivados.",
"workspace_access": "Acceso al espacio de trabajo"
@@ -3680,7 +3679,7 @@
"enum": "enum",
"failed_to_load_feedback_records": "Error al cargar los registros de comentarios",
"feedback_date": "Fecha actual",
"feedback_directory": "Directorio de Feedback",
"feedback_directory": "Directorio de feedback",
"feedback_record_created_successfully": "Registro de comentarios creado correctamente",
"feedback_record_details": "Detalles del registro de comentarios",
"feedback_record_details_description": "Revise y actualice los campos del registro de comentarios.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Valores de metadatos de solo lectura (no cadenas)",
"metadata_value": "Valor de metadatos",
"missing_feedback_source_title": "¿Falta alguna fuente de feedback?",
"no_feedback_directory_available": "No hay ningún directorio de feedback asignado a este espacio de trabajo. Crea o asigna uno primero.",
"no_feedback_directory_available": "No hay ningún directorio de feedback asignado a este espacio de trabajo. Primero crea o asigna uno.",
"no_feedback_records": "Aún no hay registros de comentarios. Los registros aparecerán aquí una vez que tus conectores empiecen a enviar datos.",
"no_source_fields_loaded": "Aún no se han cargado campos de origen",
"no_sources_connected": "Aún no hay fuentes conectadas. Añade una fuente para empezar.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Solicitar integración de fuente",
"required": "Obligatorio",
"save_changes": "Guardar cambios",
"search_feedback": "Buscar feedback",
"select_a_survey_to_see_questions": "Selecciona una encuesta para ver sus preguntas",
"select_a_value": "Selecciona un valor...",
"select_feedback_directory": "Selecciona un directorio",
@@ -3741,6 +3741,20 @@
"select_survey": "Seleccionar encuesta",
"select_survey_and_questions": "Seleccionar encuesta y preguntas",
"select_survey_questions_description": "Elige qué preguntas de la encuesta deben crear FeedbackRecords.",
"semantic_search_failed": "No se pudieron buscar los registros de feedback",
"semantic_search_input_label": "Buscar registros de feedback por tema",
"semantic_search_missing_text": "Este registro de feedback no tiene texto para mostrar.",
"semantic_search_no_directories": "Todavía no hay ningún directorio de registros de feedback asignado a este espacio de trabajo. Añade una fuente de feedback para empezar a buscar feedback por significado.",
"semantic_search_no_results": "No se encontraron registros de feedback coincidentes. Prueba con un tema más amplio o una frase diferente.",
"semantic_search_placeholder": "Busca un tema, por ejemplo, quejas sobre precios",
"semantic_search_relevance": "{score}% de relevancia",
"semantic_search_results_count": "{count, plural, one {# registro de feedback coincidente} other {# registros de feedback coincidentes}}",
"semantic_search_unavailable": "La búsqueda semántica aún no está disponible. Configura los embeddings del Hub para usar esta vista previa.",
"semantic_topics_example_confusing_onboarding": "onboarding confuso",
"semantic_topics_example_pricing_complaints": "quejas sobre precios",
"semantic_topics_example_slow_checkout": "proceso de pago lento",
"semantic_topics_preview_description": "Introduce un tema o frase para encontrar registros de comentarios por significado. Esta es una vista previa temprana de futuros Temas y Subtemas.",
"semantic_topics_preview_title": "Buscar comentarios por tema",
"set_value": "establecer valor",
"setup_connection": "Configurar conexión",
"showing_count_loaded": "Mostrando {count} registros",
@@ -3768,6 +3782,7 @@
"submission_id": "ID de envío",
"survey_has_no_questions": "Esta encuesta no tiene preguntas",
"topics_and_subtopics": "Temas y subtemas",
"try_searching_for": "Prueba a buscar",
"unify_feedback": "Unificar feedback",
"update_mapping_description": "Actualiza la configuración de mapeo para esta fuente.",
"updated_at": "Actualizado el",
+29 -14
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Certains fichiers n'ont pas pu être téléchargés",
"something_went_wrong": "Quelque chose s'est mal passé.",
"something_went_wrong_please_try_again": "Une erreur s'est produite. Veuillez réessayer.",
"soon": "Bientôt",
"sort_by": "Trier par",
"start_free_trial": "Commencer l'essai gratuit",
"status": "Statut",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrer les données",
"filters": "Filtres",
"filters_toggle_description": "Inclure uniquement les données qui répondent aux conditions suivantes.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Accéder aux répertoires de retours",
"granularity": "Granularité",
"granularity_day": "Jour",
"granularity_hour": "Heure",
@@ -1770,7 +1769,7 @@
"no_data_available": "Aucune donnée disponible",
"no_data_returned": "Aucune donnée retournée par la requête",
"no_data_returned_for_chart": "Aucune donnée retournée pour le graphique",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Aucun répertoire de retours n'est attribué à cet espace de travail.",
"no_grouping": "Aucun (filtre uniquement)",
"no_valid_data_to_display": "Aucune donnée valide à afficher",
"not_contains": "ne contient pas",
@@ -1849,10 +1848,10 @@
"api_key_updated": "Clé API mise à jour",
"delete_api_key_confirmation": "Toute application utilisant cette clé ne pourra plus accéder à vos données Formbricks.",
"duplicate_access": "Accès en double à l'espace de travail non autorisé",
"duplicate_directory_access": "L'accès en double au répertoire de feedback n'est pas autorisé",
"feedback_directory_access": "Accès au répertoire de feedback",
"duplicate_directory_access": "L'accès en double au répertoire de retours n'est pas autorisé",
"feedback_directory_access": "Accès au répertoire de retours",
"no_api_keys_yet": "Vous n'avez pas encore de clés API",
"no_directory_permissions_found": "Aucune autorisation de répertoire de feedback trouvée",
"no_directory_permissions_found": "Aucune autorisation de répertoire de retours trouvée",
"no_workspace_permissions_found": "Aucune autorisation d'espace de travail trouvée",
"organization_access": "Accès à l'organisation",
"organization_access_description": "Sélectionnez les privilèges de lecture ou d'écriture pour les ressources à l'échelle de l'organisation.",
@@ -2542,10 +2541,10 @@
"archive_directory": "Archiver le répertoire",
"archive_not_allowed": "Vous n'êtes pas autorisé à archiver ce répertoire.",
"are_you_sure_you_want_to_archive": "Es-tu sûr de vouloir archiver ce répertoire ? Les espaces de travail n'y auront plus accès.",
"assign_workspaces_description": "Contrôle quels espaces de travail peuvent accéder à ce répertoire de feedback.",
"assign_workspaces_description": "Contrôle quels espaces de travail peuvent accéder à ce répertoire de retours.",
"connectors_description": "Connecteurs qui envoient des enregistrements de retour d'expérience vers ce répertoire.",
"create_feedback_directory": "Créer un répertoire de commentaires",
"description": "Gère les répertoires de feedback et leurs affectations aux espaces de travail.",
"description": "Gère les répertoires de retours et leurs attributions d'espaces de travail.",
"directory_archived_successfully": "Répertoire archivé avec succès",
"directory_created_successfully": "Répertoire créé avec succès",
"directory_id": "ID du répertoire",
@@ -2554,20 +2553,20 @@
"directory_settings_title": "Paramètres de {directoryName}",
"directory_unarchived_successfully": "Répertoire désarchivé avec succès",
"directory_updated_successfully": "Répertoire mis à jour avec succès",
"empty_state": "Aucun répertoire de feedback trouvé. Crée-en un pour commencer.",
"empty_state": "Aucun répertoire de retours trouvé. Crée-en un pour commencer.",
"error_directory_has_connectors": "Impossible d'archiver un répertoire auquel des connecteurs sont liés. Supprimez d'abord tous les connecteurs.",
"error_directory_name_duplicate": "Un répertoire de feedback avec ce nom existe déjà.",
"error_directory_name_duplicate": "Un répertoire de retours avec ce nom existe déjà.",
"error_directory_name_required": "Le nom du répertoire est requis.",
"error_directory_workspaces_invalid_org": "Certains espaces de travail spécifiés n'appartiennent pas à cette organisation.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Répertoires de feedback",
"no_access": "Tu n'as pas la permission de gérer les répertoires de feedback.",
"no_access": "Tu n'as pas la permission de gérer les répertoires de retours.",
"no_connectors": "Aucun connecteur lié à ce répertoire pour le moment.",
"pause_connectors_confirmation_description": "Si vous mettez ces connecteurs en pause, aucun nouvel enregistrement ne sera ajouté.",
"pause_connectors_confirmation_title": "Mettre en pause les connecteurs liés ?",
"select_workspaces_placeholder": "Sélectionner des espaces de travail...",
"show_archived": "Afficher les éléments archivés",
"title": "Répertoires de feedback",
"title": "Répertoires de retours",
"unarchive": "Désarchiver",
"unarchive_workspace_conflict": "Impossible de désarchiver ce répertoire, car un ou plusieurs espaces de travail attribués sont archivés.",
"workspace_access": "Accès à lespace de travail"
@@ -3680,7 +3679,7 @@
"enum": "enum",
"failed_to_load_feedback_records": "Échec du chargement des enregistrements de feedback",
"feedback_date": "Date actuelle",
"feedback_directory": "Répertoire de feedback",
"feedback_directory": "Répertoire de retours",
"feedback_record_created_successfully": "Enregistrement de commentaires créé avec succès",
"feedback_record_details": "Détails de l'enregistrement des commentaires",
"feedback_record_details_description": "Examiner et mettre à jour les champs denregistrement des commentaires.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Valeurs de métadonnées en lecture seule (non-chaîne)",
"metadata_value": "Valeur des métadonnées",
"missing_feedback_source_title": "Il manque une source de feedback ?",
"no_feedback_directory_available": "Aucun répertoire de feedback n'est assigné à cet espace de travail. Créez-en un ou assignez-en un d'abord.",
"no_feedback_directory_available": "Aucun répertoire de retours attribué à cet espace de travail. Crée-en un ou attribue-en un d'abord.",
"no_feedback_records": "Aucun enregistrement de feedback pour le moment. Les enregistrements apparaîtront ici une fois que vos connecteurs commenceront à envoyer des données.",
"no_source_fields_loaded": "Aucun champ source chargé pour le moment",
"no_sources_connected": "Aucune source connectée pour le moment. Ajoutez une source pour commencer.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Demander une intégration de source",
"required": "Requis",
"save_changes": "Enregistrer les modifications",
"search_feedback": "Rechercher des retours",
"select_a_survey_to_see_questions": "Sélectionnez une enquête pour voir ses questions",
"select_a_value": "Sélectionnez une valeur...",
"select_feedback_directory": "Sélectionner un répertoire",
@@ -3741,6 +3741,20 @@
"select_survey": "Sélectionner l'enquête",
"select_survey_and_questions": "Sélectionner l'enquête et les questions",
"select_survey_questions_description": "Choisissez quelles questions d'enquête doivent créer des FeedbackRecords.",
"semantic_search_failed": "Échec de la recherche des enregistrements de retours",
"semantic_search_input_label": "Recherche des enregistrements de retours par sujet",
"semantic_search_missing_text": "Cet enregistrement de retours n'a pas de texte à afficher.",
"semantic_search_no_directories": "Aucun répertoire d'enregistrements de retours n'est encore attribué à cet espace de travail. Ajoute une source de retours pour commencer à rechercher des retours par signification.",
"semantic_search_no_results": "Aucun enregistrement de retours correspondant trouvé. Essaie un sujet plus large ou une formulation différente.",
"semantic_search_placeholder": "Recherche un sujet, par ex. plaintes sur les prix",
"semantic_search_relevance": "{score} % de pertinence",
"semantic_search_results_count": "{count, plural, one {# enregistrement de retours correspondant} other {# enregistrements de retours correspondants}}",
"semantic_search_unavailable": "La recherche sémantique n'est pas encore disponible. Configure les embeddings Hub pour utiliser cet aperçu.",
"semantic_topics_example_confusing_onboarding": "intégration confuse",
"semantic_topics_example_pricing_complaints": "plaintes sur les prix",
"semantic_topics_example_slow_checkout": "passage en caisse lent",
"semantic_topics_preview_description": "Saisissez un sujet ou une phrase pour retrouver des retours clients par signification. Ceci est un aperçu des futurs Sujets et Sous-sujets.",
"semantic_topics_preview_title": "Rechercher des retours par sujet",
"set_value": "définir la valeur",
"setup_connection": "Configurer la connexion",
"showing_count_loaded": "Affichage de {count} enregistrements",
@@ -3768,6 +3782,7 @@
"submission_id": "ID de soumission",
"survey_has_no_questions": "Ce sondage n'a pas de questions",
"topics_and_subtopics": "Thèmes et sous-thèmes",
"try_searching_for": "Essayez de rechercher",
"unify_feedback": "Unifier les retours",
"update_mapping_description": "Mettre à jour la configuration de mappage pour cette source.",
"updated_at": "Mis à jour à",
+26 -11
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Néhány fájlt nem sikerült feltölteni",
"something_went_wrong": "Valami probléma történt",
"something_went_wrong_please_try_again": "Valami probléma történt. Próbálja meg újra.",
"soon": "Hamarosan",
"sort_by": "Rendezési sorrend",
"start_free_trial": "Ingyenes próbaidőszak indítása",
"status": "Állapot",
@@ -1746,7 +1745,7 @@
"filter_data": "Adatok szűrése",
"filters": "Szűrők",
"filters_toggle_description": "Csak azokat az adatokat tartalmazza, amelyek megfelelnek a következő feltételeknek.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Ugrás a visszajelzési könyvtárakhoz",
"granularity": "Részletesség",
"granularity_day": "Nap",
"granularity_hour": "óra",
@@ -1770,7 +1769,7 @@
"no_data_available": "Nincsenek elérhető adatok",
"no_data_returned": "A lekérdezés nem adott vissza adatokat",
"no_data_returned_for_chart": "A diagram nem adott vissza adatokat",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Ehhez a munkaterülethez nincs visszajelzési könyvtár hozzárendelve.",
"no_grouping": "Nincs (csak szűrés)",
"no_valid_data_to_display": "Nincsenek megjeleníthető érvényes adatok",
"not_contains": "nem tartalmazza",
@@ -1849,8 +1848,8 @@
"api_key_updated": "API-kulcs frissítve",
"delete_api_key_confirmation": "Az ezt a kulcsot használó bármely alkalmazás többé nem fog tudni hozzáférni a Formbricks adataihoz.",
"duplicate_access": "A kettőzött munkaterület-hozzáférés nem engedélyezett",
"duplicate_directory_access": "A duplikált visszajelzési könyvtár hozzáférése nem engedélyezett",
"feedback_directory_access": "Visszajelzési Könyvtár Hozzáférés",
"duplicate_directory_access": "Duplikált visszajelzési könyvtár hozzáférés nem engedélyezett",
"feedback_directory_access": "Visszajelzési könyvtár hozzáférés",
"no_api_keys_yet": "Még nincs semmilyen API-kulcsa",
"no_directory_permissions_found": "Nem találhatók visszajelzési könyvtár jogosultságok",
"no_workspace_permissions_found": "Nem találhatók munkaterület-jogosultságok",
@@ -2554,20 +2553,20 @@
"directory_settings_title": "{directoryName} beállításai",
"directory_unarchived_successfully": "A könyvtár archiválása sikeresen visszavonva",
"directory_updated_successfully": "A könyvtár sikeresen frissítve",
"empty_state": "Nem található visszajelzési könyvtár. Hozzon létre egyet a kezdéshez.",
"empty_state": "Nem találhatók visszajelzési könyvtárak. Hozzon létre egyet a kezdéshez.",
"error_directory_has_connectors": "Nem archiválható olyan könyvtár, amelyhez csatlakozók vannak társítva. Először távolítson el minden csatlakozót.",
"error_directory_name_duplicate": "Ezzel a névvel már létezik visszajelzési könyvtár.",
"error_directory_name_duplicate": "Már létezik visszajelzési könyvtár ezzel a névvel.",
"error_directory_name_required": "A könyvtár neve kötelező megadni.",
"error_directory_workspaces_invalid_org": "Egyes megadott munkaterületek nem ehhez a szervezethez tartoznak.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Visszajelzési könyvtárak",
"no_access": "Nem rendelkezik jogosultsággal a visszajelzési könyvtárak kezeléséhez.",
"no_access": "Önnek nincs jogosultsága a visszajelzési könyvtárak kezeléséhez.",
"no_connectors": "Még nincsenek csatlakozók társítva ehhez a könyvtárhoz.",
"pause_connectors_confirmation_description": "Ha szünetelteti ezeket a csatlakozókat, nem kerülnek be új rekordok.",
"pause_connectors_confirmation_title": "Szünetelteti a kapcsolódó csatlakozókat?",
"select_workspaces_placeholder": "Munkaterületek kiválasztása...",
"show_archived": "Archivált elemek megjelenítése",
"title": "Visszajelzési Könyvtárak",
"title": "Visszajelzési könyvtárak",
"unarchive": "Archiválás visszavonása",
"unarchive_workspace_conflict": "A könyvtár nem állítható vissza, mert egy vagy több hozzárendelt munkaterület archiválva van.",
"workspace_access": "Munkaterület-hozzáférés"
@@ -3680,7 +3679,7 @@
"enum": "felsorolás",
"failed_to_load_feedback_records": "Nem sikerült betölteni a visszajelzési rekordokat",
"feedback_date": "Aktuális dátum",
"feedback_directory": "Visszajelzési Könyvtár",
"feedback_directory": "Visszajelzési könyvtár",
"feedback_record_created_successfully": "A visszajelzési rekord sikeresen létrehozva",
"feedback_record_details": "A visszajelzési rekord részletei",
"feedback_record_details_description": "Tekintse át és frissítse a visszajelzési rekordmezőket.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Csak olvasható metaadatértékek (nem karakterlánc)",
"metadata_value": "A metaadat értéke",
"missing_feedback_source_title": "Hiányzik egy visszajelzési forrás?",
"no_feedback_directory_available": "Ehhez a munkaterülethez nem tartozik visszajelzési könyvtár. Először hozzon létre vagy rendeljen hozzá egyet.",
"no_feedback_directory_available": "Ehhez a munkaterülethez nincs visszajelzési könyvtár hozzárendelve. Hozzon létre vagy rendeljen hozzá egyet először.",
"no_feedback_records": "Még nincsenek visszajelzési rekordok. A rekordok itt fognak megjelenni, amint a csatlakozók elkezdik küldeni az adatokat.",
"no_source_fields_loaded": "Még nincsenek forrás mezők betöltve",
"no_sources_connected": "Még nincsenek források csatlakoztatva. Adj hozzá egy forrást a kezdéshez.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Forrásintegráció kérése",
"required": "Kötelező",
"save_changes": "Változtatások mentése",
"search_feedback": "Visszajelzések keresése",
"select_a_survey_to_see_questions": "Válassz egy kérdőívet a kérdések megtekintéséhez",
"select_a_value": "Válassz egy értéket...",
"select_feedback_directory": "Válasszon egy könyvtárat",
@@ -3741,6 +3741,20 @@
"select_survey": "Kérdőív kiválasztása",
"select_survey_and_questions": "Kérdőív és kérdések kiválasztása",
"select_survey_questions_description": "Válassza ki, mely kérdőívkérdések hozzanak létre visszajelzési rekordokat.",
"semantic_search_failed": "A visszajelzési rekordok keresése sikertelen",
"semantic_search_input_label": "Visszajelzési rekordok keresése téma szerint",
"semantic_search_missing_text": "Ez a visszajelzési rekord nem tartalmaz megjeleníthető szöveget.",
"semantic_search_no_directories": "Ehhez a munkaterülethez még nincs visszajelzési rekord könyvtár hozzárendelve. Adjon hozzá egy visszajelzési forrást a jelentés szerinti keresés megkezdéséhez.",
"semantic_search_no_results": "Nem találhatók egyező visszajelzési rekordok. Próbálkozzon tágabb témával vagy más kifejezéssel.",
"semantic_search_placeholder": "Keressen egy témát, például árazási panaszok",
"semantic_search_relevance": "{score}% relevancia",
"semantic_search_results_count": "{count, plural, one {# egyező visszajelzési rekord} other {# egyező visszajelzési rekord}}",
"semantic_search_unavailable": "A szemantikai keresés még nem érhető el. Konfigurálja a Hub beágyazásokat az előnézet használatához.",
"semantic_topics_example_confusing_onboarding": "zavaró regisztráció",
"semantic_topics_example_pricing_complaints": "árazási panaszok",
"semantic_topics_example_slow_checkout": "lassú pénztári folyamat",
"semantic_topics_preview_description": "Adjon meg egy témát vagy kifejezést, hogy tartalmilag kapcsolódó visszajelzési bejegyzéseket jelenítsen meg. Ez egy korai előnézet a jövőbeli Témák és Altémák funkcióról.",
"semantic_topics_preview_title": "Visszajelzések keresése téma szerint",
"set_value": "érték beállítása",
"setup_connection": "Kapcsolat beállítása",
"showing_count_loaded": "{count} rekord megjelenítése",
@@ -3768,6 +3782,7 @@
"submission_id": "Beküldés azonosítója",
"survey_has_no_questions": "Ez a felmérés nem tartalmaz kérdéseket",
"topics_and_subtopics": "Témák és altémák",
"try_searching_for": "Próbálja ki a következő keresést",
"unify_feedback": "Visszajelzések egyesítése",
"update_mapping_description": "Frissítse a leképezési konfigurációt ehhez a forráshoz.",
"updated_at": "Frissítve",
+24 -9
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "一部のファイルのアップロードに失敗しました",
"something_went_wrong": "問題が発生しました",
"something_went_wrong_please_try_again": "問題が発生しました。もう一度お試しください。",
"soon": "近日公開",
"sort_by": "並び替え",
"start_free_trial": "無料トライアルを開始",
"status": "ステータス",
@@ -1746,7 +1745,7 @@
"filter_data": "データをフィルター",
"filters": "フィルター",
"filters_toggle_description": "以下の条件を満たすデータのみを含めます。",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "フィードバックディレクトリに移動",
"granularity": "粒度",
"granularity_day": "日",
"granularity_hour": "時間",
@@ -1770,7 +1769,7 @@
"no_data_available": "利用可能なデータがありません",
"no_data_returned": "クエリからデータが返されませんでした",
"no_data_returned_for_chart": "チャートのデータが返されませんでした",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "このワークスペースにはフィードバックディレクトリが割り当てられていません。",
"no_grouping": "なし(フィルターのみ)",
"no_valid_data_to_display": "表示する有効なデータがありません",
"not_contains": "を含まない",
@@ -1849,8 +1848,8 @@
"api_key_updated": "APIキーを更新しました",
"delete_api_key_confirmation": "このキーを使用しているアプリケーションは、Formbricksデータにアクセスできなくなります。",
"duplicate_access": "ワークスペースへの重複アクセスは許可されていません",
"duplicate_directory_access": "重複したフィードバックディレクトリへのアクセスは許可されていません",
"feedback_directory_access": "フィードバックディレクトリへのアクセス",
"duplicate_directory_access": "フィードバックディレクトリへの重複アクセスは許可されていません",
"feedback_directory_access": "フィードバックディレクトリアクセス",
"no_api_keys_yet": "まだAPIキーがありません",
"no_directory_permissions_found": "フィードバックディレクトリの権限が見つかりません",
"no_workspace_permissions_found": "ワークスペースの権限が見つかりません",
@@ -2545,7 +2544,7 @@
"assign_workspaces_description": "このフィードバックディレクトリにアクセスできるワークスペースを管理します。",
"connectors_description": "このディレクトリにフィードバックレコードを送信するコネクタ。",
"create_feedback_directory": "フィードバックディレクトリを作成",
"description": "フィードバックディレクトリとワークスペースの割り当てを管理します。",
"description": "フィードバックディレクトリとワークスペースの割り当てを管理します。",
"directory_archived_successfully": "ディレクトリをアーカイブしました",
"directory_created_successfully": "ディレクトリを作成しました",
"directory_id": "ディレクトリID",
@@ -2554,9 +2553,9 @@
"directory_settings_title": "{directoryName}の設定",
"directory_unarchived_successfully": "ディレクトリのアーカイブを解除しました",
"directory_updated_successfully": "ディレクトリを更新しました",
"empty_state": "フィードバックディレクトリが見つかりません。最初のディレクトリを作成してください。",
"empty_state": "フィードバックディレクトリが見つかりません。作成して始めましょう。",
"error_directory_has_connectors": "コネクタがリンクされているディレクトリはアーカイブできません。まずすべてのコネクタを削除してください。",
"error_directory_name_duplicate": "この名前のフィードバックディレクトリはに存在します。",
"error_directory_name_duplicate": "この名前のフィードバックディレクトリはすでに存在します。",
"error_directory_name_required": "ディレクトリ名は必須です。",
"error_directory_workspaces_invalid_org": "指定されたワークスペースの一部がこの組織に属していません。",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "読み取り専用メタデータ値 (非文字列)",
"metadata_value": "メタデータ値",
"missing_feedback_source_title": "フィードバックソースが見つかりませんか?",
"no_feedback_directory_available": "このワークスペースにフィードバックディレクトリが割り当てられていません。まず作成または割り当てを行ってください。",
"no_feedback_directory_available": "このワークスペースにフィードバックディレクトリが割り当てられていません。まずディレクトリを作成または割り当ててください。",
"no_feedback_records": "フィードバックレコードはまだありません。コネクタがデータの送信を開始すると、ここにレコードが表示されます。",
"no_source_fields_loaded": "ソースフィールドがまだ読み込まれていません",
"no_sources_connected": "ソースがまだ接続されていません。開始するにはソースを追加してください。",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "ソース統合をリクエスト",
"required": "必須",
"save_changes": "変更を保存",
"search_feedback": "フィードバックを検索",
"select_a_survey_to_see_questions": "フォームを選択して質問を表示",
"select_a_value": "値を選択...",
"select_feedback_directory": "ディレクトリを選択",
@@ -3741,6 +3741,20 @@
"select_survey": "フォームを選択",
"select_survey_and_questions": "フォームと質問を選択",
"select_survey_questions_description": "フィードバックレコードを作成するフォームの質問を選択してください。",
"semantic_search_failed": "フィードバック記録の検索に失敗しました",
"semantic_search_input_label": "トピック別にフィードバック記録を検索",
"semantic_search_missing_text": "このフィードバック記録には表示するテキストがありません。",
"semantic_search_no_directories": "このワークスペースにはまだフィードバック記録ディレクトリが割り当てられていません。フィードバックソースを追加して、意味による検索を開始しましょう。",
"semantic_search_no_results": "一致するフィードバック記録が見つかりませんでした。より広いトピックや別のフレーズを試してください。",
"semantic_search_placeholder": "トピックを検索、例: 価格に関する苦情",
"semantic_search_relevance": "関連性 {score}%",
"semantic_search_results_count": "{count, plural, other {# 件のフィードバック記録}}",
"semantic_search_unavailable": "セマンティック検索はまだ利用できません。このプレビューを使用するには、Hub埋め込みを設定してください。",
"semantic_topics_example_confusing_onboarding": "わかりにくいオンボーディング",
"semantic_topics_example_pricing_complaints": "価格に関する苦情",
"semantic_topics_example_slow_checkout": "チェックアウトが遅い",
"semantic_topics_preview_description": "トピックやフレーズを入力すると、意味に基づいてフィードバック記録を表示できます。これは、今後のトピックとサブトピック機能の早期プレビューです。",
"semantic_topics_preview_title": "トピック別にフィードバックを検索",
"set_value": "値を設定",
"setup_connection": "接続を設定",
"showing_count_loaded": "{count}件のレコードを表示中",
@@ -3768,6 +3782,7 @@
"submission_id": "提出ID",
"survey_has_no_questions": "このアンケートには質問がありません",
"topics_and_subtopics": "トピックとサブトピック",
"try_searching_for": "検索してみる",
"unify_feedback": "フィードバックを統合",
"update_mapping_description": "このソースのマッピング設定を更新します。",
"updated_at": "更新日時",
+22 -7
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Sommige bestanden konden niet worden geüpload",
"something_went_wrong": "Er is iets misgegaan",
"something_went_wrong_please_try_again": "Er is iets misgegaan. Probeer het opnieuw.",
"soon": "Binnenkort",
"sort_by": "Sorteer op",
"start_free_trial": "Start gratis proefperiode",
"status": "Status",
@@ -1746,7 +1745,7 @@
"filter_data": "Data filteren",
"filters": "Filters",
"filters_toggle_description": "Neem alleen gegevens op die aan de volgende voorwaarden voldoen.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Ga naar feedbackmappen",
"granularity": "Granulariteit",
"granularity_day": "Dag",
"granularity_hour": "Uur",
@@ -1770,7 +1769,7 @@
"no_data_available": "Geen gegevens beschikbaar",
"no_data_returned": "Geen gegevens geretourneerd uit query",
"no_data_returned_for_chart": "Geen gegevens geretourneerd voor diagram",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Er is geen feedbackmap toegewezen aan deze workspace.",
"no_grouping": "Geen (alleen filteren)",
"no_valid_data_to_display": "Geen geldige gegevens om weer te geven",
"not_contains": "bevat niet",
@@ -1849,10 +1848,10 @@
"api_key_updated": "API-sleutel bijgewerkt",
"delete_api_key_confirmation": "Alle applicaties die deze sleutel gebruiken, hebben geen toegang meer tot uw Formbricks-gegevens.",
"duplicate_access": "Dubbele workspace-toegang niet toegestaan",
"duplicate_directory_access": "Duplicate toegang tot feedbackmap niet toegestaan",
"feedback_directory_access": "Toegang tot Feedbackmap",
"duplicate_directory_access": "Dubbele feedbackmaptoegang niet toegestaan",
"feedback_directory_access": "Feedbackmaptoegang",
"no_api_keys_yet": "U heeft nog geen API-sleutels",
"no_directory_permissions_found": "Geen machtigingen voor feedbackmap gevonden",
"no_directory_permissions_found": "Geen feedbackmaprechten gevonden",
"no_workspace_permissions_found": "Geen Workspace-rechten gevonden",
"organization_access": "Organisatietoegang",
"organization_access_description": "Selecteer lees- of schrijfrechten voor organisatiebrede bronnen.",
@@ -2545,7 +2544,7 @@
"assign_workspaces_description": "Bepaal welke workspaces toegang hebben tot deze feedbackmap.",
"connectors_description": "Connectoren die feedbackrecords naar deze map sturen.",
"create_feedback_directory": "Feedbackmap maken",
"description": "Beheer feedbackmappen en hun workspace-toewijzingen.",
"description": "Beheer feedbackmappen en hun workspacetoewijzingen.",
"directory_archived_successfully": "Map succesvol gearchiveerd",
"directory_created_successfully": "Map succesvol aangemaakt",
"directory_id": "Map-ID",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Bronintegratie aanvragen",
"required": "Vereist",
"save_changes": "Wijzigingen opslaan",
"search_feedback": "Zoek feedback",
"select_a_survey_to_see_questions": "Selecteer een enquête om de vragen te zien",
"select_a_value": "Selecteer een waarde...",
"select_feedback_directory": "Selecteer een map",
@@ -3741,6 +3741,20 @@
"select_survey": "Selecteer enquête",
"select_survey_and_questions": "Selecteer enquête & vragen",
"select_survey_questions_description": "Kies welke enquêtevragen FeedbackRecords moeten aanmaken.",
"semantic_search_failed": "Feedbackrecords zoeken is mislukt",
"semantic_search_input_label": "Zoek feedbackrecords op onderwerp",
"semantic_search_missing_text": "Dit feedbackrecord heeft geen tekst om weer te geven.",
"semantic_search_no_directories": "Er is nog geen feedbackmap toegewezen aan deze workspace. Voeg een feedbackbron toe om te beginnen met zoeken op betekenis.",
"semantic_search_no_results": "Geen overeenkomende feedbackrecords gevonden. Probeer een breder onderwerp of een andere zoekopdracht.",
"semantic_search_placeholder": "Zoek naar een onderwerp, bijv. klachten over prijzen",
"semantic_search_relevance": "{score}% relevant",
"semantic_search_results_count": "{count, plural, one {# overeenkomend feedbackrecord} other {# overeenkomende feedbackrecords}}",
"semantic_search_unavailable": "Semantisch zoeken is nog niet beschikbaar. Configureer Hub-embeddings om deze preview te gebruiken.",
"semantic_topics_example_confusing_onboarding": "verwarrende onboarding",
"semantic_topics_example_pricing_complaints": "klachten over prijzen",
"semantic_topics_example_slow_checkout": "trage afrekening",
"semantic_topics_preview_description": "Voer een onderwerp of zin in om feedbackrecords op betekenis te vinden. Dit is een vroege preview van toekomstige Onderwerpen & Subonderwerpen.",
"semantic_topics_preview_title": "Zoek feedback op onderwerp",
"set_value": "waarde instellen",
"setup_connection": "Verbinding instellen",
"showing_count_loaded": "Er worden {count} records weergegeven",
@@ -3768,6 +3782,7 @@
"submission_id": "Inzendings-ID",
"survey_has_no_questions": "Deze enquête heeft geen vragen",
"topics_and_subtopics": "Onderwerpen en subonderwerpen",
"try_searching_for": "Probeer te zoeken naar",
"unify_feedback": "Feedback verenigen",
"update_mapping_description": "Werk de mappingconfiguratie voor deze bron bij.",
"updated_at": "Bijgewerkt op",
+20 -5
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Alguns arquivos falharam ao enviar",
"something_went_wrong": "Algo deu errado",
"something_went_wrong_please_try_again": "Algo deu errado. Tente novamente.",
"soon": "Em breve",
"sort_by": "Ordenar por",
"start_free_trial": "Iniciar teste gratuito",
"status": "status",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrar dados",
"filters": "Filtros",
"filters_toggle_description": "Incluir apenas dados que atendam às seguintes condições.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Ir para Diretórios de Feedback",
"granularity": "Granularidade",
"granularity_day": "Dia",
"granularity_hour": "Hora",
@@ -1770,7 +1769,7 @@
"no_data_available": "Nenhum dado disponível",
"no_data_returned": "Nenhum dado retornado da consulta",
"no_data_returned_for_chart": "Nenhum dado retornado para o gráfico",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Nenhum diretório de feedback está atribuído a este workspace.",
"no_grouping": "Nenhum (apenas filtro)",
"no_valid_data_to_display": "Nenhum dado válido para exibir",
"not_contains": "não contém",
@@ -2542,10 +2541,10 @@
"archive_directory": "Arquivar Diretório",
"archive_not_allowed": "Você não tem permissão para arquivar este diretório.",
"are_you_sure_you_want_to_archive": "Tem certeza de que deseja arquivar este diretório? Os espaços de trabalho não terão mais acesso a ele.",
"assign_workspaces_description": "Controle quais espaços de trabalho podem acessar este diretório de feedback.",
"assign_workspaces_description": "Controle quais workspaces podem acessar este diretório de feedback.",
"connectors_description": "Conectores que enviam registros de feedback para este diretório.",
"create_feedback_directory": "Criar diretório de feedback",
"description": "Gerencie diretórios de feedback e suas atribuições de espaços de trabalho.",
"description": "Gerencie diretórios de feedback e suas atribuições de workspace.",
"directory_archived_successfully": "Diretório arquivado com sucesso",
"directory_created_successfully": "Diretório criado com sucesso",
"directory_id": "ID do Diretório",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Solicitar integração de fonte",
"required": "Obrigatório",
"save_changes": "Salvar alterações",
"search_feedback": "Buscar feedback",
"select_a_survey_to_see_questions": "Selecione uma pesquisa para ver suas perguntas",
"select_a_value": "Selecione um valor...",
"select_feedback_directory": "Selecione um diretório",
@@ -3741,6 +3741,20 @@
"select_survey": "Selecionar pesquisa",
"select_survey_and_questions": "Selecionar pesquisa e perguntas",
"select_survey_questions_description": "Escolha quais perguntas da pesquisa devem criar FeedbackRecords.",
"semantic_search_failed": "Falha ao buscar registros de feedback",
"semantic_search_input_label": "Busque registros de feedback por tópico",
"semantic_search_missing_text": "Este registro de feedback não possui texto para exibir.",
"semantic_search_no_directories": "Nenhum diretório de registro de feedback está atribuído a este workspace ainda. Adicione uma fonte de feedback para começar a buscar feedback por significado.",
"semantic_search_no_results": "Nenhum registro de feedback correspondente encontrado. Tente um tópico mais amplo ou uma frase diferente.",
"semantic_search_placeholder": "Busque por um tópico, ex.: reclamações sobre preço",
"semantic_search_relevance": "{score}% de relevância",
"semantic_search_results_count": "{count, plural, one {# registro de feedback correspondente} other {# registros de feedback correspondentes}}",
"semantic_search_unavailable": "A busca semântica ainda não está disponível. Configure os embeddings do Hub para usar esta prévia.",
"semantic_topics_example_confusing_onboarding": "onboarding confuso",
"semantic_topics_example_pricing_complaints": "reclamações sobre preço",
"semantic_topics_example_slow_checkout": "checkout lento",
"semantic_topics_preview_description": "Digite um tópico ou frase para encontrar registros de feedback por significado. Esta é uma prévia antecipada dos futuros Tópicos e Subtópicos.",
"semantic_topics_preview_title": "Buscar feedback por tópico",
"set_value": "definir valor",
"setup_connection": "Configurar conexão",
"showing_count_loaded": "Mostrando {count} registros",
@@ -3768,6 +3782,7 @@
"submission_id": "ID de envio",
"survey_has_no_questions": "Esta pesquisa não possui perguntas",
"topics_and_subtopics": "Tópicos e subtópicos",
"try_searching_for": "Tente buscar por",
"unify_feedback": "Unificar feedback",
"update_mapping_description": "Atualize a configuração de mapeamento para esta fonte.",
"updated_at": "Atualizado em",
+24 -9
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Alguns ficheiros falharam ao carregar",
"something_went_wrong": "Algo correu mal",
"something_went_wrong_please_try_again": "Algo correu mal. Por favor, tente novamente.",
"soon": "Em breve",
"sort_by": "Ordem",
"start_free_trial": "Iniciar teste gratuito",
"status": "Estado",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrar dados",
"filters": "Filtros",
"filters_toggle_description": "Incluir apenas dados que cumpram as seguintes condições.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Ir para Diretórios de Feedback",
"granularity": "Granularidade",
"granularity_day": "Dia",
"granularity_hour": "Hora",
@@ -1770,7 +1769,7 @@
"no_data_available": "Nenhum dado disponível",
"no_data_returned": "Nenhum dado devolvido pela consulta",
"no_data_returned_for_chart": "Nenhum dado devolvido para o gráfico",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Nenhum diretório de feedback está atribuído a este workspace.",
"no_grouping": "Nenhum (apenas filtro)",
"no_valid_data_to_display": "Nenhum dado válido para exibir",
"not_contains": "não contém",
@@ -1849,10 +1848,10 @@
"api_key_updated": "Chave API atualizada",
"delete_api_key_confirmation": "Quaisquer aplicações que utilizem esta chave deixarão de poder aceder aos seus dados Formbricks.",
"duplicate_access": "Acesso duplicado ao workspace não permitido",
"duplicate_directory_access": "Não é permitido o acesso duplicado ao diretório de feedback",
"duplicate_directory_access": "Não é permitido acesso duplicado ao diretório de feedback",
"feedback_directory_access": "Acesso ao Diretório de Feedback",
"no_api_keys_yet": "Ainda não tem nenhuma chave de API",
"no_directory_permissions_found": "Não foram encontradas permissões para o diretório de feedback",
"no_directory_permissions_found": "Nenhuma permissão de diretório de feedback encontrada",
"no_workspace_permissions_found": "Não foram encontradas permissões de Espaço de Trabalho",
"organization_access": "Acesso à organização",
"organization_access_description": "Selecione privilégios de leitura ou escrita para recursos de toda a organização.",
@@ -2542,10 +2541,10 @@
"archive_directory": "Arquivar Diretório",
"archive_not_allowed": "Não tens permissão para arquivar este diretório.",
"are_you_sure_you_want_to_archive": "Tens a certeza de que queres arquivar este diretório? Os espaços de trabalho deixarão de ter acesso ao mesmo.",
"assign_workspaces_description": "Controla quais os espaços de trabalho que podem aceder a este diretório de feedback.",
"assign_workspaces_description": "Controla quais workspaces podem aceder a este diretório de feedback.",
"connectors_description": "Conectores que enviam registos de feedback para este diretório.",
"create_feedback_directory": "Criar diretório de feedback",
"description": "Gere diretórios de feedback e as suas atribuições de espaços de trabalho.",
"description": "Gere diretórios de feedback e as suas atribuições de workspace.",
"directory_archived_successfully": "Diretório arquivado com sucesso",
"directory_created_successfully": "Diretório criado com sucesso",
"directory_id": "ID do Diretório",
@@ -2554,7 +2553,7 @@
"directory_settings_title": "Definições de {directoryName}",
"directory_unarchived_successfully": "Diretório desarquivado com sucesso",
"directory_updated_successfully": "Diretório atualizado com sucesso",
"empty_state": "Não foram encontrados diretórios de feedback. Cria um para começar.",
"empty_state": "Nenhum diretório de feedback encontrado. Cria um para começar.",
"error_directory_has_connectors": "Não é possível arquivar um diretório que tem conectores associados. Remove todos os conectores primeiro.",
"error_directory_name_duplicate": "Já existe um diretório de feedback com este nome.",
"error_directory_name_required": "O nome do diretório é obrigatório.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Valores de metadados somente leitura (sem string)",
"metadata_value": "Valor dos metadados",
"missing_feedback_source_title": "Falta alguma fonte de feedback?",
"no_feedback_directory_available": "Não há nenhum diretório de feedback atribuído a este espaço de trabalho. Cria ou atribui um primeiro.",
"no_feedback_directory_available": "Nenhum diretório de feedback atribuído a este workspace. Cria ou atribui um primeiro.",
"no_feedback_records": "Ainda não há registos de feedback. Os registos aparecerão aqui assim que os teus conectores começarem a enviar dados.",
"no_source_fields_loaded": "Ainda não foram carregados campos de origem",
"no_sources_connected": "Ainda não há origens ligadas. Adicione uma origem para começar.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Solicitar integração de fonte",
"required": "Obrigatório",
"save_changes": "Guardar alterações",
"search_feedback": "Pesquisar feedback",
"select_a_survey_to_see_questions": "Selecione um inquérito para ver as suas perguntas",
"select_a_value": "Selecione um valor...",
"select_feedback_directory": "Selecionar um diretório",
@@ -3741,6 +3741,20 @@
"select_survey": "Selecionar inquérito",
"select_survey_and_questions": "Selecionar inquérito e perguntas",
"select_survey_questions_description": "Escolha quais perguntas do inquérito devem criar FeedbackRecords.",
"semantic_search_failed": "Falha ao pesquisar registos de feedback",
"semantic_search_input_label": "Pesquisar registos de feedback por tópico",
"semantic_search_missing_text": "Este registo de feedback não tem texto para mostrar.",
"semantic_search_no_directories": "Ainda não há nenhum diretório de registos de feedback atribuído a este workspace. Adiciona uma fonte de feedback para começar a pesquisar por significado.",
"semantic_search_no_results": "Nenhum registo de feedback correspondente encontrado. Tenta um tópico mais abrangente ou uma frase diferente.",
"semantic_search_placeholder": "Pesquisar por um tópico, ex: reclamações sobre preços",
"semantic_search_relevance": "{score}% de relevância",
"semantic_search_results_count": "{count, plural, one {# registo de feedback correspondente} other {# registos de feedback correspondentes}}",
"semantic_search_unavailable": "A pesquisa semântica ainda não está disponível. Configura os embeddings do Hub para usar esta pré-visualização.",
"semantic_topics_example_confusing_onboarding": "onboarding confuso",
"semantic_topics_example_pricing_complaints": "reclamações sobre preços",
"semantic_topics_example_slow_checkout": "checkout lento",
"semantic_topics_preview_description": "Introduz um tópico ou frase para encontrar registos de feedback por significado. Esta é uma pré-visualização de futuros Tópicos e Subtópicos.",
"semantic_topics_preview_title": "Pesquisar feedback por tópico",
"set_value": "definir valor",
"setup_connection": "Configurar ligação",
"showing_count_loaded": "A mostrar {count} registos",
@@ -3768,6 +3782,7 @@
"submission_id": "ID de envio",
"survey_has_no_questions": "Este inquérito não tem perguntas",
"topics_and_subtopics": "Tópicos e subtópicos",
"try_searching_for": "Experimenta pesquisar por",
"unify_feedback": "Unificar feedback",
"update_mapping_description": "Atualiza a configuração de mapeamento para esta origem.",
"updated_at": "Atualizado em",
+22 -7
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Unele fișiere nu au reușit să se încarce",
"something_went_wrong": "Ceva nu a mers bine",
"something_went_wrong_please_try_again": "Ceva nu a mers bine. Vă rugăm să încercați din nou.",
"soon": "În curând",
"sort_by": "Sortare după",
"start_free_trial": "Începe perioada de probă gratuită",
"status": "Stare",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrează datele",
"filters": "Filtre",
"filters_toggle_description": "Include doar datele care îndeplinesc următoarele condiții.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Mergi la Directoare de Feedback",
"granularity": "Granularitate",
"granularity_day": "Zi",
"granularity_hour": "Oră",
@@ -1770,7 +1769,7 @@
"no_data_available": "Nu există date disponibile",
"no_data_returned": "Nu au fost returnate date din interogare",
"no_data_returned_for_chart": "Nu au fost returnate date pentru grafic",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Niciun director de feedback nu este atribuit acestui spațiu de lucru.",
"no_grouping": "Niciuna (doar filtru)",
"no_valid_data_to_display": "Nu există date valide de afișat",
"not_contains": "nu conține",
@@ -1852,7 +1851,7 @@
"duplicate_directory_access": "Accesul duplicat la directorul de feedback nu este permis",
"feedback_directory_access": "Acces la Directorul de Feedback",
"no_api_keys_yet": "Nu ai încă nicio cheie API",
"no_directory_permissions_found": "Nu s-au găsit permisiuni pentru directorul de feedback",
"no_directory_permissions_found": "Nu au fost găsite permisiuni pentru directoare de feedback",
"no_workspace_permissions_found": "Nu s-au găsit permisiuni pentru Workspace",
"organization_access": "Acces organizație",
"organization_access_description": "Selectează privilegii de citire sau scriere pentru resursele la nivel de organizație.",
@@ -2542,7 +2541,7 @@
"archive_directory": "Arhivează directorul",
"archive_not_allowed": "Nu ai permisiunea să arhivezi acest director.",
"are_you_sure_you_want_to_archive": "Ești sigur că vrei să arhivezi acest director? Spațiile de lucru nu vor mai avea acces la el.",
"assign_workspaces_description": "Controlează care spații de lucru pot accesa acest director de feedback.",
"assign_workspaces_description": "Controlează ce spații de lucru pot accesa acest director de feedback.",
"connectors_description": "Conectori care trimit înregistrări de feedback către acest director.",
"create_feedback_directory": "Creează director de feedback",
"description": "Gestionează directoarele de feedback și atribuirile lor la spații de lucru.",
@@ -3680,7 +3679,7 @@
"enum": "enum",
"failed_to_load_feedback_records": "Nu s-au putut încărca înregistrările de feedback",
"feedback_date": "Data curentă",
"feedback_directory": "Director de feedback",
"feedback_directory": "Director de Feedback",
"feedback_record_created_successfully": "Înregistrare de feedback creată cu succes",
"feedback_record_details": "Detaliile înregistrării feedback-ului",
"feedback_record_details_description": "Examinați și actualizați câmpurile pentru înregistrarea de feedback.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Valori de metadate numai pentru citire (fără șir)",
"metadata_value": "Valoarea metadatelor",
"missing_feedback_source_title": "Lipsește o sursă de feedback?",
"no_feedback_directory_available": "Niciun director de feedback atribuit acestui spațiu de lucru. Creează sau atribuie unul mai întâi.",
"no_feedback_directory_available": "Niciun director de feedback nu este atribuit acestui spațiu de lucru. Creează sau atribuie unul mai întâi.",
"no_feedback_records": "Nu există încă înregistrări de feedback. Înregistrările vor apărea aici după ce conectorii tăi vor începe să trimită date.",
"no_source_fields_loaded": "Nu au fost încă încărcate câmpuri sursă",
"no_sources_connected": "Nicio sursă conectată încă. Adaugă o sursă pentru a începe.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Solicită integrarea sursei",
"required": "Obligatoriu",
"save_changes": "Salvează modificările",
"search_feedback": "Caută feedback",
"select_a_survey_to_see_questions": "Selectează un chestionar pentru a vedea întrebările",
"select_a_value": "Selectează o valoare...",
"select_feedback_directory": "Selectează un director",
@@ -3741,6 +3741,20 @@
"select_survey": "Selectează chestionar",
"select_survey_and_questions": "Selectează chestionar și întrebări",
"select_survey_questions_description": "Alege ce întrebări din chestionar vor crea FeedbackRecords.",
"semantic_search_failed": "Căutarea înregistrărilor de feedback a eșuat",
"semantic_search_input_label": "Caută înregistrări de feedback după subiect",
"semantic_search_missing_text": "Această înregistrare de feedback nu conține text de afișat.",
"semantic_search_no_directories": "Încă nu este atribuit niciun director de înregistrări de feedback acestui spațiu de lucru. Adaugă o sursă de feedback pentru a începe căutarea după înțeles.",
"semantic_search_no_results": "Nu au fost găsite înregistrări de feedback corespunzătoare. Încearcă un subiect mai general sau o altă formulare.",
"semantic_search_placeholder": "Caută un subiect, de ex. plângeri despre prețuri",
"semantic_search_relevance": "{score}% relevanță",
"semantic_search_results_count": "{count, plural, one {# înregistrare de feedback corespunzătoare} few {# înregistrări de feedback corespunzătoare} other {# de înregistrări de feedback corespunzătoare}}",
"semantic_search_unavailable": "Căutarea semantică nu este disponibilă încă. Configurează încorporările Hub pentru a folosi această previzualizare.",
"semantic_topics_example_confusing_onboarding": "onboarding confuz",
"semantic_topics_example_pricing_complaints": "plângeri despre prețuri",
"semantic_topics_example_slow_checkout": "finalizare lentă",
"semantic_topics_preview_description": "Introdu un subiect sau o frază pentru a identifica înregistrările de feedback după sens. Aceasta este o previzualizare timpurie a viitoarelor Subiecte și Subsubiecte.",
"semantic_topics_preview_title": "Caută feedback după subiect",
"set_value": "setează valoare",
"setup_connection": "Configurează conexiunea",
"showing_count_loaded": "Se afișează {count} înregistrări",
@@ -3768,6 +3782,7 @@
"submission_id": "ID-ul trimiterii",
"survey_has_no_questions": "Acest sondaj nu are întrebări",
"topics_and_subtopics": "Subiecte și subiecte secundare",
"try_searching_for": "Încearcă să cauți",
"unify_feedback": "Unify Feedback",
"update_mapping_description": "Actualizează configurația de mapare pentru această sursă.",
"updated_at": "Actualizat la",
+28 -13
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Не удалось загрузить некоторые файлы",
"something_went_wrong": "Что-то пошло не так",
"something_went_wrong_please_try_again": "Что-то пошло не так. Пожалуйста, попробуйте ещё раз.",
"soon": "Скоро",
"sort_by": "Сортировать по",
"start_free_trial": "Начать бесплатный пробный период",
"status": "Статус",
@@ -1746,7 +1745,7 @@
"filter_data": "Фильтровать данные",
"filters": "Фильтры",
"filters_toggle_description": "Включай только те данные, которые соответствуют следующим условиям.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Перейти к директориям обратной связи",
"granularity": "Детализация",
"granularity_day": "День",
"granularity_hour": "Час",
@@ -1770,7 +1769,7 @@
"no_data_available": "Нет доступных данных",
"no_data_returned": "Запрос не вернул данных",
"no_data_returned_for_chart": "Для графика не получено данных",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "К этому рабочему пространству не привязана директория обратной связи.",
"no_grouping": "Нет (только фильтр)",
"no_valid_data_to_display": "Нет корректных данных для отображения",
"not_contains": "не содержит",
@@ -1849,10 +1848,10 @@
"api_key_updated": "API-ключ обновлён",
"delete_api_key_confirmation": "Любые приложения, использующие этот ключ, больше не смогут получить доступ к вашим данным Formbricks.",
"duplicate_access": "Дублированный доступ к рабочему пространству не разрешён",
"duplicate_directory_access": "Дублирующий доступ к каталогу обратной связи запрещен",
"feedback_directory_access": "Доступ к каталогу обратной связи",
"duplicate_directory_access": "Дублирование доступа к директории обратной связи запрещено",
"feedback_directory_access": "Доступ к директории обратной связи",
"no_api_keys_yet": "У вас ещё нет API-ключей",
"no_directory_permissions_found": "Разрешения для каталога обратной связи не найдены",
"no_directory_permissions_found": "Разрешения для директорий обратной связи не найдены",
"no_workspace_permissions_found": "Разрешения для рабочего пространства не найдены",
"organization_access": "Доступ к организации",
"organization_access_description": "Выберите права на чтение или запись для ресурсов всей организации.",
@@ -2542,10 +2541,10 @@
"archive_directory": "Архивировать каталог",
"archive_not_allowed": "У тебя нет прав для архивирования этого каталога.",
"are_you_sure_you_want_to_archive": "Ты уверен, что хочешь архивировать этот каталог? Рабочие пространства больше не будут иметь к нему доступа.",
"assign_workspaces_description": "Управляй тем, какие рабочие пространства могут получить доступ к этому каталогу отзывов.",
"assign_workspaces_description": "Управляй, какие рабочие пространства могут получить доступ к этой директории обратной связи.",
"connectors_description": "Коннекторы, которые отправляют записи обратной связи в этот каталог.",
"create_feedback_directory": "Создать директорию для отзывов",
"description": "Управляй каталогами отзывов и их назначением рабочим пространствам.",
"description": "Управляй директориями обратной связи и их привязками к рабочим пространствам.",
"directory_archived_successfully": "Каталог успешно архивирован",
"directory_created_successfully": "Каталог успешно создан",
"directory_id": "ID каталога",
@@ -2554,14 +2553,14 @@
"directory_settings_title": "Настройки {directoryName}",
"directory_unarchived_successfully": "Каталог успешно разархивирован",
"directory_updated_successfully": "Каталог успешно обновлён",
"empty_state": "Каталоги отзывов не найдены. Создай один, чтобы начать.",
"empty_state": "Директории обратной связи не найдены. Создай одну, чтобы начать.",
"error_directory_has_connectors": "Невозможно архивировать каталог, к которому привязаны коннекторы. Сначала удалите все коннекторы.",
"error_directory_name_duplicate": "Директория обратной связи с таким именем уже существует.",
"error_directory_name_duplicate": "Директория обратной связи с таким названием уже существует.",
"error_directory_name_required": "Необходимо указать имя директории.",
"error_directory_workspaces_invalid_org": "Некоторые указанные рабочие пространства не принадлежат этой организации.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Каталоги отзывов",
"no_access": "У тебя нет прав для управления каталогами отзывов.",
"no_access": "У тебя нет прав для управления директориями обратной связи.",
"no_connectors": "К этому каталогу пока не привязано ни одного коннектора.",
"pause_connectors_confirmation_description": "Если приостановить эти коннекторы, новые записи больше не будут добавляться.",
"pause_connectors_confirmation_title": "Приостановить связанные коннекторы?",
@@ -3680,7 +3679,7 @@
"enum": "enum",
"failed_to_load_feedback_records": "Не удалось загрузить отзывы",
"feedback_date": "Текущая дата",
"feedback_directory": "Каталог обратной связи",
"feedback_directory": "Директория обратной связи",
"feedback_record_created_successfully": "Запись отзыва успешно создана",
"feedback_record_details": "Детали записи обратной связи",
"feedback_record_details_description": "Просмотрите и обновите поля записи отзыва.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Значения метаданных только для чтения (нестроковые)",
"metadata_value": "Значение метаданных",
"missing_feedback_source_title": "Не нашли нужный источник обратной связи?",
"no_feedback_directory_available": "К этому рабочему пространству не назначен каталог обратной связи. Сначала создайте или назначьте каталог.",
"no_feedback_directory_available": "К этому рабочему пространству не привязана директория обратной связи. Сначала создай или привяжи её.",
"no_feedback_records": "Пока нет записей отзывов. Они появятся здесь, когда коннекторы начнут отправлять данные.",
"no_source_fields_loaded": "Поля источника ещё не загружены",
"no_sources_connected": "Нет подключённых источников. Добавьте источник, чтобы начать.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Запросить интеграцию источника",
"required": "Обязательно",
"save_changes": "Сохранить изменения",
"search_feedback": "Искать обратную связь",
"select_a_survey_to_see_questions": "Выберите опрос, чтобы увидеть его вопросы",
"select_a_value": "Выберите значение...",
"select_feedback_directory": "Выберите каталог",
@@ -3741,6 +3741,20 @@
"select_survey": "Выбрать опрос",
"select_survey_and_questions": "Выбрать опрос и вопросы",
"select_survey_questions_description": "Выберите, какие вопросы опроса должны создавать FeedbackRecords.",
"semantic_search_failed": "Не удалось найти записи обратной связи",
"semantic_search_input_label": "Ищи записи обратной связи по теме",
"semantic_search_missing_text": "В этой записи обратной связи нет текста для отображения.",
"semantic_search_no_directories": "К этому рабочему пространству пока не привязана директория с записями обратной связи. Добавь источник обратной связи, чтобы начать поиск по смыслу.",
"semantic_search_no_results": "Подходящие записи обратной связи не найдены. Попробуй более широкую тему или другую фразу.",
"semantic_search_placeholder": "Ищи по теме, например, жалобы на цены",
"semantic_search_relevance": "Релевантность {score}%",
"semantic_search_results_count": "{count, plural, one {# подходящая запись обратной связи} few {# подходящие записи обратной связи} many {# подходящих записей обратной связи} other {# подходящих записей обратной связи}}",
"semantic_search_unavailable": "Семантический поиск пока недоступен. Настрой эмбеддинги Hub, чтобы использовать эту функцию.",
"semantic_topics_example_confusing_onboarding": "запутанная регистрация",
"semantic_topics_example_pricing_complaints": "жалобы на цены",
"semantic_topics_example_slow_checkout": "медленное оформление заказа",
"semantic_topics_preview_description": "Введите тему или фразу, чтобы найти записи отзывов по смыслу. Это ранний предварительный просмотр будущих Тем и Подтем.",
"semantic_topics_preview_title": "Поиск отзывов по теме",
"set_value": "установить значение",
"setup_connection": "Настроить подключение",
"showing_count_loaded": "Показано записей: {count}",
@@ -3768,6 +3782,7 @@
"submission_id": "Идентификатор отправки",
"survey_has_no_questions": "В этом опросе нет вопросов",
"topics_and_subtopics": "Темы и подтемы",
"try_searching_for": "Попробуйте поискать",
"unify_feedback": "Обратная связь Unify",
"update_mapping_description": "Обнови настройки сопоставления для этого источника.",
"updated_at": "Обновлено",
+29 -14
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Några filer misslyckades att laddas upp",
"something_went_wrong": "Något gick fel",
"something_went_wrong_please_try_again": "Något gick fel. Försök igen.",
"soon": "Snart",
"sort_by": "Sortera efter",
"start_free_trial": "Starta gratis provperiod",
"status": "Status",
@@ -1746,7 +1745,7 @@
"filter_data": "Filtrera data",
"filters": "Filter",
"filters_toggle_description": "Inkludera bara data som uppfyller följande villkor.",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "Gå till feedback-kataloger",
"granularity": "Detaljnivå",
"granularity_day": "Dag",
"granularity_hour": "timme",
@@ -1770,7 +1769,7 @@
"no_data_available": "Ingen data tillgänglig",
"no_data_returned": "Ingen data returnerades från frågan",
"no_data_returned_for_chart": "Ingen data returnerades för diagrammet",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "Ingen feedback-katalog är tilldelad till denna arbetsyta.",
"no_grouping": "Ingen (endast filter)",
"no_valid_data_to_display": "Ingen giltig data att visa",
"not_contains": "innehåller inte",
@@ -1849,10 +1848,10 @@
"api_key_updated": "API-nyckel uppdaterad",
"delete_api_key_confirmation": "Alla applikationer som använder denna nyckel kommer inte längre att kunna komma åt din Formbricks-data.",
"duplicate_access": "Duplicerad arbetsyteåtkomst är inte tillåten",
"duplicate_directory_access": "Duplicerad åtkomst till feedbackkatalog är inte tillåten",
"feedback_directory_access": "Åtkomst till feedbackkatalog",
"duplicate_directory_access": "Duplicerad åtkomst till feedback-katalog är inte tillåten",
"feedback_directory_access": "Åtkomst till feedback-katalog",
"no_api_keys_yet": "Du har inga API-nycklar ännu",
"no_directory_permissions_found": "Inga behörigheter för feedbackkatalog hittades",
"no_directory_permissions_found": "Inga behörigheter för feedback-katalog hittades",
"no_workspace_permissions_found": "Inga behörigheter för arbetsytan hittades",
"organization_access": "Organisationsåtkomst",
"organization_access_description": "Välj läs- eller skrivbehörighet för resurser på organisationsnivå.",
@@ -2542,10 +2541,10 @@
"archive_directory": "Arkivera katalog",
"archive_not_allowed": "Du har inte behörighet att arkivera den här katalogen.",
"are_you_sure_you_want_to_archive": "Är du säker på att du vill arkivera den här katalogen? Arbetsytor kommer inte längre ha tillgång till den.",
"assign_workspaces_description": "Styr vilka arbetsytor som kan komma åt den här feedbackkatalogen.",
"assign_workspaces_description": "Styr vilka arbetsytor som kan komma åt denna feedback-katalog.",
"connectors_description": "Kopplingar som skickar feedbackposter till den här katalogen.",
"create_feedback_directory": "Skapa feedbackkatalog",
"description": "Hantera feedbackkataloger och deras arbetsytstilldelningar.",
"description": "Hantera feedback-kataloger och deras arbetsytetilldelningar.",
"directory_archived_successfully": "Katalogen arkiverades",
"directory_created_successfully": "Katalogen skapades",
"directory_id": "Katalog-ID",
@@ -2554,20 +2553,20 @@
"directory_settings_title": "Inställningar för {directoryName}",
"directory_unarchived_successfully": "Katalogen återställdes från arkivet",
"directory_updated_successfully": "Katalogen uppdaterades",
"empty_state": "Inga feedbackkataloger hittades. Skapa en för att komma igång.",
"empty_state": "Inga feedback-kataloger hittades. Skapa en för att komma igång.",
"error_directory_has_connectors": "Kan inte arkivera en katalog som har kopplingar kopplade till den. Ta bort alla kopplingar först.",
"error_directory_name_duplicate": "En feedbackkatalog med detta namn finns redan.",
"error_directory_name_duplicate": "En feedback-katalog med detta namn finns redan.",
"error_directory_name_required": "Katalognamn krävs.",
"error_directory_workspaces_invalid_org": "Vissa angivna arbetsytor tillhör inte denna organisation.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Feedbackkataloger",
"no_access": "Du har inte behörighet att hantera feedbackkataloger.",
"no_access": "Du har inte behörighet att hantera feedback-kataloger.",
"no_connectors": "Inga kopplingar länkade till den här katalogen ännu.",
"pause_connectors_confirmation_description": "Om du pausar dessa kopplingar kommer inga nya poster att läggas till.",
"pause_connectors_confirmation_title": "Pausa länkade kopplingar?",
"select_workspaces_placeholder": "Välj arbetsytor...",
"show_archived": "Visa arkiverade",
"title": "Feedbackkataloger",
"title": "Feedback-kataloger",
"unarchive": "Avarkivera",
"unarchive_workspace_conflict": "Den här katalogen kan inte avarkiveras eftersom en eller flera tilldelade arbetsytor är arkiverade.",
"workspace_access": "Arbetsyteåtkomst"
@@ -3680,7 +3679,7 @@
"enum": "enum",
"failed_to_load_feedback_records": "Det gick inte att ladda feedbackposter",
"feedback_date": "Aktuellt datum",
"feedback_directory": "Feedbackkatalog",
"feedback_directory": "Feedback-katalog",
"feedback_record_created_successfully": "Feedbackposten har skapats",
"feedback_record_details": "Feedbackpostdetaljer",
"feedback_record_details_description": "Granska och uppdatera fält för feedbackposter.",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Skrivskyddade metadatavärden (icke-sträng)",
"metadata_value": "Metadatavärde",
"missing_feedback_source_title": "Missing feedback source?",
"no_feedback_directory_available": "Ingen feedbackkatalog tilldelad till den här arbetsytan. Skapa eller tilldela en först.",
"no_feedback_directory_available": "Ingen feedback-katalog är tilldelad till denna arbetsyta. Skapa eller tilldela en först.",
"no_feedback_records": "Inga feedbackposter ännu. Poster visas här när dina connectors börjar skicka data.",
"no_source_fields_loaded": "Inga källfält har laddats än",
"no_sources_connected": "Inga källor är anslutna än. Lägg till en källa för att komma igång.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Request source integration",
"required": "Obligatoriskt",
"save_changes": "Spara ändringar",
"search_feedback": "Sök feedback",
"select_a_survey_to_see_questions": "Välj en enkät för att se dess frågor",
"select_a_value": "Välj ett värde...",
"select_feedback_directory": "Välj en katalog",
@@ -3741,6 +3741,20 @@
"select_survey": "Välj enkät",
"select_survey_and_questions": "Välj enkät & frågor",
"select_survey_questions_description": "Välj vilka enkätfrågor som ska skapa FeedbackRecords.",
"semantic_search_failed": "Misslyckades med att söka i feedback-poster",
"semantic_search_input_label": "Sök feedback-poster efter ämne",
"semantic_search_missing_text": "Denna feedback-post har ingen text att visa.",
"semantic_search_no_directories": "Ingen feedback-katalog är tilldelad till denna arbetsyta ännu. Lägg till en feedback-källa för att börja söka feedback efter mening.",
"semantic_search_no_results": "Inga matchande feedback-poster hittades. Prova ett bredare ämne eller en annan fras.",
"semantic_search_placeholder": "Sök efter ett ämne, t.ex. klagomål om priser",
"semantic_search_relevance": "{score}% relevans",
"semantic_search_results_count": "{count, plural, one {# matchande feedback-post} other {# matchande feedback-poster}}",
"semantic_search_unavailable": "Semantisk sökning är inte tillgänglig ännu. Konfigurera Hub-inbäddningar för att använda denna förhandsvisning.",
"semantic_topics_example_confusing_onboarding": "förvirrande onboarding",
"semantic_topics_example_pricing_complaints": "klagomål om priser",
"semantic_topics_example_slow_checkout": "långsam utcheckning",
"semantic_topics_preview_description": "Ange ett ämne eller en fras för att hitta feedbackposter baserat på betydelse. Detta är en tidig förhandsgranskning av framtida Ämnen & Underämnen.",
"semantic_topics_preview_title": "Sök feedback efter ämne",
"set_value": "ange värde",
"setup_connection": "Ställ in anslutning",
"showing_count_loaded": "Visar {count} poster",
@@ -3768,6 +3782,7 @@
"submission_id": "Inlämnings-ID",
"survey_has_no_questions": "Den här enkäten har inga frågor",
"topics_and_subtopics": "Ämnen och delämnen",
"try_searching_for": "Prova att söka efter",
"unify_feedback": "Samla feedback",
"update_mapping_description": "Uppdatera mappningskonfigurationen för den här källan.",
"updated_at": "Uppdaterad",
+23 -8
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "Bazı dosyalar yüklenemedi",
"something_went_wrong": "Bir şeyler ters gitti",
"something_went_wrong_please_try_again": "Bir sorun oluştu. Lütfen tekrar deneyin.",
"soon": "Yakında",
"sort_by": "Sıralama",
"start_free_trial": "Ücretsiz denemeyi başlat",
"status": "Durum",
@@ -1770,7 +1769,7 @@
"no_data_available": "Veri mevcut değil",
"no_data_returned": "Sorgudan veri döndürülmedi",
"no_data_returned_for_chart": "Grafik için veri döndürülmedi",
"no_data_source_available": "Bu çalışma alanına atanmış bir geri bildirim dizini yok.",
"no_data_source_available": "Bu çalışma alanına atanmış geri bildirim dizini yok.",
"no_grouping": "Yok (sadece filtre)",
"no_valid_data_to_display": "Görüntülenecek geçerli veri yok",
"not_contains": "içermez",
@@ -1849,10 +1848,10 @@
"api_key_updated": "API anahtarı güncellendi",
"delete_api_key_confirmation": "Bu anahtarı kullanan tüm uygulamalar artık Formbricks verilerine erişemeyecek.",
"duplicate_access": "Yinelenen çalışma alanı erişimine izin verilmiyor",
"duplicate_directory_access": "Yinelenen geri bildirim dizin erişimine izin verilmiyor",
"feedback_directory_access": "Geri Bildirim Dizin Erişimi",
"duplicate_directory_access": "Yinelenen geri bildirim dizini erişimine izin verilmiyor",
"feedback_directory_access": "Geri Bildirim Dizini Erişimi",
"no_api_keys_yet": "Henüz hiç API anahtarınız yok",
"no_directory_permissions_found": "Geri bildirim dizin izinleri bulunamadı",
"no_directory_permissions_found": "Geri bildirim dizini izni bulunamadı",
"no_workspace_permissions_found": "Çalışma Alanı izni bulunamadı",
"organization_access": "Organizasyon Erişimi",
"organization_access_description": "Organizasyon genelindeki kaynaklar için okuma veya yazma yetkilerini seçin.",
@@ -2556,12 +2555,12 @@
"directory_updated_successfully": "Dizin başarıyla güncellendi",
"empty_state": "Geri bildirim dizini bulunamadı. Başlamak için bir tane oluştur.",
"error_directory_has_connectors": "Bağlayıcıları bağlı olan bir dizin arşivlenemez. Önce tüm bağlayıcıları kaldır.",
"error_directory_name_duplicate": "Bu ada sahip bir geri bildirim dizini zaten mevcut.",
"error_directory_name_duplicate": "Bu adda bir geri bildirim dizini zaten mevcut.",
"error_directory_name_required": "Dizin adı gereklidir.",
"error_directory_workspaces_invalid_org": "Belirtilen çalışma alanlarından bazıları bu organizasyona ait değil.",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "Geri Bildirim Dizinleri",
"no_access": "Geri bildirim dizinlerini yönetme izniniz yok.",
"no_access": "Geri bildirim dizinlerini yönetme yetkin yok.",
"no_connectors": "Bu dizine henüz bağlı bağlayıcı yok.",
"pause_connectors_confirmation_description": "Bu bağlayıcıları duraklatırsanız yeni kayıtlar eklenmez.",
"pause_connectors_confirmation_title": "Bağlı bağlayıcılar duraklatılsın mı?",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "Salt okunur meta veri değerleri (dize dışı)",
"metadata_value": "Meta veri değeri",
"missing_feedback_source_title": "Missing feedback source?",
"no_feedback_directory_available": "Bu çalışma alanına atanmış bir geri bildirim dizini yok. Önce bir tane oluştur veya ata.",
"no_feedback_directory_available": "Bu çalışma alanına atanmış geri bildirim dizini yok. Önce bir tane oluştur veya ata.",
"no_feedback_records": "Henüz geri bildirim kaydı yok. Bağlayıcıların veri göndermeye başlamasıyla kayıtlar burada görünecek.",
"no_source_fields_loaded": "Henüz kaynak alan yüklenmedi",
"no_sources_connected": "Henüz bağlı kaynak yok. Başlamak için bir kaynak ekle.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Request source integration",
"required": "Gerekli",
"save_changes": "Değişiklikleri kaydet",
"search_feedback": "Geri bildirim ara",
"select_a_survey_to_see_questions": "Sorularını görmek için bir anket seç",
"select_a_value": "Bir değer seç...",
"select_feedback_directory": "Bir dizin seç",
@@ -3741,6 +3741,20 @@
"select_survey": "Anket Seç",
"select_survey_and_questions": "Anket ve Soruları Seç",
"select_survey_questions_description": "Hangi anket sorularının GeriBildirimKayıtları oluşturması gerektiğini seçin.",
"semantic_search_failed": "Geri bildirim kayıtları aranamadı",
"semantic_search_input_label": "Geri bildirim kayıtlarını konuya göre ara",
"semantic_search_missing_text": "Bu geri bildirim kaydında görüntülenecek metin yok.",
"semantic_search_no_directories": "Bu çalışma alanına henüz geri bildirim kayıt dizini atanmamış. Anlamsal aramaya başlamak için bir geri bildirim kaynağı ekle.",
"semantic_search_no_results": "Eşleşen geri bildirim kaydı bulunamadı. Daha geniş bir konu veya farklı bir ifade dene.",
"semantic_search_placeholder": "Bir konu ara, örn. fiyatlandırma şikayetleri",
"semantic_search_relevance": "%{score} uygunluk",
"semantic_search_results_count": "{count, plural, one {# eşleşen geri bildirim kaydı} other {# eşleşen geri bildirim kaydı}}",
"semantic_search_unavailable": "Anlamsal arama henüz kullanıma sunulmadı. Bu önizlemeyi kullanmak için Hub gömme ayarlarını yapılandır.",
"semantic_topics_example_confusing_onboarding": "kafa karıştırıcı onboarding",
"semantic_topics_example_pricing_complaints": "fiyatlandırma şikayetleri",
"semantic_topics_example_slow_checkout": "yavaş ödeme",
"semantic_topics_preview_description": "Anlam bazında geri bildirim kayıtlarını ortaya çıkarmak için bir konu veya ifade gir. Bu, gelecekteki Konular ve Alt Konular özelliğinin erken bir ön izlemesidir.",
"semantic_topics_preview_title": "Konuya göre geri bildirim ara",
"set_value": "değer belirle",
"setup_connection": "Bağlantıyı kur",
"showing_count_loaded": "{count} kayıt gösteriliyor",
@@ -3768,6 +3782,7 @@
"submission_id": "Gönderim Kimliği",
"survey_has_no_questions": "Bu ankette soru yok",
"topics_and_subtopics": "Konular ve alt konular",
"try_searching_for": "Şunu aramayı dene",
"unify_feedback": "Geri Bildirimleri Birleştir",
"update_mapping_description": "Bu kaynak için eşleme yapılandırmasını güncelle.",
"updated_at": "Güncellenme tarihi",
+21 -6
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "某些文件上传失败",
"something_went_wrong": "出错了",
"something_went_wrong_please_try_again": "出错了 。请 尝试 再次 操作 。",
"soon": "即将推出",
"sort_by": "排序 依据",
"start_free_trial": "开始免费试用",
"status": "状态",
@@ -1746,7 +1745,7 @@
"filter_data": "筛选数据",
"filters": "筛选条件",
"filters_toggle_description": "仅包含符合以下条件的数据。",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "前往反馈目录",
"granularity": "粒度",
"granularity_day": "天",
"granularity_hour": "小时",
@@ -1770,7 +1769,7 @@
"no_data_available": "暂无数据",
"no_data_returned": "查询未返回数据",
"no_data_returned_for_chart": "该图表未返回数据",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "此工作区未分配反馈目录。",
"no_grouping": "无(仅筛选)",
"no_valid_data_to_display": "无有效数据可显示",
"not_contains": "不包含",
@@ -1850,7 +1849,7 @@
"delete_api_key_confirmation": "使用此密钥的任何应用将无法再访问您的 Formbricks 数据。",
"duplicate_access": "不允许重复的工作区访问权限",
"duplicate_directory_access": "不允许重复的反馈目录访问权限",
"feedback_directory_access": "反馈目录访问",
"feedback_directory_access": "反馈目录访问权限",
"no_api_keys_yet": "您还没有任何 API 密钥",
"no_directory_permissions_found": "未找到反馈目录权限",
"no_workspace_permissions_found": "未找到工作区权限",
@@ -2554,9 +2553,9 @@
"directory_settings_title": "{directoryName} 设置",
"directory_unarchived_successfully": "目录已成功取消归档",
"directory_updated_successfully": "目录已成功更新",
"empty_state": "未找到反馈目录。创建一个开始使用。",
"empty_state": "未找到反馈目录。创建一个开始使用。",
"error_directory_has_connectors": "无法归档已链接连接器的目录。请先移除所有连接器。",
"error_directory_name_duplicate": "已存在同名的反馈目录。",
"error_directory_name_duplicate": "已存在使用此名称的反馈目录。",
"error_directory_name_required": "目录名称为必填项。",
"error_directory_workspaces_invalid_org": "某些指定的工作区不属于此组织。",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Request source integration",
"required": "必填",
"save_changes": "保存更改",
"search_feedback": "搜索反馈",
"select_a_survey_to_see_questions": "请选择一个调查以查看其问题",
"select_a_value": "选择一个值...",
"select_feedback_directory": "选择目录",
@@ -3741,6 +3741,20 @@
"select_survey": "选择调查",
"select_survey_and_questions": "选择调查和问题",
"select_survey_questions_description": "选择哪些调查问题会创建反馈记录。",
"semantic_search_failed": "搜索反馈记录失败",
"semantic_search_input_label": "按主题搜索反馈记录",
"semantic_search_missing_text": "此反馈记录没有可显示的文本。",
"semantic_search_no_directories": "此工作区尚未分配反馈记录目录。添加反馈来源以开始按含义搜索反馈。",
"semantic_search_no_results": "未找到匹配的反馈记录。尝试使用更宽泛的主题或不同的短语。",
"semantic_search_placeholder": "搜索主题,例如:定价投诉",
"semantic_search_relevance": "相关度 {score}%",
"semantic_search_results_count": "{count, plural, other {# 条匹配的反馈记录}}",
"semantic_search_unavailable": "语义搜索暂不可用。配置 Hub 嵌入以使用此预览功能。",
"semantic_topics_example_confusing_onboarding": "令人困惑的引导流程",
"semantic_topics_example_pricing_complaints": "定价投诉",
"semantic_topics_example_slow_checkout": "结账慢",
"semantic_topics_preview_description": "输入主题或短语,按含义查找反馈记录。这是未来主题和子主题功能的早期预览。",
"semantic_topics_preview_title": "按主题搜索反馈",
"set_value": "设置值",
"setup_connection": "设置连接",
"showing_count_loaded": "显示 {count} 条记录",
@@ -3768,6 +3782,7 @@
"submission_id": "提交ID",
"survey_has_no_questions": "该调查没有任何问题",
"topics_and_subtopics": "主题和子主题",
"try_searching_for": "尝试搜索",
"unify_feedback": "统一反馈",
"update_mapping_description": "更新此来源的映射配置。",
"updated_at": "更新于",
+23 -8
View File
@@ -434,7 +434,6 @@
"some_files_failed_to_upload": "部分檔案上傳失敗",
"something_went_wrong": "發生錯誤",
"something_went_wrong_please_try_again": "發生錯誤。請再試一次。",
"soon": "即將推出",
"sort_by": "排序方式",
"start_free_trial": "開始免費試用",
"status": "狀態",
@@ -1746,7 +1745,7 @@
"filter_data": "篩選資料",
"filters": "篩選條件",
"filters_toggle_description": "只包含符合下列條件的資料。",
"go_to_feedback_directories": "Go to Feedback Directories",
"go_to_feedback_directories": "前往意見回饋目錄",
"granularity": "粒度",
"granularity_day": "天",
"granularity_hour": "小時",
@@ -1770,7 +1769,7 @@
"no_data_available": "沒有可用資料",
"no_data_returned": "查詢沒有回傳資料",
"no_data_returned_for_chart": "此圖表沒有回傳資料",
"no_data_source_available": "No feedback directory is assigned to this workspace.",
"no_data_source_available": "此工作區未指派任何意見回饋目錄。",
"no_grouping": "無(僅篩選)",
"no_valid_data_to_display": "沒有可顯示的有效資料",
"not_contains": "不包含",
@@ -1850,7 +1849,7 @@
"delete_api_key_confirmation": "使用此金鑰的任何應用程式將無法再存取您的 Formbricks 資料。",
"duplicate_access": "不允許重複工作區存取",
"duplicate_directory_access": "不允許重複的意見回饋目錄存取權限",
"feedback_directory_access": "意見回饋目錄存取",
"feedback_directory_access": "意見回饋目錄存取權限",
"no_api_keys_yet": "您目前尚未有任何 API 金鑰",
"no_directory_permissions_found": "找不到意見回饋目錄權限",
"no_workspace_permissions_found": "找不到工作區權限",
@@ -2545,7 +2544,7 @@
"assign_workspaces_description": "控制哪些工作區可以存取此意見回饋目錄。",
"connectors_description": "將意見回饋記錄傳送至此目錄的連接器。",
"create_feedback_directory": "建立意見回饋目錄",
"description": "管理意見回饋目錄及其工作區配置。",
"description": "管理意見回饋目錄及其工作區指派。",
"directory_archived_successfully": "目錄已成功封存",
"directory_created_successfully": "目錄已成功建立",
"directory_id": "目錄 ID",
@@ -2554,14 +2553,14 @@
"directory_settings_title": "{directoryName} 設定",
"directory_unarchived_successfully": "目錄已成功取消封存",
"directory_updated_successfully": "目錄已成功更新",
"empty_state": "找不到任何意見回饋目錄。建立一個開始使用。",
"empty_state": "找不到意見回饋目錄。建立一個開始使用。",
"error_directory_has_connectors": "無法封存已連結連接器的目錄。請先移除所有連接器。",
"error_directory_name_duplicate": "已存在同名的意見回饋目錄。",
"error_directory_name_required": "目錄名稱為必填項目。",
"error_directory_workspaces_invalid_org": "部分指定的工作區不屬於此組織。",
"error_workspace_already_assigned": "One or more workspaces are already linked to a different active directory. Reassign them first.",
"nav_label": "意見回饋目錄",
"no_access": "沒有權限管理意見回饋目錄。",
"no_access": "沒有權限管理意見回饋目錄。",
"no_connectors": "此目錄尚未連結任何連接器。",
"pause_connectors_confirmation_description": "暫停這些連接器後,將不會再新增新紀錄。",
"pause_connectors_confirmation_title": "暫停已連結的連接器?",
@@ -3720,7 +3719,7 @@
"metadata_read_only_entries": "唯讀元資料值(非字串)",
"metadata_value": "元資料值",
"missing_feedback_source_title": "Missing feedback source?",
"no_feedback_directory_available": "此工作區未指派意見回饋目錄。請先建立或指派一個目錄。",
"no_feedback_directory_available": "此工作區未指派意見回饋目錄。請先建立或指派一個。",
"no_feedback_records": "目前尚無回饋紀錄。當你的連接器開始傳送資料時,紀錄會顯示在這裡。",
"no_source_fields_loaded": "尚未載入來源欄位",
"no_sources_connected": "尚未連接任何來源。請新增來源以開始使用。",
@@ -3732,6 +3731,7 @@
"request_feedback_source": "Request source integration",
"required": "必填",
"save_changes": "儲存變更",
"search_feedback": "搜尋意見回饋",
"select_a_survey_to_see_questions": "請選擇問卷以查看其問題",
"select_a_value": "請選擇一個值...",
"select_feedback_directory": "選擇目錄",
@@ -3741,6 +3741,20 @@
"select_survey": "選擇問卷",
"select_survey_and_questions": "選擇問卷與問題",
"select_survey_questions_description": "請選擇哪些問卷問題要建立 FeedbackRecords。",
"semantic_search_failed": "搜尋意見回饋記錄失敗",
"semantic_search_input_label": "依主題搜尋意見回饋記錄",
"semantic_search_missing_text": "此意見回饋記錄沒有可顯示的文字。",
"semantic_search_no_directories": "此工作區尚未指派意見回饋記錄目錄。新增意見回饋來源以開始依語意搜尋意見回饋。",
"semantic_search_no_results": "找不到相符的意見回饋記錄。試試更廣泛的主題或不同的描述方式。",
"semantic_search_placeholder": "搜尋主題,例如:價格投訴",
"semantic_search_relevance": "相關度 {score}%",
"semantic_search_results_count": "{count, plural, other {找到 # 筆相符的意見回饋記錄}}",
"semantic_search_unavailable": "語意搜尋尚無法使用。請設定 Hub 嵌入功能以使用此預覽功能。",
"semantic_topics_example_confusing_onboarding": "令人困惑的入門流程",
"semantic_topics_example_pricing_complaints": "價格投訴",
"semantic_topics_example_slow_checkout": "結帳速度慢",
"semantic_topics_preview_description": "輸入主題或詞彙,以語意方式找出相關的意見回饋記錄。這是未來主題與子主題功能的早期預覽版本。",
"semantic_topics_preview_title": "依主題搜尋意見回饋",
"set_value": "設定值",
"setup_connection": "設定連線",
"showing_count_loaded": "顯示 {count} 筆記錄",
@@ -3768,6 +3782,7 @@
"submission_id": "提交ID",
"survey_has_no_questions": "此問卷沒有任何題目",
"topics_and_subtopics": "主題與子主題",
"try_searching_for": "試試搜尋",
"unify_feedback": "整合回饋",
"update_mapping_description": "更新此來源的對應設定。",
"updated_at": "更新時間",
+2 -4
View File
@@ -2,10 +2,10 @@ import "server-only";
import { NextRequest } from "next/server";
import { feedbackRecordsEnvoyAuthorizer } from "@/modules/hub/feedback-records-gateway";
import {
TEnvoyRequestAuthorizer,
authenticateEnvoyRequest,
buildStatusResponse,
parseEnvoyRequestMetadata,
TEnvoyRequestAuthorizer,
} from "./shared";
const envoyAuthorizers: TEnvoyRequestAuthorizer[] = [feedbackRecordsEnvoyAuthorizer];
@@ -16,9 +16,7 @@ export const authorizeEnvoyRequest = async (request: NextRequest): Promise<Respo
return requestMetadata.errorResponse;
}
const authorizer = envoyAuthorizers.find((candidate) =>
candidate.matches(requestMetadata.originalRequest)
);
const authorizer = envoyAuthorizers.find((candidate) => candidate.matches(requestMetadata.originalRequest));
if (!authorizer) {
return buildStatusResponse(400, "Unsupported Envoy auth route");
}
@@ -1,5 +1,5 @@
import { describe, expect, test } from "vitest";
import { getGatewayAuthServiceTokenPurpose, ZGatewayAuthService } from "./service";
import { ZGatewayAuthService, getGatewayAuthServiceTokenPurpose } from "./service";
describe("gateway auth service registry", () => {
test("returns the configured token purpose for feedbackRecords", () => {
+96 -10
View File
@@ -1,5 +1,15 @@
import { beforeEach, describe, expect, test, vi } from "vitest";
import { createCacheKey } from "@formbricks/cache";
import FormbricksHub from "@formbricks/hub";
import {
createFeedbackRecord,
createFeedbackRecordsBatch,
getFeedbackRecordTenant,
listFeedbackRecords,
retrieveFeedbackRecord,
semanticSearchFeedbackRecords,
updateFeedbackRecord,
} from "./service";
import type { FeedbackRecordCreateParams } from "./types";
vi.mock("@formbricks/logger", () => ({
@@ -31,14 +41,6 @@ vi.mock("@/lib/cache", () => ({
const { getHubClient } = await import("./hub-client");
const { cache } = await import("@/lib/cache");
const {
createFeedbackRecord,
createFeedbackRecordsBatch,
getFeedbackRecordTenant,
listFeedbackRecords,
retrieveFeedbackRecord,
updateFeedbackRecord,
} = await import("./service");
const sampleInput: FeedbackRecordCreateParams = {
field_id: "el-1",
@@ -49,6 +51,8 @@ const sampleInput: FeedbackRecordCreateParams = {
field_label: "Question?",
value_number: 5,
collected_at: "2026-02-24T10:00:00.000Z",
submission_id: "sub-1",
tenant_id: "tenant-1",
};
describe("hub service", () => {
@@ -117,7 +121,7 @@ describe("hub service", () => {
feedbackRecords: { list: vi.fn().mockResolvedValue(listResponse) },
} as any);
const result = await listFeedbackRecords({ tenant_id: "env-1", limit: 50, offset: 0 });
const result = await listFeedbackRecords({ tenant_id: "env-1", limit: 50 });
expect(result.error).toBeNull();
expect(result.data).toEqual(listResponse);
@@ -133,7 +137,6 @@ describe("hub service", () => {
expect(result.data).toBeNull();
expect(result.error).toMatchObject({ status: 0, message: "Network error" });
});
});
describe("retrieveFeedbackRecord", () => {
@@ -164,6 +167,89 @@ describe("hub service", () => {
});
});
describe("semanticSearchFeedbackRecords", () => {
test("returns error result when getHubClient returns null", async () => {
vi.mocked(getHubClient).mockReturnValue(null);
const result = await semanticSearchFeedbackRecords({
tenant_id: "env-1",
query: "slow checkout",
});
expect(result.data).toBeNull();
expect(result.error).toMatchObject({
status: 0,
message: "HUB_API_KEY is not set; Hub integration is disabled.",
});
});
test("returns data when client.search.performSemanticSearch succeeds", async () => {
const searchResponse = {
data: [
{
feedback_record_id: "018e1234-5678-9abc-def0-123456789abc",
score: 0.91,
field_label: "What can we improve?",
value_text: "Checkout feels slow.",
},
],
limit: 10,
};
const performSemanticSearch = vi.fn().mockResolvedValue(searchResponse);
vi.mocked(getHubClient).mockReturnValue({
feedbackRecords: { search: { performSemanticSearch } },
} as any);
const input = {
tenant_id: "env-1",
query: "slow checkout",
limit: 10,
min_score: 0.7,
};
const result = await semanticSearchFeedbackRecords(input);
expect(result.error).toBeNull();
expect(result.data).toEqual(searchResponse);
expect(performSemanticSearch).toHaveBeenCalledWith(input);
});
test("returns error with status when client.search.performSemanticSearch throws APIError", async () => {
const apiError = new (FormbricksHub.APIError as any)("Embeddings are not configured", 503);
vi.mocked(getHubClient).mockReturnValue({
feedbackRecords: {
search: { performSemanticSearch: vi.fn().mockRejectedValue(apiError) },
},
} as any);
const result = await semanticSearchFeedbackRecords({
tenant_id: "env-1",
query: "slow checkout",
});
expect(result.data).toBeNull();
expect(result.error).toMatchObject({
status: 503,
message: "Embeddings are not configured",
});
});
test("returns error result when call throws non-API error", async () => {
vi.mocked(getHubClient).mockReturnValue({
feedbackRecords: {
search: { performSemanticSearch: vi.fn().mockRejectedValue(new Error("Network error")) },
},
} as any);
const result = await semanticSearchFeedbackRecords({
tenant_id: "env-1",
query: "slow checkout",
});
expect(result.data).toBeNull();
expect(result.error).toMatchObject({ status: 0, message: "Network error" });
});
});
describe("updateFeedbackRecord", () => {
test("returns error when client is null", async () => {
vi.mocked(getHubClient).mockReturnValue(null);
+34 -3
View File
@@ -1,6 +1,6 @@
import "server-only";
import FormbricksHub from "@formbricks/hub";
import { createCacheKey } from "@formbricks/cache";
import FormbricksHub from "@formbricks/hub";
import { logger } from "@formbricks/logger";
import { cache } from "@/lib/cache";
import { getHubClient } from "./hub-client";
@@ -10,6 +10,8 @@ import type {
FeedbackRecordListParams,
FeedbackRecordListResponse,
FeedbackRecordUpdateParams,
SemanticSearchInput,
SemanticSearchResponse,
} from "./types";
type HubError = { status: number; message: string; detail: string };
@@ -25,9 +27,15 @@ const NO_CONFIG_ERROR = {
detail: "HUB_API_KEY is not set; Hub integration is disabled.",
} as const;
const getErrorMessage = (err: unknown): string => {
if (err instanceof Error) return err.message;
if (typeof err === "string") return err;
return "Unknown error";
};
const createResultFromError = (err: unknown): HubFeedbackRecordResult => {
const status = err instanceof FormbricksHub.APIError ? err.status : 0;
const message = err instanceof Error ? err.message : String(err);
const message = getErrorMessage(err);
return { data: null, error: { status, message, detail: message } };
};
@@ -95,6 +103,11 @@ export type ListFeedbackRecordsResult = {
error: HubError | null;
};
export type SemanticSearchFeedbackRecordsResult = {
data: SemanticSearchResponse | null;
error: HubError | null;
};
export type FeedbackRecordTenantResult = {
data: { tenantId: string } | null;
error: { status: number; message: string; detail: string } | null;
@@ -116,7 +129,25 @@ export const listFeedbackRecords = async (
} catch (err) {
logger.warn({ err }, "Hub: listFeedbackRecords failed");
const status = err instanceof FormbricksHub.APIError ? err.status : 0;
const message = err instanceof Error ? err.message : String(err);
const message = getErrorMessage(err);
return { data: null, error: { status, message, detail: message } };
}
};
export const semanticSearchFeedbackRecords = async (
input: SemanticSearchInput
): Promise<SemanticSearchFeedbackRecordsResult> => {
const client = getHubClient();
if (!client) {
return { data: null, error: { ...NO_CONFIG_ERROR } };
}
try {
const data = await client.feedbackRecords.search.performSemanticSearch(input);
return { data, error: null };
} catch (err) {
logger.warn({ err, tenantId: input.tenant_id }, "Hub: semanticSearchFeedbackRecords failed");
const status = err instanceof FormbricksHub.APIError ? err.status : 0;
const message = getErrorMessage(err);
return { data: null, error: { status, message, detail: message } };
}
};
+4
View File
@@ -5,3 +5,7 @@ export type FeedbackRecordData = FormbricksHub.FeedbackRecordData;
export type FeedbackRecordListParams = FormbricksHub.FeedbackRecordListParams;
export type FeedbackRecordListResponse = FormbricksHub.FeedbackRecordListResponse;
export type FeedbackRecordUpdateParams = FormbricksHub.FeedbackRecordUpdateParams;
export type SemanticSearchInput = FormbricksHub.FeedbackRecords.SearchPerformSemanticSearchParams;
export type SemanticSearchResponse = FormbricksHub.FeedbackRecords.SearchPerformSemanticSearchResponse;
export type SemanticSearchResultItem = FormbricksHub.FeedbackRecords.SearchPerformSemanticSearchResponse.Data;